前面篇幅介绍的全连接层和简单卷积神经网络,层数都比较少,现在来加多几层,对于加深了的深度神经网络,其实就是我们常说的深度学习,类似搭积木,只需要叠加层即可。现在来构建一个深度的CNN,这里使用的卷积层全是3x3的小型滤波器,特点是随着层的加深,通道数在变大,然后经过池化层逐渐减小中间数据的空间大小。
我们还是使用MNIST手写数据集来实现这个深度CNN,网络结构如下:

输入图片-->Conv-->ReLU-->Conv-->ReLU-->Pool-->Conv-->ReLU-->Conv-->ReLU-->Pool-->Conv-->ReLU-->Conv-->ReLU-->Pool-->Affine-->ReLU-->Dropout-->Affine-->Dropout-->Softmax-->分类输出

deepconv.py

import numpy as np
import pickle
from collections import OrderedDict
from common.layers import *class DeepConvNet:'''深度的卷积网络层(3x3的滤波器)结构层(6个卷积层+3个池化层,全连接层后面用dropout):conv-relu-conv-relu-pool-       [16个滤波器]conv-relu-conv-relu-pool-       [32个滤波器]conv-relu-conv-relu-pool-       [64个滤波器]affine-relu-dropout-affine-dropout-softmax'''def __init__(self, input_dim=(1, 28, 28),conv1={'filterNum':16,'filterSize':3,'pad':1,'stride':1},conv2={'filterNum':16,'filterSize':3,'pad':1,'stride':1},conv3={'filterNum':32,'filterSize':3,'pad':1,'stride':1},conv4={'filterNum':32,'filterSize':3,'pad':2,'stride':1},conv5={'filterNum':64,'filterSize':3,'pad':1,'stride':1},conv6={'filterNum':64,'filterSize':3,'pad':1,'stride':1},hiddenSize=50, outputSize=10):#上一层的神经元数量pre_n=np.array([1*3*3,16*3*3,16*3*3,32*3*3,32*3*3,64*3*3,64*4*4,hiddenSize])#权重初始值使用He,因为激活函数是ReLUweight_inits=np.sqrt(2.0/pre_n)self.params={}pre_channel_n=input_dim[0]#通道数,每经过一个卷积层更新for i,conv in enumerate([conv1,conv2,conv3,conv4,conv5,conv6]):self.params['W'+str(i+1)]=weight_inits[i]*np.random.randn(conv['filterNum'],pre_channel_n,conv['filterSize'],conv['filterSize'])self.params['b'+str(i+1)]=np.zeros(conv['filterNum'])pre_channel_n=conv['filterNum']#更新通道数self.params['W7']=weight_inits[6]*np.random.randn(64*4*4,hiddenSize)self.params['b7']=np.zeros(hiddenSize)self.params['W8']=weight_inits[7]*np.random.randn(hiddenSize,outputSize)self.params['b8']=np.zeros(outputSize)#生成各层(21层)self.layers=[]self.layers.append(Convolution(self.params['W1'],self.params['b1'],conv1['stride'],conv1['pad']))self.layers.append(Relu())self.layers.append(Convolution(self.params['W2'],self.params['b2'],conv2['stride'],conv2['pad']))self.layers.append(Relu())self.layers.append(Pooling(pool_h=2,pool_w=2,stride=2))self.layers.append(Convolution(self.params['W3'],self.params['b3'],conv3['stride'],conv3['pad']))self.layers.append(Relu())self.layers.append(Convolution(self.params['W4'],self.params['b4'],conv4['stride'],conv4['pad']))self.layers.append(Relu())self.layers.append(Pooling(pool_h=2,pool_w=2,stride=2))self.layers.append(Convolution(self.params['W5'],self.params['b5'],conv5['stride'],conv5['pad']))self.layers.append(Relu())self.layers.append(Convolution(self.params['W6'],self.params['b6'],conv6['stride'],conv6['pad']))self.layers.append(Relu())self.layers.append(Pooling(pool_h=2,pool_w=2,stride=2))self.layers.append(Affine(self.params['W7'],self.params['b7']))self.layers.append(Relu())self.layers.append(Dropout(0.5))self.layers.append(Affine(self.params['W8'],self.params['b8']))self.layers.append(Dropout(0.5))self.last_layer=SoftmaxWithLoss()def predict(self,x,train_flg=False):for layer in self.layers:if isinstance(layer,Dropout):#判断层是不是Dropout类型x=layer.forward(x,train_flg)else:x=layer.forward(x)return xdef loss(self,x,t):y=self.predict(x,train_flg=True)return self.last_layer.forward(y,t)def accuracy(self,x,t,batch_size=100):if t.ndim!=1:t=np.argmax(t,axis=1)acc=0.0for i in range(int(x.shape[0]/batch_size)):tx=x[i*batch_size:(i+1)*batch_size]tt=t[i*batch_size:(i+1)*batch_size]y=self.predict(tx,train_flg=False)y=np.argmax(y,axis=1)acc+=np.sum(y==tt)return acc/x.shape[0]def gradient(self,x,t):#forwardself.loss(x,t)#backwarddout=1dout=self.last_layer.backward(dout)tmp_layers=self.layers.copy()tmp_layers.reverse()for layer in tmp_layers:dout=layer.backward(dout)grads={}#遍历包含权重偏置的层for i,layer_i in enumerate((0,2,5,7,10,12,15,18)):grads['W'+str(i+1)]=self.layers[layer_i].dWgrads['b'+str(i+1)]=self.layers[layer_i].dbreturn gradsdef save_params(self,fname='params.pkl'):params={}for k,v in self.params.items():params[k]=vwith open(fname,'wb') as f:pickle.dump(params,f)def load_params(self,fname='params.pkl'):with open(fname,'rb') as f:params=pickle.load(f)for k,v in params.items():self.params[k]=vfor i,layer_i in enumerate((0,2,5,7,10,12,15,18)):self.layers[layer_i].W=self.params['W'+str(i+1)]self.layers[layer_i].b=self.params['b'+str(i+1)]

