tensorflow入门(7):MNIST手写数字识别:分类入门(单个神经元、单隐层、双隐层、多隐层_定义全连接层函数)

 

1、由单个神经元构成的神经网络:

# -*- coding: utf-8 -*-
"""
Created on Mon May 11 09:11:59 2020

@author: DELL
"""

# 1、载入数据
# MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取
import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNST_data/",one_hot=True)
# 该站点上有四个文件:
# train-images-idx3-ubyte.gz:训练集图像(9912422字节)
# train-labels-idx1-ubyte.gz:训练集标签(28881 字节)
# t10k-images-idx3-ubyte.gz:测试集图像(1648877字节)
# t10k-labels-idx1-ubyte.gz:测试集标签(4542字节)

print('训练集 train 数量:',mnist.train.num_examples,
      '验证集 validation 数量',mnist.validation.num_examples,
      '测试集 test 数量',mnist.test.num_examples)
print('train images shape:', mnist.train.images.shape,
      'labels shape',mnist.train.labels.shape)
print('validation images shape:',mnist.validation.images.shape,
      'labels shape:',mnist.validation.labels.shape)
print('test images shape:',mnist.test.images.shape,
      'labels shape:',mnist.test.labels.shape)


# 2、构建模型
# 定义待输入数据的占位符
x = tf.placeholder(tf.float32, [None, 784], name ="X")  # mnist中每张图片共有28*28=784个像素点
y = tf.placeholder(tf.float32,[None, 10], name="Y")     # 0-9一共10个数字->10个类别

# 定义模型变量
# 本案例中,以正态分布的随机数初始化权重W,以常数0初始化偏置b
W = tf.Variable(tf.random_normal([784,10],name="W"))
b = tf.Variable(tf.zeros([10]),name="b")

# 定义前向计算
forward = tf.matmul(x,W) + b
# 结果分类
pred = tf.nn.softmax(forward)


# 3、训练模型
# 设置训练参数
train_epochs = 100                                       # 训练轮数
batch_size = 55                                        # 单次训练样本数(批次大小)
total_batch = int(mnist.train.num_examples/batch_size)  # 一轮训练有多少批次
display_step = 5                                        # 显示粒度
learning_rate = 0.02                                    # 学习率

# 定义损失函数
loss_function = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)) # 交叉熵
# loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y,logits=forward)) # tensorflow提供带softmax的交叉熵函数
                                                                                                   # 用于避免因为log(0)值为NaN造成的数据不稳定

# 选择优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function) # 梯度下降优化器
# optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate).minimize(loss_function)

# 定义准确率
correct_prediction = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))     # 检查预测类别与实际类别的匹配情况
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))  # 将布尔值转化为浮点数,并计算平均值

sess = tf.compat.v1.Session()                         # 声明会话
init = tf.compat.v1.global_variables_initializer()    # 变量初始化
sess.run(init)

# 开始训练
for epoch in range(train_epochs):
    for batch in range(total_batch):
        xs,ys = mnist.train.next_batch(batch_size)  # 读取批次数据
        sess.run(optimizer,feed_dict={x:xs,y:ys})   # 执行批次训练
    
    # total_batch个批次训练完成后,使用验证数据计算误差与准确率;验证集没有分批
    loss,acc = sess.run([loss_function,accuracy],
                        feed_dict={x:mnist.validation.images,
                                   y:mnist.validation.labels})
    
    # 打印训练过程中的详细信息
    if (epoch+1) % display_step ==0:
        print("Train Epoch:",'%02d' %(epoch+1), "Loss=","{:.9f}".format(loss),\
              "Accuracy=","{:.4f}".format(acc))
print("Train Finished!")

Output:

可以看出,Loss趋于更小,准确率Accuracy越来越高。

接着,评估模型、模型应用与可视化:

