本文主要介绍Python深度学习中神经网络残差块的例子,有需要的朋友可以借鉴。希望能有所帮助,祝你进步很大。
目录
ResNet模型培训模型
NET遵循VGG完整的Katex解析错误:未定义的控制序列:\ time at position 2: 3 \ time 3卷积层设计。在残差块中,有两个卷积层的katex解析错误:未定义的控制序列:\ time at position 2: 3 \ time 3具有相同数量的输出通道。每个卷积层后面都有一个批处理归一化层和ReLU激活函数。然后我们通过跨层数据路径跳过这两个卷积运算,直接在最终的ReLU激活函数之前添加输入。这种设计要求两个卷积层的输出与输入具有相同的形状,因此它们可以相加。如果要改变通道数,就需要额外引入1 1 1\times1 11卷积层,这样就可以把输入变换成需要的形状,然后叠加。
残差块实现如下:
进口火炬
从火炬进口nn
从torch.nn导入功能为F
从d2l进口火炬为d2l
类残差(nn。模块):
def __init__(self,input_channels,num_channels,use_1x1conv=False,strides=1):
超级()。__init__()
self.conv1=nn。Conv2d(输入通道,通道数,内核大小=3,填充=1,步幅=步幅)
self.conv2=nn。Conv2d(通道数,通道数,内核大小=3,填充=1)
如果使用_1x1conv:
self.conv3=nn。Conv2d(输入通道数,通道数,内核大小=1,步幅=步幅)
否则:
self.conv3=无
self.bn1=nn。BatchNorm2d(通道数)
self.bn2=nn。BatchNorm2d(通道数)
self.relu=nn。ReLU(原地=真)
向前定义(自身,X):
Y=F.relu(self.bn1(self.conv1(X)))
Y=self.bn2(self.conv2(Y))
if self.conv3:
X=self.conv3(X)
Y=X
return F.relu(Y)
如下图所示,此外,代码生成两种类型的网络:一种是在使用_ 1x1conv=false和应用ReLU非线性函数之前,将输入加到输出上。另一种是在use _ 1xconv=true时,增加1 1卷积调整的通道和分辨率。
让我们看看输入和输出形状相同的情况。
blk=残差(3,3)
X=torch.rand(4,3,6,6)
Y=blk(X)
y形
火炬。大小([4,3,6,6])
我们还可以增加输出通道的数量,同时将输出高度和宽度减半。
blk=Residual(3,6,use_1x1conv=True,跨距=2)
blk(X)。形状
火炬。大小([4,6,3,3])
ResNet模型
ResNet的前两层是:64路输出2步的7 7卷积层后,连接2步的3 3最大收敛层。不同的是,在ResNet的每一个卷积层之后都增加了一个批量归一化层。
b1=nn。顺序(nn。Conv2d(1,64,kernel_size=7,stride=2,padding=3),
nn。批次Norm2d(64),nn。ReLU(),
nn。MaxPool2d(kernel_size=3,stride=2,padding=1))
NET使用四个由残差块组成的模块,每个模块使用几个输出通道数相同的残差块。第一模块的通道数与输入通道数相同。由于之前已经使用了跨距为2的最大会聚层,所以不需要减小高度和宽度。之后,每个模块在第一个剩余块中将前一个模块的通道数增加一倍,高度和宽度减半。
让我们实现这个模块。请注意,我们对第一个模块进行了特殊处理。
def resnet_block(input_channels,num_channels,num _ residuals,first_block=False):
blk=[]
对于范围内的I(剩余数量):
如果i==0且不是first_block:
blk . append(Residual(input _ channels,num_channels,use_1x1conv=True,strides=2))
否则:
blk.append(Residual(数量通道,数量通道))
返回块
然后将ResNet中的所有残差块相加,其中每个模块使用2个残差块。
b2=nn。Sequential(*resnet_block(64,64,2,first_block=True))
b3=nn。顺序(*resnet_block(64,128,2))
b4=nn。顺序(*resnet_block(128,256,2))
b5=nn。顺序(*resnet_block(256,512,2))
最后,将全局平均收敛层和全连接层输出添加到ResNet中。
net=nn。顺序(b1,b2,b3,b4,b5,
nn。AdaptiveAvgPool2d((1,1)),
nn。Flatten(),nn。线性(512,10))
每个模块有4个卷积层(不包括恒等式映射的1 1 1\times1 11卷积层)。加上第一个7 7 7\times7 77卷积层和最后一个全连接层,一共18层。因此,这种型号通常被称为ResNet-18。通过在模块中配置不同的通道数和残差块,可以得到不同的ResNet模型,比如更深的152层ResNet-152。ResNet结构更简单,修改更方便。所有这些因素导致了ResNet的迅速和广泛使用。下图描述了完整的ResNet-18。
在训练ResNet之前,我们先观察一下ResNet中不同模块的输入形状是如何变化的。在所有以前的架构中,分辨率降低,通道数量增加,直到全局平均会聚层收集所有特征。
X=torch.rand(size=(1,1,224,224))
对于网络中的层:
X=层(X)
打印(图层。__class__。__name__,'输出形状:\t ',X.shape)
顺序输出形状:火炬。大小([1,64,56,56])
顺序输出形状:火炬。大小([1,64,56,56])
顺序输出形状:火炬。大小([1,128,28,28])
顺序输出形状:火炬。大小([1,256,14,14])
顺序输出形状:火炬。大小([1,512,7,7])
AdaptiveAvgPool2d输出形状:火炬。大小([1,512,1,1])
展平输出形状:火炬。尺寸([1,512])
线性输出形状:火炬。大小([1,10])
训练模型
像以前一样,我们在时尚-MNIST数据集上训练ResNet。
lr,num _ epochs,batch_size=0.05,10,256
train_iter,test _ ITER=d2l . load _ data _ fashion _ mnist(batch _ size,resize=96)
d2l.train_ch6(net,train_iter,test_iter,num_epochs,lr,d2l.try_gpu())
损失0.014,训练符合0.996,测试符合0.895
cuda上每秒4680.2个示例:0
以上是Python深度学习神经网络残差块的详细内容。更多关于Python神经网络的信息,请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。