TensorFlow实战笔记之(2):简单神经网络 实现手写数字识别

本文使用一个最简单的单隐层前馈网络实现手写数字识别,借助TensorFlow可以很容易地实现。

一、数据集

数据集使用MNIST,由数万张28像素×28像素的手写数字组成,这些图片只包含灰度值信息。其中包含训练集55000个样本,测试集10000个样本,以及验证集5000个样本。MNIST数据集可以在THE MNIST DATABASE下载,也可以使用下面的代码直接在python中导入:

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)

二、神经网络设计

将28×28的图片转换成向量,长度为784,因此神经网络的输入层有784个神经元;输出层显然需要10个神经元,因为输出的是0~9这10个数字;隐含层采用15个神经元。网络结构如下:

TensorFlow实战笔记之(2):简单神经网络 实现手写数字识别_第1张图片

隐层的激活函数采用 sigmoid 函数,输出层的激活函数采用 softmax 函数。常用的激活函数及其选择方法见参考文献2和3。

损失函数为实际的label与概率归一化预测输出的交叉熵,具体采用 “tf.nn.softmax_cross_entropy_with_logits” 进行计算,其原理见参考文献4。

优化算法(梯度下降算法)采用Adam算法,即tensorflow中的“tf.train.AdamOptimizer”。详见参考文献5。

三、代码

程序运行版本为:python-->3.7.3,tensorflow-->1.13.1 

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

# move warning
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
old_v = tf.logging.get_verbosity()
tf.logging.set_verbosity(tf.logging.ERROR)

# read data
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)

# create model
# input layer
x = tf.placeholder(tf.float32, [None, 784])  # input images
y_ = tf.placeholder(tf.float32, [None, 10])  # input labels

# hidden layer
hidden_layer_count = 15
w1 = tf.Variable(tf.zeros([784, hidden_layer_count]))
b1 = tf.Variable(tf.zeros([hidden_layer_count]))
y1 = tf.sigmoid(tf.matmul(x, w1) + b1)

# output layer
output_layer_count = 10
w2 = tf.Variable(tf.zeros([hidden_layer_count, output_layer_count]))
b2 = tf.Variable(tf.zeros(output_layer_count))
y2 = tf.nn.softmax(tf.matmul(y1, w2) + b2)

# loss function & optimization algorithm
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y2))
train_step = tf.train.AdamOptimizer(learning_rate=0.01).minimize(cross_entropy)

# new session
sess = tf.Session()
sess.run(tf.global_variables_initializer())

# train
for i in range(10000):
    batch_xs, batch_ys = mnist.train.next_batch(50)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
    if i % 1000 == 0:
        loss = sess.run(cross_entropy, {x: batch_xs, y_: batch_ys})
        print("Iter: %s loss: %s" % (i, loss))

# test
correct_prediction = tf.equal(tf.argmax(y_, 1), tf.argmax(y2, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Accuracy: ', sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

tf.logging.set_verbosity(old_v)

该方法最终的准确率约为80%。此外可以通过调整隐层神经元的个数、w和b的初始值、激活函数、学习率、每批训练样本的个数、训练的迭代次数等尝试提高准确率。

 

参考文献

  1. 用最简单的神经网络识别手写数字
  2. 常用激活函数(激励函数)理解与总结
  3. 深度学习基础篇:如何选择正确的激活函数?
  4. tf.softmax_cross_entropy_with_logits()的计算过程及代码演示
  5. TensorFlow优化算法 tf.train.AdamOptimizer 简介

你可能感兴趣的:(TensorFlow,神经网络)