梯度消失的问题
梯度消失的問題
1.1什么是梯度消失
有人在CIFAR10這個數據集上面做了一個實驗,是不是卷積層越多越好,結果發現并不是如此。在層數增加之后表現并沒有有效的變好。這其實就是觸發了梯度消失的問題。
因為每一層計算的梯度最終都會乘算到一起,這個數值在最后的時候就會越來越小,乘的層數多了,自然而然就會變得越來越小。底層的網絡的梯度會變得特別小,很難得到有效的訓練,所以整體的準確度不高。
1.2這個問題如何解決—深度殘差網絡
我們可以使用如下的情況來進行解決,將一個沒有經過層處理的x直接傳下去。
這樣到底能達到一個怎樣的結果呢?其實得到就是下面這個結果:
每次計算梯度的時候,因為我們加了一個x那么永遠都有一個+1的存在,所以這樣我們永遠也不會出現梯度乘起來為0的情況了。
2.1實現
這里注意一點,想要兩個可以加和,那么必須存在這樣的一個情況就是,傳遞下來的x要和經過計算的y的(branch,channel,height,weight)是完全相同的才可以,所以我們一定要注意不能發生變形。
import numpy import torch from torchvision import functional as F class ResidualBlocK(torch.nn.Module):def __init__(self,input_channel):super(ResidualBlocK,self).__init__()#這里我們注意我們之前使用的是矩陣合并,合并的時候是除了合并的那一個維度之外所有維度都需要相等。#這里我們是使用矩陣加和,所以兩者的所有維度都必須是相等的,所以輸入和輸出的通道必須是相同的。self.conv1=torch.nn.Conv2d(input_channel,input_channel,kernel_size=3,padding=1)self.conv2=torch.nn.Conv2d(input_channel,input_channel,kernel_size=3,padding=1)self.input_channel=input_channeldef forward(x):y=F.relu(conv1(x))y=conv2(y)return F.relu(x)#這里我們注意一個小的細節,relu的位置我們要帶著x一起relu才可以。class Net(torch.nn.Module):def __init__(self,channel):super(Net,self).__init__()self.conv1=torch.nn.Conv2d(channel,16,kernel_size=5)self.conv2=torch.nn.Conv2d(16,32,kernel_size=5)self.resi1=ResidualBlocK(16)self.resi2=ResidualBlocK(32)self.maxpool=torch.nn.MaxPool2d(2)self.fullconnect=torch.nn.Linear(256,10)#同樣這個256也是算出來的,但是我們為了穩妥起見,還是自己構造一個數據集來新進行測試一下。逐步測試,每一次逐步的漸增。#最好是使用增量式開發來進行開發。def forward(x):input_num=x.size(0)x=self.maxpool(F.relu(self.conv1(x)))x=self.resi1(x)x=self.maxpool(F.relu(self.conv2(x)))x=self.resi2(x)x=x.view(input_num,-1)x=self.fullconnect(x)2.2更多的工作
大家可以參考:
論文:Identity Mappings in Deep Residual Networks
中文翻譯:https://blog.csdn.net/cdknight_happy/article/details/78994071
總結
- 上一篇: 卷积神经网络补充—GoogleNet
- 下一篇: anaconda不同虚拟环境下使用jup