神经网络与深度学习课程内容第二周

一.深度学习平台

        目前神经网络的研究均是基于Pytorch、Tensorflow、Keras、caffe等框架进行模型的搭建以及训练。深度学习平台集成了很多神经网络中的常用操作的API,将神经网络的搭建和训练变得更加简单。除了上述的框架之外,近些年还推出了基于特定任务的框架如dectection2等。

        Pytorch是由Facebook人工智能研究院根据torch开发的主要以Python优先的深度学习框架。PyTorch的前身是Torch,其底层和Torch框架一样,但是使用Python重新写了很多内容,不仅更加灵活,支持动态图,而且提供了Python接口。它是由Torch7团队开发,是一个以Python优先的深度学习框架,不仅能够实现强大的GPU加速,同时还支持动态神经网络。该框架入门简单、灵活性高、性能好、论坛环境优秀、用户文档丰富,因此pytorch受到了广泛的好评并积累了一定数量的用户。

        pytorch主要使用tensor(张量)这一数据结构,并且搭建网络模型简单便利。如下:

def build_net(device, num_input, num_output):
    net = nn.Sequential(nn.Flatten(),
                        nn.Linear(num_input, 64),
                        nn.ReLU(),
                        nn.Linear(64, num_output))
    net.apply(init_weights)
    net = net.to(device)
    return net

上述内容即是构造一个多层感知机的模型。可见深度学习平台极大的简化了深度学习研究人员的编码难度。

二.卷积神经网络

        BP神经网络的输入是一维向量,而图像数据则是二维矩阵。图片是由像素组成的,整张图片相当于一个二维矩阵,矩阵中坐标(x,y)则是对应像素的位置。如果图片是灰度图,则在每个坐标中保存一个0到255的数据,从0到255则对应该像素从黑到白。如果图片是彩色图片,则每个坐标保存三个数据,这三个数据分别是RGB三色的数值。通过基础三原色R(red)、G(green)、B(blue)的不同比例的融合叠加便可以得到其他的任意颜色。

        BP神经网络只能使用一维向量来进行学习,因此最初会将图片二维矩阵按照行拆分成若干行,最后再将这若干行向量拼接成一个行向量便得到了BP神经网络的输入向量。

        卷积神经网络则通过卷积层可以直接对输入的图片二维矩阵进行卷积。卷积神经网络拥有强大的特征提取能力,因此在图像处理领域内应用广泛,除此之外卷积神经网络因使用了卷积核可以实现权值共享,极大的减少了深度学习任务的参数量,提高了深度学习的速度。卷积神经网络的主要结构一般为输入层,卷积层,池化层,最后将数据展平后与全连接层按照一定的结构相连。

        卷积层是卷积神经网络特有的结构。卷积操作就是一个窗口即卷积核在网络中的特征图上按照规定的方法进行滑动并对特征图进行计算得到新的特征图。卷积操作可以理解为一个滤波器,该滤波器在输入图像或者特征图上进行滤波,得到我们想要的图片数据的高层次特征组合。下图将展示卷积的计算过程。

 

图 卷积计算过程实例

        假设一个图片矩阵某像素的位置为(X,Y),该像素值为GX,Y,卷积核在滑动到该区域时与该像素所对应的权重为WX,Y。设卷积核为M×N矩阵,则卷积运算结果的数学描述为:

  

        卷积核的工作方式是相似于人眼视觉系统的信息感受方式。人的视觉感受神经系统有感受野的概念,感受野[20]的概念就是当视觉神经系统的某一个神经元处于兴奋状态时,这表明了为该神经元提供输入信号的光感受器观察到了正确的视觉信号刺激。每个卷积核就相当于是一个感受野的某种特征的光感受器,不同的卷积核用来感受不同的图像特征如明暗,形状等。当卷积生成的特征图的某一坐标数值较大时,这就表示在该坐标所对应的前一层特征图中存在较为满足该卷积核所定义的特征信息。当使用了多个具有不同滤波特性的卷积核去分别遍历前层特征图时,便可以在下一层生成各种特征的高阶组合。这些高阶的特征组合就相当于人眼视觉系统中的感受野,它可以实现对图像特征的分类和定位。

        卷积神经网络由于使用卷积核遍历扫描特征图实现了参数权重共享。全连接神经网络的参数权重则是相邻两层全部神经元之间批次互相联系,因此全连接神经网络的训练参数相较于卷积神经网络的参数数量更多。卷积神经网络不仅提取特征的能力强大而且能够做到权值共享,极大的降低了对硬件存储的要求并有效的提高了神经网络的训练速度。

 池化层

        池化层(pooling)是一种下采样操作[21]。当我们降低一张图片数据的分辨率时,只要没有将分辨率降低到特别模糊的状态,但是我们人眼仍能够分辨出图片的信息。池化层的作用是对输入特征图进行下采样,能够做到对图像进行稀疏处理,降低特征图的数据量,但该下采样方法不可避免地会出现网络的部分中间节点的丢失,但相对而言特征图的主要特征能够得以保存。通过池化层,可以加速神经网络的训练速度。池化方法目前比较常见的有最大池化和平均池化两种,如图2.6所示。

 

