TensorFlow學習記錄1

1、神經網絡實現過程

一、準備數據集,提取特徵,做爲輸入餵給神經網絡
二、搭建NN(Neural Network)結構,從輸入到輸出(先搭建計算圖,在用會話執行)(NN前向傳播算法→計算輸出)
三、大量特徵數據餵給NN,迭代優化NN參數(NN反向傳播算法→優化參數訓練模型)
四、使用訓練好的模型預測和分類算法

2、前向傳播

image.png
參數W的維數爲:前行後列(即前面一層的個數爲W的行數 後面一層的個數爲W的列數)
image.pngsegmentfault

前向傳播代碼示例:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  #隱藏輸出警告
import tensorflow as tf

#定義輸入和參數用placeholder定義輸入 (sess.run喂入一組或多組數據)
#tf.Variable表示生成隨機數 shape(a, b)表示數據類型爲a行b列
x = tf.placeholder(tf.float32,shape=(None, 2)) #多組數據的話使用none表示
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))

#定義前向傳播過程
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

#調用會話計算結果 (變量初始化,計算圖節點運算,都要用會話(with結構)實現)
with tf.Session() as sess:
#變量初始化
init_op = tf.global_variables_initializer()
#計算圖節點運算:在sess.run函數中寫入帶運算的節點
sess.run(init_op) 
#用tf.placeholder在前面佔位,在sess.run函數中用feed_dict喂入數據
print("the result of 前向傳播 is :n", sess.run(y,feed_dict={x:[[0.7, 0.5], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]}))
print("w1:", sess.run(w1))
print("w2:", sess.run(w2))

3、反向傳播

一、反向傳播的做用:訓練模型參數,在全部參數上用梯度降低方法,使NN模型在訓練數據上的損失函數最小
二、損失函數(loss):用於預測值(y)和已知標準答案(y_)的差距
三、均方偏差MSE:可用TensorFlow的函數表示:loss = tf.reduce_mean(tf,square(y_ - y))
四、反向傳播訓練方法有三種:都是以減少loss值爲優化目標網絡

train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
train_step = tf.train.MomentumOptimizer(0.001, 0.9).minimize(loss)
train_step = tf.train.AdamOptimizer(0.001).minimize(loss)

五、學習率:決定參數每次更新的幅度app

反向傳播代碼示例:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
import numpy as np   #numpy是Python的科學計算模塊
BATCH_SIZE = 8 #一次喂入神經網絡的數據組數
seed = 23455 #隨機種子
#基於seed產生隨機數
rng = np.random.RandomState(seed)
#隨機數返回 32行2列的矩陣 表示32組 體積和重量 做爲輸入數據集
X = rng.rand(32, 2)
#從X這個32行2列的矩陣中 取出一行  判斷若是和小於1 給Y賦值1 若是不小於1 則賦值0
#做爲輸入數據集的標籤(正確答案)
Y = [[int(x0 + x1 < 1)] for (x0, x1) in X]
print("X:", X)
print("Y:", Y)
#1定義神經網絡的輸入和輸出 定義前向傳播過程
x = tf.placeholder(tf.float32, shape=(None, 2)) #神經網絡輸入的數據
y_ = tf.placeholder(tf.float32, shape=(None, 1)) #與輸入數據對應的標準輸出

w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
#前向傳播計算過程
a = tf.matmul(x, w1) #第一層輸出
y = tf.matmul(a, w2) #第二層輸出

#2定義損失函數以及反向傳播方法
loss = tf.reduce_mean(tf.square(y-y_)) #使用均方偏差計算loss
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss) #使用梯度降低實現訓練過程,minimize表示向減少的方向優化
# train_step = tf.train.MomentumOptimizer(0.001, 0.9).minimize(loss)
# train_step = tf.train.AdamOptimizer(0.001).minimize(loss)
#3生成會話 訓練STEPS輪
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    #輸出目前(未經訓練)的參數取值
 print("w1:",sess.run(w1))
    print("w2:",sess.run(w2))
    print("n")
    #訓練模型
 STEP = 3000
 for i in range(STEP):
        start = (i*BATCH_SIZE) % 32
 end = start + BATCH_SIZE
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
        if i % 500 == 0:
            total_loss = sess.run(loss, feed_dict={x: X, y_: Y})
            print("after %d training step(s), loss on all data is %g" %(i, total_loss))
    #輸出訓練後的參數取值
 print("n")
    print("w1:n", sess.run(w1))
    print("w2:n", sess.run(w2))

4、損失函數

神經元模型的升級
image.png
神經網絡中經常使用的激活函數
image.pngdom

