1、Keras輸出的loss,val這些值如何保存到文本中去:
Keras中的fit函數會返回一個History對象,它的History.history屬性會把之前的那些值全保存在里面,如果有驗證集的話,也包含了驗證集的這些指標變化情況,具體寫法:
hist=model.fit(train_set_x,train_set_y,batch_size=256,shuffle=True,nb_epoch=nb_epoch,validation_split=0.1) with open('log_sgd_big_32.txt','w') as f: f.write(str(hist.history))
我覺得保存之前的loss,val這些值還是比較重要的,在之后的調參過程中有時候還是需要之前loss的結果作為參考的。
2.關於優化方法使用的問題:
開始總會糾結哪個優化方法好用,但是最好的辦法就是試,無數次嘗試后不難發現,Sgd的這種學習率非自適應的優化方法,調整學習率和初始化的方法會使它的結果有很大不同,但是由於收斂確實不快,總感覺不是很方便,我覺得之前一直使用Sgd的原因一方面是因為優化方法不多,其次是用Sgd都能有這么好的結果,說明你網絡該有多好啊。其他的Adam,Adade,RMSprop結果都差不多,Nadam因為是adam的動量添加的版本,在收斂效果上會更出色。所以如果對結果不滿意的話,就把這些方法換着來一遍吧。
有很多初學者人會好奇怎么使sgd的學習率動態的變化,其實Keras里有個反饋函數叫LearningRateScheduler,具體使用如下:
def step_decay(epoch): initial_lrate = 0.01 drop = 0.5 epochs_drop = 10.0 lrate = initial_lrate * math.pow(drop,math.floor((1+epoch)/epochs_drop)) return lrate lrate = LearningRateScheduler(step_decay) sgd = SGD(lr=0.0, momentum=0.9, decay=0.0, nesterov=False) model.fit(train_set_x, train_set_y, validation_split=0.1, nb_epoch=200, batch_size=256, callbacks=[lrate])
上面代碼是使學習率指數下降,具體如下圖:

當然也可以直接在sgd聲明函數中修改參數來直接修改學習率,學習率變化如下圖:
sgd = SGD(lr=learning_rate, decay=learning_rate/nb_epoch, momentum=0.9, nesterov=True)

具體可以參考這篇文章Using Learning Rate Schedules for Deep Learning Models in Python with Keras
3.關於過擬合問題的討論:
我現在所知道的解決方法大致只有兩種,第一種就是添加dropout層,dropout的原理我就不多說了,主要說一些它的用法,dropout可以放在很多類層的后面,用來抑制過擬合現象,常見的可以直接放在Dense層后面,對於在Convolutional和Maxpooling層中dropout應該放置在Convolutional和Maxpooling之間,還是Maxpooling后面的說法,我的建議是試!這兩種放置方法我都見過,但是孰優孰劣我也不好說,但是大部分見到的都是放在Convolutional和Maxpooling之間。關於Dropout參數的選擇,這也是只能不斷去試,但是我發現一個問題,在Dropout設置0.5以上時,會有驗證集精度普遍高於訓練集精度的現象發生(??),但是對驗證集精度並沒有太大影響,相反結果卻不錯,我的解釋是Dropout相當於Ensemble,dropout過大相當於多個模型的結合,一些差模型會拉低訓練集的精度。當然,這也只是我的猜測,大家有好的解釋,不妨留言討論一下。
當然還有第二種就是使用參數正則化,也就是在一些層的聲明中加入L1或L2正則化系數,正則化的原理什么的我就不細說了,具體看代碼:
C1 = Convolution2D(20, 4, 4, border_mode='valid', init='he_uniform', activation='relu',W_regularizer=l2(regularizer_params))
其中W_regularizer=l2(regularizer_params)就是用於設置正則化的系數,這個對於過擬合有着不錯的效果,在一定程度上提升了模型的泛化能力。
4.Batchnormalization層的放置問題:
BN層是真的吊,簡直神器,除了會使網絡搭建的時間和每個epoch的時間延長一點之外,但是關於這個問題我看到了無數的說法,對於卷積和池化層的放法,又說放中間的,也有說池化層后面的,對於dropout層,有說放在它后面的,也有說放在它前面的,對於這個問題我的說法還是試!雖然麻煩。。。但是DL本來不就是一個偏工程性的學科嗎。。。還有一點是需要注意的,就是BN層的參數問題,我一開始也沒有注意到,仔細看BN層的參數:
keras.layers.normalization.BatchNormalization(epsilon=1e-06, mode=0, axis=-1, momentum=0.9, weights=None, beta_init='zero', gamma_init='one')
-
mode:整數,指定規范化的模式,取0或1
-
0:按特征規范化,輸入的各個特征圖將獨立被規范化。規范化的軸由參數axis指定。注意,如果輸入是形如(samples,channels,rows,cols)的4D圖像張量,則應設置規范化的軸為1,即沿着通道軸規范化。輸入格式是‘tf’同理。
-
1:按樣本規范化,該模式默認輸入為2D
我們大都使用的都是mode=0也就是按特征規范化,對於放置在卷積和池化之間或之后的4D張量,需要設置axis=1,而Dense層之后的BN層則直接使用默認值就好了。
-
reference:深度學習框架Keras使用心得