# 4、评估模型
# 完成训练后,在验证集上评估模型的准确率
accu_validation = sess.run(accuracy,feed_dict={x:mnist.validation.images,y:mnist.validation.labels})
print("Test Accuracy:",accu_validation)
# Test Accuracy: 0.9058

# 完成训练后,在测试集上评估模型的准确率
accu_test = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Test Accuracy:",accu_test)
# Test Accuracy: 0.9056


# 5、模型应用与可视化
# 在建立模型并进行训练后,若认为准确率可以接受,则可以使用此模型进行预测
# 由于pred预测结果是One-hot编码格式,所以需要转换为0-9数字
prediction_result = sess.run(tf.argmax(pred,1),feed_dict={x:mnist.test.images})
# 查看预测结果中的前10项
prediction_result[0:10]     # array([7, 2, 1, 0, 4, 1, 4, 9, 6, 9], dtype=int64)
# 定义可视化函数
import matplotlib.pyplot as plt
import numpy as np
def plot_images_labels_prediction(images,       # 图像列表
                                  labels,       # 标签列表
                                  prediction,   # 预测值列表
                                  index,        # 从第index个开始显示
                                  num=10):      # 缺省显示10幅
    fig = plt.gcf()                     # 获取当前图表,get current figure
    fig.set_size_inches(10,12)          # 1英寸 = 2.54cm
    if num>25:
        num = 25                        # 最多显示25个子图
    for i in range(0,num):
        ax = plt.subplot(5,5,i+1)       # 获取当前要处理的子图
        ax.imshow(np.reshape(images[index],(28,28)),cmap='binary')   # 显示第index个图像
        title = "label=" + str(np.argmax(labels[index]))             # 构建该图上要显示的title信息
        if len(prediction)>0:
            title += ", predict=" + str(prediction[index])
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])               # 不显示坐标轴
        ax.set_yticks([])
        index+=1
    plt.show()

plot_images_labels_prediction(mnist.test.images,mnist.test.labels,prediction_result,0,10)

plot_images_labels_prediction(mnist.test.images,mnist.test.labels,[],0,5)

Output:

 

 

 

 

2、单隐层神经网络

# -*- coding: utf-8 -*-
"""
Created on Mon May 11 21:00:26 2020

@author: DELL

mnist数字识别,单隐层神经网络。
"""


# 1、载入数据
# MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取
import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNST_data/",one_hot=True)
# 该站点上有四个文件:
# train-images-idx3-ubyte.gz:训练集图像(9912422字节)
# train-labels-idx1-ubyte.gz:训练集标签(28881 字节)
# t10k-images-idx3-ubyte.gz:测试集图像(1648877字节)
# t10k-labels-idx1-ubyte.gz:测试集标签(4542字节)

# 2、构建模型
# 定义待输入数据的占位符
x = tf.placeholder(tf.float32, [None, 784], name ="X")  # mnist中每张图片共有28*28=784个像素点
y = tf.placeholder(tf.float32,[None, 10], name="Y")     # 0-9一共10个数字->10个类别

# 构建隐藏层
H1_NN = 256

W1 = tf.Variable(tf.random.normal([784,H1_NN])) # 正态分布随机数
b1 = tf.Variable(tf.zeros([H1_NN]))

Y1 = tf.nn.relu(tf.matmul(x,W1)+b1)

# 构建输出层
W2 = tf.Variable(tf.random.normal([H1_NN,10]))
b2 = tf.Variable(tf.zeros([10]))

forward = tf.matmul(Y1,W2) + b2    # 定义前向计算
pred = tf.nn.softmax(forward)   # 结果分类


# 3、训练模型
# 设置训练参数
train_epochs = 30                                       # 训练轮数
batch_size = 50                                        # 单次训练样本数(批次大小)
total_batch = int(mnist.train.num_examples/batch_size)  # 一轮训练有多少批次
display_step = 2                                        # 显示粒度
learning_rate = 0.01                                    # 学习率

