前言
【Tensorflow】Tensorflow實現線性迴歸及邏輯迴歸
前一篇介紹了使用 Tensorflow
實現線性迴歸及邏輯迴歸,並實現了手寫數字識別的案例;後一篇介紹了BP神經網絡,以及Python實現。本篇將通過 Tensorflow
實現簡單神經網絡(1個輸入層、2個隱藏層、1個輸出層),並應用有手寫數字識別案例。
代碼
# 引入包
import tensorflow as tf
import matplotlib as mpl
from tensorflow.examples.tutorials.mnist import input_data
# 設置字符集,防止中文亂碼
mpl.rcParams['font.sans-serif'] = [u'simHei']
mpl.rcParams['axes.unicode_minus'] = False
# 數據加載
mnist = input_data.read_data_sets('../data/', one_hot=True)
# print(mnist.train.images.shape)
# print(mnist.train.labels)
# 構建神經網絡(4層、1 input, 2 hidden,1 output)
n_unit_hidden_1 = 256 # 第一層hidden中的神經元數目
n_unit_hidden_2 = 128 # 第二層的hidden中的神經元數目
n_input = 784 # 輸入的一個樣本(圖像)是28*28像素的
n_classes = 10 # 輸出的類別數目
# 定義輸入的佔位符
x = tf.placeholder(tf.float32, shape=[None, n_input], name='x')
y = tf.placeholder(tf.float32, shape=[None, n_classes], name='y')
# 構建初始化的w和b
weights = {
"w1": tf.Variable(tf.random_normal(shape=[n_input, n_unit_hidden_1], stddev=0.1)),
"w2": tf.Variable(tf.random_normal(shape=[n_unit_hidden_1, n_unit_hidden_2], stddev=0.1)),
"out": tf.Variable(tf.random_normal(shape=[n_unit_hidden_2, n_classes], stddev=0.1))
}
biases = {
"b1": tf.Variable(tf.random_normal(shape=[n_unit_hidden_1], stddev=0.1)),
"b2": tf.Variable(tf.random_normal(shape=[n_unit_hidden_2], stddev=0.1)),
"out": tf.Variable(tf.random_normal(shape=[n_classes], stddev=0.1))
}
def multiplayer_perceotron(_X, _weights, _biases):
# 第一層 -> 第二層 input -> hidden1
layer1 = tf.nn.sigmoid(tf.add(tf.matmul(_X, _weights['w1']), _biases['b1']))
# 第二層 -> 第三層 hidden1 -> hidden2
layer2 = tf.nn.sigmoid(tf.add(tf.matmul(layer1, _weights['w2']), _biases['b2']))
# 第三層 -> 第四層 hidden2 -> output
return tf.matmul(layer2, _weights['out']) + _biases['out']
# 獲取預測值
act = multiplayer_perceotron(x, weights, biases)
# 構建模型的損失函數
# softmax_cross_entropy_with_logits: 計算softmax中的每個樣本的交叉熵,logits指定預測值,labels指定實際值
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=act, labels=y))
# 使用梯度下降求解
# 使用梯度下降,最小化誤差
# learning_rate: 要注意,不要過大,過大可能不收斂,也不要過小,過小收斂速度比較慢
train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)
# 得到預測的類別是那一個
# tf.argmax:對矩陣按行或列計算最大值對應的下標,和numpy中的一樣
# tf.equal:是對比這兩個矩陣或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩陣維度和A是一樣的
pred = tf.equal(tf.argmax(act, axis=1), tf.argmax(y, axis=1))
# 正確率(True轉換爲1,False轉換爲0)
acc = tf.reduce_mean(tf.cast(pred, tf.float32))
# 初始化
init = tf.global_variables_initializer()
# 執行模型的訓練
batch_size = 100 # 每次處理的圖片數
display_step = 1 # 每4次迭代打印一次
# LAUNCH THE GRAPH
with tf.Session() as sess:
# 進行數據初始化
sess.run(init)
# 模型保存、持久化
saver = tf.train.Saver()
epoch = 0
while True:
avg_cost = 0
# 計算出總的批次
total_batch = int(mnist.train.num_examples / batch_size)
# 迭代更新
for i in range(total_batch):
# 獲取x和y
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
feeds = {x: batch_xs, y: batch_ys}
# 模型訓練
sess.run(train, feed_dict=feeds)
# 獲取損失函數值
avg_cost += sess.run(cost, feed_dict=feeds)
# 重新計算平均損失(相當於計算每個樣本的損失值)
avg_cost = avg_cost / total_batch
# DISPLAY 顯示誤差率和訓練集的正確率以此測試集的正確率
if (epoch + 1) % display_step == 0:
print("批次: %03d 損失函數值: %.9f" % (epoch, avg_cost))
feeds = {x: mnist.train.images, y: mnist.train.labels}
train_acc = sess.run(acc, feed_dict=feeds)
print("訓練集準確率: %.3f" % train_acc)
feeds = {x: mnist.test.images, y: mnist.test.labels}
test_acc = sess.run(acc, feed_dict=feeds)
print("測試準確率: %.3f" % test_acc)
# 訓練和測試準確率大於0.9退出訓練
if train_acc > 0.9 and test_acc > 0.9:
saver.save(sess, './mn/model')
break
epoch += 1
# 模型可視化輸出
writer = tf.summary.FileWriter('./mn/graph', tf.get_default_graph())
writer.close()
運行結果:
代碼可見:Github
tensorboard
可視化
終端執行:tensorboard --logdir F:\Github_sources\Tensorflow\tensorflow_bp\mn\graph
後面的路徑是程序中:
writer = tf.summary.FileWriter('./mn/graph', tf.get_default_graph())
指定的,寫絕對路徑
打開瀏覽器輸入:http://用戶名:6006