用tensorflow的mnist做图像分类

16 篇文章 1 订阅
3 篇文章 0 订阅

1.mnist.py

import math

import tensorflow as tf

# MNIST 有10个类
NUM_CLASSES = 10
# MNIST 图像都是 28x28 展开成784维的特征向量
IMAGE_SIZE = 28
IMAGE_PIXELS = IMAGE_SIZE * IMAGE_SIZE
batch_size = 50  #
hidden1_units = 20 #第一隐藏层的大小
hidden2_units = 15 #第二隐藏层的大小
learning_rate = 0.1 #学习率

images_placeholder = tf.placeholder(tf.float32, shape=(batch_size, IMAGE_PIXELS))
labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))


#学习器模型的前向预测过程
def inference(images, hidden1_units, hidden2_units):
  # Hidden 1:y1 = relu(x*W1 +b1)
  with tf.name_scope('hidden1'):
    weights = tf.Variable(
        tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
                            stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),
                            name='weights')
    biases = tf.Variable(tf.zeros([hidden1_units]), name='biases')
    hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)
  # Hidden 2: y2 = relu(y1*W2 + b2)
  with tf.name_scope('hidden2'):
    weights = tf.Variable(
        tf.truncated_normal([hidden1_units, hidden2_units],
                            stddev=1.0 / math.sqrt(float(hidden1_units))),
                            name='weights')
    biases = tf.Variable(tf.zeros([hidden2_units]), name='biases')
    hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)
  # Linear: logits = y2*W3 + b3
  with tf.name_scope('softmax_linear'):
    weights = tf.Variable(
        tf.truncated_normal([hidden2_units, NUM_CLASSES],
                            stddev=1.0 / math.sqrt(float(hidden2_units))),
                            name='weights')
    biases = tf.Variable(tf.zeros([NUM_CLASSES]), name='biases')
    logits = tf.matmul(hidden2, weights) + biases
  return logits


#logits和labels计算输出层损失函数
def loss(logits, labels):
  labels = tf.to_int64(labels)
  cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
      labels=labels, logits=logits, name='xentropy')
  return tf.reduce_mean(cross_entropy, name='xentropy_mean')


# 训练节点
def training(loss, learning_rate):
  # 为保存loss的值添加一个标量汇总(scalar summary).
  tf.summary.scalar('loss', loss)
  # 创建梯度下降优化器
  optimizer = tf.train.GradientDescentOptimizer(learning_rate)
  # 创建一个变量来跟踪global step
  global_step = tf.Variable(0, name='global_step', trainable=False)
  # optimizer将梯度下降法应用到可调参数上来最小化损失函数
  # (同时不断增加 global step 计数器)
  train_op = optimizer.minimize(loss=loss, global_step=global_step)
  return train_op


#评估模型
def evaluation(logits, labels):
  correct = tf.nn.in_top_k(logits, labels, 1)
  # 当前批次的样本中预测正确的样本数量
  return tf.reduce_sum(tf.cast(correct, tf.int32))


logits = inference(images_placeholder,hidden1_units, hidden2_units)

batch_loss = loss(logits=logits, labels=labels_placeholder)

train_on_batch = training(loss=batch_loss, learning_rate=learning_rate)

correct_counts = evaluation(logits=logits, labels=labels_placeholder)

# 写入计算图
writer = tf.summary.FileWriter("logs/mnistboard", tf.get_default_graph())
writer.close()

2.训练模型

import argparse
import os.path
import sys
import time
import os
from six.moves import xrange
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 全局变量 存放模型(超)参数.
FLAGS = None


#产生 placeholder variables 来表达输入张量
def placeholder_inputs(batch_size):
  # 注意:placeholders的shape与整体数据集中图像集和标签集的shape是相互匹配的
  # 除了第一个维度现在是batch_size而不是训练集或测试集的全部大小
  images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,
                                                         mnist.IMAGE_PIXELS))
  labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))
  return images_placeholder, labels_placeholder