一、NN的優化目標:loss最小(有三種方法)
第一種:mse(Mean Squared Error)均方偏差:表示預測值與標準值之間的距離
第二種:自定義
image.png
第三種:ce(Cross Entropy)交叉熵:表示兩個機率分佈之間的距離
image.png
image.png函數

5、學習率

一、參數的變化過程
image.png學習

二、學習率大了震盪不收斂,小了收斂速度慢(解決辦法:使用指數衰減學習率)
image.png優化

三、指數衰減代碼示例

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
#設損失函數loss = (w1 + 1)^2 令w初值爲常數5 反向傳播就是求最優w 即求最小loss對應的w值
#使用指數衰減的學習率,在迭代初期獲得較高的降低速度,能夠在較小的訓練輪數下取得更有收斂度
import tensorflow as tf
LEARNING_RATE_BASE = 0.1 #最初的學習率
LEARNING_RATE_DECAY = 0.99 #學習率衰減率
LEARNING_RATE_STEP = 1 #喂入多少輪BATCH_SIZE後,更新一次學習率,通常設爲:總樣本數/BATCH_SIZE
#運行了幾輪BATCH_SIZE的計數器,初值給0,設爲不被訓練
global_step = tf.Variable(0, trainable=False)
#定義指數降低學習率
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, LEARNING_RATE_STEP, LEARNING_RATE_DECAY, staircase=True)
#定義待優化參數,初值給10
w = tf.Variable(tf.constant(5, dtype=tf.float32))
#定義損失函數loss
loss = tf.square(w+1)
#定義反向傳播方法
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
#生成會話,訓練40輪
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    for i in range(40):
        sess.run(train_step)
        learning_rate_val = sess.run(learning_rate)
        globals_step_val = sess.run(global_step)
        w_val = sess.run(w)
        loss_val = sess.run(loss)
        print("After %s steps: global_step is %f,w is %f, learning rate is %f, loss is %f" %(i, globals_step_val, w_val, learning_rate_val, loss_val))

四、滑動平均代碼示例

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
#1.定義變量及滑動平均類
#定義一個32位浮點變量,初值爲0.0 這個代碼就是不斷更新w1參數, 優化w1參數,滑動平均作了個w1的影子
w1 = tf.Variable(0, dtype=tf.float32)
#定義num_updates(NN的迭代輪次),初始值爲0時表示不可被優化(訓練),這個參數不訓練
global_step = tf.Variable(0, trainable=False)
# 實例化滑動平均類, 給衰減率爲0.99,當前輪數global_step
MOVING_AVERAGE_DECAY = 0.99
ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
#apply後的括號裏是更行列表,每次運行sess.run(ema_op)時,對更新列表中的元素求滑動平均值
#在實際應用中會使用tf.trainable_variables()自動將多有待訓練的參數彙總爲列表
#ema_op = ema.apply([w21])
ema_op = ema.apply(tf.trainable_variables())
#查看不一樣迭代中變量取值的變化
with tf.Session() as sess:
    # 初始化
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    #用ema.average(w1)獲取w1滑動平均值(要運行多個節點,做爲列表中的元素列出,寫在sess,run中)
    #打印出當前參數w1和w1的滑動平均值
    print(sess.run([w1, ema.average(w1)]))
    #參數w1賦值爲1
    sess.run(tf.assign(w1, 1))
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))
    #更新step和w1的值,模擬出100輪迭代後,參數w1變爲10
    sess.run(tf.assign(global_step, 100))
    sess.run(tf.assign(w1, 10))
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))
    #每次sess,run會更新一次w1的滑動平均值
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))

6、正則化

一、做用:防止模型過擬合,致使訓練是正確率高,預測時正確率小的問題 包含正則化的模型曲線會比沒有正則化的更加平滑spa

