PyTorch上实现卷积神经网络CNN的方法


Posted in Python onApril 28, 2018

一、卷积神经网络

卷积神经网络(ConvolutionalNeuralNetwork,CNN)最初是为解决图像识别等问题设计的,CNN现在的应用已经不限于图像和视频,也可用于时间序列信号,比如音频信号和文本数据等。CNN作为一个深度学习架构被提出的最初诉求是降低对图像数据预处理的要求,避免复杂的特征工程。在卷积神经网络中,第一个卷积层会直接接受图像像素级的输入,每一层卷积(滤波器)都会提取数据中最有效的特征,这种方法可以提取到图像中最基础的特征,而后再进行组合和抽象形成更高阶的特征,因此CNN在理论上具有对图像缩放、平移和旋转的不变性。

卷积神经网络CNN的要点就是局部连接(LocalConnection)、权值共享(WeightsSharing)和池化层(Pooling)中的降采样(Down-Sampling)。其中,局部连接和权值共享降低了参数量,使训练复杂度大大下降并减轻了过拟合。同时权值共享还赋予了卷积网络对平移的容忍性,池化层降采样则进一步降低了输出参数量并赋予模型对轻度形变的容忍性,提高了模型的泛化能力。可以把卷积层卷积操作理解为用少量参数在图像的多个位置上提取相似特征的过程。

二、代码实现

import torch 
import torch.nn as nn 
from torch.autograd import Variable 
import torch.utils.data as Data 
import torchvision 
import matplotlib.pyplot as plt 
 
torch.manual_seed(1) 
 
EPOCH = 1 
BATCH_SIZE = 50 
LR = 0.001 
DOWNLOAD_MNIST = True 
 
# 获取训练集dataset 
training_data = torchvision.datasets.MNIST( 
       root='./mnist/', # dataset存储路径 
       train=True, # True表示是train训练集,False表示test测试集 
       transform=torchvision.transforms.ToTensor(), # 将原数据规范化到(0,1)区间 
       download=DOWNLOAD_MNIST, 
       ) 
 
# 打印MNIST数据集的训练集及测试集的尺寸 
print(training_data.train_data.size()) 
print(training_data.train_labels.size()) 
# torch.Size([60000, 28, 28]) 
# torch.Size([60000]) 
 
plt.imshow(training_data.train_data[0].numpy(), cmap='gray') 
plt.title('%i' % training_data.train_labels[0]) 
plt.show() 
 
# 通过torchvision.datasets获取的dataset格式可直接可置于DataLoader 
train_loader = Data.DataLoader(dataset=training_data, batch_size=BATCH_SIZE, 
                shuffle=True) 
 
# 获取测试集dataset 
test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) 
# 取前2000个测试集样本 
test_x = Variable(torch.unsqueeze(test_data.test_data, dim=1), 
         volatile=True).type(torch.FloatTensor)[:2000]/255 
# (2000, 28, 28) to (2000, 1, 28, 28), in range(0,1) 
test_y = test_data.test_labels[:2000] 
 
class CNN(nn.Module): 
  def __init__(self): 
    super(CNN, self).__init__() 
    self.conv1 = nn.Sequential( # (1,28,28) 
           nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, 
                stride=1, padding=2), # (16,28,28) 
    # 想要con2d卷积出来的图片尺寸没有变化, padding=(kernel_size-1)/2 
           nn.ReLU(), 
           nn.MaxPool2d(kernel_size=2) # (16,14,14) 
           ) 
    self.conv2 = nn.Sequential( # (16,14,14) 
           nn.Conv2d(16, 32, 5, 1, 2), # (32,14,14) 
           nn.ReLU(), 
           nn.MaxPool2d(2) # (32,7,7) 
           ) 
    self.out = nn.Linear(32*7*7, 10) 
 
  def forward(self, x): 
    x = self.conv1(x) 
    x = self.conv2(x) 
    x = x.view(x.size(0), -1) # 将(batch,32,7,7)展平为(batch,32*7*7) 
    output = self.out(x) 
    return output 
 
cnn = CNN() 
print(cnn) 
''''' 
CNN ( 
 (conv1): Sequential ( 
  (0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)) 
  (1): ReLU () 
  (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) 
 ) 
 (conv2): Sequential ( 
  (0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)) 
  (1): ReLU () 
  (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) 
 ) 
 (out): Linear (1568 -> 10) 
) 
''' 
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) 
loss_function = nn.CrossEntropyLoss() 
 
for epoch in range(EPOCH): 
  for step, (x, y) in enumerate(train_loader): 
    b_x = Variable(x) 
    b_y = Variable(y) 
 
    output = cnn(b_x) 
    loss = loss_function(output, b_y) 
    optimizer.zero_grad() 
    loss.backward() 
    optimizer.step() 
 
    if step % 100 == 0: 
      test_output = cnn(test_x) 
      pred_y = torch.max(test_output, 1)[1].data.squeeze() 
      accuracy = sum(pred_y == test_y) / test_y.size(0) 
      print('Epoch:', epoch, '|Step:', step, 
         '|train loss:%.4f'%loss.data[0], '|test accuracy:%.4f'%accuracy) 
 