# 定义损失函数
# loss_function = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)) # 交叉熵
loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y,logits=forward)) # tensorflow提供带softmax的交叉熵函数
                                                                                                   # 用于避免因为log(0)值为NaN造成的数据不稳定

# 选择优化器
# optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function) # 梯度下降优化器
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate).minimize(loss_function)

# 定义准确率
correct_prediction = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))     # 检查预测类别与实际类别的匹配情况
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))  # 将布尔值转化为浮点数,并计算平均值

# 记录训练开始时间
from time import time
startTime=time()

sess = tf.compat.v1.Session()                         # 声明会话
init = tf.compat.v1.global_variables_initializer()    # 变量初始化
sess.run(init)

# 开始训练
for epoch in range(train_epochs):
    for batch in range(total_batch):
        xs,ys = mnist.train.next_batch(batch_size)  # 读取批次数据
        sess.run(optimizer,feed_dict={x:xs,y:ys})   # 执行批次训练
    
    # total_batch个批次训练完成后,使用验证数据计算误差与准确率;验证集没有分批
    loss,acc = sess.run([loss_function,accuracy],
                        feed_dict={x:mnist.validation.images,
                                   y:mnist.validation.labels})
    
    # 打印训练过程中的详细信息
    if (epoch+1) % display_step ==0:
        print("Train Epoch:",'%02d' %(epoch+1), "Loss=","{:.9f}".format(loss),\
              "Accuracy=","{:.4f}".format(acc))
print("Train Finished!")

# 显示运行总时间
duration = time()-startTime
print("Train Finished takes:","{:.2f}".format(duration))


# 4、评估模型
# 完成训练后,在验证集上评估模型的准确率
accu_validation = sess.run(accuracy,feed_dict={x:mnist.validation.images,y:mnist.validation.labels})
print("Test Accuracy:",accu_validation)
# Test Accuracy: 0.9058

# 完成训练后,在测试集上评估模型的准确率
accu_test = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Test Accuracy:",accu_test)
# Test Accuracy: 0.9056


# 5、模型应用与可视化
# 在建立模型并进行训练后,若认为准确率可以接受,则可以使用此模型进行预测
# 由于pred预测结果是One-hot编码格式,所以需要转换为0-9数字
prediction_result = sess.run(tf.argmax(pred,1),
                             feed_dict={x:mnist.test.images})
# 查看预测结果中的前10项
prediction_result[0:10]     # array([7, 2, 1, 0, 4, 1, 4, 9, 6, 9], dtype=int64)
# 定义可视化函数
import matplotlib.pyplot as plt
import numpy as np
def plot_images_labels_prediction(images,       # 图像列表
                                  labels,       # 标签列表
                                  prediction,   # 预测值列表
                                  index,        # 从第index个开始显示
                                  num=10):      # 缺省显示10幅
    fig = plt.gcf()                     # 获取当前图表,get current figure
    fig.set_size_inches(10,12)          # 1英寸 = 2.54cm
    if num>25:
        num = 25                        # 最多显示25个子图
    for i in range(0,num):
        ax = plt.subplot(5,5,i+1)       # 获取当前要处理的子图
        ax.imshow(np.reshape(images[index],(28,28)),cmap='binary')   # 显示第index个图像
        title = "label=" + str(np.argmax(labels[index]))             # 构建该图上要显示的title信息
        if len(prediction)>0:
            title += ", predict=" + str(prediction[index])
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])               # 不显示坐标轴
        ax.set_yticks([])
        index+=1
    plt.show()

plot_images_labels_prediction(mnist.test.images,mnist.test.labels,prediction_result,0,10)

plot_images_labels_prediction(mnist.test.images,mnist.test.labels,[],0,5)


# 6、找出预测错误
compare_lists = prediction_result==np.argmax(mnist.test.labels,1)
print(compare_lists)

err_lists =[i for i in range(len(compare_lists)) if compare_lists[i]==False]
print(err_lists, len(err_lists))