二、正則化示例代碼

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
BATCH_SIZE = 30
seed = 2
# 基於seed產生隨機數、
rdm = np.random.RandomState(seed)
# 隨機數返回300行2列的矩陣,表示300組座標點(x0,x1)做爲輸入數據集
X = rdm.randn(300, 2)
# 從x這個300行2列的矩陣中取出一行,判斷若是兩個座標的平方和小於2,給Y賦值1 相反則賦值0
# 做爲輸入數據集的標籤(正確答案)
Y_ = [int(x0*x0 + x1*x1 < 2) for (x0, x1) in X]
# 遍歷Y中的每一個元素,1賦值red 其他賦值blue,這樣可視化顯示時人能夠直觀區分
Y_c = [['red' if y else 'blue'] for y in Y_]
# 對數據集X和標籤Y進行shape整理,第一個元素爲-1表示,隨第二個參數計算獲得,第二個元素表示多少列,吧X整理爲n行2列,把Y整理爲n行1列
X = np.vstack(X).reshape(-1, 2)
Y_ = np.vstack(Y_).reshape(-1, 1)
print(X)
print(Y_)
print(Y_c)
# 用plt.scatter畫出數據集X各行中第0列元素和第1列元素的點即各行的(x0,x1),用各行Y_c對應的值表示顏色(c是color的縮寫)
plt.scatter(X[:, 0], X[:, 1], c = np.squeeze(Y_c))
plt.show()
# 定義神經網絡的輸入、參數和輸出,定義前向傳播過程
# 生成w的函數
def get_weight(shape, reularizer):
    w = tf.Variable(tf.random_normal(shape), dtype=tf.float32)
    tf.add_to_collection('losses', tf.keras.regularizers.l2(reularizer)(w)) # TensorFlow高版本中contrib.l2沒有了,故使用Keras來進行正則化
 return w
# 生成偏執值b的函數
def get_bias(shape):
    b = tf.Variable(tf.constant(0.01, shape = shape))
    return b
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
# 第一層
w1 = get_weight([2, 11], 0.01) # ([行數,列數], 權重)
b1 = get_bias([11])
y1 = tf.nn.relu(tf.matmul(x, w1)+b1)
# 第二層
w2 = get_weight([11, 1], 0.01)
b2 = get_bias([1])
y = tf.matmul(y1, w2)+b2 # 輸出層不過激活
# 定義損失函數
loss_mse = tf.reduce_mean(tf.square(y - y_)) # 均方偏差的損失函數
loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))# 均方偏差的損失 + 正則化w的損失
# 定義反向傳播方法:不含正則化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_mse) # 使用AdamOptimizer優化器進行優化
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEP = 20000
 for i in range(STEP):
        start = (i*BATCH_SIZE) % 300
 end = start + BATCH_SIZE
        sess.run(train_step, feed_dict={x:X[start:end], y_:Y_[start:end]})
        if i % 2000 == 0:
            loss_mse_v = sess.run(loss_mse, feed_dict={x:X, y_:Y_})
            print("After %d steps, loss is :%f" %(i, loss_mse_v))
    # xx在-3到3之間以步長爲0.01, yy在-3到3之間以步長0.01,生成二位網格座標點
 xx, yy = np.mgrid[-3:3:0.1, -3:3:0.1]
    # 將xx, yy拉直,併合併成一個2列的矩陣,獲得一個網格座標點的集合
 grid = np.c_[xx.ravel(), yy.ravel()]
    # 件網格座標點喂入神經網絡,probs輸出
 probs = sess.run(y, feed_dict={x:grid})
    # probs的shape調整成xx的樣子
 probs = probs.reshape(xx.shape)
    print("w1 :n",sess.run(w1))
    print("b1 :n", sess.run(b1))
    print("w2 :n", sess.run(w2))
    print("b2 :n", sess.run(b2))
plt.scatter(X[:, 0], X[:, 1], c = np.squeeze(Y_c))
plt.contour(xx, yy, probs, levels=[.5])
plt.show()
# 定義反向傳播方法:包含正則化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_total) # 使用AdamOptimizer優化器進行優化
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEP = 20000
 for i in range(STEP):
        start = (i*BATCH_SIZE) % 300
 end = start + BATCH_SIZE
        sess.run(train_step, feed_dict={x:X[start:end], y_:Y_[start:end]})
        if i % 2000 == 0:
            loss_mse_v = sess.run(loss_mse, feed_dict={x:X, y_:Y_})
            print("After %d steps, loss is :%f" %(i, loss_mse_v))
    # xx在-3到3之間以步長爲0.01, yy在-3到3之間以步長0.01,生成二位網格座標點
 xx, yy = np.mgrid[-3:3:0.1, -3:3:0.1]
    # 將xx, yy拉直,併合併成一個2列的矩陣,獲得一個網格座標點的集合
 grid = np.c_[xx.ravel(), yy.ravel()]
    # 件網格座標點喂入神經網絡,probs輸出
 probs = sess.run(y, feed_dict={x:grid})
    # probs的shape調整成xx的樣子
 probs = probs.reshape(xx.shape)
    print("w1 :n",sess.run(w1))
    print("b1 :n", sess.run(b1))
    print("w2 :n", sess.run(w2))
    print("b2 :n", sess.run(b2))
plt.scatter(X[:, 0], X[:, 1], c = np.squeeze(Y_c))
plt.contour(xx, yy, probs, levels=[.5])
plt.show()
相關文章
相關標籤/搜索