【Pytorch】学习笔记(五)

卷积神经网络(加强)

0. 1*1的卷积有什么用呢?

  1. 降低运算量
  2. 信息融合
  3. 改变通道数量
    在这里插入图片描述
    在这里插入图片描述

1. GoogLeNet

在这里插入图片描述

Inception Block

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

沿着通道的维度进行拼接
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

完整代码

"""
2021.08.10
author:alian
11 基于pytorch的卷积神经网络(GoogleNet)
"""
import torch
import torch.nn.functional as F
# GoogleNet
class InceptionA(torch.nn.Module):
    def __init__(self,in_channels):
        super(InceptionA,self).__init__()
        self.branch1x1 = torch.nn.Conv2d(in_channels,16, kernel_size=1)

        self.branch5x5_1 = torch.nn.Conv2d(in_channels, 16, kernel_size=1)
        self.branch5x5_2 = torch.nn.Conv2d(16, 24, kernel_size=5, padding=2)

        self.branch3x3_1 = torch.nn.Conv2d(in_channels, 16, kernel_size=1)
        self.branch3x3_2 = torch.nn.Conv2d(16, 24, kernel_size=3, padding=1)
        self.branch3x3_3 = torch.nn.Conv2d(24, 24, kernel_size=3, padding=1)

        self.branch_pool = torch.nn.Conv2d(in_channels, 24, kernel_size=1)

    def forward(self,x):
        branch1x1 = self.branch1x1(x)

        branch5x5 = self.branch5x5_1(x)
        branch5x5 = self.branch5x5_2(branch5x5)

        branch3x3 = self.branch3x3_1(x)
        branch3x3 = self.branch3x3_2(branch3x3)
        branch3x3 = self.branch3x3_3(branch3x3)

        branch_pool = F.avg_pool2d(x,kernel_size=3,stride=1,padding=1)
        branch_pool = self.branch_pool(branch_pool)

        outputs = [branch1x1,branch5x5,branch3x3,branch_pool]
        return torch.cat(outputs,dim=1)

class googleNet(torch.nn.Module):
    def __init__(self):
        super(googleNet,self).__init__()
        self.conv1 = torch.nn.Conv2d(1,10,kernel_size=5)
        self.conv2 = torch.nn.Conv2d(88,20,kernel_size=5)

        self.incep1 = InceptionA(in_channels=10)
        self.incep2 = InceptionA(in_channels=20)

        self.mp = torch.nn.MaxPool2d(2)
        self.fc = torch.nn.Linear(1408,10)  # 全连接层(线性层)

    def forward(self,x):
        in_size = x.size(0)
        x = F.relu(self.mp(self.conv1(x)))
        x = self.incep1(x)
        x = F.relu(self.mp(self.conv2(x)))
        x = self.incep2(x)
        x = x.view(in_size,-1)
        x = self.fc(x)
        return x

2. ResNet

梯度消失:
反向传播,链式法则求梯度(一连串地将梯度乘起来),假如每一处的梯度都是<1,则一连串地相乘会导致梯度趋近于0,当梯度趋近于0时,根据权重更新公式: w = w − α g w=w-\alpha g w=wαg ( g g g为梯度),权重将得不到更新,无法得到充分训练。
在这里插入图片描述
上述的残差单元,在输出加上一个输入x,将来反向传播回传的梯度(即使非常小)也趋近于1,链式法则梯度相乘不会造成梯度消失问题,开始的网络层能得到很好的训练。要求:残差单元输出和输入的张量维度必须一致

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

完整代码

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

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

class ResNet(torch.nn.Module):
    def __init__(self):
        super(ResNet,self).__init__()
        self.conv1 = torch.nn.Conv2d(1,16,kernel_size=5)
        self.conv2 = torch.nn.Conv2d(16,32,kernel_size=5)
        self.res1 = ResidualBlock(16)
        self.res2 = ResidualBlock(32)
        self.pool = torch.nn.MaxPool2d(2)
        self.fc = torch.nn.Linear(512,10)

    def forward(self,x):  # 输入张量
        in_size = x.size(0)
        x = self.pool(F.relu(self.conv1(x)))
        x = self.res1(x)
        x = self.pool(F.relu(self.conv2(x)))
        x = self.res2(x)
        x.view(in_size,-1) # Flatten data from(batch_size,32,4,4) to (batch_size,512)
        x = self.fc(x)
        return x
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值