本文已参与「新人创作礼」活动,一起开启掘金创作之路。
写在前面: 想必很多深度学习小白,跟我一样对深度学习的模型很是迷惑,前面我对手写MNIST数字识别和Cifar的10类物体识做了简单的介绍,今天给大家介绍Resnet,这个模块,为啥叫模块呢,其实它不是一个网络模型,理解为一个思想即可,我将用通俗易懂的语言把问题说明白,一起学习。
1、Resnet经典图片 (知道这玩意就好,重点在后面)
相信很多人,一提到Resne就是这样一幅图,但是有不明白旁边的弧线和中间的直线箭头又做了什么,有什么作用?当初我刚看到也是这样一脸的懵逼
继续往下看....
2、Resnet模块代码实现
上面的图中其实有很多的思想在里面,光看图很难理解里面具体做了什么,接下来我们用代码来说话
# 继承 nn.Module,这个模块里面给我提供了很多实用的函数
class ResBlk(nn.Module):
# __init__ 理解Wie构造函数
# ch_in 为输入通道
# ch_out 为输出通道
# stride 为步长
def __init__(self, ch_in, ch_out, stride=2):
super(ResBlk, self).__init__()
# 卷积 参数就很简单了
self.conv1 = nn.Conv2d(ch_in, ch_out, kernel_size=3, stride=stride, padding=1)
# 标准化
self.bn1 = nn.BatchNorm2d(ch_out)
# 卷积
self.conv2 = nn.Conv2d(ch_out, ch_out, kernel_size=3, stride=1, padding=1)
# 标准化
self.bn2 = nn.BatchNorm2d(ch_out)
# 创建 Sequential
self.extra = nn.Sequential()
# 如果输入和输出通道不一样就需要改变通道
if ch_out != ch_in:
self.extra = nn.Sequential(
nn.Conv2d(ch_in, ch_out, kernel_size=1, stride=stride),
nn.BatchNorm2d(ch_out)
)
# nn.Module里面提供的一个很实用的方法,必须要重写
def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
print(self.extra(x).shape)
print(out.shape)
out = self.extra(x) + out
return out
上面的代码我做个简单的介绍,想必很多问题还是没有讲清楚,接来下结合上面那张经典的图来分析
2.1、理论介绍
如果我们不看旁边的曲线,只看直线呢,计算的结果是我们在forward中的哪一个?其实就是self.extra(x),
- 为什么要加个extra包起来? 其实是为了保证输入的维度在经过计算后,特征维度保持不变,例如[b,64,w,h]>[b,64,w2,h2],w,h就是图片的宽高,这样一来才能与forward向加
- 怎么实现? 我们可以看到。当输入维度和输出维度不相等的时候(ch_out != ch_in:),那就需要通过卷积来改变,这里使用了一维卷积来实现,什么是一维卷积,这里不做过多介绍,查下资料。一维卷积不改变特征的W,H,只改变特征维度大小
2.2、举例子
很多理论说出来感觉也是很难理解,接下来我举例子来说明吧,我们假设有个数据为[2,3,32,32]
- 你这是啥数据? 这个就是假设的图片数据组,[batchSize,通道,长,宽],这样说能明白?
- 你有啥用? 这个数据如果从上面的直线部分计算下来,假设在 out = self.bn2(self.conv2(out))得到的结果是 [2,128,16,16],而def forward(self, x):里面的x是[2,64,16,16],这这两个矩阵是没办法相加的,因此只能吧前面这个128降到64,这就通过卷积来操作了,也就是
self.extra = nn.Sequential(
nn.Conv2d(ch_in, ch_out, kernel_size=1, stride=stride),
nn.BatchNorm2d(ch_out)
)
3、结果? 最后的相加为 [2,64,16,16]+[2,64,16,16] = [2,128,16,16]
4、看下真是打印日志
def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
print("弧线部分:",self.extra(x).shape)
print("直线计算部分:",out.shape)
out = self.extra(x) + out
print("相加后的结果",out.shape)
return out
2.3、简单总结一下
其实吧,这个残差模块就是把经过卷积计算的和没经过卷积计算的加在一起,然后在继续后面的步骤,总结的可能不是很到位,欢迎评论区指正。
3、Resnet18
3.1 简单介绍
接下来我们用这个模块完成一个Resnet18的中度大小的网络模型,我们首先来看下Resnet18的网络模型
我们简单看下18层那一列,后面的34层之类的,本文不会涉及,学会了18层,其他的当然也很简单了,首先分析下,3*3 是卷积核 64 、128 、256、 512 无非就是特征层数目咯,看起来也没啥难的,无非就是很多卷积层堆在一起使劲卷积。接下来根据代码来看这个图
3.2 代码实现
下来有解析
class Resnet18(nn.Module):
def __init__(self):
super(Resnet18, self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=3, stride=3, padding=1),
nn.BatchNorm2d(64),
)
# 第一层
self.blk1 = ResBlk(64, 128, stride=2)
# 第二层
self.blk2 = ResBlk(128, 256, stride=2)
# 第三层
self.blk3 = ResBlk(256, 512, stride=2)
# 第四层
self.blk4 = ResBlk(512, 512, stride=2)
self.outlayer = nn.Linear(512 * 1 * 1, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = self.blk1(x)
x = self.blk2(x)
x = self.blk3(x)
x = self.blk4(x)
x = F.adaptive_avg_pool2d(x, [1, 1])
x = x.view(x.size(0),-1)
x = self.outlayer(x)
return x
很多读者肯定要骂我,尼玛在哪里复制的代码,忽悠人?
- 哪里有18层?
不要急,大家看上面的图是不是有4个大的模块,这里用blk1~blk4来代替,每个blk里面有两个卷积,是不是跟上面的图对应起来了,而且特征维数是不是也跟上面对应起来
- adaptive_avg_pool2d是啥逼玩意? 这个是一个特殊的池化,比如数据为[2,512,4,4] ,通过这个池化,他能转化成[2,512,1,1]
上面这里面就相当于有4个残差模块
4、Cifar10数据集实战
我前面有写到一篇文章,可以点进去看下
# 交叉熵损失函数
criterion = nn.CrossEntropyLoss()
#创建网络模型
# model = MyNet()
# 这里我们更新为Resnet18模型
model = Resnet18()
# 创建优化器
optimizer = optim.SGD(model.parameters(),lr=1e-3)
我们替换下模型,使用我们的Resnet18模型来训练
5、结果
D:\anaconda3\python.exe G:/hyh/demo/myDemo/MyMNIST2.py
Train Epoch:0 [0/60000 (0%)] loss: 2.294964
Train Epoch:0 [3200/60000 (5%)] loss: 2.237801
Train Epoch:0 [6400/60000 (11%)] loss: 2.011762
Train Epoch:0 [9600/60000 (16%)] loss: 1.759162
Train Epoch:0 [12800/60000 (21%)] loss: 1.505532
Train Epoch:0 [16000/60000 (27%)] loss: 0.987569
Train Epoch:0 [19200/60000 (32%)] loss: 0.930402
Train Epoch:0 [22400/60000 (37%)] loss: 0.811298
Train Epoch:0 [25600/60000 (43%)] loss: 0.652959
Train Epoch:0 [28800/60000 (48%)] loss: 0.729086
Train Epoch:0 [32000/60000 (53%)] loss: 0.613935
Train Epoch:0 [35200/60000 (59%)] loss: 0.723560
Train Epoch:0 [38400/60000 (64%)] loss: 0.728303
Train Epoch:0 [41600/60000 (69%)] loss: 0.842518
Train Epoch:0 [44800/60000 (75%)] loss: 0.648385
Train Epoch:0 [48000/60000 (80%)] loss: 0.505248
Train Epoch:0 [51200/60000 (85%)] loss: 0.652041
Train Epoch:0 [54400/60000 (91%)] loss: 0.497621
Train Epoch:0 [57600/60000 (96%)] loss: 0.352911
Test set: Average loss: 0.006191, Accuracy: 8953/10000 (90%)
Train Epoch:1 [0/60000 (0%)] loss: 0.600680
Train Epoch:1 [3200/60000 (5%)] loss: 0.722403
Train Epoch:1 [6400/60000 (11%)] loss: 0.371574
Train Epoch:1 [9600/60000 (16%)] loss: 0.434216
Train Epoch:1 [12800/60000 (21%)] loss: 0.314467
Train Epoch:1 [16000/60000 (27%)] loss: 0.455340
Train Epoch:1 [19200/60000 (32%)] loss: 0.457373
Train Epoch:1 [22400/60000 (37%)] loss: 0.341132
Train Epoch:1 [25600/60000 (43%)] loss: 0.297870
Train Epoch:1 [28800/60000 (48%)] loss: 0.208670
Train Epoch:1 [32000/60000 (53%)] loss: 0.398009
Train Epoch:1 [35200/60000 (59%)] loss: 0.238587
Train Epoch:1 [38400/60000 (64%)] loss: 0.270295
Train Epoch:1 [41600/60000 (69%)] loss: 0.256037
Train Epoch:1 [44800/60000 (75%)] loss: 0.179486
Train Epoch:1 [48000/60000 (80%)] loss: 0.209409
Train Epoch:1 [51200/60000 (85%)] loss: 0.266206
Train Epoch:1 [54400/60000 (91%)] loss: 0.324935
Train Epoch:1 [57600/60000 (96%)] loss: 0.238938
Test set: Average loss: 0.004278, Accuracy: 9196/10000 (92%)
Train Epoch:2 [0/60000 (0%)] loss: 0.378060
Train Epoch:2 [3200/60000 (5%)] loss: 0.355457
Train Epoch:2 [6400/60000 (11%)] loss: 0.387908
Train Epoch:2 [9600/60000 (16%)] loss: 0.179793
Train Epoch:2 [12800/60000 (21%)] loss: 0.339362
Train Epoch:2 [16000/60000 (27%)] loss: 0.256857
Train Epoch:2 [19200/60000 (32%)] loss: 0.344574
Train Epoch:2 [22400/60000 (37%)] loss: 0.199149
Train Epoch:2 [25600/60000 (43%)] loss: 0.340128
Train Epoch:2 [28800/60000 (48%)] loss: 0.580189
Train Epoch:2 [32000/60000 (53%)] loss: 0.223620
Train Epoch:2 [35200/60000 (59%)] loss: 0.148303
Train Epoch:2 [38400/60000 (64%)] loss: 0.170245
Train Epoch:2 [41600/60000 (69%)] loss: 0.237442
Train Epoch:2 [44800/60000 (75%)] loss: 0.090744
Train Epoch:2 [48000/60000 (80%)] loss: 0.225519
Train Epoch:2 [51200/60000 (85%)] loss: 0.174443
Train Epoch:2 [54400/60000 (91%)] loss: 0.204935
Train Epoch:2 [57600/60000 (96%)] loss: 0.248697
Test set: Average loss: 0.003536, Accuracy: 9334/10000 (93%)
Train Epoch:3 [0/60000 (0%)] loss: 0.382281
Train Epoch:3 [3200/60000 (5%)] loss: 0.272914
Train Epoch:3 [6400/60000 (11%)] loss: 0.276294
Train Epoch:3 [9600/60000 (16%)] loss: 0.265971
Train Epoch:3 [12800/60000 (21%)] loss: 0.251176
Train Epoch:3 [16000/60000 (27%)] loss: 0.195396
Train Epoch:3 [19200/60000 (32%)] loss: 0.279023
Train Epoch:3 [22400/60000 (37%)] loss: 0.368021
Train Epoch:3 [25600/60000 (43%)] loss: 0.316035
Train Epoch:3 [28800/60000 (48%)] loss: 0.145247
Train Epoch:3 [32000/60000 (53%)] loss: 0.226747
Train Epoch:3 [35200/60000 (59%)] loss: 0.191336
Train Epoch:3 [38400/60000 (64%)] loss: 0.176705
Train Epoch:3 [41600/60000 (69%)] loss: 0.140882
Train Epoch:3 [44800/60000 (75%)] loss: 0.189857
Train Epoch:3 [48000/60000 (80%)] loss: 0.141690
Train Epoch:3 [51200/60000 (85%)] loss: 0.259225
Train Epoch:3 [54400/60000 (91%)] loss: 0.406788
Train Epoch:3 [57600/60000 (96%)] loss: 0.270289
Test set: Average loss: 0.003197, Accuracy: 9376/10000 (94%)
Train Epoch:4 [0/60000 (0%)] loss: 0.149766
Train Epoch:4 [3200/60000 (5%)] loss: 0.263228
Train Epoch:4 [6400/60000 (11%)] loss: 0.218906
Train Epoch:4 [9600/60000 (16%)] loss: 0.152136
Train Epoch:4 [12800/60000 (21%)] loss: 0.260611
Train Epoch:4 [16000/60000 (27%)] loss: 0.213420
Train Epoch:4 [19200/60000 (32%)] loss: 0.198862
Train Epoch:4 [22400/60000 (37%)] loss: 0.288100
Train Epoch:4 [25600/60000 (43%)] loss: 0.074646
Train Epoch:4 [28800/60000 (48%)] loss: 0.105436
Train Epoch:4 [32000/60000 (53%)] loss: 0.189825
Train Epoch:4 [35200/60000 (59%)] loss: 0.160365
Train Epoch:4 [38400/60000 (64%)] loss: 0.126713
Train Epoch:4 [41600/60000 (69%)] loss: 0.106857
Train Epoch:4 [44800/60000 (75%)] loss: 0.202397
Train Epoch:4 [48000/60000 (80%)] loss: 0.159816
Train Epoch:4 [51200/60000 (85%)] loss: 0.117604
Train Epoch:4 [54400/60000 (91%)] loss: 0.207035
Train Epoch:4 [57600/60000 (96%)] loss: 0.235623
Test set: Average loss: 0.002806, Accuracy: 9489/10000 (95%)
Train Epoch:5 [0/60000 (0%)] loss: 0.374420
Train Epoch:5 [3200/60000 (5%)] loss: 0.406806
Train Epoch:5 [6400/60000 (11%)] loss: 0.178646
Train Epoch:5 [9600/60000 (16%)] loss: 0.201204
Train Epoch:5 [12800/60000 (21%)] loss: 0.280689
Train Epoch:5 [16000/60000 (27%)] loss: 0.141928
Train Epoch:5 [19200/60000 (32%)] loss: 0.163563
Train Epoch:5 [22400/60000 (37%)] loss: 0.093672
Train Epoch:5 [25600/60000 (43%)] loss: 0.201995
Train Epoch:5 [28800/60000 (48%)] loss: 0.210607
Train Epoch:5 [32000/60000 (53%)] loss: 0.131123
Train Epoch:5 [35200/60000 (59%)] loss: 0.102232
Train Epoch:5 [38400/60000 (64%)] loss: 0.110739
Train Epoch:5 [41600/60000 (69%)] loss: 0.155341
Train Epoch:5 [44800/60000 (75%)] loss: 0.172590
Train Epoch:5 [48000/60000 (80%)] loss: 0.092284
Train Epoch:5 [51200/60000 (85%)] loss: 0.135048
Train Epoch:5 [54400/60000 (91%)] loss: 0.065666
Train Epoch:5 [57600/60000 (96%)] loss: 0.072437
Test set: Average loss: 0.002498, Accuracy: 9537/10000 (95%)
Train Epoch:6 [0/60000 (0%)] loss: 0.098339
Train Epoch:6 [3200/60000 (5%)] loss: 0.176009
Train Epoch:6 [6400/60000 (11%)] loss: 0.123667
Train Epoch:6 [9600/60000 (16%)] loss: 0.129188
Train Epoch:6 [12800/60000 (21%)] loss: 0.153258
Train Epoch:6 [16000/60000 (27%)] loss: 0.106575
Train Epoch:6 [19200/60000 (32%)] loss: 0.120937
Train Epoch:6 [22400/60000 (37%)] loss: 0.122063
Train Epoch:6 [25600/60000 (43%)] loss: 0.098095
Train Epoch:6 [28800/60000 (48%)] loss: 0.107750
Train Epoch:6 [32000/60000 (53%)] loss: 0.065200
Train Epoch:6 [35200/60000 (59%)] loss: 0.141142
Train Epoch:6 [38400/60000 (64%)] loss: 0.041179
Train Epoch:6 [41600/60000 (69%)] loss: 0.071994
Train Epoch:6 [44800/60000 (75%)] loss: 0.197366
Train Epoch:6 [48000/60000 (80%)] loss: 0.223126
Train Epoch:6 [51200/60000 (85%)] loss: 0.177952
Train Epoch:6 [54400/60000 (91%)] loss: 0.313582
Train Epoch:6 [57600/60000 (96%)] loss: 0.075954
Test set: Average loss: 0.00229, Accuracy: 9560/10000 (96%)
Train Epoch:7 [0/60000 (0%)] loss: 0.125720
Train Epoch:7 [3200/60000 (5%)] loss: 0.054778
Train Epoch:7 [6400/60000 (11%)] loss: 0.194493
Train Epoch:7 [9600/60000 (16%)] loss: 0.117354
Train Epoch:7 [12800/60000 (21%)] loss: 0.062103
Train Epoch:7 [16000/60000 (27%)] loss: 0.140656
Train Epoch:7 [19200/60000 (32%)] loss: 0.041279
Train Epoch:7 [22400/60000 (37%)] loss: 0.268337
Train Epoch:7 [25600/60000 (43%)] loss: 0.173277
Train Epoch:7 [28800/60000 (48%)] loss: 0.152429
Train Epoch:7 [32000/60000 (53%)] loss: 0.137271
Train Epoch:7 [35200/60000 (59%)] loss: 0.237030
Train Epoch:7 [38400/60000 (64%)] loss: 0.155353
Train Epoch:7 [41600/60000 (69%)] loss: 0.240660
Train Epoch:7 [44800/60000 (75%)] loss: 0.313683
Train Epoch:7 [48000/60000 (80%)] loss: 0.139403
Train Epoch:7 [51200/60000 (85%)] loss: 0.085569
Train Epoch:7 [54400/60000 (91%)] loss: 0.165206
Train Epoch:7 [57600/60000 (96%)] loss: 0.147184
Test set: Average loss: 0.002176, Accuracy: 9596/10000 (96%)
Train Epoch:8 [0/60000 (0%)] loss: 0.075009
Train Epoch:8 [3200/60000 (5%)] loss: 0.078678
Train Epoch:8 [6400/60000 (11%)] loss: 0.151321
Train Epoch:8 [9600/60000 (16%)] loss: 0.096767
Train Epoch:8 [12800/60000 (21%)] loss: 0.224672
Train Epoch:8 [16000/60000 (27%)] loss: 0.064915
Train Epoch:8 [19200/60000 (32%)] loss: 0.089332
Train Epoch:8 [22400/60000 (37%)] loss: 0.099901
Train Epoch:8 [25600/60000 (43%)] loss: 0.093629
Train Epoch:8 [28800/60000 (48%)] loss: 0.149652
Train Epoch:8 [32000/60000 (53%)] loss: 0.170166
Train Epoch:8 [35200/60000 (59%)] loss: 0.074138
Train Epoch:8 [38400/60000 (64%)] loss: 0.105759
Train Epoch:8 [41600/60000 (69%)] loss: 0.173976
Train Epoch:8 [44800/60000 (75%)] loss: 0.086330
Train Epoch:8 [48000/60000 (80%)] loss: 0.090361
Train Epoch:8 [51200/60000 (85%)] loss: 0.232216
Train Epoch:8 [54400/60000 (91%)] loss: 0.122482
Train Epoch:8 [57600/60000 (96%)] loss: 0.111162
Test set: Average loss: 0.001921, Accuracy: 9633/10000 (96%)
Train Epoch:9 [0/60000 (0%)] loss: 0.096367
Train Epoch:9 [3200/60000 (5%)] loss: 0.151983
Train Epoch:9 [6400/60000 (11%)] loss: 0.044134
Train Epoch:9 [9600/60000 (16%)] loss: 0.139661
Train Epoch:9 [12800/60000 (21%)] loss: 0.134544
Train Epoch:9 [16000/60000 (27%)] loss: 0.066025
Train Epoch:9 [19200/60000 (32%)] loss: 0.279654
Train Epoch:9 [22400/60000 (37%)] loss: 0.176228
Train Epoch:9 [25600/60000 (43%)] loss: 0.202844
Train Epoch:9 [28800/60000 (48%)] loss: 0.130943
Train Epoch:9 [32000/60000 (53%)] loss: 0.095190
Train Epoch:9 [35200/60000 (59%)] loss: 0.148061
Train Epoch:9 [38400/60000 (64%)] loss: 0.248789
Train Epoch:9 [41600/60000 (69%)] loss: 0.190105
Train Epoch:9 [44800/60000 (75%)] loss: 0.040033
Train Epoch:9 [48000/60000 (80%)] loss: 0.124854
Train Epoch:9 [51200/60000 (85%)] loss: 0.107912
Train Epoch:9 [54400/60000 (91%)] loss: 0.219310
Train Epoch:9 [57600/60000 (96%)] loss: 0.074278
Test set: Average loss: 0.001824, Accuracy: 9645/10000 (96%)
Process finished with exit code 0