残差网络(Pytorch实现)

本文详细介绍了如何在PyTorch中运用残差网络,重点讲解了 + 运算在保持通道数一致以便于相加的重要性,以及如何通过卷积操作调整输入和输出的通道数。通过实例展示了ResBlock的定义和代码实现,以及网络结构的设计。
摘要由CSDN通过智能技术生成

0. 前言

本文讲如何使用Pytorch实现残差网络,残差网络的结构如图:
在这里插入图片描述
输入x,输出output=F(x)+x:F(x)为输入经过卷积运算后的结果,x为输入本身。实际上就是将输出结果再次加上了本身。

1. 如何理解"+"号运算?

这里的加法实际上就是对应位的数值相加,比如[1,2,3]和[4,5,6]相加的结果为[5,7,9],并不是通道的拼接,如此便要求xF(x)应当拥有相同的shape。我们通过实验来看加号(F(x)具体运算省略):

定义输入x
在这里插入图片描述
F(x)为:
在这里插入图片描述
x+F(x)的结果为:
在这里插入图片描述

2. 要求:x和F(x)的shape一样

我们知道➕是对应位相加,则要求两者shape一样才能正确相加。一般F(x)经过卷积运算后,与x的通道数是不一样的,所以我们在将两者相加是,需要将x的通道数变为和F(x)一样,这里同样通过卷积操作完成。具体看下面代码。

3. 代码实现

3.1 定义ResBlock网络

import torch
import torch.nn as nn


class ResBlock(nn.Module):
    def __init__(self, input_channels, out_channels, kernel_size):
        super(ResBlock, self).__init__()

        self.function=nn.Sequential(
            nn.Conv2d(input_channels, out_channels, kernel_size, padding=1),
            nn.Conv2d(out_channels, out_channels, kernel_size, padding=1)
        )

        self.downsample=nn.Sequential(
            nn.Conv2d(input_channels,out_channels,kernel_size,padding=1)
        )

    def forward(self, x):
        identify = x
        identify=self.downsample(identify)

        f = self.function(x)
        out = f + identify
        return out


model=ResBlock(3,8,3) # 定义一个输入通道为3,输出通道为8,卷积核size为3的ResBlock网络
input=torch.randn(1,3,100,100) # 产生一个shape=[1,3,100,100]的数据作为输入
print(model(input).shape) # 推理,并打印推理结果的shape

在这里插入图片描述
实现代码和网络结构图如上,downsample的功能就是将x原本的3通道变为8通道,以此保证相加时两个形状一致。downsample本身实际上就是一个卷积运算,因为卷积运算是可以增加通道数的。

残差网络是一种能够通过增加深度来提高准确率的神经网络模型。它使用了跳跃连接来缓解梯度消失问题,并且容易进行优化。在PyTorch中,我们可以使用代码实现残差网络。 以下是一个使用PyTorch实现残差网络的示例代码: ```python import torch import torch.nn as nn import torch.nn.functional as F class ResidualBlock(nn.Module): def __init__(self, channels): super(ResidualBlock, self).__init__() self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1) self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(channels) def forward(self, x): residual = x out = F.relu(self.bn(self.conv1(x))) out = self.bn(self.conv2(out)) out += residual out = F.relu(out) return out class ResidualNetwork(nn.Module): def __init__(self): super(ResidualNetwork, self).__init__() self.conv1 = nn.Conv2d(1, 16, kernel_size=5) self.conv2 = nn.Conv2d(16, 32, kernel_size=5) self.mp = nn.MaxPool2d(2) self.rblock1 = ResidualBlock(16) self.rblock2 = ResidualBlock(32) self.fc = nn.Linear(512, 10) def forward(self, x): in_size = x.size(0) x = self.mp(F.relu(self.conv1(x))) x = self.rblock1(x) x = self.mp(F.relu(self.conv2(x))) x = self.rblock2(x) x = x.view(in_size, -1) out = self.fc(x) return out model = ResidualNetwork() ``` 在这个示例代码中,我们定义了一个`ResidualBlock`类来表示残差块,其中包含了两个卷积层和批标准化层。然后,我们定义了一个`ResidualNetwork`类,它包含了两个残差块和其他的卷积层、池化层和全连接层。最后,我们创建了一个`ResidualNetwork`对象作为我们的残差网络模型。 这是一个简单的残差网络模型,在实际应用中,你可以根据需要修改网络的结构和参数。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一个对称矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值