• Python CNN卷积神经网络实例讲解,CNN实战,CNN代码实例,超实用


    一、CNN简介

    1. 神经网络基础

    输入层(Input layer),众多神经元(Neuron)接受大量非线形输入讯息。输入的讯息称为输入向量。
    输出层(Output layer),讯息在神经元链接中传输、分析、权衡,形成输出结果。输出的讯息称为输出向量。
    隐藏层(Hidden layer),简称“隐层”,是输入层和输出层之间众多神经元和链接组成的各个层面。如果有多个隐藏层,则意味着多个激活函数。

    2. 卷积一下哦

    卷积神经网络(Convolutional Neural Network,CNN)针对全连接网络的局限做出了修正,加入了卷积层(Convolution层)和池化层(Pooling层)。通常情况下,卷积神经网络由若干个卷积层(Convolutional Layer)、激活层(Activation Layer)、池化层(Pooling Layer)及全连接层(Fully Connected Layer)组成。

    下面看怎么卷积的

    1.如图,可以看到:

    (1)两个神经元,即depth=2,意味着有两个滤波器。
    (2)数据窗口每次移动两个步长取3*3的局部数据,即stride=2。
    (3)边缘填充,zero-padding=1,主要为了防止遗漏边缘的像素信息。
        然后分别以两个滤波器filter为轴滑动数组进行卷积计算,得到两组不同的结果。

    2.如果初看上图,可能不一定能立马理解啥意思,但结合上文的内容后,理解这个动图已经不是很困难的事情:

    (1)左边是输入(7*7*3中,7*7代表图像的像素/长宽,3代表R、G、B 三个颜色通道)
    (2)中间部分是两个不同的滤波器Filter w0、Filter w1
    (3)最右边则是两个不同的输出
    (4)随着左边数据窗口的平移滑动,滤波器Filter w0 / Filter w1对不同的局部数据进行卷积计算。

    局部感知:左边数据在变化,每次滤波器都是针对某一局部的数据窗口进行卷积,这就是所谓的CNN中的局部感知机制。打个比方,滤波器就像一双眼睛,人类视角有限,一眼望去,只能看到这世界的局部。如果一眼就看到全世界,你会累死,而且一下子接受全世界所有信息,你大脑接收不过来。当然,即便是看局部,针对局部里的信息人类双眼也是有偏重、偏好的。比如看美女,对脸、胸、腿是重点关注,所以这3个输入的权重相对较大。
    参数共享:数据窗口滑动,导致输入在变化,但中间滤波器Filter w0的权重(即每个神经元连接数据窗口的权重)是固定不变的,这个权重不变即所谓的CNN中的参数(权重)共享机制。

    3卷积计算:

    图中最左边的三个输入矩阵就是我们的相当于输入d=3时有三个通道图,每个通道图都有一个属于自己通道的卷积核,我们可以看到输出(output)的只有两个特征图意味着我们设置的输出的d=2,有几个输出通道就有几层卷积核(比如图中就有FilterW0和FilterW1),这意味着我们的卷积核数量就是输入d的个数乘以输出d的个数(图中就是2*3=6个),其中每一层通道图的计算与上文中提到的一层计算相同,再把每一个通道输出的输出再加起来就是绿色的输出数字啦!
    举例:

    绿色输出的第一个特征图的第一个值:

    1通道x[ : :0] 1*1+1*0 = 1 (0像素点省略)

    2通道x[ : :1] 1*0+1*(-1)+2*0 = -1

    3通道x[ : :2] 2*0 = 0 

    b = 1

    输出:1+(-1)+ 0 + 1(这个是b)= 1 

    绿色输出的第二个特征图的第一个值:

    1通道x[ : :0] 1*0+1*0 = 0 (0像素点省略)

    2通道x[ : :1] 1*0+1*(-1)+2*0 = -1

    3通道x[ : :2] 2*0 = 0 

    b = 0

    输出:0+(-1)+ 0 + 1(这个是b)= 0

    二、CNN实例代码:

    1. import torch
    2. import torch.nn as nn
    3. from torch.autograd import Variable
    4. import torch.utils.data as Data
    5. import torchvision
    6. import matplotlib.pyplot as plt

    模型训练超参数设置,构建训练数据:如果你没有源数据,那么DOWNLOAD_MNIST=True

    1. #Hyper prameters
    2. EPOCH = 2
    3. BATCH_SIZE = 50
    4. LR = 0.001
    5. DOWNLOAD_MNIST = True
    6. train_data = torchvision.datasets.MNIST(
    7. root ='./mnist',
    8. train = True,
    9. download = DOWNLOAD_MNIST
    10. )

    数据下载后是不可以直接看的,查看第一张图片数据:

    1. print(train_data.data.size())
    2. print(train_data.targets.size())
    3. print(train_data.data[0])

    结果:60000张图片数据,维度都是28*28,单通道

    画一个图片显示出来

    1. # 画一个图片显示出来
    2. plt.imshow(train_data.data[0].numpy(),cmap='gray')
    3. plt.title('%i'%train_data.targets[0])
    4. plt.show()

    结果:

    训练和测试数据准备,数据导入:

    1. #训练和测试数据准备
    2. train_loader=Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
    3. test_data=torchvision.datasets.MNIST(
    4. root='./mnist',
    5. train=False,
    6. )
    7. #这里只取前3千个数据吧,差不多已经够用了,然后将其归一化。
    8. with torch.no_grad():
    9. test_x=Variable(torch.unsqueeze(test_data.data, dim=1)).type(torch.FloatTensor)[:3000]/255
    10. test_y=test_data.targets[:3000]

    注意:这里的归一化在此模型中区别不大

    构建CNN模型:

    1. '''开始建立CNN网络'''
    2. class CNN(nn.Module):
    3. def __init__(self):
    4. super(CNN,self).__init__()
    5. '''
    6. 一般来说,卷积网络包括以下内容:
    7. 1.卷积层
    8. 2.神经网络
    9. 3.池化层
    10. '''
    11. self.conv1=nn.Sequential(
    12. nn.Conv2d( #--> (1,28,28)
    13. in_channels=1, #传入的图片是几层的,灰色为1层,RGB为三层
    14. out_channels=16, #输出的图片是几层
    15. kernel_size=5, #代表扫描的区域点为5*5
    16. stride=1, #就是每隔多少步跳一下
    17. padding=2, #边框补全,其计算公式=(kernel_size-1)/2=(5-1)/2=2
    18. ), # 2d代表二维卷积 --> (16,28,28)
    19. nn.ReLU(), #非线性激活层
    20. nn.MaxPool2d(kernel_size=2), #设定这里的扫描区域为2*2,且取出该2*2中的最大值 --> (16,14,14)
    21. )
    22. self.conv2=nn.Sequential(
    23. nn.Conv2d( # --> (16,14,14)
    24. in_channels=16, #这里的输入是上层的输出为16层
    25. out_channels=32, #在这里我们需要将其输出为32层
    26. kernel_size=5, #代表扫描的区域点为5*5
    27. stride=1, #就是每隔多少步跳一下
    28. padding=2, #边框补全,其计算公式=(kernel_size-1)/2=(5-1)/2=
    29. ), # --> (32,14,14)
    30. nn.ReLU(),
    31. nn.MaxPool2d(kernel_size=2), #设定这里的扫描区域为2*2,且取出该2*2中的最大值 --> (32,7,7),这里是三维数据
    32. )
    33. self.out=nn.Linear(32*7*7,10) #注意一下这里的数据是二维的数据
    34. def forward(self,x):
    35. x=self.conv1(x)
    36. x=self.conv2(x) #(batch,32,7,7)
    37. #然后接下来进行一下扩展展平的操作,将三维数据转为二维的数据
    38. x=x.view(x.size(0),-1) #(batch ,32 * 7 * 7)
    39. output=self.out(x)
    40. return output

    把模型实例化打印一下:

    1. cnn=CNN()
    2. print(cnn)

    结果:

     开始训练:

    1. # 添加优化方法
    2. optimizer=torch.optim.Adam(cnn.parameters(),lr=LR)
    3. # 指定损失函数使用交叉信息熵
    4. loss_fn=nn.CrossEntropyLoss()
    5. '''
    6. 开始训练我们的模型哦
    7. '''
    8. step=0
    9. for epoch in range(EPOCH):
    10. #加载训练数据
    11. for step,data in enumerate(train_loader):
    12. x,y=data
    13. #分别得到训练数据的x和y的取值
    14. b_x=Variable(x)
    15. b_y=Variable(y)
    16. output=cnn(b_x) #调用模型预测
    17. loss=loss_fn(output,b_y)#计算损失值
    18. optimizer.zero_grad() #每一次循环之前,将梯度清零
    19. loss.backward() #反向传播
    20. optimizer.step() #梯度下降
    21. #每执行50次,输出一下当前epoch、loss、accuracy
    22. if (step%50==0):
    23. #计算一下模型预测正确率
    24. test_output=cnn(test_x)
    25. y_pred=torch.max(test_output,1)[1].data.squeeze()
    26. accuracy=sum(y_pred==test_y).item()/test_y.size(0)
    27. print('now epoch : ', epoch, ' | loss : %.4f ' % loss.item(), ' | accuracy : ' , accuracy)
    28. '''
    29. 打印十个测试集的结果
    30. '''
    31. test_output=cnn(test_x[:10])
    32. y_pred=torch.max(test_output,1)[1].data.squeeze() #选取最大可能的数值所在的位置
    33. print(y_pred.tolist(),'predecton Result')
    34. print(test_y[:10].tolist(),'Real Result')

    结果:

     卷积层维度变化:

    (1)输入1*28*28,即1通道,28*28维;

    (2)卷积层-01:16*28*28,即16个卷积核,卷积核维度5*5,步长1,边缘填充2,维度计算公式B = (A + 2*P - K) / S + 1,即(28+2*2-5)/1 +1 = 28

    (3)池化层:池化层为2*2,所以输出为16*14*14

    (4)卷积层-02:32*14*14,即32卷积核,其它同卷积层-01

    (5)池化层:池化层为2*2,所以输出为32*7*7;

    (6)fc层:由于输出为1*10,即10个类别的概率,那么首先对最后的池化层进行压缩为二维(1,32*7*7),然后全连接层维度(32*7*7,10),最后(1,32*7*7)*(32*7*7,10)

  • 相关阅读:
    学系统集成项目管理工程师(中项)系列26_新兴信息技术
    关键词搜索抖音商品列表API接口-(item_search-根据关键词取商品列表API接口)
    小程序内容管理系统设计
    Linux 文件目录指令(常见)
    分类选择,最多五级
    模型线上线下一致性问题
    AOP是什么? AOP底层原理、AOP的术语
    misc corrupt
    [De1CTF2019]Babylfsr
    IP行业查询API:为用户分析提供帮助
  • 原文地址:https://blog.csdn.net/L_goodboy/article/details/128079113