Pytorch Document学习笔记
Pytorch Document學習筆記
- Pytorch Document學習筆記
- 1. 網絡層
- 1.1 torch.nn.Conv2d
- 1.2 torch.nn.MaxPool2d / torch.nn.MaxUnpool2d
- 1.3 torch.nn.ReLU
- 1.4 torch.nn.BatchNorm2d
- 2. 優化器
- 2.1 torch.optim.SGD
- 2.2 torch.optim.Adagrad
- 2.3 torch.optim.RMSprop
- 2.4 torch.optim.Adam
- 3. 損失函數
- 3.1 torch.nn.L1Loss
- 3.2 torch.nn.MSELoss
- 3.3 torch.nn.CrossEntropyLoss
- 4. 初始化
- 4.1 torch.nn.init.uniform
- 4.2 torch.nn.init.normal
- 4.3 torch.nn.init.constant
- 4.4 torch.nn.init.xavier_uniform / torch.nn.init.xavier_normal
- 4.5 torch.nn.init.kaiming_uniform / torch.nn.init.kaiming_normal
Pytorch Document學習筆記
最近花了些時間補充了Pytorch相關的知識,正好借著Pytorch的官方文檔補充下深度學習的基礎知識,主要是看看Pytorch中封裝有哪些庫函數,搞清楚這些庫函數后面具體使用的算法,由于面比較廣,可能深度不是很夠
1. 網絡層
1.1 torch.nn.Conv2d
卷積層的目的主要是提取特征,in_channels和out_channels分別控制著輸入通道和輸出通道的數量,kerner_size, stride和padding組合控制這卷積后輸出特征層的大小,另外:
dilation為空洞卷積的間隔,在圖像分割領域,在dilation提出來之前,主要通過pooling和up sampling來提高單個像素的感受野,dilation的主要作用就是在不用pooling的情況下也能夠增大像素的感受野,以達到更好的分割效果,如下圖所示:
groups為分組卷積,所謂分組卷積就是將32通道的卷積任務分為兩個16通道卷積進行,主要作用是減少參數量,因為減少了參數量,對于網絡來說相當于進行了正則化。
bias為卷積偏置,偏置的存在主要是為兩個更好地擬合數據
1.2 torch.nn.MaxPool2d / torch.nn.MaxUnpool2d
池化層的作用主要是去掉特征中的冗余信息,相當于下采樣操作,當return_indices設置為True時,函數會輸出最大值的序號,而最大反池化則等同于上采樣,輸入為最大池化操作的輸出以及序號,將非最大值部分設置為0
pytorch中出來最大池化操作,池化操作還包括AvgPool2d, FractionalMaxPool2d, LPPool2d, AdaptiveMaxPool2d, AdaptiveAvgPool2d
1.3 torch.nn.ReLU
非線性激活層存在的目的是為了讓網絡對非線性的數學模型具有擬合效果,與其類似的激活函數還包括ELU, PReLU, LeakyReLU, Threshold, Sigmoid, Tanh等等等等
1.4 torch.nn.BatchNorm2d
批歸一化層相對來說會復雜一些,起主要目的是改變小批量數據的分布(均值和方差),批歸一化的位置如果放在激活層之前則是對節點的輸出進行歸一化,如果放在激活后則是對下一個節點的輸入進行歸一化,都是可以的,批歸一化層的公式如下y=x?mean?[x]Var?[x]+??gamma?+beta?y=\frac{x-\operatorname{mean}[x]}{\sqrt{\operatorname{Var}[x]}+\epsilon} * \text { gamma }+\text { beta } y=Var[x]?+?x?mean[x]???gamma?+?beta?其中meanmeanmean和varvarvar分別為批數據的均值和方差,gammagammagamma和betabetabeta為可以學習的參數,在訓練過程中通過反向傳播更新該參數,而在預測過程中則將該參數固定,Batch Normalization(BN)超詳細解析對批歸一化層進行了詳細的解釋,參考其總結一下加入批歸一層帶來的好處:
2. 優化器
2.1 torch.optim.SGD
隨機梯度下降法的定義是隨機選取批量數據中單個樣本梯度進行梯度下降,其優勢是算法收斂速度快,但是精度會有所損失,在實際應用為了權衡速度和精度,通常我們是批量樣本中隨機選取小批量樣本進行梯度計算,例如我們隨機隨機了mmm個樣本{x(1),…,x(m)}\left\{x^{(1)}, \ldots, x^{(m)}\right\}{x(1),…,x(m)},對應的目標為y(i)y^{(i)}y(i),進行梯度估計有g←1m?w∑iL(f(x(i);w),y(i))g \leftarrow \frac{1}{m} \nabla_{w} \sum_{i} L\left(f\left(x^{(i)} ;w \right), y^{(i)}\right)g←m1??w?i∑?L(f(x(i);w),y(i))進行權重更新有w←w+gw \leftarrow w+gw←w+g隨機梯度下降法中有如下幾個參數:
動量因子momentum,在上面例子的基礎上,多了一步速度更新v←αv??gv \leftarrow \alpha v-\epsilon gv←αv??g然后在進行權重更新w←w+vw \leftarrow w+vw←w+v這樣改進之后,當前時刻的梯度與歷史時刻梯度相似時,這種趨勢在當前時刻會加強,如果不同,則當前時刻的梯度方向減弱,由此動量因子可以讓那些因為學習率太大而來回擺動的參數梯度前后抵消,從而阻止發散。
權重衰減系數weight_decay,該系數和L2正則化有關,所謂L2正則化就是在代價函數后面再加上一個正則化項C=C0+λ2n∑ww2C=C_{0}+\frac{\lambda}{2 n} \sum_{w} w^{2} C=C0?+2nλ?w∑?w2L2正則化的作用主要是的權重www變小,防止過擬合。我們對加入L2正則化后的代價函數進行推導有:?C?w=?C0?w+λnw\frac{\partial C}{\partial w}=\frac{\partial C_{0}}{\partial w}+\frac{\lambda}{n} w ?w?C?=?w?C0??+nλ?w?C?b=?C0?b\frac{\partial C}{\partial b}=\frac{\partial C_{0}}{\partial b}?b?C?=?b?C0??我們發現,L2正則化后對偏置bbb沒有影響,但是對于權重www的更新有影響:KaTeX parse error: Undefined control sequence: \alphaC at position 56: …frac{\partial \?a?l?p?h?a?C?_{0}}{\partial …在不適用L2正則化時,求導結果中的www之前的系數是1,而1?ηλn1-\frac{\eta \lambda}{n}1?nηλ?小于1,其效果是減小www,這就是權重衰減系數的由來,在he實際應用中,學習率衰減通常有線性衰減(間隔固定epoch學習率減半)和指數衰減(間隔固定epoch學習率乘以0.9998)兩種。
Nesterov加速梯度是在動量因子的基礎上可以進一步加快收斂速度,使得收斂曲線更加穩定,經典動量的公式如下:vt=αvt?1??g(wt?1)v_{t}=\alpha v_{t-1}-\epsilon g\left(w_{t-1}\right) vt?=αvt?1???g(wt?1?)wt=wt?1+vtw_{t}=w_{t-1}+v_{t} wt?=wt?1?+vt?
而Nesterov加速梯度后的公式如下:wt?1ahead=wt?1+μvt?1w_{t-1}^{a h e a d}=w_{t-1}+\mu v_{t-1} wt?1ahead?=wt?1?+μvt?1?vt=αvt?1??g(wt?1ahead)v_{t}=\alpha v_{t-1}-\epsilon g\left(w_{t-1}^{a h e a d}\right) vt?=αvt?1???g(wt?1ahead?)wt=wt?1+vtw_{t}=w_{t-1}+v_{t} wt?=wt?1?+vt?即Nesterov加速梯度中計算的梯度是在當前權重加上累計速度后的梯度
2.2 torch.optim.Adagrad
Adagrad算法相對SGD算法能夠更加有效地收斂,能夠在數據分布系數的場景,更好利用系數梯度的信息,我們計算梯度有:g←1m?w∑iL(f(x(i);w),y(i))g \leftarrow \frac{1}{m} \nabla_{\boldsymbol{w}} \sum_{i} L\left(f\left(\boldsymbol{x}^{(i)} ; \boldsymbol{w}\right), \boldsymbol{y}^{(i)}\right) g←m1??w?i∑?L(f(x(i);w),y(i))累積平方梯度:r←r+g⊙gr \leftarrow r+g \odot g r←r+g⊙g計算更新Δθ←??δ+r⊙g\Delta \boldsymbol{\theta} \leftarrow-\frac{\epsilon}{\delta+\sqrt{r}} \odot g Δθ←?δ+r???⊙g應用更新θ←θ+Δθ\theta \leftarrow \theta+\Delta \theta θ←θ+Δθ通常Adagrad算法一開始是激勵收斂的,后面慢慢就變成懲罰收斂,這也就導致了會出現學習綠收縮到太小而無法進行有效收斂的情況
2.3 torch.optim.RMSprop
RMSprop算法與Adagrad算法唯一的不同就在于累積平方梯度的方法不同,其累積平方梯度的方式為:r←ρr+(1?ρ)g⊙gr \leftarrow \rho r+(1-\rho) g \odot g r←ρr+(1?ρ)g⊙g其實就是添加了一個衰減系數來控制歷史信息獲取多少,在該函數中同樣可以配置動量因子momentum以及權重衰減系數weight_decay
2.4 torch.optim.Adam
Adam算法全稱為adaptive moment estimation,Adam算法其實就是momentum和RMSporp的結合,其通過計算梯度的一階矩估計和二階矩估計而為不同的參數設計獨立的自適應學習率,具體算法如下,同樣先估計梯度:g←1m?w∑iL(f(x(i);w),y(i))\boldsymbol{g} \leftarrow \frac{1}{m} \nabla_{\boldsymbol{w}} \sum_{i} L\left(f\left(\boldsymbol{x}^{(i)} ; \boldsymbol{w}\right), \boldsymbol{y}^{(i)}\right) g←m1??w?i∑?L(f(x(i);w),y(i))然后是更新一階矩估計,也就是momenturm項:s←ρ1s+(1?ρ1)gs \leftarrow \rho_{1} s+\left(1-\rho_{1}\right) g s←ρ1?s+(1?ρ1?)g更新二階矩估計,相當于二階矩估計:r←ρ2r+(1?ρ2)g⊙gr \leftarrow \rho_{2} r+\left(1-\rho_{2}\right) g \odot g r←ρ2?r+(1?ρ2?)g⊙g然后分別修正一階矩偏差和二階矩偏差s^←s1?ρ1t\hat{\boldsymbol{s}} \leftarrow \frac{\boldsymbol{s}}{1-\rho_{1}^{t}} s^←1?ρ1t?s?r^←r1?ρ2t\hat{\boldsymbol{r}} \leftarrow \frac{\boldsymbol{r}}{1-\rho_{2}^{t}} r^←1?ρ2t?r?然后逐元素計算更新Δθ=??s^r^+δ\Delta \theta=-\epsilon \frac{\hat{\boldsymbol{s}}}{\sqrt{\hat{\boldsymbol{r}}}+\delta} Δθ=??r^?+δs^?最后應用更新:θ←θ+Δθ\theta \leftarrow \theta+\Delta \theta θ←θ+ΔθAdam算法的優勢是適合解決大規模數據的參數優化問題,同時適用于非穩態目標
pytorch中還有的優化方法有Adadelta,Adamax,ASGD,LBFGS以及RProp
3. 損失函數
3.1 torch.nn.L1Loss
計算輸入xxx和目標yyy之間的絕對值的平均值loss?(x,y)=1/n∑∣xi?yi∣\operatorname{loss}(x, y)=1 / n \sum \mid x_{i}-y_{i}| loss(x,y)=1/n∑∣xi??yi?∣
3.2 torch.nn.MSELoss
計算輸入xxx和目標yyy之間的均方誤差loss?(x,y)=1/n∑(xi?yi)2\operatorname{loss}(x, y)=1 / n \sum\left(x_{i}-y_{i}\right)^{2} loss(x,y)=1/n∑(xi??yi?)2
3.3 torch.nn.CrossEntropyLoss
用于多分類器的交叉熵損失loss?(x,class?)=?log?exp?(x[class?])∑jexp?(x[j]))=?x[class?]+log?(∑jexp?(x[j]))\operatorname{loss}(x, \text { class })=-\log \frac{\exp (x[\text { class }])}{\left.\sum_{j} \exp (x[j])\right)} \quad=-x[\text { class }]+\log \left(\sum_{j} \exp (x[j])\right) loss(x,?class?)=?log∑j?exp(x[j]))exp(x[?class?])?=?x[?class?]+log(j∑?exp(x[j]))
pytorch中還有的損失函數有NLLLoss,KLDivLoss,BCELoss,MarginRankingLoss,HingeEmbeddingLoss,MultiLabelMarginLoss,SmoothL1Loss,SoftMarginLoss,MultiLabelSoftMarginLOss,CosineEmbeddingLoss,MultiMarginLoss
4. 初始化
4.1 torch.nn.init.uniform
從給定的上下界的均勻分布中生成值,然后填充入張量或者變量進行初始化
4.2 torch.nn.init.normal
從給定的均值和方差的正態分布中生成值,然后填充入張量或者變量進行初始化
4.3 torch.nn.init.constant
將給定的常量填充入張量或者變量進行初始化
4.4 torch.nn.init.xavier_uniform / torch.nn.init.xavier_normal
為了使得網絡中信息更好的流動,每一層輸出的方差應該盡量相同,這就是xavier算法的核心思想,對于一層卷積有
y=w1x1+?+wnixni+by=w_{1} x_{1}+\cdots+w_{n_{i}} x_{n_{i}}+b y=w1?x1?+?+wni??xni??+b其中nin_ini?表示輸入個數,根據概率統計知識我們有如下方差公式:Var?(wixi)=E[wi]2Var?(xi)+E[xi]2Var?(wi)+Var?(wi)Var?(xi)\operatorname{Var}\left(w_{i} x_{i}\right)=E\left[w_{i}\right]^{2} \operatorname{Var}\left(x_{i}\right)+E\left[x_{i}\right]^{2} \operatorname{Var}\left(w_{i}\right)+\operatorname{Var}\left(w_{i}\right) \operatorname{Var}\left(x_{i}\right) Var(wi?xi?)=E[wi?]2Var(xi?)+E[xi?]2Var(wi?)+Var(wi?)Var(xi?)特別地,當我們假設輸入和權重都是0均值時有Var?(wixi)=Var?(wi)Var?(xi)\operatorname{Var}\left(w_{i} x_{i}\right)=\operatorname{Var}\left(w_{i}\right) \operatorname{Var}\left(x_{i}\right) Var(wi?xi?)=Var(wi?)Var(xi?)進一步假設輸入的xxx和www都是獨立同分布,則有:Var?(y)=niVar?(wi)Var?(xi)\operatorname{Var}(y)=n_{i} \operatorname{Var}\left(w_{i}\right) \operatorname{Var}\left(x_{i}\right) Var(y)=ni?Var(wi?)Var(xi?)于是,為了保證輸入與輸出方差一致,則應該有:Var?(wi)=1ni\operatorname{Var}\left(w_{i}\right)=\frac{1}{n_{i}} Var(wi?)=ni?1?對于一個多層網絡,某一層的方差可以用累計的形式表達:Var?[zi]=Var?[x]∏i′=0i?1ni′Var?[Wi′]\operatorname{Var}\left[z^{i}\right]=\operatorname{Var}[x] \prod_{i^{\prime}=0}^{i-1} n_{i^{\prime}} \operatorname{Var}\left[W^{i^{\prime}}\right] Var[zi]=Var[x]i′=0∏i?1?ni′?Var[Wi′]反向傳播時具有類似的形式:Var?[?Cost??si]=Var?[?Cost??sd]∏i′=idni′+1Var?[Wi′]\operatorname{Var}\left[\frac{\partial \text { Cost }}{\partial s^{i}}\right]=\operatorname{Var}\left[\frac{\partial \text { Cost }}{\partial s^ze8trgl8bvbq}\right] \prod_{i^{\prime}=i}^ze8trgl8bvbq n_{i^{\prime}+1} \operatorname{Var}\left[W^{i^{\prime}}\right] Var[?si??Cost??]=Var[?sd??Cost??]i′=i∏d?ni′+1?Var[Wi′]則為了保證前向傳播和反向傳播時每一層的方差一致,則應該滿足?i,niVar?[Wi]=1\forall i, \quad n_{i} \operatorname{Var}\left[W^{i}\right]=1 ?i,ni?Var[Wi]=1?i,ni+1Var?[Wi]=1\forall i, \quad n_{i+1} \operatorname{Var}\left[W^{i}\right]=1 ?i,ni+1?Var[Wi]=1但是實際中輸入和輸出的個數通常不相等,因此最終我們的權重方差應該滿足:?i,Var?[Wi]=2ni+ni+1\forall i, \quad \operatorname{Var}\left[W^{i}\right]=\frac{2}{n_{i}+n_{i+1}} ?i,Var[Wi]=ni?+ni+1?2?對于[a, b]區間中的均勻分布的方差為:Var?=(b?a)212\operatorname{Var}=\frac{(b-a)^{2}}{12} Var=12(b?a)2?那么,滿足xavier算法的均勻分布是W~U[?6nj+nj+1,6nj+nj+1]W \sim U\left[-\frac{\sqrt{6}}{\sqrt{n_{j}+n_{j+1}}}, \frac{\sqrt{6}}{\sqrt{n_{j}+n_{j+1}}}\right] W~U[?nj?+nj+1??6??,nj?+nj+1??6??]同理我們可知滿足xavier算法的高斯分布是W~N[0,2nj+nj+1]W\sim N\left[0, \frac{\sqrt{2}}{\sqrt{n_{j}+n_{j+1}}}\right]W~N[0,nj?+nj+1??2??]
4.5 torch.nn.init.kaiming_uniform / torch.nn.init.kaiming_normal
上述xavier初始化的問題主要在只適用于線性激活函數,但實際上,對于深層神經網絡來說,線性激活函數沒有價值。kaiming算法就是針對是非線性的Relu激活函數設計的一種初始化方法。對于均值為0的輸出來說,Relu激活函數會將小于零的部分都置為0,這樣上述xavier初始化中均值為0的假設就不成立了,具體的推到可以參考論文Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
pytorch中還有的初始化方式有eye,dirac,sparse
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Pytorch Document学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双目视觉——SGM中的动态规划
- 下一篇: Eigen有哪些需要注意的操作