一、準備數據集,提取特徵,做爲輸入餵給神經網絡
二、搭建NN(Neural Network)結構,從輸入到輸出(先搭建計算圖,在用會話執行)(NN前向傳播算法→計算輸出)
三、大量特徵數據餵給NN,迭代優化NN參數(NN反向傳播算法→優化參數訓練模型)
四、使用訓練好的模型預測和分類算法
參數W的維數爲:前行後列(即前面一層的個數爲W的行數 後面一層的個數爲W的列數)
segmentfault
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))
一、反向傳播的做用:訓練模型參數,在全部參數上用梯度降低方法,使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))
神經元模型的升級
神經網絡中經常使用的激活函數
dom
一、NN的優化目標:loss最小(有三種方法)
第一種:mse(Mean Squared Error)均方偏差:表示預測值與標準值之間的距離
第二種:自定義
第三種:ce(Cross Entropy)交叉熵:表示兩個機率分佈之間的距離
函數
一、參數的變化過程
學習
二、學習率大了震盪不收斂,小了收斂速度慢(解決辦法:使用指數衰減學習率)
優化
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)]))
一、做用:防止模型過擬合,致使訓練是正確率高,預測時正確率小的問題 包含正則化的模型曲線會比沒有正則化的更加平滑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()