神经网络初级阶段——卷积神经网络CNN(一)

发布于:2023-01-04 ⋅ 阅读:(483) ⋅ 点赞:(0)

全连接神经网络存在很多不足,现在常用的网络是CNN。

一、全连接神经网络的缺点:

在结构方面上:参数居多,容易丢失空间信息(NV结构———(批次,h*w*c))
如果只有两个隐藏层,每层256个节点,则MNIST数据集所需要的参数是:(28*28*256+256*256+256*10)个w,再加上(256+256+10)个b。除了计算过程中需要存储的海量的参数,还有海量的计算。大量的参数过多会导致过拟合。

一个好的拟合应该具有很强的泛化能力,不仅仅是训练时候损失低,测试的时候也需如此。

解决办法:1.训练集增加更多的数据(数据增强)2.降低模型的复杂度

二、卷积神经网络(CNN-Convolutional Neural Networks)

1、为什么用CNN?

在我们最熟悉的图像处理方面,卷积过程是考虑到图像的局部特征,能够更加准确的抽取空间特征。如果使用全连接的话,我们可能会考虑到很多不相关的信息。CNN有平移不变性,因为权值共享,图像平移了,卷积核还是可以识别出来,但是全连接则做不到,其次,目前很多计算采用的是边缘计算,很多使用的是精简指令集,在较小的内存条件下使用全连接神经网络是不现实的。

2、什么是卷积(提炼特征)

什么是卷积?通俗来讲:你在过去不同时刻惹女朋友生气的叠加,对女朋友现在坏心情的贡献就是卷积。卷积运算本质上就是在滤波器和输入数据的局部区域间做点积,将卷积层的前向传播变成一个巨大的矩阵乘法,卷积结构可以减少深层网络占用的内存量。

卷积有三个关键——局部感受野、权值共享、池化层(后面补充讲解),有效的减少了网络的参数个数,缓解了模型的过拟合问题。

在图像处理上:

二维——img.shape(1*6*6),卷积核(1*3*3),输出(1*4*4)

如图中所示,目前卷积核滑动到了图像左上角,我们把图像上的9个值与卷积核的9个数值按照对应位置相乘再相加得到一个和,这个和就是我们得到的卷积值。然后把卷积核向右移动一个像素,再执行对应位置相乘再相加的过程得到第二个卷积值,当把所有像素遍历完成之后我们得到的结果就构成了一幅图像。这就是卷积得到的图像。

上面这些看起来有些抽象,我们来看一看动图:

(1)单输入通道单输出卷积

(2)多输入通道单输出卷积(channel=3)

(3)多输入通道多输出通道卷积(2个卷积,2个输出)

(4)4维度结构可视图N(3张图)C(3通道)H(长10)W(宽10)3*3*10*10

(5)卷积神经网络结构可视化

三、代码实现

#4层卷积-一层全连接神经网络实现,#输入图像shape=1*3*39*31

(1)不加全连接不加池化:

import torch
import torch.nn as nn
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.layer=nn.Sequential(
            # 由卷积和全连接构成NCHW
            # 定义卷积层
            # 输出通道3,输出通道(20),卷积核尺寸(2*2)、步长1
            nn.Conv2d(3 , 20, 2, 1),
            nn.ReLU(),
            nn.Conv2d(20, 40, 2, 1),
            nn.ReLU(),
            nn.Conv2d(40, 60, 2, 1),
            nn.ReLU(),
            nn.Conv2d(60, 80, 2, 1),
        )
    def forward(self,x):#前向传播
        Conv_out = self.layer(x)
        return Conv_out
#测试
if __name__ == '__main__':
    net=Net()
    x=torch.randn(1,3,39,31)#NCHW
    y=net.forward(x)
    print(y.shape)
    #输出为#(1,80,35,27)

(2)加入全连接未加池化:


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        #卷积层
        self.Conv_layer=nn.Sequential(
            # 由卷积和全连接构成NCHW
            # 定义卷积层
            # 输出通道3,输出通道(20),卷积核尺寸(2*2)、步长1
            nn.Conv2d(3 , 20, 2, 1),
            nn.ReLU(),
            nn.Conv2d(20, 40, 2, 1),
            nn.ReLU(),
            nn.Conv2d(40, 60, 2, 1),
            nn.ReLU(),
            nn.Conv2d(60, 80, 2, 1),
        )
        #全连接层
        self.Fnn_layer=nn.Sequential(
            ##卷积层的最终输出为#(1,80,35,27)
            #则全连接的输入为(NV结构-N(1)V(80*35*27)
            nn.Linear(80*35*27,160),
            nn.Softmax(dim=1)
        )
    def forward(self,x):#前向传播
        Conv_out = self.Conv_layer(x)
        #将NCHW转为NV结构
        out=Conv_out.reshape(-1,80*35*27)
        out=self.Fnn_layer(out)#将NV传入全连接神经网络
        return out
#测试
if __name__ == '__main__':
    net=Net()
    x=torch.randn(1,3,39,31)#NCHW
    y=net.forward(x)
    print(y.shape)
    #输出为#(1,160)NV

总结

以上我们久基本了解了卷积神经网络的基本原理和结构了,后面我们将深入分析卷积神经网络里的各种优化方法(如pooling(池化)等,我将在《卷积神经网络(CNN)基础理解(二)》里面详细解释。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到