神經(jīng)元模型
用數(shù)學公式表示為:
f為激活函數(shù)。引入非線性激活因素,提高模型的表達力。
常見的激活函數(shù)有relu,sigmoid,tanh等。
損失函數(shù)
用來預測表示預測值(y)與已知答案(y_)的差距。在訓練神經(jīng)網(wǎng)絡時,通過不斷改變神經(jīng)網(wǎng)絡中的所有參數(shù),使損失函數(shù)不斷減小,從而訓練出更高準確率的神經(jīng)網(wǎng)絡模型。
常用的損失函數(shù)有均方誤差,自定義和交叉熵等。
代碼示例1
預測酸奶日銷售量y, x1和x2為影響日銷售量的兩個因素。
利用TensorFlow中的函數(shù)隨機生成x1,x2,制造標準答案y_=x1+x2,為了更真實,求和后還加了正負0.05的隨機噪音。
#coding:utf-8
#預測多或預測少的影響一樣
import tensorflow as tf
import numpy as np
BATCH_SIZE=8
seed=23455
#基于seed產(chǎn)生隨機數(shù)
rng=np.random.RandomState(seed)
#隨機數(shù)返回32行2列的矩陣 表示32組 體積和重量 作為輸入數(shù)據(jù)集
X=rng.rand(32,2)
#作為輸入數(shù)據(jù)集的標簽(正確答案)
Y=[[int(x0+x1+(rng.rand()/10.0-0.05))] for (x0,x1) in X]
print "X:\n",X
print "Y:\n",Y
#定義神經(jīng)網(wǎng)絡的輸入 參數(shù)和輸出,定義前向傳播過程。
x=tf.placeholder(tf.float32,shape=(None,2))
y_=tf.placeholder(tf.float32,shape=(None,1))
w1=tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))
#定義向前傳播過程
y=tf.matmul(x,w1)
#定義損失函數(shù)及反向傳播方法
loss=tf.reduce_mean(tf.square(y_-y))
train_step=tf.train.GradientDescentOptimizer(0.001).minimize(loss)
#生成會話,訓練STEPS
with tf.Session() as sess:
init_op=tf.initialize_all_variables()
sess.run(init_op)
#輸出目前(未經(jīng)訓練)的參數(shù)取值
print "w1:\n",sess.run(w1)
print "\n"
#訓練模型
STEPS=20000
for i in range(STEPS):
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%5000)==0:
print "w1:\n",sess.run(w1)
#輸出訓練后的參數(shù)取值
print "\n"
print "w1:\n",sess.run(w1)
但是我這邊測試跑出來的結果跟教程里的不一樣,x1離標準答案1差的比較遠。(這個問題后續(xù)再研究)
自定義損失函數(shù)
損失函數(shù)表示,若預測結果y小于標準答案y_,損失函數(shù)為利潤乘以預測結果y與標準答案y_之差;
若預測結果y大于標準答案y_,損失函數(shù)為成本乘以預測結果y與標準答案y_之差。
將損失函數(shù)修改如下:
loss=tf.reduce_sum(tf.select(tf.greater(y,y_),(y-y_)1,(y_-y)9))
教程中為where,應該是版本問題,這邊改成select
交叉熵(Cross Entropy)
表示兩個概率分布之間的距離。交叉熵越大,兩個概率分布距離越遠,兩個概率分布越相異;交叉熵越小,兩個概率分布距離越近,兩個概率分布越相似。
損失函數(shù)如下:
ce=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1))
loss=tf.reduce_mean(ce)
學習率(learning_rate)
表示了每次參數(shù)更新的幅度大小。學習率過大,會導致待優(yōu)化的參數(shù)在最小值附近波動,不收斂;學習率過小,會導致待優(yōu)化的參數(shù)收斂緩慢。
示例代碼2
#coding:utf-8
#設損失函數(shù) loss=(w+1)^2,令w初值為常數(shù)5。反向傳播就是求最優(yōu)w,即求最小loss對應的w值
import tensorflow as tf
#定義待優(yōu)化參數(shù)w初始值5
w=tf.Variable(tf.constant(5,dtype=tf.float32))
#定義損失函數(shù)
loss=tf.square(w+1)
#定義反向傳播方法
train_step=tf.train.GradientDescentOptimizer(0.2).minimize(loss)
#生成會話,訓練40輪
with tf.Session() as sess:
init_op=tf.initialize_all_variables()
sess.run(init_op)
for i in range(40):
sess.run(train_step)
w_val=sess.run(w)
loss_val=sess.run(loss)
print "After %s steps: w is %f,loss is %f."%(i,w_val,loss_val)
指數(shù)衰減學習率
學習率隨著訓練輪數(shù)變化而動態(tài)更新
tf里的代碼為:
LEARNING_RATE_BASE=0.1 #最初學習率
LEARNING_RATE_DECAY=0.99 #學習率衰減率
LEARNING_RATE_STEP =1 #喂入多少輪BATCH_SIZE后,更新一次學習率,一般設為:總樣本數(shù)/BATCH_SIZE
#運行了幾輪BATCH_SIZE的計數(shù)器,初值為0,設為不被訓練
global_step=tf.Variable(0,trainable=False)
#定義指數(shù)下降學習率
learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,LEARNING_RATE_STEP,LEARNING_RATE_DECAY,staircase=True)
滑動平均
記錄了一段時間內模型中所有參數(shù)w和b各自的平均值。利用滑動平均值可以增強模型的泛化能力。
過擬合
神經(jīng)網(wǎng)絡模型在訓練數(shù)據(jù)集上的準確率較高,在新的數(shù)據(jù)進行預測或分類時準確率較低,說明模型的泛化能力差
正則化
在損失函數(shù)中給每個參數(shù)w加上權重,引入模型復雜度指標,從而抑制模型噪聲,減少過擬合。