【打好基础之深度学习】Task 1:复现Resnet

写在前面

        作为研究目标检测的研究僧一枚,接触深度学习许久,但是仍感觉自己的理论基础和代码基础超级薄弱。因此决定从最基础的网络框架以及代码重新学习,加油!!!

Resnet学习 

一、原论文知识补充(2024.2.26)

1.残差网络实现功能:如果主干网络学习效果不加,直接通过残差边进行学习。

2.解决当时一个固有思路:网络越深,效果越好。实则不然,网络层数越深,可能会导致训练效果的退化————因此提出resnet。

二、代码复现(2024.2.26-3.1)

复现Resnet-18,主要应用下图残差网络块。

Jupyter Notebook补充知识 

1.代码使用jupyter,安装下载后,cmd中输入jupyter notebook,即可打开。

jupyter notebook

2.将图片保存在Jupyter

3.代码补全快捷键:Tab键

1.导入torch框架

# 导入torch框架
import torch
import torch.nn as nn

2.搭建残差网络模块Residual block,网络框架如上图所示。

# Residual block残差网络块
# 继承nn.module类
class ResidualBlock(nn.Module):
    # 初始化参数
    def __init__(self, in_channels, out_channels, stride=1):
        # 多继承
        super(ResidualBlock, self).__init__()
        # 两个卷积层设置
        # 注:如果卷积层后有bn层,那么将偏执bias关闭,因为bn层有调节bias的作用
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size = 3, stride = stride, padding = 1, bias = False)
        # 归一化,对数据进行处理,数据更规范,避免梯度爆炸,梯度消失
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace = True)
        
        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size = 3, stride = 1, padding = 1, bias = False)
        self.bn2 = nn.BatchNorm2d(out_channels)
        
        # 残差边与原始边如果维度不一致的话,无法拼接,所以需要做整合操作
        # 利用squential,如果一致,则不需要改变
        self.shortcut = nn.Sequential()
        # 不一致,需要用1*1卷积核,步长等于原步长即可
        if stride != 1 or in_channels != out_channels:
            self.shortcut = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size = 1, stride = stride, bias = False),
                                       nn.BatchNorm2d(out_channels))
            
        

        
    # 前向传播
    def forward(self, x):
        identity = x
        
        out1 = self.conv1(x)
        out1 = self.bn1(out1)
        out1 = self.relu(out1)
        
        out2 = self.conv2(out1)
        out2 = self.bn2(out2)
        
        out2 += self.shortcut(identity)
        out = self.relu(out2)
        
        return out

3.利用搭建好的残差模块构建ResNet18网络框架

# Resnet18网络块,用于分类
class ResNet18(nn.Module):
    def __init__(self, num_classes = 1000):
        super(ResNet18, self).__init__()
        # 依次定义各层网络
        self.conv1 = nn.Conv2d(3, 64, kernel_size = 7, stride = 2, padding = 3, bias = False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace = True)
        
        self.maxpool = nn.MaxPool2d(kernel_size = 3, stride = 2, padding = 1)
        
        self.layer1 = self._make_layer(64, 64, 2, stride = 1)
        self.layer2 = self._make_layer(64, 128, 2, stride = 2)
        self.layer3 = self._make_layer(128, 256, 2, stride = 2)
        self.layer4 = self._make_layer(256, 512, 2, stride = 2)
        
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        
        self.fc = nn.Linear(512, num_classes)
    
    # 简化残差块的代码编写
    def _make_layer(self, in_channels, out_channels, blocks, stride = 1):
        # 建立列表
        layer = []
        layer.append(ResidualBlock(in_channels, out_channels, stride))
        
        for _ in range(1, blocks):
            layer.append(ResidualBlock(out_channels, out_channels))
        # 打包成一个结构,*代表layer里面的所有元素以列表的形式返回给sequential
        return nn.Sequential(*layer)
    
    def forward(self, x):
        out1 = self.conv1(x)
        out1 = self.bn1(out1)
        out1 = self.relu(out1)
        
        out2 = self.maxpool(out1)
        
        out3 = self.layer1(out2)
        out3 = self.layer2(out3)
        out3 = self.layer3(out3)
        out3 = self.layer4(out3)
        
        out4 = self.avgpool(out3)
        out4 = touch.flatten(out4, 1)
        out = self.fc(out4)
        
        return out

注:为了简化残差块的代码编写,利用列表layer以及for循环,将残差块打包成一个结构,最后返回给sequential。

4.打印ResNet18模型并测试

# 建立模型并打印
model = ResNet18()
print(model)

# 利用summary函数测试输入输出
from torchsummary import summary
summary(model, (3, 224, 224))
三、总结

1.熟练运用Jupyter Notebook;

2.精化代码,使代码简单化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值