# 定义一个输出错误分类的函数
import numpy as np
def print_predict_errs(labels,      # 标签列表
                       prediction): # 预测值列表
    count = 0
    compare_lists = (prediction==np.argmax(labels,1))
    err_lists =[i for i in range(len(compare_lists)) if compare_lists[i]==False]
    for x in err_lists:
        print("index="+str(x)+
              "标签值=",np.argmax(labels[x]),
              "预测值=",prediction[x])
        count+=1
    print("总计:"+str(count))

print_predict_errs(labels=mnist.test.labels,
                   prediction=prediction_result)

plot_images_labels_prediction(mnist.test.images,mnist.test.labels,prediction_result,9745,20)

Output:

……

 

 

3、双隐层神经网络

# -*- coding: utf-8 -*-
"""
Created on Mon May 11 22:58:04 2020

@author: DELL

mnist数字识别,双隐层神经网络。
"""


# 1、载入数据
# MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取
import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNST_data/",one_hot=True)
# 该站点上有四个文件:
# train-images-idx3-ubyte.gz:训练集图像(9912422字节)
# train-labels-idx1-ubyte.gz:训练集标签(28881 字节)
# t10k-images-idx3-ubyte.gz:测试集图像(1648877字节)
# t10k-labels-idx1-ubyte.gz:测试集标签(4542字节)

# 2、构建模型
# 定义待输入数据的占位符
x = tf.placeholder(tf.float32, [None, 784], name ="X")  # mnist中每张图片共有28*28=784个像素点
y = tf.placeholder(tf.float32,[None, 10], name="Y")     # 0-9一共10个数字->10个类别

# 构建隐藏层
H1_NN = 256     # 第1隐藏层神经元256个
H2_NN = 64      # 第2隐藏层神经元64个

# 输入层 - 第1隐藏层参数和偏置项
W1 = tf.Variable(tf.random.normal([784,H1_NN],stddev=0.1)) # 正态分布随机数
b1 = tf.Variable(tf.zeros([H1_NN]))

# 第1隐藏层 - 第2隐藏层参数和偏置项
W2 = tf.Variable(tf.random.normal([H1_NN,H2_NN],stddev=0.1))
b2 = tf.Variable(tf.zeros([H2_NN]))

# 第2隐藏层 - 输出层参数和偏置项
W3 = tf.Variable(tf.random.normal([H2_NN,10]))
b3 = tf.Variable(tf.zeros([10]))

# 计算第1隐藏层结果
Y1 = tf.nn.relu(tf.matmul(x,W1)+b1)

# 计算第2隐藏层结果
Y2 = tf.nn.relu(tf.matmul(Y1,W2)+b2)

# 计算输出结果
forward = tf.matmul(Y2,W3) + b3 # 定义前向计算
pred = tf.nn.softmax(forward)   # 结果分类


# 3、训练模型
# 设置训练参数
train_epochs = 30                                       # 训练轮数
batch_size = 50                                        # 单次训练样本数(批次大小)
total_batch = int(mnist.train.num_examples/batch_size)  # 一轮训练有多少批次
display_step = 2                                        # 显示粒度
learning_rate = 0.01                                    # 学习率

# 定义损失函数
# loss_function = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)) # 交叉熵
loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y,logits=forward)) # tensorflow提供带softmax的交叉熵函数
                                                                                                   # 用于避免因为log(0)值为NaN造成的数据不稳定

# 选择优化器
# optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function) # 梯度下降优化器
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate).minimize(loss_function)

# 定义准确率
correct_prediction = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))     # 检查预测类别与实际类别的匹配情况
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))  # 将布尔值转化为浮点数,并计算平均值

# 记录训练开始时间
from time import time
startTime=time()

sess = tf.compat.v1.Session()                         # 声明会话
init = tf.compat.v1.global_variables_initializer()    # 变量初始化
sess.run(init)

