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中的对象,方法,类,实例,函数用法分析
Jan 15 Python
Python判断文本中消息重复次数的方法
Apr 27 Python
Python实现信用卡系统(支持购物、转账、存取钱)
Jun 24 Python
JSON Web Tokens的实现原理
Apr 02 Python
Python实现扣除个人税后的工资计算器示例
Mar 26 Python
python 实现判断ip连通性的方法总结
Apr 22 Python
python利用selenium进行浏览器爬虫
Apr 25 Python
Win10下用Anaconda安装TensorFlow(图文教程)
Jun 18 Python
PyCharm+PyQt5+QtDesigner配置详解
Aug 12 Python
如何使用Python调整图像大小
Sep 26 Python
python实现简易自习室座位预约系统
Jun 30 Python
Python实现制作销售数据可视化看板详解
Nov 27 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的一个完整SMTP类(解决邮件服务器需要验证时的问题)
2006/10/09 PHP
PHP 存取 MySQL 数据库的一个例子
2006/10/09 PHP
php使浏览器直接下载pdf文件的方法
2013/11/15 PHP
PHP实现HTML生成PDF文件的方法
2014/11/07 PHP
php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总
2015/04/03 PHP
PHP表单数据写入MySQL数据库的代码
2016/05/31 PHP
JavaScript更改class和id的方法
2008/10/10 Javascript
jQuery+CSS 实现的超Sexy下拉菜单
2010/01/17 Javascript
js 图片等比例缩放代码
2010/05/13 Javascript
location对象的属性和方法应用(解析URL)
2013/04/12 Javascript
使用简洁的jQuery方法实现隔行换色功能
2014/01/02 Javascript
JS合并数组的几种方法及优劣比较
2014/09/19 Javascript
jQuery实现提示密码强度的代码
2015/07/15 Javascript
AngularJS中实现显示或隐藏动画效果的方式总结
2015/12/31 Javascript
JS实现物体带缓冲的间歇运动效果示例
2016/12/22 Javascript
解决vue页面DOM操作不生效的问题
2018/03/17 Javascript
详解使用jest对vue项目进行单元测试
2018/09/07 Javascript
vue2.0 路由模式mode="history"的作用
2018/10/18 Javascript
jQuery 图片查看器插件 Viewer.js用法简单示例
2020/04/04 jQuery
解决Vue watch里调用方法的坑
2020/11/07 Javascript
vue实现拖拽进度条
2021/03/01 Vue.js
[03:48]2014DOTA2 TI专访71DK夺冠不靠小组赛高排名
2014/07/11 DOTA
压缩包密码破解示例分享(类似典破解)
2014/01/17 Python
Python中字典映射类型的学习教程
2015/08/20 Python
Python对数据库操作
2016/03/28 Python
Python 判断是否为质数或素数的实例
2017/10/30 Python
浅谈python中对于json写入txt文件的编码问题
2018/06/07 Python
python导入坐标点的具体操作
2019/05/10 Python
keras分类模型中的输入数据与标签的维度实例
2020/07/03 Python
mac系统下安装pycharm、永久激活、中文汉化详细教程
2020/11/24 Python
利用css3 translate完美实现表头固定效果
2017/02/28 HTML / CSS
Python面试题:Python里面如何生成随机数
2015/03/12 面试题
文明倡议书范文
2014/04/15 职场文书
护士上岗前培训自我鉴定
2014/04/20 职场文书
汽车4S店销售经理岗位职责
2015/04/02 职场文书
2015年消防工作总结
2015/04/24 职场文书