test_output = cnn(test_x[:10]) 
pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze() 
print(pred_y, 'prediction number') 
print(test_y[:10].numpy(), 'real number') 
''''' 
Epoch: 0 |Step: 0 |train loss:2.3145 |test accuracy:0.1040 
Epoch: 0 |Step: 100 |train loss:0.5857 |test accuracy:0.8865 
Epoch: 0 |Step: 200 |train loss:0.0600 |test accuracy:0.9380 
Epoch: 0 |Step: 300 |train loss:0.0996 |test accuracy:0.9345 
Epoch: 0 |Step: 400 |train loss:0.0381 |test accuracy:0.9645 
Epoch: 0 |Step: 500 |train loss:0.0266 |test accuracy:0.9620 
Epoch: 0 |Step: 600 |train loss:0.0973 |test accuracy:0.9685 
Epoch: 0 |Step: 700 |train loss:0.0421 |test accuracy:0.9725 
Epoch: 0 |Step: 800 |train loss:0.0654 |test accuracy:0.9710 
Epoch: 0 |Step: 900 |train loss:0.1333 |test accuracy:0.9740 
Epoch: 0 |Step: 1000 |train loss:0.0289 |test accuracy:0.9720 
Epoch: 0 |Step: 1100 |train loss:0.0429 |test accuracy:0.9770 
[7 2 1 0 4 1 4 9 5 9] prediction number 
[7 2 1 0 4 1 4 9 5 9] real number 
'''

 三、分析解读

通过利用torchvision.datasets可以快速获取可以直接置于DataLoader中的dataset格式的数据,通过train参数控制是获取训练数据集还是测试数据集,也可以在获取的时候便直接转换成训练所需的数据格式。

卷积神经网络的搭建通过定义一个CNN类来实现,卷积层conv1,conv2及out层以类属性的形式定义,各层之间的衔接信息在forward中定义,定义的时候要留意各层的神经元数量。

CNN的网络结构如下:

CNN (

 (conv1): Sequential (

  (0): Conv2d(1, 16,kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))

  (1): ReLU ()

  (2): MaxPool2d (size=(2,2), stride=(2, 2), dilation=(1, 1))

 )

 (conv2): Sequential (

  (0): Conv2d(16, 32,kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))

  (1): ReLU ()

  (2): MaxPool2d (size=(2,2), stride=(2, 2), dilation=(1, 1))

 )

 (out): Linear (1568 ->10)

)

经过实验可见,在EPOCH=1的训练结果中,测试集准确率可达到97.7%。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python的collections模块中的OrderedDict有序字典
Jul 07 Python
python之DataFrame实现excel合并单元格
Feb 22 Python
对pandas中时间窗函数rolling的使用详解
Nov 28 Python
Python发送邮件功能示例【使用QQ邮箱】
Dec 04 Python
python调用pyaudio使用麦克风录制wav声音文件的教程
Jun 26 Python
python实现单张图像拼接与批量图片拼接
Mar 23 Python
Python ini文件常用操作方法解析
Apr 26 Python
浅析python 动态库m.so.1.0错误问题
May 09 Python
Python urllib2运行过程原理解析
Jun 04 Python
python如何进行矩阵运算
Jun 05 Python
深入理解Python变量的数据类型和存储
Feb 01 Python
Python爬虫基础初探selenium
May 31 Python
python 日志增量抓取实现方法
Apr 28 #Python
Django 使用logging打印日志的实例
Apr 28 #Python
python实现log日志的示例代码
Apr 28 #Python
Python学习笔记之open()函数打开文件路径报错问题
Apr 28 #Python
Python之读取TXT文件的方法小结
Apr 27 #Python
如何利用python查找电脑文件
Apr 27 #Python
Python3 中把txt数据文件读入到矩阵中的方法
Apr 27 #Python
You might like
php函数实现判断是否移动端访问
2015/03/03 PHP
PHP中抽象类、接口的区别与选择分析
2016/03/29 PHP
控制打印时页眉角的代码
2007/02/08 Javascript
js分页代码分享
2014/04/28 Javascript
使用时间戳解决ie缓存的问题
2014/08/20 Javascript
JavaScript中的继承方式详解
2015/02/11 Javascript
Jquery树插件zTree用法入门教程
2015/02/17 Javascript
js实现带圆角的两级导航菜单效果代码
2015/08/24 Javascript
JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
2015/10/10 Javascript
js生成随机数的过程解析
2015/11/24 Javascript
javascript合并表格单元格实例代码
2016/01/03 Javascript
详解如何将angular-ui的图片轮播组件封装成一个指令
2017/05/09 Javascript
Vue项目中跨域问题解决方案
2018/06/05 Javascript
vue 中使用 watch 出现了如下的报错的原因分析
2019/05/21 Javascript
微信小程序动态设置图片大小的方法
2019/11/21 Javascript
js实现自动播放匀速轮播图
2020/02/06 Javascript
vue过滤器实现日期格式化的案例分析
2020/07/02 Javascript
nodejs中内置模块fs,path常见的用法说明
2020/11/07 NodeJs
[42:23]完美世界DOTA2联赛PWL S3 Forest vs Rebirth 第二场 12.10
2020/12/13 DOTA
python对象及面向对象技术详解
2016/07/19 Python
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
css3实现二维码扫描特效的示例
2020/10/29 HTML / CSS
欧洲著名的珠宝和手表网上商城:uhrcenter
2017/04/10 全球购物
eDreams加拿大:廉价航班、酒店和度假
2019/03/29 全球购物
货代行业个人求职简历的自我评价
2013/10/22 职场文书
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
银行先进个人事迹材料
2014/05/11 职场文书
博士生求职信
2014/07/06 职场文书
励志广播稿300字(5篇)
2014/09/15 职场文书
领导班子个人查摆问题对照检查材料
2014/10/02 职场文书
求职简历自我评价范文
2015/03/10 职场文书
联谊会开场白
2015/06/01 职场文书
在职证明书模板
2015/06/15 职场文书
2015年新教师个人工作总结
2015/10/14 职场文书
教师远程研修感悟
2015/11/18 职场文书
Python文件的操作示例的详细讲解
2021/04/08 Python