tensorflow筆記(二)之構造一個簡單的神經網絡
版權聲明:本文為博主原創文章,轉載請指明轉載地址
http://www.cnblogs.com/fydeblog/p/7425200.html
前言
這篇博客將一步步構建一個tensorflow的神經網絡去擬合曲線,並將誤差和結果可視化。博客的末尾會放本篇博客的jupyter notebook,可以下載自己調試調試。
實踐——構造神經網絡
本次構造的神經網絡是要擬合一個二次曲線,神經網絡的輸入層是一個特征,即只有一個神經元,隱藏層有10個特征,即有10個神經元,輸出為一個神經元,總結起來就是1—10—1的結構,如果沒有神經網絡結構的朋友,還請去補一補
首先我們先導入要用到的模塊
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt
然后我們先構造出原始數據,並畫出它的圖形(為了更加符合實際,我們會加一些噪聲)
x_data = np.linspace(-1,1,300) [:, np.newaxis] # [:,np.newaxis] make row vector transform column vector noise = np.random.normal(0, 0.05, x_data.shape) y_data = np.square(x_data) - 0.5 + noise
x_data是一個范圍-1到1,以300分之2等份的列向量,noise的shape與x_data一樣,值屬於正態分布,0到0.05之間,y_data則是x_data的平方,減0.5,加噪聲
fig=plt.figure() ax = fig.add_subplot(1,1,1) ax.scatter(x_data,y_data) plt.xlabel('x_data') plt.ylabel('y_data') plt.show()
現在我們先寫一個添加神經網絡層的函數,函數名為add_nn_layer
def add_nn_layer(inputs, in_size, out_size, activation_function=None): Weights = tf.Variable(tf.random_normal([in_size, out_size])) biases = tf.Variable(tf.zeros([1, out_size]) + 0.1) Wx_plus_b = tf.matmul(inputs, Weights) + biases if activation_function is None: outputs = Wx_plus_b else: outputs = activation_function(Wx_plus_b) return outputs
神經網絡的基本構造是要有輸入,還要有輸入映射到下一層的權重和偏差,最后神經元還有一個激活函數(這個有沒有看需求),控制輸出
我們上面講到這個神經網絡的結構是1—10—1,所以要添加兩個層,一層是從輸入層到隱藏層,另一層是隱藏層到輸出層。
從輸入層到隱藏層,1—10,輸入是300x1的向量,到第二層則是300x10,權重則是1x10,偏差的shape與輸出相同
從隱藏層到輸出層,10—1,輸入是300x10的向量,輸出是300x1,可見權重是10x1,偏差的shape與輸出相同
由此可以知道上面函數中各種變量的構造原因,簡單說神經網絡的構造就是輸入乘以權重加上偏差,進入神經元的激活函數,然后輸出
接下來我們開始寫其他代碼
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])
tf.placeholder函數是一個非常重要的函數,以后用到它的次數會非常多,它表示占位符,相應的值會在sess.run里面feed進去,這樣處理會非常靈活,大部分的學習都是分批的,不是一次傳入,占位符滿足這種需求
這里的xs和ys都是列向量,列數為1,行數不確定,feed的輸入行數是多少就是多少
# add hidden layer l1 = add_nn_layer(xs, 1, 10, activation_function=tf.nn.relu) # add output layer prediction = add_nn_layer(l1, 10, 1, activation_function=None)
這里隱藏層的激活函數用的是tf.nn.relu,relu全名是修正線性單元,詳細請參考wiki(https://en.wikipedia.org/wiki/Rectifier_(neural_networks) ),它的性質簡單的說就是輸入神經元的數據大於0則等於自身,小於0則等於0,使用它更符合神經網絡的性質,即有抑制區域和激活區域,我試了沒加激活函數和sigmoid激活函數,效果要比用relu差許多,你們可以試試。
#compute loss loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),reduction_indices=[1])) # creat train op,then we can sess.run(train) to minimize loss train = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
# creat init init = tf.global_variables_initializer()
# creat a Session sess = tf.Session()
# system initialize sess.run(init)
# training for i in range(1000): sess.run(train, feed_dict={xs: x_data, ys: y_data}) prediction_value = sess.run(prediction, feed_dict={xs: x_data}) if i % 50 == 0: # to see the step improvement print('loss:',sess.run(loss, feed_dict={xs: x_data, ys: y_data}))
最后我們來看一下擬合的效果
fig=plt.figure() bx = fig.add_subplot(1,1,1) bx.scatter(x_data,y_data) bx.plot(x_data,prediction_value,'g-',lw=6) plt.xlabel('x_data') plt.ylabel('y_data') plt.show()
可見擬合的不錯
結尾
下一個筆記將講講tensorboard的一些用法,敬請期待!
百度雲鏈接: https://pan.baidu.com/s/1skAfUGH 密碼: qw1g