# 开始训练
for epoch in range(train_epochs):
    for batch in range(total_batch):
        xs,ys = mnist.train.next_batch(batch_size)  # 读取批次数据
        sess.run(optimizer,feed_dict={x:xs,y:ys})   # 执行批次训练
    
    # total_batch个批次训练完成后,使用验证数据计算误差与准确率;验证集没有分批
    loss,acc = sess.run([loss_function,accuracy],
                        feed_dict={x:mnist.validation.images,
                                   y:mnist.validation.labels})
    
    # 打印训练过程中的详细信息
    if (epoch+1) % display_step ==0:
        print("Train Epoch:",'%02d' %(epoch+1), "Loss=","{:.9f}".format(loss),\
              "Accuracy=","{:.4f}".format(acc))
print("Train Finished!")

# 显示运行总时间
duration = time()-startTime
print("Train Finished takes:","{:.2f}".format(duration))


# 4、评估模型
# 完成训练后,在验证集上评估模型的准确率
accu_validation = sess.run(accuracy,feed_dict={x:mnist.validation.images,y:mnist.validation.labels})
print("Test Accuracy:",accu_validation)
# Test Accuracy: 0.9058

# 完成训练后,在测试集上评估模型的准确率
accu_test = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Test Accuracy:",accu_test)
# Test Accuracy: 0.9056


# 5、可视化
# 在建立模型并进行训练后,若认为准确率可以接受,则可以使用此模型进行预测
# 由于pred预测结果是One-hot编码格式,所以需要转换为0-9数字
prediction_result = sess.run(tf.argmax(pred,1),
                             feed_dict={x:mnist.test.images})
# 定义可视化函数
import matplotlib.pyplot as plt
import numpy as np
def plot_images_labels_prediction(images,       # 图像列表
                                  labels,       # 标签列表
                                  prediction,   # 预测值列表
                                  index,        # 从第index个开始显示
                                  num=10):      # 缺省显示10幅
    fig = plt.gcf()                     # 获取当前图表,get current figure
    fig.set_size_inches(10,12)          # 1英寸 = 2.54cm
    if num>25:
        num = 25                        # 最多显示25个子图
    for i in range(0,num):
        ax = plt.subplot(5,5,i+1)       # 获取当前要处理的子图
        ax.imshow(np.reshape(images[index],(28,28)),cmap='binary')   # 显示第index个图像
        title = "label=" + str(np.argmax(labels[index]))             # 构建该图上要显示的title信息
        if len(prediction)>0:
            title += ", predict=" + str(prediction[index])
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])               # 不显示坐标轴
        ax.set_yticks([])
        index+=1
    plt.show()


# 6、找出预测错误
compare_lists = prediction_result==np.argmax(mnist.test.labels,1)
print(compare_lists)

err_lists =[i for i in range(len(compare_lists)) if compare_lists[i]==False]
print(err_lists, len(err_lists))

# 定义一个输出错误分类的函数
import numpy as np
def print_predict_errs(labels,      # 标签列表
                       prediction): # 预测值列表
    count = 0
    compare_lists = (prediction==np.argmax(labels,1))
    err_lists =[i for i in range(len(compare_lists)) if compare_lists[i]==False]
    for x in err_lists:
        print("index="+str(x)+
              "标签值=",np.argmax(labels[x]),
              "预测值=",prediction[x])
        count+=1
    print("总计:"+str(count))

print_predict_errs(labels=mnist.test.labels,
                   prediction=prediction_result)

plot_images_labels_prediction(mnist.test.images,mnist.test.labels,prediction_result,9745,20)

Output:

多层效果不一定就比单层网络效果好。

 

 

4、多隐层神经网络(定义全连接层函数)

# -*- coding: utf-8 -*-
"""
Created on Tue May 12 19:23:06 2020

@author: DELL

mnist数字识别,多隐层神经网络。
"""



