第五章

描述卷积神经网络中卷积层和池化层的工作原理,并解释填充、步幅、输入通道和输出通道的含义

  • 二维卷积层

  • 填充和步幅

  • 多输入通道和多输出通道

  • 使用重复元素的网络(VGG)

  • 残差网络(ResNet)

二维卷积层

from mxnet import autograd, nd 
from mxnet.gluon import nn 
def corr2d(X, K): 
    # 本函数已保存在d2lzh包中方便以后使用
    # 二维卷积层将输入和卷积核做互相关运算,并加上一个标量偏差来得到输出
    h, w = K.shape 
    Y = nd.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1)) 
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i, j] = (X[i: i + h, j: j + w] * K).sum() 
        return Y

class Conv2D(nn.Block): 
#函数__init__里我们声明weight和bias这两个模型参数。前向计算函数forward则是直接调用corr2d函数再加上偏 差
    def __init__(self, kernel_size, **kwargs): 
        super(Conv2D, self).__init__(**kwargs) 
        self.weight = self.params.get('weight', shape=kernel_size) 
        self.bias = self.params.get('bias', shape=(1,)) 
    def forward(self, x): 
        return corr2d(x, self.weight.data()) + self.bias.data()

特征图和感受野

二维卷积层输出的二维数组可以看作是输入在空间维度(宽和高)上某一级的表征,也叫特征图 (feature map)

填充和步幅

填充 (padding)是指在输入高和宽的两侧填充元素 (通常是0元素) 卷积神经网络经常使用奇数高宽的卷积核,如1、3、5和7,所以两端上的填充个数相等。 卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数和列数称为步幅(stride),可以减小输出的高和宽。

多输入通道和多输出通道

1 X 1卷积层

池化层

填充

多通道

使用重复元素的网络(VGG)

VGG块的组成规律是:连续使用数个相同的填充为1、窗口形状为3X3的卷积层后接上一个步幅为2、窗口形状为2X2的最大池化层。卷积层保持输入的高和宽不变,而池化层则对其减半。我们使用vgg_block函数来实现这个基础的VGG块,它可以指定卷积层的数量num_convs和输出通道数num_channels

import d2lzh as d2l 
from mxnet import gluon, init, nd 
from mxnet.gluon import nn 
def vgg_block(num_convs, num_channels): #卷积层的数,输出通道数
    blk = nn.Sequential() 
    for _ in range(num_convs): 
        blk.add(nn.Conv2D(num_channels, kernel_size=3, padding=1, activation='relu'))          
    blk.add(nn.MaxPool2D(pool_size=2, strides=2)) 
    return blk

与AlexNet和LeNet一样,VGG网络由卷积层模块后接全连接层模块构成。卷积层模块串联数个vgg_block,其超参数由变量conv_arch定义。该变量指定了每个VGG块里卷积层个数和输出通道数。全连接模块则跟AlexNet中的一样。 现在我们构造一个VGG网络。 它有5个卷积块,前2块使用单卷积层,而后3块使用双卷积层。第 一块的输出通道是64,之后每次对输出通道数翻倍,直到变为512。因为这个网络使用了8个卷积 层和3个全连接层,所以经常被称为VGG-11

def vgg(conv_arch): 
    net = nn.Sequential() 
    # 卷积层部分 
    for (num_convs, num_channels) in conv_arch: 
        net.add(vgg_block(num_convs, num_channels)) 
    # 全连接层部分 
    net.add(nn.Dense(4096, activation='relu'), nn.Dropout(0.5), 
            nn.Dense(4096, activation='relu'), nn.Dropout(0.5), 
            nn.Dense(10)) 
    return net net = vgg(conv_arch)

残差网络(ResNet)

最后更新于

这有帮助吗?