簡介
TensorFlow是采用數(shù)據(jù)流圖,用于數(shù)值計算的深度學習框架(常用于神經(jīng)網(wǎng)絡(luò)相),其中在數(shù)據(jù)流圖里,節(jié)點表示數(shù)學操作,線表示節(jié)點間相互聯(lián)系的數(shù)據(jù),即張量(tensor)
安裝
其分為CPU和GPU(更快,但要有硬件支持)版本,安裝命令如下:
pip install tensorflow
pip install tensorflow-gpu
注:
安裝時要求python版本為2.7+或者3.5+(3.5需要為64位)
使用步驟
Tensorflow不單獨地運行單一的復雜計算,而是讓我們可以先用圖描述一系列可交互的計算操作,然后全部一起在Python之外運行,從而減少開銷,因此基本上所有的 Tensorflow 代碼都包含兩個重要部分:
1.計算圖(Graph),表示計算任務
2.會話(Session),用于執(zhí)行計算圖中的運算
因此使用步驟大體如下:
1.導入tensorflow框架:import tensorflow as tf
2.創(chuàng)建計算圖,定義張量(如:常量tf.constant()、變量tf.Variable()等)和運算方法(如:矩陣乘法tf.matmul()等)
3.創(chuàng)建會話(sess = tf.session()),用于運行計算圖中運算
4.通過會話運行計算(sess.run())
5.關(guān)閉會話(sess.close())
簡單示例
import tensorflow as tf
x = tf.constant([[1,2]])
# 創(chuàng)建一個1行2列的矩陣
y = tf.constant([[3], [4]])
# 創(chuàng)建一個兩行一列的矩陣
mul = tf.matmul(x, y)
# 將兩個矩陣相乘
sess = tf.Session()
# 創(chuàng)建一個會話
result = sess.run(mul)
# 執(zhí)行前面運算圖中定義的常量和運算方法
print(result)
# 輸出運算圖中乘法運算執(zhí)行的結(jié)果
sess.close()
# 關(guān)閉會話
由于會話執(zhí)行結(jié)束后需要關(guān)閉,因此上面的也可以使用with關(guān)鍵字來實現(xiàn)自動關(guān)閉,舉例:
import tensorflow as tf
with tf.Session() as sess:
# 使用with關(guān)鍵字可以在sess使用結(jié)束時自動關(guān)閉資源
x = tf.constant([[1, 2]])
y = tf.constant([[3], [4]])
mul = tf.matmul(x, y)
result = sess.run(mul)
print(result)
基本語句
定義常量
tf.constant()
注:
當運算圖中定義了變量以后,需要在會話中先調(diào)用語句tf.global_variables_initializer()來對所有變量進行初始化
定義變量
tf.Variable()
數(shù)據(jù)類型轉(zhuǎn)換
tf.cast(x, xtype),可以將前面的數(shù)據(jù)類型進行轉(zhuǎn)換,舉例:
x = tf.Variable([1,2,3,4,5])
y = tf.cast(x,dtype=tf.float32)
基本運算
加減乘除
tf.add(x, y)/subtract(x, y)/tf.multiply(x, y)/tf.div(x, y)(整除)/tf.divide(x, y)(小數(shù)除,需要除數(shù)被除數(shù)都為float),舉例:
import tensorflow as tf
init = tf.Variable(10.0)
# 定義一個變量
two = tf.constant(2.0)
# 定義一個常量
div_two = tf.divide(init, two)
# 定義一個除法運算
矩陣相乘
tf.matmul(x, y)
平方運算
tf.square(x)
獲取矩陣里數(shù)的總和/平均值/最大值/最小值
tf.reduce_sum(x)/reduce_mean(x)/reduce_max(x)/reduce_min(x)
生成幾行幾列的隨機數(shù)矩陣
tf.random_uniform([m], x, y),即生成格式為m,數(shù)值全為x到y的隨機數(shù)矩陣
生成幾行幾列的全零矩陣
tf.zeros([m]),生成格式為m的全零矩陣
判斷是否相等
tf.equal(x, y),判斷x、y的值是否相等,返回bool類型
更新(賦值)變量
tf.assign(x, way),將x以way方式更新數(shù)據(jù),即賦值操作
使用舉例:
import tensorflow as tf
init = tf.Variable(0)
# 定義一個變量
one = tf.constant(1)
# 定義一個常量
add_one = tf.add(init, one)
# 定義一個加法運算
update = tf.assign(init, add_one)
# 定義一個將當前值加一并更新的運算
init_var = tf.global_variables_initializer()
# 定義一個變量初始化
with tf.Session() as sess:
sess.run(init_var)
# 初始化變量
for i in range(3):
print(sess.run(update), end="\t")
# 輸出每次加1并更新后的結(jié)果
# 結(jié)果為:
# 1 2 3
返回最大值索引
tf.argmax(input,axis),返回輸入內(nèi)容的最大值索引,當axis為0時代表一維,根據(jù)每一列返回最大索引,axis為1時代表二維,根據(jù)每一行返回最大索引,以此類推
詳細參考:
https://blog.csdn.net/u012300744/article/details/81240580
傳值/返回值
feed_dict傳參
對于會話中的run()方法,一般都是將常量和初始化完成的變量傳入運算,但其實也可以通過feed_dict參數(shù)將數(shù)值以字典方式傳入,此時對于這些值,需要先通過tf.placeholder()方法創(chuàng)建占位符,然后再傳入對應格式的數(shù)據(jù),舉例:
import tensorflow as tf
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
# 創(chuàng)建兩個float型占位符
output = tf.multiply(input1, input2)
# 進行乘法運算
with tf.Session() as sess:
print(sess.run([output], feed_dict={input1:7., input2:2.}))
# 傳入兩個占位符的值分別為7.0和2.0
占位符
tf.placeholder(xtype[, shape, name=xx])占位符的傳參依次分別是:傳入類型、傳入格式和命名(name),由于命名為名稱參數(shù),主要在可視化當中使用,這里不說。這里介紹下傳入類型和傳入格式
- 傳入類型
tf.float32 -> float(最常用)
tf.float64 -> double
tf.double -> double(和上面那個一樣的)
tf.int32 -> int
tf.uint32 -> int(正數(shù)部分)
...
從源代碼當中也可以看到傳入類型的定義:
np.bool_: (False, True),
np.bool8: (False, True),
np.uint8: (0, 255),
np.uint16: (0, 65535),
np.int8: (-128, 127),
np.int16: (-32768, 32767),
np.int64: (-2**63, 2**63 - 1),
np.uint64: (0, 2**64 - 1),
np.int32: (-2**31, 2**31 - 1),
np.uint32: (0, 2**32 - 1),
np.float32: (-1, 1),
np.float64: (-1, 1)
- 傳入格式
傳入格式需要說明的不多,就是就是定義幾行幾列、比如2行1列就是:[2, 1],如果多維度,就幾維幾行幾列那樣以此類推,可以參考np.array()的shape,要注意的是None,這個代表任意的意思,比如任意行1列就是:[None, 1]
舉例:
tf.placeholder(tf.float32, [None, 1])
# 定義數(shù)據(jù)為浮點數(shù),任意行,1列的占位符
Fetch返回值
執(zhí)行會話操作時的sess.run()語句時,將會返回對應輸入?yún)?shù)的結(jié)果值
其他方法
tf.pad
擴展矩陣,分別從各個維度方向擴展數(shù)據(jù),參考:
https://blog.csdn.net/qq_40994943/article/details/85331327
https://blog.csdn.net/luoganttcc/article/details/83303522
激活函數(shù)
激活函數(shù)作用簡單來說就是原來的中間層只是單純的矩陣相乘,因此只能解決線性問題,使用激活函數(shù)以后,就能解決線性相關(guān)問題了,具體參考:
https://blog.csdn.net/program_developer/article/details/78704224
tanh
tf.nn.tanh,數(shù)據(jù)隨tanh函數(shù)的曲線變化
relu
tf.nn.relu,其將所有小于0的數(shù)置為0,大于0的數(shù)保持不變
參考:https://blog.csdn.net/Random_R/article/details/80523265
sigmoid
tf.nn.sigmoid,數(shù)據(jù)隨1/(1+e^-x)函數(shù)曲線變化
softmax
tf.nn.softmax
參考:https://blog.csdn.net/red_stone1/article/details/80687921
損失函數(shù)/交叉熵函數(shù)
學習訓練模型時,需要有一個參照值作為訓練的標準,比如設(shè)置一個損失函數(shù),其值為預測值和正確值之差的平方和取平均值,代碼如下:
loss = tf.reduce_mean(tf.square(y-prediction))
損失函數(shù)的變化梯度和激活函數(shù)的梯度相關(guān),而交叉熵的變化梯度則和預測值和正確值之間的誤差有關(guān),當誤差越大時,梯度越大,反之越小,因此線性預測時,適合用損失函數(shù),非線性的適合用交叉熵,其中交叉熵一般和sigmoid()/softmax()結(jié)合使用(tf.nn.softmax_cross_entropy_with_logits()/tf.nn.sigmoid_cross_entropy_with_logits()),交叉熵使用舉例:
loss = tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction)
# labels傳入正確值,logits傳入預測值
注:
使用上面的交叉熵函數(shù)時,里面包括了sigmoid()/softmax()方法,因此不需要再調(diào)用這些激活函數(shù)
優(yōu)化器
tf.train(),其下提供了很多優(yōu)化器,其中最簡單的就是梯度下降GradientDescentOptimizer(),里面需要傳入學習率(優(yōu)化器的用法基本都差不多),舉例:
optimizer = tf.train.GradientDescentOptimizer(0.01)
# 基于梯度下降法,學習率為0.01的優(yōu)化器
優(yōu)化器的作用就是設(shè)置一個參照值,在設(shè)置一個目標,比如越小越好,以此為根據(jù)從而不斷訓練,例如以前面的損失函數(shù)為標準,目標是越低越好,舉例:
train = optimizer.minimize(loss)
AdamOptimizer()
這個是比較好的優(yōu)化器,較為推薦
各種優(yōu)化器詳解
https://blog.csdn.net/weixin_40170902/article/details/80092628
學習率問題
使用優(yōu)化器時,設(shè)置學習率是個很重要的問題,學習率設(shè)置過大,則可能無法擬合數(shù)據(jù),設(shè)置過小,則可能擬合過慢,并且隨著迭代次數(shù)的增加,擬合的變化量將越來越小,此時如果學習率不夠小,也將無法繼續(xù)擬合,因此可以在設(shè)置起始學習率時,調(diào)一個差不多的值,并隨著迭代次數(shù)減小學習率,從而達到能夠較快速且不斷擬合的效果
擬合問題
對于模型訓練,如果提供的數(shù)據(jù)量過少,則可能出現(xiàn)過擬合問題,此時解決方案一般有以下幾種:
1.增加數(shù)據(jù)量
2.數(shù)據(jù)正則化
3.dropout隨機選取
dropout()
一次隨機選取一定比例的神經(jīng)元,舉例:
tf.nn.dropout(x, 0.5)
# 在x中選取一半的數(shù)據(jù)
會話操作
創(chuàng)建會話
sess = tf.Session()
執(zhí)行運算
sess.run()
注:
如果只傳入一個運算,那么當前會話會返回該運算執(zhí)行完畢后對應的結(jié)果,但如果想進行多個運算并返回多個對應的結(jié)果,則可以通過一個列表將多個運算一起傳入,結(jié)果也是一個列表,依次為每個運算的結(jié)果
注2:
當傳入多個運算時,其將一起執(zhí)行,而不是按傳入順序去執(zhí)行,因此如果在一次run()里傳入多個相同的運算,那么就相當于執(zhí)行一次
關(guān)閉會話
sess.close()
模型保存和載入
保存模型
在會話操作前通過saver = tf.train.Saver()定義一個保存器,當模型訓練完畢時,通過saver.save(sess, '路徑')來保存模型,舉例:
# 定義操作
...
saver = tf.train.Saver()
with tf.Session() as sess:
# 模型訓練操作
...
saver.save(sess, 'test_model.ckpt')
# 訓練完成,保存模型
載入模型
通過saver.restore(sess, '路徑')來載入模型,舉例:
...
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, 'test_model.ckpt')
# 載入模型到sess
# 可以直接使用模型進行操作了
...
簡單綜合示例
import tensorflow as tf
# 預測一個一元線性方程y=Wx+b的W和b的值,使其符合當x依次為1,2,3,4時,對應的y值依次為0,-1,-2,-3
W = tf.Variable(1., tf.float32)
b = tf.Variable(-1., tf.float32)
# 定義變量W和b,值分別為1.0和-1.0
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
# 定義占位符,用于執(zhí)行開始時的數(shù)據(jù)輸入
init = tf.global_variables_initializer()
# 定義初始化變量
linear_model = W*x + b
# 定義y=Wx+b的一元線性方程模型
squared_deltas = tf.square(linear_model - y)
# 定義期望值和實際值之差的平方,用于后面的損失函數(shù)
loss = tf.reduce_sum(squared_deltas)
# 定義損失函數(shù),值為所有計算差的平方和
optimizer = tf.train.GradientDescentOptimizer(0.01)
# 定義一個梯度下降的優(yōu)化器,學習速率為0.01
train = optimizer.minimize(loss)
# 通過梯度下降方法盡可能使損失函數(shù)的值減小
with tf.Session() as sess:
sess.run(init)
# 初始化變量
for i in range(1000):
sess.run(train, {x: [1., 2., 3., 4.], y: [0., -1., -2., -3.]})
# 訓練1000次,并在這期間自動調(diào)整W和b的大小
print(sess.run([W, b]))
# 輸出訓練1000次后W和b的值:[-0.99999523, 0.999986](最完美的是W=-1,b=1,但不可能達到)
示例2
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis]
# 生成-0.5到0.5的200個等差數(shù)列,并轉(zhuǎn)成二維數(shù)據(jù),即從1行200列轉(zhuǎn)成200行1列
noise = np.random.normal(0, 0.02, x_data.shape)
# 生成和x_data格式相同的噪音數(shù)據(jù)
y_data = np.square(x_data) + noise
# 期望值為x_data的平方加上噪音
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])
# 定義兩個占位符,要求格式為:任意行,1列的數(shù)據(jù)
# 定義中間層
W1 = tf.Variable(tf.random_normal([1, 10]))
# 定義1行10列的隨機矩陣權(quán)重,即中間層有10個神經(jīng)元
b1 = tf.Variable(tf.zeros([1, 10]))
# 定義偏差
y_Wb1 = tf.matmul(x, W1) + b1
# 中間層對輸入數(shù)據(jù)進行計算:輸入數(shù)據(jù)與權(quán)重相乘后加上偏差值
lay1 = tf.nn.tanh(y_Wb1)
# 通過tanh激活函數(shù)來傳達到下一層
# 定義輸出層
W2 = tf.Variable(tf.random_normal([10, 1]))
# 經(jīng)過中間層,輸出結(jié)果由1行1列轉(zhuǎn)成了1行10列,因此定義10行1列隨機矩陣權(quán)重進行接收
b2 = tf.Variable(tf.zeros([1, 1]))
# 定義偏差
y_Wb2 = tf.matmul(lay1, W2) + b2
# 計算輸出結(jié)果
output = tf.nn.tanh(y_Wb2)
# 激活函數(shù)輸出
loss = tf.reduce_mean(tf.square(y - output))
# 損失函數(shù)值為輸出結(jié)果與期望結(jié)果之差平方的平均值
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
# 定義梯度下降優(yōu)化器,學習率為0.1,盡量讓損失值小
init = tf.global_variables_initializer()
# 注意初始化要寫在所有變量定義結(jié)束后
with tf.Session() as sess:
sess.run(init)
# 初始化變量
fig = plt.figure()
plt.ion()
# 動態(tài)交互式圖形
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data, y_data)
# 繪畫散點數(shù)據(jù)
for i in range(2000):
sess.run(train_step, feed_dict={x:x_data, y:y_data})
# 訓練2000次
if i % 100 == 0:
prediction = sess.run(output, feed_dict={x:x_data})
# 每訓練100次的預測曲線
plt.pause(0.1)
try:
ax.lines.remove(lines[0])
# 刪除原先折線
except Exception as e:
pass
lines = ax.plot(x_data, prediction, 'red', lw=5)
# 繪畫預測數(shù)據(jù)折線
plt.ioff()
# 關(guān)閉交互
plt.show()
上面的代碼結(jié)合神經(jīng)網(wǎng)絡(luò)層的原理,還可以換成下面那樣表示:
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
def add_layer(input, input_size, output_size, activation=None):
'''定義神經(jīng)網(wǎng)絡(luò)層'''
W = tf.Variable(tf.random.normal([input_size, output_size]))
b = tf.Variable(tf.zeros([1, output_size]))
layer = tf.matmul(input, W) + b
if activation:
layer = activation(layer)
return layer
x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis]
noise = np.random.normal(0, 0.02, x_data.shape)
y_data = np.square(x_data) + noise
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])
layer1 = add_layer(x, 1, 10, tf.nn.tanh)
# 進入隱藏層
output = add_layer(layer1, 10, 1, tf.nn.tanh)
# 輸出層
loss = tf.reduce_mean(tf.square(y-output))
train = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plt.ion()
plt.scatter(x_data, y_data)
for i in range(2000):
sess.run(train, feed_dict={x: x_data, y: y_data})
if i % 50 == 0:
result = sess.run(output, feed_dict={x: x_data})
plt.pause(0.1)
try:
ax.lines.remove(lines[0])
except:
pass
lines = ax.plot(x_data, result, 'red')
plt.ioff()
plt.show()
小小拓展:
如果把一開始初始化的數(shù)據(jù)改大點(比如:-5~5),觀察下運行情況可以發(fā)現(xiàn)上面的代碼就完全不擬合了,其原因如下:
1.由于輸出層使用了tanh()激活函數(shù),最終的結(jié)果被壓縮到了-1~1之間,因此無法進行擬合,此時只要把輸出層的激活函數(shù)給去掉就行了。
如果依舊擬合不是很好,那么可以再參考以下優(yōu)化方法:
1.增加初始化數(shù)據(jù)集的量
2.增加神經(jīng)層數(shù)和神經(jīng)元的數(shù)量
3.修改損失函數(shù)
4.修改優(yōu)化器或優(yōu)化器的學習率
...
比如修改成-5~5之間可以把代碼修改如下:
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
x_data = np.linspace(-5, 5, 2000)[:, np.newaxis]
# 數(shù)據(jù)量增加到2000
noise = np.random.normal(0, 0.02, x_data.shape)
y_data = np.square(x_data) + noise
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])
W1 = tf.Variable(tf.random_normal([1, 10]))
b1 = tf.Variable(tf.zeros([1, 10]))
y_Wb1 = tf.matmul(x, W1) + b1
lay1 = tf.nn.tanh(y_Wb1)
W2 = tf.Variable(tf.random_normal([10, 1]))
b2 = tf.Variable(tf.zeros([1, 1]))
y_Wb2 = tf.matmul(lay1, W2) + b2
output = y_Wb2
# 取消輸出層的激活函數(shù)
loss = tf.reduce_mean(tf.square(y - output))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
# 降低學習率
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
fig = plt.figure()
plt.ion()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data, y_data)
for i in range(2000):
sess.run(train_step, feed_dict={x:x_data, y:y_data})
if i % 100 == 0:
prediction = sess.run(output, feed_dict={x:x_data})
plt.pause(0.1)
try:
ax.lines.remove(lines[0])
except Exception as e:
pass
lines = ax.plot(x_data, prediction, 'red', lw=5)
plt.ioff()
plt.show()
卷積神經(jīng)網(wǎng)絡(luò)CNN
傳統(tǒng)神經(jīng)網(wǎng)絡(luò)問題:權(quán)值多,計算量大,需要大量樣本進行訓練,卷積神經(jīng)網(wǎng)絡(luò)則是分塊處理,取特征值,一般包括卷積層和池化層,常用于圖像處理等
卷積層
通過tf.nn.conv2d(input, filter, strides, padding)實現(xiàn),傳入?yún)?shù)說明:
1.input:輸入數(shù)據(jù),是一個列表:[batch, in_height, in_width, in_channels],分別代表數(shù)據(jù)量,數(shù)據(jù)高寬,以及通道數(shù)(黑白則為1,彩色包括紅綠藍則為3)
2.filter:濾波器,即每次分塊處理的參數(shù),是一個列表:[filter_height, filter_width, in_channels, out_channels],分別代表濾波器高寬,以及輸入輸出通道數(shù)
3.strides:步長,也是個列表:[1, x, y, 1],第一個和最后一個參數(shù)為1,中間兩個代表x,y方向的步長
4.padding:卷積操作(特征抽取),有same和valid兩種方法,第一種代表當分塊時整體內(nèi)容不夠湊一塊,則周圍用0補全,然后再取特征值,第二種則直接放棄特征值抽取
池化層
通過tf.nn.max_pool(input, ksize, strides, padding)實現(xiàn),傳入?yún)?shù)說明:
1.input:輸入數(shù)據(jù)
2.ksize:池化窗口大小,是一個列表:[1, height, width, 1],第一個和第四個必須為1,中間兩個為尺寸
3.strides:步長
4.padding:卷積操作,有same和valid兩種方法
循環(huán)神經(jīng)網(wǎng)絡(luò)RNN
循環(huán)神經(jīng)網(wǎng)絡(luò),里面存在隱層,能夠?qū)⑶耙粋€的分析結(jié)果往后傳遞,類似反向傳播,但因為RNN中信號向下傳播時會逐漸減弱,因此需要有能夠選擇性記住靠譜信號,過濾不靠譜信號的模型,即LSTM(Long Short TermMemory)
RNN實現(xiàn)
1.通過tf.contrib.rnn.core_rnn_cell.BasicLSTMCell()設(shè)置LSTM單元數(shù)
2.通過tf.nn.dynamic_rnn(lstm_cell, input, dtype)實現(xiàn)RNN,分別傳入三個參數(shù):LTMS單元、輸入數(shù)據(jù)以及格式,返回的值有輸出結(jié)果和final_state,其中final_state是一個列表,第一個值為0代表cell_state,為1代表hidden_state,第二個是批次樣本數(shù)batch_size,舉例:
def RNN(X,weights,biases):
inputs = tf.reshape(X,[-1,max_time,n_inputs])
lstm_cell = tf.contrib.rnn.core_rnn_cell.BasicLSTMCell(lstm_size)
outputs,final_state = tf.nn.dynamic_rnn(lstm_cell,inputs,dtype=tf.float32)
results = tf.nn.softmax(tf.matmul(final_state[1],weights) + biases)
return results
可視化框架tensorboard
使用步驟
1.首先需要給各個部分通過tf.name_scope設(shè)置命名空間
2.分別對命名空間下的數(shù)據(jù)設(shè)置name屬性,否則會自動設(shè)置默認屬性
3.在會話當中通過tf.summary.FileWriter('文件生成路徑', sess.graph)生成圖像
4.在文件生成路徑的父文件夾中打開命令行輸入命令:tensorboard --logdir=路徑 --host 127.0.0.1,進入網(wǎng)址找到graph即可,舉例:
tensorboard --logdir=logs --host 127.0.0.1
代碼示例
import numpy as np
import tensorflow as tf
def add_layer(input, input_size, output_size, activation=None):
'''定義神經(jīng)網(wǎng)絡(luò)層'''
with tf.name_scope('Weight'):
W = tf.Variable(tf.random.normal([input_size, output_size]), name='W')
with tf.name_scope('biases'):
b = tf.Variable(tf.random.normal([1, output_size]), name='b')
with tf.name_scope('Y_Wb'):
layer = tf.matmul(input, W) + b
if activation:
layer = activation(layer)
return layer
lr = 0.001
x_data = np.linspace(-1, 1, 200)[:, np.newaxis]
noise = np.random.normal(0, 0.1, x_data.shape)
y_data = np.square(x_data) + noise
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [None, 1], name='x')
y = tf.placeholder(tf.float32, [None, 1], name='y')
with tf.name_scope('layer1'):
layer1 = add_layer(x, 1, 3, tf.nn.relu)
with tf.name_scope('layer2'):
layer2 = add_layer(layer1, 3, 5, tf.nn.relu)
with tf.name_scope('layer3'):
prediction = add_layer(layer2, 5, 1, tf.nn.relu)
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.square(y-prediction))
with tf.name_scope('train'):
train = tf.train.AdamOptimizer(lr).minimize(loss)
init = tf.global_variables_initializer()
# 不用設(shè)置init,默認會自動創(chuàng)建
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter('logs/', sess.graph)
for i in range(2000):
sess.run(train, feed_dict={x: x_data, y: y_data})
lr *= 0.99
if i % 50 == 0:
result = sess.run(prediction, feed_dict={x: x_data})
print(sess.run(loss, feed_dict={x: x_data, y: y_data}))
# 在生成文件目錄的上一層打開命令行輸入以下命令:
# tensorboard --logdir=logs --host 127.0.0.1
# 進入提供的網(wǎng)址即可
注:
使用中出現(xiàn)問題:oserror: [errno 22] invalid argument
參考:https://blog.csdn.net/u013244846/article/details/88380860
數(shù)據(jù)記錄展示
如果希望展示某些數(shù)據(jù)的走向趨勢的話,可以通過tf.summary.scalar()來對數(shù)據(jù)進行曲線展示,tf.summary.histogram()進行直方圖展示,然后再會話當中通過tf.summary.merge_all()合并所有展示內(nèi)容,最后通過writer.add_summary()將內(nèi)容寫至生成文件當中,舉例:
import numpy as np
import tensorflow as tf
def add_layer(input, input_size, output_size, activation=None):
with tf.name_scope('Weight'):
W = tf.Variable(tf.random.normal([input_size, output_size]), name='W')
with tf.name_scope('biases'):
b = tf.Variable(tf.random.normal([1, output_size]), name='b')
with tf.name_scope('Y_Wb'):
layer = tf.matmul(input, W) + b
if activation:
layer = activation(layer)
return layer
lr = 0.001
x_data = np.linspace(-1, 1, 200)[:, np.newaxis]
noise = np.random.normal(0, 0.1, x_data.shape)
y_data = np.square(x_data) + noise
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [None, 1], name='x')
y = tf.placeholder(tf.float32, [None, 1], name='y')
with tf.name_scope('layer1'):
layer1 = add_layer(x, 1, 3, tf.nn.relu)
with tf.name_scope('layer2'):
layer2 = add_layer(layer1, 3, 5, tf.nn.relu)
with tf.name_scope('layer3'):
prediction = add_layer(layer2, 5, 1, tf.nn.relu)
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.square(y-prediction))
with tf.name_scope('summary'):
tf.summary.scalar('mean', tf.reduce_mean(loss))
tf.summary.scalar('max', tf.reduce_max(loss))
tf.summary.scalar('min', tf.reduce_min(loss))
tf.summary.histogram('loss', loss)
# 展示損失函數(shù)的平均、最大、最小值變化,以及自身值的直方圖
with tf.name_scope('train'):
train = tf.train.AdamOptimizer(lr).minimize(loss)
init = tf.global_variables_initializer()
merged = tf.summary.merge_all()
# 合并所有展示內(nèi)容
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter('logs/', sess.graph)
for i in range(2000):
_, summary = sess.run([train, merged], feed_dict={x: x_data, y: y_data})
writer.add_summary(summary, i)
# 數(shù)據(jù)圖表添加到文件當中
lr *= 0.99
if i % 50 == 0:
result = sess.run(prediction, feed_dict={x: x_data})
print(sess.run(loss, feed_dict={x: x_data, y: y_data}))
莫凡TensorFlow教程
https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/1-1-A-ANN-and-NN/