【Pytorch】Identity Mappings in Deep Residual Networks经典论文模型复现(1)

本文探讨了深度学习中残差块的几种变体,包括常数缩放、卷积快捷方式、门控机制等。通过实验比较,发现这些变体对模型收敛和性能的影响,其中门控机制(如shortcut-only gating和exclusive gating)表现出了对信号传递和残差函数的不同调节效果。尽管某些变体在训练过程中能收敛,但最终的测试误差仍不及原始残差块模型。研究表明,初始化参数和门控系数的选择对模型性能至关重要。

一、目标
本文主要完成除带随机失活dropout shortcut)以外的模型。
在这里插入图片描述

二、关键代码
(1)constant scaling
与原始残差块的差别在于,将输出从y=f(x)+x变成了y=0.5[f(x)+x]。
如图Fig.2(b)所示,设置\lambda=0.5,即h(xl)=0.5xl,对于残差函数F有两种处理方式,一种是不加缩放系数,另一种是残差函数F以1-\lambda为系数进行缩放。试验结果表明,第一种方式的模型无法很好的收敛,第二种方式的模型能够收敛,但在最终的测试集上的分类错误率大于原始的模型。

class ResidualBlock(nn.Module):
    def __init__(self, channels):
        super(ResidualBlock, self).__init__()
        self.channels = channels
        self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)

    def forward(self, x):
        y = F.relu(self.conv1(x))
        y = self.conv2(y)
        return 0.5*F.relu(x + y)

在这里插入图片描述
在这里插入图片描述

(2)conv shortcut
将输出y=f(x)+x中的x经过一个1*1的卷积层。
在shortcut部分使用1×1卷积,效果远不如原始网络,证明了1×1卷积依然阻碍了信号的传递过程。

class ResidualBlock(nn.Module):
    def __init__(self, channels):
        super(ResidualBlock, self).__init__()
        self.channels = channels
        self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(channels, channels, kernel_size=1)
    def forward(self, x):
        y = F.relu(self.conv1(x))
        y = self.conv2(y)
        z = self.conv3(x)+y
        return F.relu(z)

在这里插入图片描述在这里插入图片描述

(3)shortcut-only gating
在卷积后,多加了一个sigmoid层,变为线性输出,再用1去减去结果。
如图Fig.2(d)所示,这种方式不再对残差部分进行处理,而是只对shortcut部分乘以1-g(x),bg的取值依然很关键,当bg为0时,1-g(x)的期望是0.5,最终网络的误差为12.86%。如果设置bg为-6,那么1-g(x)很接近1,网络接近于恒等映射,取得的6.91%的误差耶很接近原始网络。

class ResidualBlock(nn.Module):
    def __init__(self, channels):
        super(ResidualBlock, self).__init__()
        self.channels = channels
        self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(channels, channels, kernel_size=1)
        self.sigmoid = torch.nn.Sigmoid()
    def forward(self, x):
        y = F.relu(self.conv1(x))
        y = self.conv2(y)
        con = 1-(self.sigmoid(self.conv3(x)))
        z = con*x
        return F.relu(z+y)

在这里插入图片描述
在这里插入图片描述

(4)exclusive gating
如图Fig.2©所示,考虑一个gating函数,g(x)通过1×1的卷积实现。对于残差函数F部分乘以系数g(x),shortcut部分乘以系数1-g(x),实验发现偏置项bg的初始化非常重要,最好的情况是bg=-6是在测试集上得到了8.70%的误差,依然不如原始网络。

exclusive gating的影响有两个方面:当1-g(x)接近于1,g(x)就接近于0,在这种情况下shortcut约等于恒等映射,有助于信号的传递过程,但此时的g(x)接近于0,这抑制了残差函数的作用。为了进一步分析在shortcutbu部分的gating作用,作者进一步设计了shortcut-only gating的方式

class ResidualBlock(nn.Module):
    def __init__(self, channels):
        super(ResidualBlock, self).__init__()
        self.channels = channels
        self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(channels, channels, kernel_size=1)
        self.sigmoid = torch.nn.Sigmoid()
    def forward(self, x):
        y = F.relu(self.conv1(x))
        y = self.conv2(y)
        con = 1-(self.sigmoid(self.conv3(x)))
        z = con*x
        y = y*con
        return F.relu(z+y)

在这里插入图片描述

在这里插入图片描述

三、后续安排
继续学习BN,随机失活等神经网络中的常用层,然后再精读这篇论文,看以下其他方向的研究。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值