残差网络
残差网络的核心思想是:每个附加层都应该更容易地包含原始函数作为其元素之一。
残差块
串联一个层改变函数类,我们希望扩大函数类,残差块加入快速通道来得到f(x)=x+g(x)的结果
ResNet块
1.高宽减半的ResNet块(步幅2)
2.后接多个高宽不变的ResNet块
ResNet架构
1.类似VGG和GoogLeNet总体架构
2.但替换成ResNet块
总结
残差块使得很深的网络更加容易训练,甚至可以训练一千层的网络
代码实现
ResNet沿用了VGG完整的3X3卷积层设计。 残差块里首先有2个有相同输出通道数的3X3卷积层。 每个卷积层后接一个批量规范化层和ReLU激活函数。 然后我们通过跨层数据通路,跳过这2个卷积运算,将输入直接加在最后的ReLU激活函数前。 这样的设计要求2个卷积层的输出与输入形状一样,从而使它们可以相加。 如果想改变通道数,就需要引入一个额外的
1X1卷积层来将输入变换成需要的形状后再做相加运算。
import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2l
class Residual(nn.Module): #save
def __init__(self, input_channels, num_channels,
use_1x1conv=False, strides=1):
super().__init__()
self.conv1 = nn.Conv2d(input_channels, num_channels,
kernel_size=3, padding=1, stride=strides)
self.conv2 = nn.Conv2d(num_channels, num_channels,
kernel_size=3, padding=1)
if use_1x1conv:
self.conv3 = nn