入门篇
《Tensorflow入门(六)——初识卷积神经网络(CNN)》
《Tensorflow入门(七)——CNN经典模型:LeNet》
原文链接:https://my.oschina.net/u/876354/blog/1926060
本文在原文基础上进行细微的修改和完善。
关于MNIST的介绍可以参考《Tensorflow实战(一)——MNIST》
在构建AI模型时,一般有以下主要步骤:准备数据、数据预处理、划分数据集、配置模型、训练模型、评估优化、模型应用,如下图所示:

下面将按照主要步骤进行介绍。
注意: 由于MNIST数据集太经典了,很多深度学习书籍在介绍该入门模型案例时,基本上就是直接下载获取数据,然后就进行模型训练,最后得出一个准确率出来。但这样的入门案例学习后,当要拿自己的数据来训练模型,却往往不知该如何处理数据、如何训练、如何应用。在本文,将分两种情况进行介绍:
(1)使用MNIST数据(本案例)
(2)使用自己的数据。
下面将针对模型训练的各个主要环节进行介绍,便于读者快速迁移去训练自己的数据模型。
1. 准备数据
准备数据是训练模型的第一步,基础数据可以是网上公开的数据集,也可以是自己的数据集。视觉、语音、语言等各种类型的数据在网上都能找到相应的数据集。
(1)使用MNIST数据(本案例)
MNIST数据集由于非常经典,已集成在tensorflow里面,可以直接加载使用,也可以从MNIST的官网上(http://yann.lecun.com/exdb/mnist/) 直接下载数据集,代码如下:
# 从tensorflow.examples.tutorials.mnist引入模块。这是TensorFlow为了教学MNIST而提前编制的程序
from tensorflow.examples.tutorials.mnist import input_data
# 从MNIST_data/中读取MNIST数据。这条语句在数据不存在时,会自动执行下载
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)
集成或下载的MNIST数据集已经是打好标签了,直接使用就行。
(2)使用自己的数据
如果是使用自己的数据集,在准备数据时的重要工作是“标注数据”,也就是对数据进行打标签,主要的标注方式有:
① 整个文件打标签。例如MNIST数据集,每个图像只有1个数字,可以从0至9建10个文件夹,里面放相应数字的图像;也可以定义一个规则对图像进行命名,如按标签+序号命名;还可以在数据库里面创建一张对应表,存储文件名与标签之间的关联关系。如下图:

