TensorFlow实现简单的CNN的方法


Posted in Python onJuly 18, 2019

这里,我们将采用Tensor Flow内建函数实现简单的CNN,并用MNIST数据集进行测试

第1步:加载相应的库并创建计算图会话

import numpy as np
import tensorflow as tf
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
import matplotlib.pyplot as plt
 
#创建计算图会话
sess = tf.Session()

第2步:加载MNIST数据集,这里采用TensorFlow自带数据集,MNIST数据为28×28的图像,因此将其转化为相应二维矩阵

#数据集
data_dir = 'MNIST_data'
mnist = read_data_sets(data_dir)
 
train_xdata = np.array([np.reshape(x,[28,28]) for x in mnist.train.images] )
test_xdata = np.array([np.reshape(x,[28,28]) for x in mnist.test.images] )
 
train_labels = mnist.train.labels
test_labels = mnist.test.labels

第3步:设置模型参数

这里采用随机批量训练的方法,每训练10次对测试集进行测试,共迭代1500次,学习率采用指数下降的方式,初始学习率为0.1,每训练10次,学习率乘0.9,为了进行对比,后面会给出固定学习率为0.01的损失曲线图和准确率图

#设置模型参数
 
batch_size = 100 #批量训练图像张数
initial_learning_rate = 0.1 #学习率
global_step = tf.Variable(0, trainable=False) ;
learning_rate = tf.train.exponential_decay(initial_learning_rate,
                      global_step=global_step,
                      decay_steps=10,decay_rate=0.9)
 
evaluation_size = 500 #测试图像张数
 
image_width = 28 #图像的宽和高
image_height = 28
 
target_size = 10  #图像的目标为0~9共10个目标
num_channels = 1    #灰度图,颜色通道为1
generations = 1500  #迭代500次
evaluation_step = 10 #每训练十次进行一次测试
 
conv1_features = 25  #卷积层的特征个数
conv2_features = 50
 
max_pool_size1 = 2  #池化层大小
max_pool_size2 = 2
 
fully_connected_size = 100 #全连接层的神经元个数

第4步:声明占位符,注意这里的目标y_target类型为int32整型

#声明占位符
 
x_input_shape = [batch_size,image_width,image_height,num_channels]
x_input = tf.placeholder(tf.float32,shape=x_input_shape)
y_target = tf.placeholder(tf.int32,shape=[batch_size])
 
evaluation_input_shape = [evaluation_size,image_width,image_height,num_channels]
evaluation_input = tf.placeholder(tf.float32,shape=evaluation_input_shape)
evaluation_target = tf.placeholder(tf.int32,shape=[evaluation_size])

第5步:声明卷积层和全连接层的权重和偏置,这里采用2层卷积层和1层隐含全连接层

#声明卷积层的权重和偏置
#卷积层1
#采用滤波器为4X4滤波器,输入通道为1,输出通道为25
conv1_weight = tf.Variable(tf.truncated_normal([4,4,num_channels,conv1_features],stddev=0.1,dtype=tf.float32))
conv1_bias = tf.Variable(tf.truncated_normal([conv1_features],stddev=0.1,dtype=tf.float32))
 
#卷积层2
#采用滤波器为4X4滤波器,输入通道为25,输出通道为50
conv2_weight = tf.Variable(tf.truncated_normal([4,4,conv1_features,conv2_features],stddev=0.1,dtype=tf.float32))
conv2_bias = tf.Variable(tf.truncated_normal([conv2_features],stddev=0.1,dtype=tf.float32))
 
#声明全连接层权重和偏置
 
#卷积层过后图像的宽和高
conv_output_width = image_width // (max_pool_size1 * max_pool_size2) #//表示整除
conv_output_height = image_height // (max_pool_size1 * max_pool_size2)
 
#全连接层的输入大小
full1_input_size = conv_output_width * conv_output_height *conv2_features
 
full1_weight = tf.Variable(tf.truncated_normal([full1_input_size,fully_connected_size],stddev=0.1,dtype=tf.float32))
full1_bias = tf.Variable(tf.truncated_normal([fully_connected_size],stddev=0.1,dtype=tf.float32))
 
