参考博客:https://www.cnblogs.com/further-further-further/p/10737065.html
目录
1.踩过的坑(tensorflow)
2.tensorboard
3.代码实现(python3.5)
4.运行结果以及分析
1.踩过的坑(tensorflow)
上一章CNN中各个算法都是纯手工实现的,可能存在一些难以发现的问题,这也是准确率不高的一个原因,这章主要利用tensorflow框架来实现卷积神经网络,数据源还是cifar(具体下载见上一章)
在利用tensorflow框架实现CNN时,需要注意以下几点:
1.输入数据定义时,x只是起到占位符的作用(看不到真实值,只是为了能够运行代码,获取相应的tensor节点,这一点跟我们之前代码流程完全相反, 真正数据流的执行在session会话里)
x:输入数据,y_: 标签数据,keep_prob: 概率因子,防止过拟合。
定义,且是全局变量。
x = tf.placeholder(tf.float32, [None, 3072], name='x')
y_ = tf.placeholder(tf.float32, [None, 10], name='y_')
keep_prob = tf.placeholder(tf.float32)
后面在session里必须要初始化
train_accuracy = accuracy.eval(feed_dict={
x: batch[0], y_: batch[1], keep_prob: 1.0})
在session run时必须要传得到该tensor节点含有参数值(x, y_, keep_prob)
sess.run(tf.global_variables_initializer())
2.原始数据集标签要向量化;
例如cifar有10个类别,如果类别标签是 6 对应向量[0,0,0,0,0,1,0,0,0,0]
3.知道每一步操作的数据大小的变化,不然,报错的时候很难定位(个人认为这也是tensorflow的弊端,无法实时追踪定位);
注意padding = 'SAME’和’VALID’的区别
padding = ‘SAME’ => Height_后 = Height_前/Strides 跟padding无关 向上取整
padding = ‘VALID’=> Height_后 = (Height_前 - Filter + 1)/Strides 向上取整
4.打印tensorboard流程图,可以直观看到每步操作数据大小的变化;
- tensorboard
tensorboard就是一个数据结构流程图的可视化工具,通过tensorboard流程图,可以直观看到神经网络的每一步操作以及数据流的变化。
操作步骤:
- 在session会话里加入如下代码,打印结果会在当前代码文件相同路径的tensorboard文件下,默认是
start.py
tf.summary.FileWriter("tensorboard/", sess.graph)
- 在运行里输入cmd,然后输入(前提是安装好了tensorboard => pip install tensorboard)
tensorboard --logdir=D:\Project\python\myProject\CNN\tensorflow\captchaIdentify\tensorboard --host=127.0.0.1
‘D:\Project\python\myProject\CNN\tensorflow\captchaIdentify\tensorboard’ 是我生成的tensorboard文件的绝对路径,你替换成你自己的就可以了。
正确运行后会显示 ‘Tensorboard at http://127.0.0.1:6006’,说明tensorboard服务已经起来了,在浏览器页面输入
http://127.0.0.1:6006即可显示流程图。
3.代码实现(python3.6)
代码逻辑实现相对比较简单,在一些重要逻辑实现上,我已做了注释,如果大家有什么疑义,可以留言给我,我们一起交流。
因为原始图片数据集太大,不好上传,大家可以直接在http://www.cs.toronto.edu/~kriz/cifar.html下载CIFAR-10 python version,
有163M,放在代码文件同路径下即可。
cifar放置路径
# co
ding=utf-8
# Disable linter warnings to maintain consistency with tutorial.
# pylint: disable=invalid-name
# pylint: disable=g-bad-import-order
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import sys
import tempfile
#from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
'''
卷积神经网络实现10类(airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck)
60000张图片的识别
5000次,准确率有 58%;
20000次,准确率有 68.89%;
相比mnist数字图片识别准确度低,原因有:
mnist训练图片是灰度图片,纹理简单,数字的可变性小,而cifar是彩色图片,纹理复杂,动物可变性大;
'''
#导入数据库
try:
from . import datesets
except Exception:
import datesets
FLAGS = None
def deepnn(x):
with tf.name_scope('reshape'):
x_image = tf.reshape(x, [-1, 32, 32, 3])#-1 表示不知道该填什么数字合适的情况下
## 第一层卷积操作 ##
with tf.name_scope('conv1'):
W_conv1 = weight_variable([5, 5, 3, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
#tf.nn.conv2d(input_data, filter_data, strides = [1, 1, 1, 1], padding = 'SAME')
#input是一个4d输入[batch_size, in_height, in_width, n_channels],表示图片的批数,大小和通道。
#filter是一个4d输入[filter_height, filter_width, in_channels, out_channels],表示kernel的大小,输入通道数和输出通道数,其中输出通道数表示从上一层提取多少特征。
#strides是一个1d输入,长度为4,其中stride[0]和stride[3]必须为1,一般格式为[1, stride[1], stride[2], 1],在大部分情况下,因为在height和width上的步进设为一样,因此通常为[1, stride, stride, 1]。
#padding是一个字符串输入,分为SAME和VALID分别表示是否需要填充,因为卷积完之后因为周围的像素没有卷积到,因此一般是会出现卷积完的输出尺寸小于输入的现象的.
with tf.name_scope('pool1'):
h_pool1 = max_pool_2x2(h_conv1)
# Second convolutional layer -- maps 32 feature maps to 64.
## 第二层卷积操作 ##
with tf.name_scope('conv2'):
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
with tf.name_scope('pool2'):
h_pool2 = max_pool_2x2(h_conv2)
## 第三层全连接操作 ##
with tf.name_scope('fc1'):
W_fc1 = weight_variable([8 * 8 * 64, 1024])
b_fc1 =