测试精度并保存学习后的参数,代码如下:

import numpy as np
from dataset.mnist import load_mnist
from deepconv import DeepConvNet
from common.trainer import Trainer#加载MNIST数据集
(x_train,t_train),(x_test,t_test)=load_mnist(flatten=False)#深度学习CNN
network=DeepConvNet()
trainer=Trainer(network,x_train,t_train,x_test,t_test,epochs=20,mini_batch_size=100,optimizer='Adam',optimizer_param={'lr':0.001},evaluate_sample_num_per_epoch=1000)
trainer.train()#保存学习的权重偏置参数,方便后续调用
network.save_params('DeepCNN_Params.pkl')
print('保存参数成功!')

上面代码的训练大概花费了6~7个小时(本人配置一般的电脑),接下来我们直接来加载深度学习完保存的权重偏置参数的pkl文件,看下这个深度CNN的精度能达到多少,以及查看20个没有被正确识别的数字图片有什么特征。

import numpy as np
import matplotlib.pyplot as plt
from deepconv import DeepConvNet
from dataset.mnist import load_mnist#加载MNIST数据集
#((60000, 1, 28, 28), (60000,)) ((10000, 1, 28, 28), (10000,))
(x_train,t_train),(x_test,t_test)=load_mnist(flatten=False)#深度学习CNN
network=DeepConvNet()
#加载生成的权重参数文件
network.load_params('DeepCNN_Params.pkl')print('正在计算识别的精度......')
#保存分类的标签索引值
classified_label_idxs=[]
acc=0.0
batchSize=100
for i in range(int(x_test.shape[0]/batchSize)):tx=x_test[i*batchSize:(i+1)*batchSize]#图片(100,1,28,28)tt=t_test[i*batchSize:(i+1)*batchSize]#正确解标签(100,1)y=network.predict(tx,train_flg=False)y=np.argmax(y,axis=1)#预测出的图片的最大索引值classified_label_idxs.append(y)#(100,100)acc+=np.sum(y==tt)#将正确预测的进行累加
acc=acc/x_test.shape[0]
print('测试的精度:'+str(acc))classified_label_idxs=np.array(classified_label_idxs)
classified_label_idxs=classified_label_idxs.flatten()#画出识别错误的图片
c_img=1
fig=plt.figure()
fig.subplots_adjust(left=0,right=1,bottom=0,top=1,hspace=0.2,wspace=0.2)
errors={}
for i,v in enumerate(classified_label_idxs==t_test):if not v:ax=fig.add_subplot(4,5,c_img,xticks=[],yticks=[])ax.imshow(x_test[i].reshape(28,28),cmap=plt.cm.gray_r,interpolation='nearest')errors[c_img]=(t_test[i],classified_label_idxs[i])c_img+=1if c_img>20:break
print("识别错误的数字对:{0}".format(errors))
plt.show()

正在计算识别的精度......
测试的精度:0.9929
识别错误的数字对:{1: (4, 2), 2: (6, 0), 3: (8, 9), 4: (7, 9), 5: (8, 2), 6: (5, 3), 7: (7, 9), 8: (7, 9), 9: (4, 2), 10: (8, 9), 11: (6, 5), 12: (7, 1), 13: (4, 6), 14: (7, 2), 15: (9, 4), 16: (4, 9), 17: (7, 3), 18: (7, 9), 19: (4, 9), 20: (7, 9)}

我们发现精度又提高了,基本在99.3%左右,有时会达到99.4%以上,这个已经是很不错的识别精度了,而我们观察那些没有被正确识别的数字图片,其实有时连我们自己也有点分辨不清楚,比如第二个,正确数字是6,容易看成是0,这就让深度学习增加了更大可能。

ValueError: shapes (100,576) and (1024,50) not aligned: 576 (dim 1) != 1024 (dim 0)
做dot点积运算的时候,形状不匹配不一致导致的。
这个是我在conv4 = {'filterNum':32, 'filterSize':3, 'pad':2, 'stride':1},
其中的pad填充填写成了1,这就造成了形状不能对齐!

DeepCNN_Params.pkl文件下载地址

