1. 程式人生 > >tensorflow(3):神經網絡優化(ema,regularization)

tensorflow(3):神經網絡優化(ema,regularization)

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)