Tensorflow入门(一)----”搭建图像识别系统“教程整理

导语:WolfgangBeyer的一篇优秀的博文,详细介绍了如何使TensorFlow搭建一个简单的图像识别系统。
本篇主要对该教程实践过程做了简单的整理。

实践目标

  • 学习Tensorflow编程思想
  • 实现简单的机器学习系统,识别图像并打上正确的标签

数据集:标准的CIFAR-10数据集

  • 10个不同的分类,每类包含6000幅图片。
  • 规格:32x32像素。

机器学习框架流程

首先,定义一个通用的数学模型将输入图像转换为输出标签
这个模型的实际输出不仅仅依赖于图像本身,还依赖模型内建的参数。这些参数并不是由我们提供,而是由计算机通过学习获得

这个过程可以被理解为一个参数的优化问题,主要步骤如下:

  1. 定义一个模型并提供初始的参数值
  2. 向模型输入图像数据集和已知的正确标签进行训练
  3. 模型重复校验,训练数据,持续调整参数值
  4. 直至找到合适的参数使模型输出尽可能多的正确结果
  5. 当训练完成,找到最优(接近最优的模型参数),该模型即可用于图像集以外的图像分类。

上述学习过程即监督学习—输入包括数据以及标签

工具及环境

  • Python2.7及以上
  • Tensorflow
  • CIFAR-10数据集:下载Python版本的数据集。

注意:cifar-10-batches-py需要解压到python源代码的目录下,其余工具及环境自行配置

Tensorflow源码分析

https://github.com/wolfib/image-classification-CIFAR10-tf

代码分析过程中主要通过代码+注释的形式,请不要忽略注释。

定义Tensorflow图

在这个过程中不执行任何操作

1. 导入需要的包

# 为了python2和python3的兼容性
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
import tensorflow as tf
import time
import data_helpers  #包内函数主要用于加载和处理数据集的函数

读取数据部分的函数单独放在data_helper.py文件中,负责读取包含数据集的文件,并把数据放入一个方便我们操作的数据结构中。

2. 准备数据集

data_sets = data_helpers.load_data() 

load_data()将数据集进行处理,返回一个dictionary类型数据,便于训练时喂养模型使用:

  • images_train:将训练集转换为50000*3072的数组,其中3072=32像素×32像素×3个颜色通道rgb
  • lables_train:训练集的50000个标签(每个数字从0到9代表图像训练集的10个分类)
  • images_test:测试集(100003232*3)
  • lables_test:测试集的10000个标签
  • classes:10个文本标签,将数字转换成文字

值得注意的是,load_data()函数将60000幅图像分为训练集和测试集。训练集包含50000幅图像,用于训练我们的模型。测试集包含1000幅图像,用于训练完成后检验模型的性能。

3. 定义训练恒参

# Parameter definitions
batch_size = 100 #将数据集随机分批喂给模型,每批100个数据
learning_rate = 0.005 #梯度优化时的学习速率
max_steps = 1000 #训练次数

4.定义模型内建参数

# Define variables (these are the values we want to optimize)
weights = tf.Variable(tf.zeros([3072, 10])) #3072*10的零矩阵
biases = tf.Variable(tf.zeros([10])) #大小为10的列表

内建参数就是我们在训练过程中想要优化的参数。我们将每幅图像以3072个浮点数(size=3027的列表)表示,作为输入;最终结果以10个浮点数(size=10的列表)表示每个种类的得分。

5.定义placeholder用于接收数据集

images_placeholder = tf.placeholder(tf.float32, shape=[None, 3072])
labels_placeholder = tf.placeholder(tf.int64, shape=[None])

placeholder主要在需要运行时给节点输入数据时使用。在这里相当于提供了一个接收训练数据输入的接口,每次训练需要输入数据时只需要使用feed_dict={images_placeholder: , labels_placeholder: }即可。

6.定义用于描述模型预测结果的表达式

logits = tf.matmul(images_placeholder, weights) + biases

7.定义预测结果与真实值之间的损失量表达式

loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits,
  labels=labels_placeholder)) #tf.reduce_mean求损失值均值,softmax函数将logits转化为概率值,能表示特征的输出。

将预测值与正确的分类标签进行比较,损失越小表示预测值越接近正确标签。

8.定义对损失值做梯度下降优化的动作

train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)

9.定义计算准确率的表达式


#tf.argmax(x,1)按行找,找到每一行中最大数值的下标,返回结果是一个列表
#correct_prediction是一个布尔型
correct_prediction = tf.equal(tf.argmax(logits, 1), labels_placeholder)

#tf.cast(x,dtype)将x转换为dtype数据格式
#计算平均准确度/平均分
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

执行Tensorflow图

将操作的执行放在Session会话中进行。
1.对所有变量完成初始化

sess.run(tf.global_variables_initializer())

2.循环迭代,每次随机抽取一批数据喂养模型

for i in range(max_steps):

    # Generate input data batch
    indices = np.random.choice(data_sets['images_train'].shape[0], batch_size)
    images_batch = data_sets['images_train'][indices]
    labels_batch = data_sets['labels_train'][indices]

    # 每100次迭代,对模型训练数据批的当前精确率进行检查。直接调用先前定义的精确率操作来完成。
    if i % 100 == 0:
      train_accuracy = sess.run(accuracy, feed_dict={
        images_placeholder: images_batch, labels_placeholder: labels_batch})
      print('Step {:5d}: training accuracy {:g}'.format(i, train_accuracy))

    # Perform a single training step
    sess.run(train_step, feed_dict={images_placeholder: images_batch,
      labels_placeholder: labels_batch})

每次训练随机抽取训练数据中的一批图像。每训练一批数据都会更新一遍模型的参数,因此批的大小代表了参数更新的频率。
批的大小需要选择相对合适的值,如果太大,每次迭代参数的更新都需要大量的计算;如果太小,会造成高频率的参数更新,但更有可能向错误的方向频繁修正。
在这个模型中,每次训练的数据大小为0-batch_size之间随机指定的一个值。

3.训练完成后,使用测试数据集测试模型效果

test_accuracy = sess.run(accuracy, feed_dict={
    images_placeholder: data_sets['images_test'],
    labels_placeholder: data_sets['labels_test']})
  print('Test accuracy {:g}'.format(test_accuracy))

模型评估总结

在命令行模式中,python softmax.py运行softmax.py脚本,通过打印的training accuracy,我们可以看到两点:

  1. 在这个测试集中训练模型的估计精度为31%左右。相比较随机猜测,该模型显然有一定的性能优势;但总的来说,该模型还比较低级,因为它只单独检测每个像素的颜色,对具体的图像比如线和形状等完全没有考虑。
  2. 对当前模型的性能而言,即使增加迭代训练次数也并不能改善模型的准确率。观察结果发现,训练的准确率随着迭代次数的增加并不是稳定上升,而是在一定范围内波动,说明当前数据量已经达到了模型的极限。

你可能感兴趣的:(人工智能,机器学习)