深度的卷积神经网络CNN(MNIST数据集示例)相关推荐

  1. 基于Python实现的卷积神经网络分类MNIST数据集

    卷积神经网络分类MNIST数据集 目录 人工智能第七次实验报告 1 卷积神经网络分类MNIST数据集 1 一 .问题背景 1 1.1 卷积和卷积核 1 1.2 卷积神经网络简介 2 1.3 卷积神经网 ...

  2. [转载] 卷积神经网络做mnist数据集识别

    参考链接: 卷积神经网络在mnist数据集上的应用 Python TensorFlow是一个非常强大的用来做大规模数值计算的库.其所擅长的任务之一就是实现以及训练深度神经网络. 在本教程中,我们将学到 ...

  3. 深度学习--卷积神经网络CNN

    主要内容 1. 神经网络 1.1 感知器 1.2 Sigmoid神经元 1.3 神经网络 2. 卷积神经网络CNN 2.1 卷积神经网络结构 2.2 数据输入层 2.3 卷积层 2.3.1 局部感知( ...

  4. 深度学习——卷积神经网络CNN

    这两天看了不少讲卷积神经网络的文章和视频,由于我本人才疏学浅,在学习过程中基本上是一头雾水,导致的结果就是不过幸好,在快要绝望的时候,我在知乎上发现了一篇宝藏文章卷积神经网络CNN完全指南终极版这篇文 ...

  5. 深度学习之利用TensorFlow实现简单的卷积神经网络(MNIST数据集)

    卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习 ...

  6. Pytorch 实现全连接神经网络/卷积神经网络训练MNIST数据集,并将训练好的模型在制作自己的手写图片数据集上测试

    使用教程 代码下载地址:点我下载 模型在训练过程中会自动显示训练进度,如果您的pytorch是CPU版本的,代码会自动选择CPU训练,如果有cuda,则会选择GPU训练. 项目目录说明: CNN文件夹 ...

  7. 一种基于深度学习(卷积神经网络CNN)的人脸识别算法-含Matlab代码

    目录 一.引言 二.算法的基本思想 三.算法数学原理 3.1 权值共享 3.2 CNN结构 四.基于卷积神经网络的人脸识别算法-Matlab代码 五.Matlab源代码获取 一.引言 在工程应用中经常 ...

  8. 深度学习 --- 卷积神经网络CNN(LeNet-5网络学习算法详解)

    上一节我们详细探讨了LeNet-5网络的架构,但是还没有解释该网络是如何进行学习的,如何更新权值的,本节将接着上一节进一步CNN的学习机制和权值更新过程,这里请大家一定要对CNN网络有一个清晰的认识, ...

  9. 深度学习 --- 卷积神经网络CNN(LeNet-5网络详解)

    卷积神经网络(Convolutional Neural Network,CNN)是一种前馈型的神经网络,其在大型图像处理方面有出色的表现,目前已经被大范围使用到图像分类.定位等领域中.相比于其他神经网 ...

最新文章

  1. 好多Javascript日期选择器呀-4
  2. NetBeans使用介绍(五)
  3. 如何判断京东达人文章是否下线
  4. unity android 原生,unity创建Android原生插件
  5. linux samba 多个目录,linux7 Samba服务配置,多个部门相应管理自己的项目目录,其他有访问权限...
  6. 各操作系统各文件系统支持的最大文件的大小
  7. npm install -s -d -g之间的区别
  8. 定时任务:java 中Timer 和 TimerTask 的使用
  9. mysql 去重命令_MySQL 命令操作
  10. 图书管理系统(课程设计)
  11. 【技术框架汇总】_开发平台_前端框架_手机端框架_测试工具_数据库中间件_监控工具_框架_汇总
  12. FPGA:生成占空比可调的PWM波
  13. (附源码)springboot物联网智能管理平台 毕业设计 211120
  14. 第二周预习——html常用标签,认识浏览器
  15. 降噪耳机推荐,四款优秀的降噪耳机分享
  16. mysql候选关键字_MySQL(三)之SQL语句分类、基本操作、三大范式
  17. 博特电子-17届智能车无线充电组恒功率方案
  18. IOS开发之—— IOS 支付 [支付宝、银联、微信]
  19. 【恢复案例】国内某公司服务器感染.[ideapad@privatemail.com].mkp新型勒索病毒
  20. vue-resource post php,Vue学习笔记进阶篇——vue-resource安装及使用

热门文章

  1. 通用mapper版+SpringBoot+MyBatis框架+mysql数据库的整合
  2. cocos2d(背景图片循环滚动)
  3. jzxx1000~1010题分析
  4. 理解typedef(转)
  5. iframe高度自适应的实现
  6. WebStorm-2018.2.2配置
  7. 管理博文Hive大数据-Mysql的安装和启动---大数据之Hive工作笔记0007
  8. AndroidStudio_你的主机中的软件中止了一个已建立的连接---Android原生开发工作笔记123
  9. C++_二维数组_定义方式_数组名称的作用_案例考试成绩统计---C++语言工作笔记021
  10. Netty工作笔记0057---Netty群聊系统服务端