#填充 feed_dict 用于一个指定的训练阶段(given training step)
def fill_feed_dict(data_set, images_pl, labels_pl):
  #为参数指定的占位符创建feed_dict,用下一个批次的`batch size`个样本填充.
  images_feed, labels_feed = data_set.next_batch(FLAGS.batch_size, FLAGS.fake_data)
  feed_dict = {images_pl: images_feed, labels_pl: labels_feed}
  return feed_dict


#在给定的数据集上执行一次评估操作
def do_eval(sess, eval_correct,images_placeholder, labels_placeholder, data_set):
  # 运行一个回合(one epoch)的评估过程
  true_count = 0  # 对预测正确的样本计数.
  steps_per_epoch = data_set.num_examples // FLAGS.batch_size #每个回合的执行步数
  num_examples = steps_per_epoch * FLAGS.batch_size  #样本总量
  #累加每个批次样本中预测正确的样本数量
  for step in xrange(steps_per_epoch):
    feed_dict = fill_feed_dict(data_set, images_placeholder, labels_placeholder)
    true_count += sess.run(eval_correct, feed_dict=feed_dict)
  #所有批次上的样本的精确度
  precision = float(true_count) / num_examples
  print('  Num examples: %d  Num correct: %d  Precision @ 1: %0.04f' %
        (num_examples, true_count, precision))

#对MNIST网络训练指定的次数(一次训练称为一个training step)
def run_training():
    # 获取用于训练,验证和测试的图像数据以及类别标签集合
    data_sets = input_data.read_data_sets(FLAGS.input_data_dir, FLAGS.fake_data)
    # 告诉TensorFlow模型将会被构建在默认的Graph上.
    with tf.Graph().as_default():
        # 为图像特征向量数据和类标签数据创建输入占位符
        images_placeholder, labels_placeholder = placeholder_inputs(FLAGS.batch_size)
        # 从前向推断模型中构建用于预测的计算图
        logits = mnist.inference(images_placeholder, FLAGS.hidden1, FLAGS.hidden2)
        # 为计算图添加计算损失的节点.
        loss = mnist.loss(logits, labels_placeholder)
        # 为计算图添加计算和应用梯度的训练节点
        train_op = mnist.training(loss, FLAGS.learning_rate)
        # 添加节点用于在评估过程中比较 logits 和 ground-truth labels
        eval_correct = mnist.evaluation(logits, labels_placeholder)

        # 基于 TF collection of Summaries构建汇总张量.
        merged_summaries = tf.summary.merge_all()
        # 创建一个 saver 用于写入 训练过程中的模型的检查点文件(checkpoints).
        saver = tf.train.Saver()

        # 添加变量初始化节点(variable initializer Op).
        init = tf.global_variables_initializer()
        # 创建一个会话用来运行计算图中的节点
        sess = tf.Session()
        # 实例化一个 SummaryWriter 输出 summaries 和 Graph.
        summary_writer = tf.summary.FileWriter(FLAGS.log_dir, sess.graph)
        summary_writer.flush()

        # 运行初始化节点来初始化所有变量(Variables).
        sess.run(init)

        # 开启训练循环.
        for step in xrange(FLAGS.max_steps):
            start_time = time.time()
            # 在此特定的训练步,使用真实的图像和类标签数据集填充 feed dictionary
            feed_dict = fill_feed_dict(data_sets.train,
                                       images_placeholder,
                                       labels_placeholder)
            # 在当前批次样本上把模型运行一步(run one step).
            # 返回值是从`train_op`和`loss`节点拿到的activations
            _, loss_value = sess.run([train_op, loss], feed_dict=feed_dict)
            # 计算当前批次的训练花费的时间
            duration = time.time() - start_time
            # 每隔100个批次就写入summaries并输出overview
            if step % 100 == 0:
                print('Step %d: loss = %.2f (%.3f sec)' % (step, loss_value, duration))
                # 更新事件文件.还是调用sess.run()方法
                summary_str = sess.run(merged_summaries, feed_dict=feed_dict)
                summary_writer.add_summary(summary_str, step)
                summary_writer.flush()
            # 周期性的保存一个检查点文件并评估当前模型的性能
            if (step + 1) % 1000 == 0 or (step + 1) == FLAGS.max_steps:
                checkpoint_file = os.path.join(FLAGS.log_dir, 'model.ckpt')
                saver.save(sess, checkpoint_file, global_step=step)
                # 在所有训练集上评估模型.
                print('Training Data Eval:')
                do_eval(sess, eval_correct, images_placeholder, labels_placeholder, data_sets.train)
                # 在验证集上评估模型.
                print('Validation Data Eval:')
                do_eval(sess, eval_correct, images_placeholder, labels_placeholder, data_sets.validation)
                # 在测试集上评估模型.
                print('Test Data Eval:')
                do_eval(sess, eval_correct, images_placeholder, labels_placeholder, data_sets.test)