full2_weight = tf.Variable(tf.truncated_normal([fully_connected_size,target_size],stddev=0.1,dtype=tf.float32))
full2_bias = tf.Variable(tf.truncated_normal([target_size],stddev=0.1,dtype=tf.float32))

第6步:声明CNN模型,这里的两层卷积层均采用Conv-ReLU-MaxPool的结构,步长为[1,1,1,1],padding为SAME

全连接层隐层神经元为100个,输出层为目标个数10

def my_conv_net(input_data):
 
  #第一层:Conv-ReLU-MaxPool
  conv1 = tf.nn.conv2d(input_data,conv1_weight,strides=[1,1,1,1],padding='SAME')
  relu1 = tf.nn.relu(tf.nn.bias_add(conv1,conv1_bias))
  max_pool1 = tf.nn.max_pool(relu1,ksize=[1,max_pool_size1,max_pool_size1,1],strides=[1,max_pool_size1,max_pool_size1,1],padding='SAME')
 
  #第二层:Conv-ReLU-MaxPool
  conv2 = tf.nn.conv2d(max_pool1, conv2_weight, strides=[1, 1, 1, 1], padding='SAME')
  relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_bias))
  max_pool2 = tf.nn.max_pool(relu2, ksize=[1, max_pool_size2, max_pool_size2, 1],
                strides=[1, max_pool_size2, max_pool_size2, 1], padding='SAME')
 
  #全连接层
  #先将数据转化为1*N的形式
  #获取数据大小
  conv_output_shape = max_pool2.get_shape().as_list()
  #全连接层输入数据大小
  fully_input_size = conv_output_shape[1]*conv_output_shape[2]*conv_output_shape[3] #这三个shape就是图像的宽高和通道数
  full1_input_data = tf.reshape(max_pool2,[conv_output_shape[0],fully_input_size])  #转化为batch_size*fully_input_size二维矩阵
  #第一层全连接
  fully_connected1 = tf.nn.relu(tf.add(tf.matmul(full1_input_data,full1_weight),full1_bias))
  #第二层全连接输出
  model_output = tf.nn.relu(tf.add(tf.matmul(fully_connected1,full2_weight),full2_bias))#shape = [batch_size,target_size]
 
  return model_output
 
model_output = my_conv_net(x_input)
test_model_output = my_conv_net(evaluation_input)

第7步:定义损失函数,这里采用softmax函数作为损失函数

#损失函数
 
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=model_output,labels=y_target))

第8步:建立测评与评估函数,这里对输出层进行softmax,再通过np.argmax找出每行最大的数所在位置,再与目标值进行比对,统计准确率

#预测与评估
prediction = tf.nn.softmax(model_output)
test_prediction = tf.nn.softmax(test_model_output)
 
def get_accuracy(logits,targets):
  batch_predictions = np.argmax(logits,axis=1)#返回每行最大的数所在位置
  num_correct = np.sum(np.equal(batch_predictions,targets))
  return 100*num_correct/batch_predictions.shape[0]

第9步:初始化模型变量并创建优化器

#创建优化器
opt = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
train_step = opt.minimize(loss)
 
#初始化变量
init = tf.initialize_all_variables()
sess.run(init)

第10步:随机批量训练并进行绘图

#开始训练
 
