写在前面的话:抄书是一个好习惯,大一学C语言时候抄书,研一学OpenCV时候抄书。抄书是强迫自己认真读书的过程。也是能让自己慢下来从作者视角思考的过程。抄书是个好习惯,尤其是对于善于走神的同学。
TensorFlow学习笔记02-《TensorFlow:实战Google深度学习框架 第2版》卷积神经网络一处错误
卷积神经网络CNN例子:LeNet5在MNIST数据集上测试
第128页(别人给的pdf,没花钱买正版恳请作者原谅,我有第一版的正版纸质版,罪过罪过):
其实这里谈不上错误,就是初始参数太不合理。LEARNING_RATE_BASE = 0.8时候效果是这样的:
这里我修改了部分输出效果用于看神经网络究竟预测出的都是些什么玩意,所以就不是只输出accuracy。第一段是验证数据的标签;第二段是验证数据输入经过LeNet5后的预测值(发现是错的),第三个浮点值是accuracy。修改LEARNING_RATE_BASE=0.01:
这里需要指出的是:训练神经网络的目的是为了做预测,书中前半部分给的神经网络结果都是accuracy,这只是对神经网络性能的评估,没有体现出来神经网络的用途,所以在如何应用神经网络上没给读者一个直观的认识。训练出的权值和定义好的网络结构是最终应用的最主要的部分。扔进去x得到输出y,整体就像是一个函数接口。下面贴出来train部分给读者参考:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 15 13:33:59 2019
@author: fq
"""
import os
import numpy as np
import tensorflow as tf
# from tensorflow.examples.tutorials.mnist import inputdata
import input_data
import mnist_inference
# 配置神经网络参数
BATCH_SIZE = 100
LEARNING_RATE_BASE = 0.01
LEARNING_RATE_DECAY = 0.99
REGULARAZTION_RATE = 0.0001
TRAINING_STEPS = 300000
MOVING_AVERAGE_DECAY = 0.99
# 模型保存的路径和文件名
MODEL_SAVE_PATH = "./path/model"
MODEL_NAME = "model.ckpt"
def train(mnist):
# 定义输入输出placeholder
# x = tf.placeholder(
# tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input')
x = tf.placeholder(
tf.float32, [BATCH_SIZE, # 第一维表示一个batch中样例的个数
mnist_inference.IMAGE_SIZE, # 第二维和第三维表示图片的尺寸
mnist_inference.IMAGE_SIZE, #
mnist_inference.NUM_CHANNELS], # 第四维表示图片的深度,对于RGB深度为3
name='x-input')
y_ = tf.placeholder(
tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')
regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)
# 直接使用mnist_inference.py中定义的前向传播过程
y = mnist_inference.inference(x,True,regularizer)
y_out = tf.argmax(y, 1)
# yTest = mnist_inference.inference(x,False,None)
global_step = tf.Variable(0, trainable=False)
# 定义损失函数/学习率/滑动平均操作以及训练过程
variable_averages = tf.train.ExponentialMovingAverage( #指数滑动平均
MOVING_AVERAGE_DECAY, global_step)
variable_averages_op = variable_averages.apply(tf.trainable_variables())
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
logits=y, labels=tf.argmax(y_, 1))
cross_entropy_mean = tf.reduce_mean(cross_entropy)
loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
learning_rate = tf.train.exponential_decay(
LEARNING_RATE_BASE, global_step, mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
with tf.control_dependencies([train_step, variable_averages_op]):
train_op = tf.no_op(name='train')
# 初始化TF持久化类
saver = tf.train.Saver()
with tf.Session() as sess:
tf.global_variables_initializer().run()
# 在训练过程中不再测试模型在验证数据上的表现,验证和测试的过程将会有一个独立的程序来完成
for i in range(TRAINING_STEPS):
xs, ys = mnist.train.next_batch(BATCH_SIZE)
# 卷积神经网络需要先做成卷积
#
reshaped_xs = np.reshape(xs, (BATCH_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS))
_, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: reshaped_xs, y_: ys})
# 每1000轮保存一次模型
if i % 1000 == 0:
# 输出当前的训练情况。这里只输出了模型在当前训练batch上的损失函数大小。通过损失函数的大小可以大概了解
# 训练的情况。在验证数据集上的正确率信息会有一个单独的程序来生成
print("After %d training step(s), loss on training"
"batch is %g." % (step, loss_value))
# 保存当前的模型。注意这里给出了global_step参数,这样可以让每个被保存模型的文件名末尾加上训练的轮数,
# 比如“model.ckpt-1000”表示训练1000轮后得到的模型
saver.save(
sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step)
# 输出验证测试的标签
print(sess.run(tf.argmax(ys, 1)))
# 用神经网络前向传播测试结果得到y
y_2 = sess.run(y_out, feed_dict={x: reshaped_xs})
print(y_2)
# 评估精度
correct_prediction = tf.equal(y_2, tf.argmax(ys, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(sess.run(accuracy))
def main(argv=None):
mnist = input_data.read_data_sets("data/", one_hot=True)
train(mnist)
if __name__ == '__main__':
tf.app.run()