# 1、载入数据
# MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取
import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNST_data/",one_hot=True)
# 该站点上有四个文件:
# train-images-idx3-ubyte.gz:训练集图像(9912422字节)
# train-labels-idx1-ubyte.gz:训练集标签(28881 字节)
# t10k-images-idx3-ubyte.gz:测试集图像(1648877字节)
# t10k-labels-idx1-ubyte.gz:测试集标签(4542字节)

# 2、构建模型
# 定义全连接层函数
def fcn_layer(inputs,           # 输入数据
              input_dim,        # 输入神经元数量
              output_dim,       # 输出神经元数量
              activation=None): # 激活函数
    W = tf.Variable(tf.random.truncated_normal([input_dim,output_dim], stddev=-.1)) # 以截断正态分布的随机数初始化W
    b = tf.Variable(tf.zeros([output_dim])) # 以0初始化b
    XWb = tf.matmul(inputs,W)+b # 建立表达式:inputs*W+b
    if activation is None:      # 默认不使用激活函数
        outputs=XWb
    else:                       # 若传入激活函数,则用其对输出结果进行变换
        outputs=activation(XWb)
    return outputs

# 定义待输入数据的占位符
x = tf.placeholder(tf.float32, [None, 784], name ="X")  # mnist中每张图片共有28*28=784个像素点
y = tf.placeholder(tf.float32,[None, 10], name="Y")     # 0-9一共10个数字->10个类别

# # 1) 单隐层
# # 构建隐藏层
# h1=fcn_layer(inputs=x, input_dim=784, output_dim=256,activation=tf.nn.relu)
# # 构建输出层
# forward = fcn_layer(inputs=h1, input_dim=256, output_dim=10,activation=None)
# pred = tf.nn.softmax(forward)   # 结果分类

# # 2) 双隐层
# # 构建隐藏层
# H1_NN=256 # 第1隐藏层神经元256个
# H2_NN=64  # 第2隐藏层神经元64个
# h1=fcn_layer(inputs=x, input_dim=784, output_dim=H1_NN,activation=tf.nn.relu)
# h2=fcn_layer(inputs=h1, input_dim=H1_NN, output_dim=H2_NN,activation=tf.nn.relu)
# # 构建输出层
# forward = fcn_layer(inputs=h2, input_dim=H2_NN, output_dim=10,activation=None)
# pred = tf.nn.softmax(forward)   # 结果分类

# 3) 三隐层
# 构建隐藏层
H1_NN=256 # 第1隐藏层神经元256个
H2_NN=64  # 第2隐藏层神经元64个
H3_NN=32  # 第3隐藏层神经元32个
h1=fcn_layer(inputs=x, input_dim=784, output_dim=H1_NN,activation=tf.nn.relu)
h2=fcn_layer(inputs=h1, input_dim=H1_NN, output_dim=H2_NN,activation=tf.nn.relu)
h3=fcn_layer(inputs=h2, input_dim=H2_NN, output_dim=H3_NN,activation=tf.nn.relu)
# 构建输出层
forward = fcn_layer(inputs=h3, input_dim=H3_NN, output_dim=10,activation=None)
pred = tf.nn.softmax(forward)   # 结果分类



# 3、训练模型
# 设置训练参数
train_epochs = 20                                       # 训练轮数
batch_size = 50                                        # 单次训练样本数(批次大小)
total_batch = int(mnist.train.num_examples/batch_size)  # 一轮训练有多少批次
display_step = 2                                        # 显示粒度
learning_rate = 0.01                                    # 学习率

# 定义损失函数
# loss_function = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)) # 交叉熵
loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y,logits=forward)) # tensorflow提供带softmax的交叉熵函数
                                                                                                   # 用于避免因为log(0)值为NaN造成的数据不稳定

# 选择优化器
# optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function) # 梯度下降优化器
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate).minimize(loss_function)

# 定义准确率
correct_prediction = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))     # 检查预测类别与实际类别的匹配情况
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))  # 将布尔值转化为浮点数,并计算平均值

# 记录训练开始时间
from time import time
startTime=time()