train_loss = []
train_acc = []
test_acc = []
Learning_rate_vec = []
for i in range(generations):
  rand_index = np.random.choice(len(train_xdata),size=batch_size)
  rand_x = train_xdata[rand_index]
  rand_x = np.expand_dims(rand_x,3)
  rand_y = train_labels[rand_index]
  Learning_rate_vec.append(sess.run(learning_rate, feed_dict={global_step: i}))
  train_dict = {x_input:rand_x,y_target:rand_y}
 
  sess.run(train_step,feed_dict={x_input:rand_x,y_target:rand_y,global_step:i})
  temp_train_loss = sess.run(loss,feed_dict=train_dict)
  temp_train_prediction = sess.run(prediction,feed_dict=train_dict)
  temp_train_acc = get_accuracy(temp_train_prediction,rand_y)
 
  #测试集
  if (i+1)%evaluation_step ==0:
    eval_index = np.random.choice(len(test_xdata),size=evaluation_size)
    eval_x = test_xdata[eval_index]
    eval_x = np.expand_dims(eval_x,3)
    eval_y = test_labels[eval_index]
 
 
    test_dict = {evaluation_input:eval_x,evaluation_target:eval_y}
    temp_test_preds = sess.run(test_prediction,feed_dict=test_dict)
    temp_test_acc = get_accuracy(temp_test_preds,eval_y)
 
    test_acc.append(temp_test_acc)
  train_acc.append(temp_train_acc)
  train_loss.append(temp_train_loss)
 
 
 
 
#画损失曲线
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(train_loss,'k-')
ax.set_xlabel('Generation')
ax.set_ylabel('Softmax Loss')
fig.suptitle('Softmax Loss per Generation')
 
#画准确度曲线
index = np.arange(start=1,stop=generations+1,step=evaluation_step)
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.plot(train_acc,'k-',label='Train Set Accuracy')
ax2.plot(index,test_acc,'r--',label='Test Set Accuracy')
ax2.set_xlabel('Generation')
ax2.set_ylabel('Accuracy')
fig2.suptitle('Train and Test Set Accuracy')
 
 
#画图
fig3 = plt.figure()
actuals = rand_y[0:6]
train_predictions = np.argmax(temp_train_prediction,axis=1)[0:6]
images = np.squeeze(rand_x[0:6])
Nrows = 2
Ncols =3
 
for i in range(6):
  ax3 = fig3.add_subplot(Nrows,Ncols,i+1)
  ax3.imshow(np.reshape(images[i],[28,28]),cmap='Greys_r')
  ax3.set_title('Actual: '+str(actuals[i]) +' pred: '+str(train_predictions[i]))
 
 
#画学习率
fig4 = plt.figure()
ax4 = fig4.add_subplot(111)
ax4.plot(Learning_rate_vec,'k-')
ax4.set_xlabel('step')
ax4.set_ylabel('Learning_rate')
fig4.suptitle('Learning_rate')
 
 
 
plt.show()

下面给出固定学习率图像和学习率随迭代次数下降的图像:

首先给出固定学习率图像:

下面是损失曲线

TensorFlow实现简单的CNN的方法

下面是准确率

TensorFlow实现简单的CNN的方法

我们可以看出,固定学习率损失函数下降速度较缓,同时其最终准确率为80%~90%之间就不再提高了

下面给出学习率随迭代次数降低的曲线:

首先给出学习率随迭代次数降低的损失曲线

TensorFlow实现简单的CNN的方法

然后给出相应的准确率曲线

TensorFlow实现简单的CNN的方法

我们可以看出其损失函数下降很快,同时准确率也可以达到90%以上

下面给出随机抓取的图像相应的识别情况:

TensorFlow实现简单的CNN的方法

至此我们实现了简单的CNN来实现MNIST手写图数据集的识别,如果想进一步提高其准确率,可以通过改变CNN网络参数,如通道数、全连接层神经元个数,过滤器大小,学习率,训练次数,加入dropout层等等,也可以通过增加CNN网络深度来进一步提高其准确率

下面给出一组参数:

初始学习率:initial_learning_rate=0.05

迭代步长:decay_steps=50,每50步改变一次学习率

下面是仿真结果:

TensorFlow实现简单的CNN的方法

TensorFlow实现简单的CNN的方法

TensorFlow实现简单的CNN的方法

TensorFlow实现简单的CNN的方法

我们可以看出,通过调整超参数,其既保证了损失函数能够快速下降,又进一步提高了其模型准确率,我们在训练次数为1500次的基础上,准确率已经达到97%以上。

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

