一下子看完這個網(wǎng)址不用跳跳跳點點點系列
學(xué)習(xí)鏈接:莫煩tensorflow
為什么選Tensorflow
什么是TensorFlow?
TensorFlow是Google開發(fā)的一款神經(jīng)網(wǎng)絡(luò)的Python外部的結(jié)構(gòu)包, 也是一個采用數(shù)據(jù)流圖來進(jìn)行數(shù)值計算的開源軟件庫.TensorFlow 讓我們可以先繪制計算結(jié)構(gòu)圖, 也可以稱是一系列可人機(jī)交互的計算操作, 然后把編輯好的Python文件 轉(zhuǎn)換成 更高效的C++, 并在后端進(jìn)行計算.
為什么要使用TensorFlow?
TensorFlow 無可厚非地能被認(rèn)定為 神經(jīng)網(wǎng)絡(luò)中最好用的庫之一. 它擅長的任務(wù)就是訓(xùn)練深度神經(jīng)網(wǎng)絡(luò).通過使用TensorFlow我們就可以快速的入門神經(jīng)網(wǎng)絡(luò), 大大降低了深度學(xué)習(xí)(也就是深度神經(jīng)網(wǎng)絡(luò))的開發(fā)成本和開發(fā)難度. TensorFlow 的開源性, 讓所有人都能使用并且維護(hù), 鞏固它. 使它能迅速更新, 提升.
BUG签赃?
貌似Tensorflow有bug谷异,雖然谷歌開發(fā)人員在盡力修改。锦聊。bug主要集中在他的選參數(shù)上面~
Tensorflow 安裝
安裝之前歹嘹,推薦兩個在線使用tensorflow的軟件:
https://colab.research.google.com/
我的配置為win10, python3.6.4, ana
估摸著TensorFlow 的安裝包目前windows版本還不支持 Python 3.6 ,于是到https://pypi.python.org/pypi/tensorflow/1.1.0rc2下載了whl文件孔庭,結(jié)果:
換成pip3還是不行:
看了網(wǎng)上的很多解決方案尺上,好像還是安裝Anaconda稍微顯得簡單一點。
安裝好Anaconda后圆到,我想檢驗一下怎抛,結(jié)果:
用'path'一看,環(huán)境變量沒配:
由于安裝的時候這一欄這么提示:
所以選擇手動添加path芽淡。
添加3個變量:
F:\Anaconda3
F:\Anaconda3\Scripts
F:\Anaconda3\Library\bin
重啟命令行:
成功马绝!
由于我安裝的最新版本的Anaconda,適用于python3.7,所以我還要設(shè)成3.6
輸入命令:'conda install python=3.6'
安裝結(jié)束后,輸入:'anaconda search -t conda tensorflow'挣菲,搜索當(dāng)前可用版本
選擇一個版本輸入:'anaconda show (對應(yīng)名稱)' 富稻,查詢安裝命令
輸入跳出的安裝命令安裝
Tensorflow基礎(chǔ)架構(gòu)
TensorFlow是采用數(shù)據(jù)流圖(data flow graphs)來計算。
首先創(chuàng)建數(shù)據(jù)流流圖白胀,然后將數(shù)據(jù)(以張量——tensor的形式存在)放在數(shù)據(jù)流中計算椭赋。
節(jié)點(nodes)表示數(shù)學(xué)操作,線(edges)表示節(jié)點間相互聯(lián)系的多維數(shù)組或杠,即張量(tensor)哪怔。訓(xùn)練模型時,tensor會不斷從數(shù)據(jù)流圖中的一個結(jié)點流(flow)到另一個節(jié)點向抢。即是tensor~~flow
張量
0階:一個數(shù)值认境,比如'[1]'
1階:向量,比如'[1,2,3]'
2階:矩陣笋额,比如'[[1,2], [1,2]]'
以此類推...感覺就是n階矩陣...
如何搭建結(jié)構(gòu)
import tensorflow as tf
import numpy as np
# 創(chuàng)建數(shù)據(jù)
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data*0.1+0.3
# 搭建模型
weights = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
biases = tf.Variable(tf.zeros([1]))
y = weights*x_data + biases
# 計算誤差
loss = tf.reduce_mean(tf.square(y-y_data))
# 傳播誤差
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
#訓(xùn)練
init = tf.global_variables_initializer() #初始化之前定義的所有Variable
sess = tf.Session()
sess.run(init)
for step in range(201):
sess.run(train)
if step % 20 == 0:
print(step.sess.run(weights), sess.run(biases))
Session
目的:控制元暴、輸出文件執(zhí)行的語句
運行'session.run()'可以獲得運算結(jié)果
import tensorflow as tf
#創(chuàng)建兩個矩陣
matrix = tf.constant([[3,3]])
matrix = tf.constant([[2],[2]])
product = tf.matmul(matrix1, matrix2) #輸出矩陣相乘結(jié)果
#因為 product 不是直接計算的步驟
#所以我們會要使用 Session 來激活 product 并得到計算結(jié)果.
#方法1
sess = tf.Session()
result = sess.run(product)
print("method1:",result)
sess.close()
#方法2
with tf.Session() as sess:
result2 = sess.run(product)
print("method2:",result2)
Placeholder
目的:占位符,暫時存儲變量兄猩。
如果想要從外部傳入data, 那就需要用tf.placeholder(), 然后以這種形式傳輸數(shù)據(jù) sess.run(***, feed_dict={input: **})
import tensorflow as tf
#定義兩個輸入
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
#做乘法運算茉盏,并輸出為output
output = tf.multiply(input1, input2)
with tf.Session() as sess:
print(sess.run(output, feed_dict={input1:[7.], input2:[2.]}))
激勵函數(shù)
目的:矩陣相乘是線性相乘鉴未,激勵函數(shù)可以將線性轉(zhuǎn)化為非線性,事實上就是套一個非線性函數(shù)鸠姨。
添加層 add_layer
目的:定義 添加層函數(shù) 可以添加一個神經(jīng)層
import tensorflow as tf
#四個參數(shù):輸入值铜秆、輸入的大小、輸出的大小和激勵函數(shù)
#設(shè)定默認(rèn)的激勵函數(shù)是None
def add_layer(inputs, in_size, out_size, activation_function=None):
#weights為一個in_size行, out_size列的隨機(jī)變量矩陣
weights = tf.Variable(tf.random_normal([in_size, out_size]))
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
#定義Wx_plus_b, 即神經(jīng)網(wǎng)絡(luò)未激活的值
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
建造神經(jīng)網(wǎng)絡(luò)
import tensorflow as tf
import numpy as n
#添加一個神經(jīng)層函數(shù)
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 output
#導(dǎo)入數(shù)據(jù)
x_data = np.linspace(-1, 1, 300, dtype=np.float32)[:, np.newaxis]
noise = np.random.normal(0, 0.05, x_data.shape).astype(np.float32)
y_data = np.square(x_data) - 0.5 + noise
#利用占位符tf.placeholder()定義我們所需的神經(jīng)網(wǎng)絡(luò)的輸入
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])
#構(gòu)建網(wǎng)絡(luò)
#輸入層1個讶迁、隱藏層10個连茧、輸出層1個的神經(jīng)網(wǎng)絡(luò)
#定義隱藏層
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu) #tf.nn.relu是自帶的激勵函數(shù)
#定義輸出層
prediction = add_layer(l1, 10, 1, activation_function=None)
#計算prediction和真實值的均方差
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction),reduction_indices=[1]))
train_step = tf.train.GradientDencentOptimizer(0.1).minimize(loss)
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)#在tensorflow中,只有session.run()才會執(zhí)行我們定義的運算巍糯。
#訓(xùn)練
for i in range(1000):
sess.run(train_step, feed_dict={xs:x_data,ys:y_data})
#每隔50次訓(xùn)練刷新一次圖形啸驯,用紅色、寬度為5的線來顯示我們的預(yù)測數(shù)據(jù)和輸入之間的關(guān)系祟峦,并暫停0.1s
if i%50 == 0:
try:
ax.lines.remove(lines[0])
except Exception:
pass
prediction_value = sess.run(prediction, feed_dict={xs: x_data})
# plot the prediction
lines = ax.plot(x_data, prediction_value, 'r-', lw=5)
plt.pause(0.1)
加速神經(jīng)網(wǎng)絡(luò)
*方法1:Stochastic Gradient Descent (SGD) 隨機(jī)梯度下降:隨機(jī)也就是只取可以近似所有的樣本的一個例子罚斗,這樣大大減少了時間。(有點像TransE算法中的負(fù)采樣)
*方法2:Momentum 更新方法
由于SGD很隨機(jī)宅楞,其更新十分不穩(wěn)定针姿。因此momentum在更新的時候在一定程度上保留之前更新的方向,同時利用當(dāng)前batch的梯度微調(diào)最終的更新方向厌衙。這樣一來距淫,可以在一定程度上增加穩(wěn)定性,從而學(xué)習(xí)地更快婶希,并且還有一定擺脫局部最優(yōu)的能力榕暇。
其實也就是說,假如我上次走的路是對的饲趋,那么我接著往前走拐揭,并且微調(diào)一下前進(jìn)的方向撤蟆,向著更準(zhǔn)確的方向進(jìn)行奕塑。
*方法三:AdaGrad 更新方法:使得每一個參數(shù)更新都會有自己與眾不同的學(xué)習(xí)率。
*方法四:RMSProp 更新方法:momentum+adagrad
*方法五:Adam 更新方法:Adam 算法根據(jù)損失函數(shù)對每個參數(shù)的梯度的一階矩估計和二階矩估計動態(tài)調(diào)整針對于每個參數(shù)的學(xué)習(xí)速率家肯。Adam 也是基于梯度下降的方法龄砰,但是每次迭代參數(shù)的學(xué)習(xí)步長都有一個確定的范圍,不會因為很大的梯度導(dǎo)致很大的學(xué)習(xí)步長讨衣,參數(shù)的值比較穩(wěn)定换棚。
用Tensorboard可視化神經(jīng)網(wǎng)絡(luò)
注:與 tensorboard 兼容的瀏覽器是 “Google Chrome”
這部分不想學(xué)了。
高階內(nèi)容
Classification 分類學(xué)習(xí)
from tensorflow.examples.tutorials.mnist import input_data
#準(zhǔn)備數(shù)據(jù)(MNIST庫反镇,MNIST庫是手寫體數(shù)字庫, 需要翻墻)
#數(shù)據(jù)中包含55000張訓(xùn)練圖片固蚤,每張圖片的分辨率是28×28
#所以我們的訓(xùn)練網(wǎng)絡(luò)輸入應(yīng)該是28×28=784個像素數(shù)據(jù)
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
#添加一個神經(jīng)層函數(shù)
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 output
#搭建網(wǎng)絡(luò)
xs = tf.placeholder(tf.float32, [None,784])
ys = tf.placeholder(tf.float32,[None,10])
#輸入數(shù)據(jù)是784個特征,輸出數(shù)據(jù)是10個特征歹茶,激勵采用softmax函數(shù)
prediction = add_layer(xs, 784, 10, activation_function=tf.nn.softmax)
#loss函數(shù)(即最優(yōu)化目標(biāo)函數(shù))選用交叉熵函數(shù)夕玩。
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), reduction_indices=[1])) # loss
#train方法(最優(yōu)化算法)采用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
#訓(xùn)練
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys})
#每訓(xùn)練50次輸出一下預(yù)測精度
if i % 50 == 0:
print(compute_accuracy(mnist.test.images, mnist.test.labels))
過擬合
解釋:做物理實驗的時候不是要描點畫線嘛你弦,通常最后是一條直線。但是數(shù)據(jù)經(jīng)過網(wǎng)絡(luò)后變成了彎彎曲曲的曲線燎孟,雖然過每一個點禽作,但是并不正確。這種情況就是過擬合揩页。