
添加和定義神經(jīng)層
神經(jīng)層中包括一個(gè)激勵(lì)函數(shù),不過在今天的神經(jīng)層我們暫時(shí)不使用激勵(lì)函數(shù)來改變我們線性函數(shù)。在每一個(gè)神經(jīng)層中都會(huì)包含 weight(權(quán)重)、 biases(偏值)和激勵(lì)函數(shù)。這也是我們?cè)诠?jié)點(diǎn)。
簡(jiǎn)單的過程就是求解方程系數(shù) Weight 和 biases。在 TensorFlow 輸入和輸出都是張量
def add_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
- inputs 傳入數(shù)據(jù),in_size 表示輸入節(jié)點(diǎn),out_size 表示輸出的節(jié)點(diǎn)數(shù)。
- Weights 定義初始值為一個(gè)隨機(jī)變量,隨機(jī)變量在生成初始位置要比全部為 0 好的多
Weights = tf.Variable(tf.random_normal([in_size, out_size]))
- tf.random_normal 表示正態(tài)分布
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
- biases 偏置也盡量避免使用 0 作為初始值,tf.zeros 產(chǎn)生全 0 數(shù)組
如果 activation_function 是 None 表示,模型為線性的方式而不是非線性的方程
if activation_function is None:
用于解決我們平時(shí)生活當(dāng)中不能用線性方程解決和概括的問題。線性方程是我們加班越多領(lǐng)導(dǎo)就越喜歡而且拿的也更多。其實(shí)也不一定因?yàn)槲覀兪怯蓸O限的,而且一天就 24 小時(shí)所以這個(gè)問題就從線性變成非線性的問題。我們將神經(jīng)網(wǎng)絡(luò)簡(jiǎn)化為一個(gè)公式,也就是 y = Wx ,我們需要表示上面描述問題,不過這個(gè)線性方程并不能改變直線形態(tài),這時(shí)候我們就需要激勵(lì)函數(shù)。y AF(Wx) 可以在瓶頸處改變我們函數(shù)的形態(tài)。AF 就是激勵(lì)函數(shù),有很多方式例如 relu , sigmoid 或者 tanh。也可以自己定義激勵(lì)函數(shù)來解決問題,不過需要保證這些激勵(lì)函數(shù)是可以微分的。
- 如果設(shè)計(jì)神經(jīng)網(wǎng)絡(luò)的隱藏層數(shù)不多,可以隨意嘗試預(yù)定義激勵(lì)函數(shù)
- 多層需要精心選擇激勵(lì)函數(shù),否則可能會(huì)引起梯度爆炸或梯度消失的問題
- 卷積神經(jīng)網(wǎng)絡(luò)推薦 relu,在循環(huán)神經(jīng)網(wǎng)推薦 relu 或者 tanh
如何建立神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),
import tensorflow as tf
import numpy as np
def add_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
x_data = np.linspace(-1, 1, 300)[:,np.newaxis]
noise = np.random.normal(0, 0.05, x_data.shape)
y_data = np.square(x_data) - 0.5 + noise
xs = tf.placeholder(tf.float32,[None, 1])
ys = tf.placeholder(tf.float32,[None, 1])
hiddenLayer = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
outputLayer = add_layer(hiddenLayer, 10, 1, activation_function=None)
loss = tf.reduce_mean(tf.reduce_sum(
tf.square(ys - outputLayer), reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
for i in range(1000):
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
if i % 50:
print(sess.run(loss,feed_dict={xs: x_data, ys: y_data}))
Session(會(huì)話)用來執(zhí)行定義好運(yùn)算,在 TensorFlow 的會(huì)話中會(huì)擁有并管理 TensorFlow 程序運(yùn)行的所有資源,計(jì)算完畢之后需要關(guān)閉會(huì)話。
x_data = np.linspace(-1, 1, 300)[:,np.newaxis]
print(x_data)
[[-1. ]
[-0.99331104]
x1 = np.array([1, 2, 3, 4, 5])
# the shape of x1 is (5,)
x1_new = x1[:, np.newaxis]
# now, the shape of x1_new is (5, 1)
# array([[1],
# [2],
# [3],
# [4],
# [5]])
x1_new = x1[np.newaxis,:]
# now, the shape of x1_new is (1, 5)
# array([[1, 2, 3, 4, 5]])
np.newaxis的作用就是在這一位置增加一個(gè)一維,這一位置指的是np.newaxis所在的位置,比較抽象,需要配合例子理解。
x_data 通過為他添加維度表示有 300 例子
noise = np.random.normal(0, 0.05, x_data.shape)
y_data = np.square(x_data) - 0.5 + noise
創(chuàng)建 y = x*2 -0.5 添加一個(gè) noise 上 y_data 在這條直線附近跳動(dòng)。
我們創(chuàng)建一個(gè) 3 層的神經(jīng)網(wǎng)結(jié)構(gòu),輸入層、輸出層以及隱藏層,輸入層是根據(jù)輸入數(shù)據(jù)數(shù)量作為輸入層,這里 x_data 只有一個(gè)屬性也就是輸入只有一個(gè)神經(jīng)元,而隱藏層我們假設(shè)有 10 個(gè)屬性而輸出也只有一個(gè)屬性所以輸出也就是 1。
先定義隱藏層
hiddenLayer = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
接下來定義輸出層
outputLayer = add_layer(hiddenLayer, 10, 1, activation_function=None)
定義好神經(jīng)層,我們就可以開始進(jìn)行預(yù)測(cè),在開始預(yù)測(cè)之前我們需要計(jì)算 loss(誤差)也就是我們輸出層值(預(yù)測(cè)值)與實(shí)際值的差
loss = tf.reduce_mean(tf.reduce_sum(
tf.square(ys - outputLayer), reduction_indices=[1]))
reduce_sum 對(duì)每一個(gè)差值進(jìn)行求和然后在用 reduce_mean 取平均值。
然后就是定義訓(xùn)練,訓(xùn)練過程是讓模型怎么通過學(xué)習(xí)來減少 loss(誤差)
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
其中 GradientDescentOptimizer 為梯度下降算法的優(yōu)化,通常我們需要傳入一個(gè)小于 1 數(shù)據(jù)作為其參數(shù)就行。
init = tf.initialize_all_variables()
對(duì)所有變量進(jìn)行初始,并通過會(huì)話來調(diào)用 Tensorflow 來進(jìn)行初始化運(yùn)算
xs = tf.placeholder(tf.float32,[None, 1])
ys = tf.placeholder(tf.float32,[None, 1])
xs 和 ys 通過 placeholder 表示兩個(gè)占位符,等待運(yùn)算時(shí)候輸入數(shù)據(jù)到占位符,None 表示樣板數(shù)量不確定
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
我們可以看出輸出的 loss(誤差)是在不斷減少,所以說明我們訓(xùn)練是有效的。
0.13406475
0.1070772
0.08847566
0.07542249
0.06607084
0.059247475
0.05415783
0.050249428
...
0.0031619053
0.0031612993
0.0031606962
0.0031600953
0.0031594988