Python 相关文章推荐
python读写ini文件示例(python读写文件)
Mar 25 Python
Python入门教程之if语句的用法
May 14 Python
python如何实现excel数据添加到mongodb
Jul 30 Python
python cs架构实现简单文件传输
Mar 20 Python
numpy.meshgrid()理解(小结)
Aug 01 Python
关于PyTorch源码解读之torchvision.models
Aug 17 Python
python保存log日志,实现用log日志画图
Dec 24 Python
Django+boostrap 美化admin后台的操作
Mar 11 Python
Python selenium页面加载慢超时的解决方案
Mar 18 Python
踩坑:pytorch中eval模式下结果远差于train模式介绍
Jun 23 Python
详解Python中的Lock和Rlock
Jan 26 Python
OpenCV-Python实现人脸磨皮算法
Jun 07 Python
windows上安装python3教程以及环境变量配置详解
Jul 18 #Python
Django 开发环境配置过程详解
Jul 18 #Python
解决Django中多条件查询的问题
Jul 18 #Python
python openpyxl使用方法详解
Jul 18 #Python
Python Django基础二之URL路由系统
Jul 18 #Python
使用django的objects.filter()方法匹配多个关键字的方法
Jul 18 #Python
Django基础三之视图函数的使用方法
Jul 18 #Python
You might like
PHP 递归效率分析
2009/11/24 PHP
php面向对象 字段的声明与使用
2012/06/14 PHP
Yii框架中sphinx索引配置方法解析
2016/10/18 PHP
2020最新版 PhpStudy V8.1版本下载安装使用详解
2020/10/30 PHP
基于Jquery的动态创建DOM元素的代码
2010/12/28 Javascript
利用Javascript判断操作系统的类型实现不同操作系统下的兼容性
2013/01/29 Javascript
JS刷新框架外页面七种实现代码
2013/02/18 Javascript
使用Java实现简单的server/client回显功能的方法介绍
2013/05/03 Javascript
方便实用的jQuery checkbox复选框全选功能简单实例
2013/10/09 Javascript
页面js遇到乱码问题的解决方法是和无法转码的情况
2014/04/30 Javascript
基于JS2Image实现圣诞树代码
2015/12/24 Javascript
BootStrap创建响应式导航条实例代码
2016/05/31 Javascript
详解AngularJS中ng-src指令的使用
2016/09/07 Javascript
在Vue项目中引入腾讯验证码服务的教程
2018/04/03 Javascript
Vue2.0 实现单选互斥的方法
2018/04/13 Javascript
[58:59]完美世界DOTA2联赛PWL S3 access vs CPG 第一场 12.13
2020/12/16 DOTA
Python基于scrapy采集数据时使用代理服务器的方法
2015/04/16 Python
Python yield与实现方法代码分析
2018/02/06 Python
pandas 使用均值填充缺失值列的小技巧分享
2019/07/04 Python
Python 迭代,for...in遍历,迭代原理与应用示例
2019/10/12 Python
Selenium alert 弹窗处理的示例代码
2020/08/06 Python
如何在Python3中使用telnetlib模块连接网络设备
2020/09/21 Python
python 使用csv模块读写csv格式文件的示例
2020/12/02 Python
解析HTML5中的新功能本地存储localStorage
2016/03/01 HTML / CSS
EJB3推出JPA的原因
2013/10/16 面试题
会计岗位描述
2014/02/22 职场文书
商务宴请邀请函范文
2015/02/02 职场文书
2016年寒假社会实践活动总结
2015/03/27 职场文书
一般纳税人申请报告
2015/05/18 职场文书
英雄儿女观后感
2015/06/09 职场文书
股东出资协议书
2016/03/21 职场文书
numpy数据类型dtype转换实现
2021/04/24 Python
python_tkinter弹出对话框创建
2022/03/20 Python
Python如何快速找到多个字典中的公共键(key)
2022/04/29 Python
MySQL如何使备份得数据保持一致
2022/05/02 MySQL
vue/cli 配置动态代理无需重启服务的方法
2022/05/20 Vue.js