② 圈定区域打标签。例如ImageNet的物体识别数据集,由于每张图片上有各种物体,这些物体位于不同位置,因此需要圈定某个区域进行标注,目前比较流行的是VOC2007、VOC2012数据格式,这是使用xml文件保存图片中某个物体的名称(name)和位置信息(xmin,ymin,xmax,ymax)。
如果图片很多,一张一张去计算位置信息,然后编写xml文件,实在是太耗时耗力了。所幸,有一位大神开源了一个数据标注工具labelImg(https://github.com/tzutalin/labelImg),只要在界面上画框标注,就能自动生成VOC格式的xml文件了,非常方便,如下图所示:

③ 数据截段打标签。针对语音识别、文字识别等,有些是将数据截成一段一段的语音或句子,然后在另外的文件中记录对应的标签信息。
2. 数据预处理
在准备好基础数据之后,需要根据模型需要对基础数据进行相应的预处理。
(1)使用MNIST数据(本案例)
由于MNIST数据集的尺寸统一,只有黑白两种像素,无须再进行额外的预处理,直接拿来建模型就行。
(2)使用自己的数据
而如果是要训练自己的数据,根据模型需要一般要进行以下预处理:

a. 统一格式: 即统一基础数据的格式,例如图像数据集,则全部统一为jpg格式;语音数据集,则全部统一为wav格式;文字数据集,则全部统一为UTF-8的纯文本格式等,方便模型的处理;
b. 调整尺寸: 根据模型的输入要求,将样本数据全部调整为统一尺寸。例如LeNet模型是32x32,AlexNet是224x224,VGG是224x224等;
c. 灰度化: 根据模型需要,有些要求输入灰度图像,有些要求输入RGB彩色图像;
d. 去噪平滑: 为提升输入图像的质量,对图像进行去噪平滑处理,可使用中值滤波器、高斯滤波器等进行图像的去噪处理。如果训练数据集的图像质量很好了,则无须作去噪处理;
e. 其它处理: 根据模型需要进行直方图均衡化、二值化、腐蚀、膨胀等相关的处理;
f. 样本增强: 有一种观点认为神经网络是靠数据喂出来的,如果能够增加训练数据的样本量,提供海量数据进行训练,则能够有效提升算法的质量。常见的样本增强方式有:水平翻转图像、随机裁剪、平移变换,颜色、光照变换等,如下图所示:

3. 划分数据集
在训练模型之前,需要将样本数据划分为训练集、测试集,有些情况下还会划分为训练集、测试集、验证集。
(1)使用MNIST数据(本案例)
本案例要训练模型的MNIST数据集,已经提供了训练集、测试集,代码如下:
# 提取训练集、测试集
train_xdata = mnist.train.images
test_xdata = mnist.test.images
# 提取标签数据
train_labels = mnist.train.labels
test_labels = mnist.test.labels
(2)使用自己的数据
如果是要划分自己的数据集,可使用scikit-learn工具进行划分,代码如下:
from sklearn.model_selection import train_test_split
# 随机选取75%的数据作为训练样本,其余25%的数据作为测试样本
# X_data:数据集
# y_labels:数据集对应的标签
X_train, X_test, y_train, y_test = train_test_split(X_data, y_labels, test_size=0.25, random_state=33)
4. 配置模型
接下来是选择模型、配置模型参数,建议先阅读深度学习经典模型的文章,可以参考《Tensorflow入门(六)——初识卷积神经网络(CNN)》,便于快速掌握深度学习模型的相关知识。
(1)选择模型
本案例将采用LeNet模型来训练MNIST手写数字模型,LeNet是一个经典卷积神经网络模型,结构简单,针对MNIST这种简单的数据集可达到比较好的效果,LeNet模型的原理介绍请见文章《Tensorflow入门(七)——CNN经典模型:LeNet》,网络结构图如下:

(2)设置参数
在训练模型时,一般要设置的参数有:
step_cnt = 5000 # 训练模型的迭代步数
batch_size = 100 # 每次迭代批量取样本数据的量
learning_rate = 0.001 # 学习率
除此之外还有卷积层权重和偏置、池化层权重、全联接层权重和偏置、优化函数等等,根据模型需要进行设置。
5. 训练模型
接下来便是根据选择好的模型,构建网络,然后开始训练。
(1)构建模型
本案例按照LeNet的网络模型结构,构建网络模型,网络结构如下:

代码如下:
# 训练数据,占位符
x = tf.placeholder("float", shape=[None, 784])
# 训练的标签数据,占位符
y_ = tf.placeholder("float", shape=[None, 10])
# 将样本数据转为28x28
x_image = tf.reshape(x, [-1, 28, 28, 1])
# 保留概率,用于 dropout 层
keep_prob = tf.placeholder(tf.float32)
# 第一层:卷积层
# 卷积核尺寸为5x5,通道数为1,深度为32,移动步长为1,采用ReLU激励函数
conv1_weights = tf.get_variable("conv1_weights", [5, 5, 1, 32], initializer=tf.truncated_normal_initializer(stddev=0.1))
conv1_biases = tf.get_variable("conv1_biases", [32], initializer=tf.constant_initializer(0.0))
conv1 = tf.nn.conv2d(x_image, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))
# 第二层:最大池化层
# 池化核的尺寸为2x2,移动步长为2,使用全0填充
pool1 = tf.nn<

最低0.47元/天 解锁文章
&spm=1001.2101.3001.5002&articleId=108020807&d=1&t=3&u=01cb742489c3469fa61622ad1679b054)
2340

被折叠的 条评论
为什么被折叠?



