1. 程式人生 > >tensorflow(2):神經網絡優化(loss,learning_rate)

tensorflow(2):神經網絡優化(loss,learning_rate)

min pre 影響 動態 star val 交叉 SQ rt+

案例: 預測酸奶的日銷量, 由此可以準備產量, 使得損失小(利潤大),假設銷量是y , 影響銷量的有兩個因素x1, x2,
需要預先采集數據,每日的x1,x2和銷量y_, 擬造數據集X,Y_, 假設y_=x1+x2,為了更真實加一個噪聲(-0.05-0.05)

batch_size=8 #一次餵給神經網絡多少數據 
seed=23455
#構造數據集
rdm=np.random.RandomState(seed) #基於seed產生隨機數
X=rdm.rand(32,2) #32組數據
Y_=[[x1+x2+(rdm.rand()/10.0-0.05)] for (x1,x2) in X] #rdm.rand()/10.0 是(0,1)隨機數
print(X:\n,X) print(Y_:\n,Y_) #定義神經網絡的輸入 參數 輸出 定義前向傳播過程 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) #定義損失函數 後向傳播方法 loss_mse=tf.reduce_mean(tf.square(y_-y)) train_step
=tf.train.GradientDescentOptimizer(0.001).minimize(loss_mse) #train_step=tf.train.MomentumOptimizer(0.001,0.9).minimize(loss) #其他方法 #train_step=tf.train.AdamOptimizer(0.001).minimize(loss) #生成會話 訓練 with tf.Session() as sess: #用會話計算結果 init_op=tf.global_variables_initializer() sess.run(init_op)
print(w1:\n, sess.run(w1)) #輸出目前(未經訓練的)參數取值 #訓練模型 steps=20000 #訓練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]}) #8組數據 if i % 500==0: #每500輪打印一次w1值 print(After %d training steps,w1 is: %i) print(sess.run(w1),\n) print(Final w1 is:,sess.run(w1)) 結果顯示 w1=[0.98,1.015] 這與Y_=x1+x2一致,預測正確!!

1.loss優化

上述例子中, loss函數是均方和, 但是實際中,預測的銷量(即要準備的產量y_) 與真實的銷量y 之間的差異導致的損失 取決於 生產成本cost 與銷售利潤profit,

當預測多了, 損失成本, 預測少了,損失利潤,

所以這裏要自定義loss, 上述代碼不變,只需要修改下loss參數

技術分享圖片

batch_size=8 #一次餵給神經網絡多少數據 
seed=23455
cost=1
profit=9
#構造數據集
rdm=np.random.RandomState(seed) #基於seed產生隨機數
X=rdm.rand(32,2) #32組數據
Y_=[[x1+x2+(rdm.rand()/10.0-0.05)] for (x1,x2) in X] #rdm.rand()/10.0 是(0,1)隨機數
print(X:\n,X)
print(Y_:\n,Y_)
#定義神經網絡的輸入 參數 輸出 定義前向傳播過程
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)   
#定義損失函數 後向傳播方法
loss=tf.reduce_sum(tf.where(tf.greater(y,y_),cost*(y-y_),profit*(y_-y)))
#tf.where(tf.greater(y,y_),cost*(y-y_),profit*(y_-y))第一個表示邏輯值,當為真時取第二項
#為假時取第三項
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) #生成會話 訓練 with tf.Session() as sess: #用會話計算結果 init_op=tf.global_variables_initializer() sess.run(init_op) print(w1:\n, sess.run(w1)) #輸出目前(未經訓練的)參數取值 #訓練模型 steps=20000 #訓練3000次 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]}) #8組數據 if i % 500==0: #每500輪打印一次結果 print(After %d training steps,w1 is: %i) print(sess.run(w1),\n) print(Final w1 is:,sess.run(w1))

得到結果是w1=[1.02,1.04] ,系數都大於1 ,這是由於多預測的損失 少於少預測的損失,結果也往多的方向預測了.要是 cost=9 ,profit=1,

最終得到參數w1=[0.96, 0.97] 都小於1

除了均方和, 自定義loss只要, 還有第三種 交叉熵(cross entropy)的loss,

交叉熵(cross entropy): 表示兩個概率分布之間的距離, ce越大,距離也就越大.

技術分享圖片

交叉熵 ce
ce=-tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-12,1.0)))
n個分類的n輸出

技術分享圖片

ce=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1))
cem=tf.reduce_mean(ce)

2.learning_rate 學習率調整

技術分享圖片

設置learning_rate=0.2

w=tf.Variable(tf.constant(5,dtype=tf.float32))
loss=tf.square(w+1) #定義損失函數
train_step=tf.train.GradientDescentOptimizer(0.2).minimize(loss)

with tf.Session() as sess:
    init_op=tf.global_variables_initializer()
    sess.run(init_op)
    for i in range(40): #叠代40次
        sess.run(train_step)
        w_val=sess.run(w)
        loss_val=sess.run(loss)
        print(after %d steps, w is %f, loss is %f.%(i,w_val,loss_val))

若上述learning_rate=0.001, w趨於-1速度很慢, learning_rate=1, w會發散,不會趨於-1

上述learning_rate 不能太大,也不能太小

技術分享圖片

#學習率 決定參數的更新 learning_rate
#根據運行的輪數決定動態更新學習率     
learning_rate=LEARNING_RATE_BASE*LEARNING_RATE_DECAY^(global_step/LEARNING_RATE_STEP)
#LEARNING_RATE_BASE是學習率初始值   LEARNING_RATE_DECAY是學習衰減率(0,1)
#多少輪更新一次學習率,LEARNING_RATE_STEP 一般是總樣本數/batch_size
global_step=tf.Variable(0,trainable=False) #記錄當前共運行了多少輪batch-size
learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,
                                        global_step, LEARNING_RATE_STEP,
                                        LEARNING_RATE_DECAY,
                                        staircase=True)
# staircase true 學習率階梯型衰減, false則為平滑下降的曲線
#根據運行的輪數決定動態更新學習率     
LEARNING_RATE_BASE=0.1 #最初學習率
LEARNING_RATE_DECAY=0.9 #學習率衰減率
LEARNING_RATE_STEP=1 # 餵入多少batch_size後更新一次學習率,一般是總樣本數/batch_size,這裏為了方便為1

global_step=tf.Variable(0,trainable=False) #記錄當前共運行了多少輪batch-size 
#定義指數下降學習率
learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,
                                        global_step, LEARNING_RATE_STEP,
                                        LEARNING_RATE_DECAY,
                                        staircase=True)

#優化參數 ,初值5
w=tf.Variable(tf.constant(5,dtype=tf.float32))
loss=tf.square(w+1) #定義損失函數
train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)

with tf.Session() as sess:
    init_op=tf.global_variables_initializer()
    sess.run(init_op)
    for i in range(40): #叠代40次
        sess.run(train_step)
        learning_rate_val=sess.run(learning_rate)
        global_step_val=sess.run(global_step)
        w_val=sess.run(w)
        loss_val=sess.run(loss)
        print(after %d steps, global_step is %f,w is %f, loss is %f. %(i,global_step_val,w_val,loss_val))

結果:

技術分享圖片

tensorflow(2):神經網絡優化(loss,learning_rate)