#创建日志文件夹  启动训练过程
def main(_):
  if tf.gfile.Exists(FLAGS.log_dir):
    tf.gfile.DeleteRecursively(FLAGS.log_dir)
  tf.gfile.MakeDirs(FLAGS.log_dir)
  #启动训练过程
  run_training()

#用ArgumentParser类把模型的(超)参数全部解析到全局变量FLAGS里面
if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--learning_rate',
      type=float,
      default=0.1,
      help='Initial learning rate.'
  )
  parser.add_argument(
      '--max_steps',
      type=int,
      default=2000,
      help='Number of steps to run trainer.'
  )
  parser.add_argument(
      '--hidden1',
      type=int,
      default=128,
      help='Number of units in hidden layer 1.'
  )
  parser.add_argument(
      '--hidden2',
      type=int,
      default=32,
      help='Number of units in hidden layer 2.'
  )
  parser.add_argument(
      '--batch_size',
      type=int,
      default=100,
      help='Batch size.  Must divide evenly into the dataset sizes.'
  )
  parser.add_argument(
      '--input_data_dir',
      type=str,
      default='MNIST_data/',
      help='Directory to put the input data.'
  )
  parser.add_argument(
      '--log_dir',
      type=str,
      default='logs/Fully_Connected_Feed',
      help='Directory to put the log data.'
  )
  parser.add_argument(
      '--fake_data',
      default=False,
      help='If true, uses fake data for unit testing.',
      action='store_true'
  )
  #把模型的(超)参数全部解析到全局变量FLAGS里面
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)

 

3.运行结果:

/Users/dongyang/AI/anaconda3/python.app/Contents/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6
  return f(*args, **kwds)
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
Step 0: loss = 2.30 (0.134 sec)
Step 100: loss = 0.51 (0.004 sec)
Step 200: loss = 0.59 (0.002 sec)
Step 300: loss = 0.36 (0.005 sec)
Step 400: loss = 0.25 (0.002 sec)
Step 500: loss = 0.55 (0.002 sec)
Step 600: loss = 0.21 (0.002 sec)
Step 700: loss = 0.25 (0.003 sec)
Step 800: loss = 0.18 (0.002 sec)
Step 900: loss = 0.19 (0.002 sec)
Training Data Eval:
  Num examples: 55000  Num correct: 51891  Precision @ 1: 0.9435
Validation Data Eval:
  Num examples: 5000  Num correct: 4740  Precision @ 1: 0.9480
Test Data Eval:
  Num examples: 10000  Num correct: 9428  Precision @ 1: 0.9428
Step 1000: loss = 0.28 (0.009 sec)
Step 1100: loss = 0.13 (0.109 sec)
Step 1200: loss = 0.13 (0.002 sec)
Step 1300: loss = 0.14 (0.002 sec)
Step 1400: loss = 0.18 (0.002 sec)
Step 1500: loss = 0.11 (0.002 sec)
Step 1600: loss = 0.07 (0.002 sec)
Step 1700: loss = 0.07 (0.002 sec)
Step 1800: loss = 0.05 (0.002 sec)
Step 1900: loss = 0.26 (0.002 sec)
Training Data Eval:
  Num examples: 55000  Num correct: 53181  Precision @ 1: 0.9669
Validation Data Eval:
  Num examples: 5000  Num correct: 4835  Precision @ 1: 0.9670
Test Data Eval:
  Num examples: 10000  Num correct: 9643  Precision @ 1: 0.9643

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值