sess = tf.compat.v1.Session()                         # 声明会话
init = tf.compat.v1.global_variables_initializer()    # 变量初始化
sess.run(init)

# 开始训练
for epoch in range(train_epochs):
    for batch in range(total_batch):
        xs,ys = mnist.train.next_batch(batch_size)  # 读取批次数据
        sess.run(optimizer,feed_dict={x:xs,y:ys})   # 执行批次训练
    
    # total_batch个批次训练完成后,使用验证数据计算误差与准确率;验证集没有分批
    loss,acc = sess.run([loss_function,accuracy],
                        feed_dict={x:mnist.validation.images,
                                   y:mnist.validation.labels})
    
    # 打印训练过程中的详细信息
    if (epoch+1) % display_step ==0:
        print("Train Epoch:",'%02d' %(epoch+1), "Loss=","{:.9f}".format(loss),\
              "Accuracy=","{:.4f}".format(acc))
print("Train Finished!")

# 显示运行总时间
duration = time()-startTime
print("Train Finished takes:","{:.2f}".format(duration))


# 4、评估模型
# 完成训练后,在验证集上评估模型的准确率
accu_validation = sess.run(accuracy,feed_dict={x:mnist.validation.images,y:mnist.validation.labels})
print("Test Accuracy:",accu_validation)
# Test Accuracy: 0.9058

# 完成训练后,在测试集上评估模型的准确率
accu_test = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Test Accuracy:",accu_test)
# Test Accuracy: 0.9056


# 5、可视化
# 在建立模型并进行训练后,若认为准确率可以接受,则可以使用此模型进行预测
# 由于pred预测结果是One-hot编码格式,所以需要转换为0-9数字
prediction_result = sess.run(tf.argmax(pred,1),
                             feed_dict={x:mnist.test.images})
# 定义可视化函数
import matplotlib.pyplot as plt
import numpy as np
def plot_images_labels_prediction(images,       # 图像列表
                                  labels,       # 标签列表
                                  prediction,   # 预测值列表
                                  index,        # 从第index个开始显示
                                  num=10):      # 缺省显示10幅
    fig = plt.gcf()                     # 获取当前图表,get current figure
    fig.set_size_inches(10,12)          # 1英寸 = 2.54cm
    if num>25:
        num = 25                        # 最多显示25个子图
    for i in range(0,num):
        ax = plt.subplot(5,5,i+1)       # 获取当前要处理的子图
        ax.imshow(np.reshape(images[index],(28,28)),cmap='binary')   # 显示第index个图像
        title = "label=" + str(np.argmax(labels[index]))             # 构建该图上要显示的title信息
        if len(prediction)>0:
            title += ", predict=" + str(prediction[index])
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])               # 不显示坐标轴
        ax.set_yticks([])
        index+=1
    plt.show()


# 6、找出预测错误
compare_lists = prediction_result==np.argmax(mnist.test.labels,1)
print(compare_lists)

err_lists =[i for i in range(len(compare_lists)) if compare_lists[i]==False]
print(err_lists, len(err_lists))

# 定义一个输出错误分类的函数
import numpy as np
def print_predict_errs(labels,      # 标签列表
                       prediction): # 预测值列表
    count = 0
    compare_lists = (prediction==np.argmax(labels,1))
    err_lists =[i for i in range(len(compare_lists)) if compare_lists[i]==False]
    for x in err_lists:
        print("index="+str(x)+
              "标签值=",np.argmax(labels[x]),
              "预测值=",prediction[x])
        count+=1
    print("总计:"+str(count))

print_predict_errs(labels=mnist.test.labels,
                   prediction=prediction_result)

plot_images_labels_prediction(mnist.test.images,mnist.test.labels,prediction_result,9745,20)

Output:

可以看到,本案例中,三隐层神经网络模型训练结果比单隐层好,第9755个预测正确了(第三行第一个)。

 

 

以上。参考Mooc课程吴明晖老师的《深度学习应用开发-TensorFlow实践》。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值