图池化演示实例图

         最大池化操作是在池化滑动窗口所对应的特征图区域内找到该区域内最大像素点并保留其像素值,平均池化操作则是在池化滑动窗口所对应的特征图区域内计算得出该区域内所有像素点的平均像素值并保存。池化运算没有训练参数,只对输入特征图的大小进行改变。最大池化操作能够有效反映出图像中的主要特征,但是会丢失部分图像的信息。平均池化操作虽然较多的保留了图像的特征信息,但是也会造成特征图的特征对比度下降。

        卷积神经网络AlexNet的pytorch实现例子如下:

class AlexNet(nn.Module):
    def __init__(self, num_classes=1000, init_weights=False):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2),  # input[3, 224, 224]  output[48, 55, 55]
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),                  # output[48, 27, 27]
            nn.Conv2d(48, 128, kernel_size=5, padding=2),           # output[128, 27, 27]
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),                  # output[128, 13, 13]
            nn.Conv2d(128, 192, kernel_size=3, padding=1),          # output[192, 13, 13]
            nn.ReLU(inplace=True),
            nn.Conv2d(192, 192, kernel_size=3, padding=1),          # output[192, 13, 13]
            nn.ReLU(inplace=True),
            nn.Conv2d(192, 128, kernel_size=3, padding=1),          # output[128, 13, 13]
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),                  # output[128, 6, 6]
        )
        self.classifier = nn.Sequential(
            nn.Dropout(p=0.5),
            nn.Linear(128 * 6 * 6, 2048),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(2048, 2048),
            nn.ReLU(inplace=True),
            nn.Linear(2048, num_classes),
        )
        if init_weights:
            self._initialize_weights()

    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, start_dim=1)
        x = self.classifier(x)
        return x

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                nn.init.constant_(m.bias, 0)

三、LeNet

LeNet模型的结构如下图

        由LeNet神经网络的模型图可知,输入图像经过卷积核的卷积会改变其深度(channel),其数值等于卷积层所使用的卷积核的数量。同时卷积操作还会改变图像的大小即高(height)和宽(width),通常输入神经网络的图像和卷积核的形状均是长和宽相等的矩形,故输入特征图经卷积操作后其矩阵大小计算公式如下,

        

        因为训练使用的是彩色RGB图像因此输入深度channel为3,所以第一层卷积层的输入深度(inchannel)为3,使用卷积核个数为16,卷积核大小为5*5。该卷积核默认步距为1,padding为0。输入图片数据经过第一层卷积后对其输出的特征图进行池化核的大小为2*2,步距为2的最大池化下采样操作。最后数据输入relu激活函数。

        第二层卷积层的输入数据深度(channel)为16,使用卷积核的个数为32,卷积核大小为5*5,其后同样使用池化核大小为2*2且步距为2等最大池化下采样。采样数据同样输入relu激活函数。

        经过两层卷积层计算后所得的数据格式为深度为32,大小为5*5的特征图,将这32*5*5个数据展平成为一维向量后与输出节点为120的全连接层相连接。之后再与输出节点为84的全连接层连接,最后输出数据与输出节点为10的全连接层连接。至此神经网络LeNet的模型搭建完成。

下图将展示使用LeNet进行手写数字识别的可视化:

可视化网站为: 3D Visualization of a Convolutional Neural Network (adamharley.com)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值