tensorflow(3):神經網絡優化(ema,regularization)
阿新 • • 發佈:2018-05-01
show mgr 數據集 width mst bat ace tac nor
1.指數滑動平均 (ema)
描述滑動平均:
with tf.control_dependencies([train_step,ema_op]) 將計算滑動平均與 訓練過程綁在一起運行
train_op=tf.no_op(name=‘train‘) 使它們合成一個訓練節點
#定義變量一級滑動平均類 #定義一個32位浮點變量,初始值為0.0, 這個代碼就是在不斷更新w1參數,優化 w1,滑動平均做了一個w1的影子 w1=tf.Variable(0,dtype=tf.float32) #定義num_updates(NN 的叠代次數)初始值為0, global_step不可被優化(訓練) 這個額參數不訓練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) #ema.apply後面的括號是更新列表,每次運行sess.run(ema_op)時,對更新列表中的元素求滑動平均值, #在實際應用中會使用tf.trainable_variable()自動將所有待訓練的參數匯總為列表 #ema_op=ema.apply([w1]) ema_op=ema.apply(tf.trainable_variables())#查看不同叠代中變量的取值變化 with tf.Session() as sess: init_op=tf.global_variables_initializer() sess.run(init_op) #ema_op=ema.apply([w1])獲取w1 的滑動平均值, print(sess.run([w1,ema.average(w1)])) #打印當前參數w1和w1 的滑動平均值 (0,0) sess.run(tf.assign(w1,1)) sess.run(ema_op) print(sess.run([w1,ema.average(w1)])) #(1,0.9)#跟新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)])) #(10,1.644) #每次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)]))
結果:
[0.0, 0.0]
[1.0, 0.9]
[10.0, 1.6445453]
[10.0, 2.3281732]
[10.0, 2.955868]
[10.0, 3.532206]
[10.0, 4.061389]
[10.0, 4.547275]
w1的移動平均會越來越趨近於w1 ...
2.正則化regularization
有時候模型對訓練集的正確率很高, 卻對新數據很難做出正確的相應, 這個叫過擬合現象.
加入噪聲後,loss變成了兩個部分,前者是以前講過的普通loss,
後者的loss(w)有兩種求法,分別稱為L1正則化與 L2正則化
以下舉例說明:
代碼:
atch_size=30 #建立數據集 seed=2 rdm=np.random.RandomState(seed) X=rdm.randn(300,2) Y_=[int(x0*x0+x1*x1<2) for (x0,x1) in X] Y_c=[[‘red‘ if y else ‘blue‘] for y in Y_] #1則紅色,0則藍色 X=np.vstack(X).reshape(-1,2) #整理為n行2列,按行的順序來 Y_=np.vstack(Y_).reshape(-1,1)# 整理為n行1列 #print(X) #print(Y_) #print(Y_c) plt.scatter(X[:,0],X[:,1],c=np.squeeze(Y_c))#np.squeeze(Y_c)變成一個list plt.show() #print(np.squeeze(Y_c)) #定義神經網絡的輸入 輸出 參數, 定義前向傳播過程 def get_weight(shape,regularizer): #w的shape 和w的權重 w=tf.Variable(tf.random_normal(shape),dtype=tf.float32) tf.add_to_collection(‘losses‘,tf.contrib.layers.l2_regularizer(regularizer)(w)) return w def get_bias(shape): #b的長度 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) #relu 激活函數 w2=get_weight([11,1],0.01) b2=get_bias([1]) y=tf.matmul(y1,w2)+b2 #輸出層不過激活函數 #定義損失函數loss loss_mse=tf.reduce_mean(tf.square(y-y_)) loss_total=loss_mse+tf.add_n(tf.get_collection(‘losses‘)) #定義反向傳播方法, 不含正則化, 要是使用正則化,則 為loss_total train_step=tf.train.AdamOptimizer(0.0001).minimize(loss_mse) with tf.Session() as sess: init_op=tf.global_variables_initializer() sess.run(init_op) steps=40000 for i in range(steps): 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%10000==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,yy=np.mgrid[-3:3:0.01,-3:3:0.01] grid=np.c_[xx.ravel(),yy.ravel()] probs=sess.run(y,feed_dict={x:grid}) probs=probs.reshape(xx.shape) #調整成xx的樣子 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]) #給probs=0.5的值上色 (顯示分界線) plt.show() #使用個正則化 train_step=tf.train.AdamOptimizer(0.0001).minimize(loss_total) with tf.Session() as sess: init_op=tf.global_variables_initializer() sess.run(init_op) steps=40000 for i in range(steps): 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%10000==0: loss_v=sess.run(loss_total,feed_dict={x:X,y_:Y_}) print(‘after %d steps,loss is:%f‘%(i,loss_v)) xx,yy=np.mgrid[-3:3:0.01,-3:3:0.01] grid=np.c_[xx.ravel(),yy.ravel()] probs=sess.run(y,feed_dict={x:grid}) probs=probs.reshape(xx.shape) #調整成xx的樣子 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]) #給probs=0.5的值上色 plt.show()
結果顯示:
顯然 經過正則化,分割線更加平滑,數據集中的噪聲對模型的影響更小,
tensorflow(3):神經網絡優化(ema,regularization)