在進行模型搭建時常用的解決過擬合的方法有以下幾種:
· 采用更多的數據
· 迫使模型的復雜度降低(減少層數、正則化)
· dropout(提高魯棒性)
· 提早結束訓練過程
· 數據增強
這里重點講正則化(regularization)
假定對於一個二分類問題,它的交叉熵損失函數為
J(ω) = - 1/m Σ [ yilnyi' + (1-yi)ln(1-yi') ]
所謂正則化,即在損失函數的基礎上加上一個范數,當加上L1范數時,被稱為L1正則化,當加上L2范數時,被稱為L2正則化
其思想就是在損失函數中加入被稱為正則化項(Regularizer)的懲罰
L1(θ) = ||θ||1 = Σ|θi|
L2(θ) = ||θ||22= Σ|θi|2
待優化的函數就從J(ω)變為了J(ω)+λL1(θ)或J(ω)+λL2(θ)
那么如何給網絡結構添加這樣的結構?代碼如下:
l2_model = keras.Sequential([ keras.layers.Dense(16,kernal_regularizer=keras.regularizers.l2(0.001)), keras.layers.Dense(16,kernel_regularizer=keras.regularizers.l2(0.001)), keras.layers.Dense(1,activation=tf.nn.sigmoid) ])
更加靈活的添加方式如下:
for step,(x,y) in enumerate(db): with tf.GradientTape() as tape: # …… loss = tf.reduce_mean(tf.losses.categorical_crossentropy(y_onehot,out,from_logits=True)) loss_regularization = [] for p in network.trainable_variables: loss_regularization.append(tf.nn.l2_loss(p)) loss_regularization = tf.reduce_sum(tf.stack(loss_regularization)) loss = loss +0.0001 * loss_regularization grad = tape.gradient(loss,network.trainable_variables) optimizer.apply_gradients(zip(grad,network.trainable_variables))
最小化J(ω)+λL(θ)意味着需要在偏好小范數權重和擬合訓練數據之間找到一個平衡,其根本思想是通過限制權重的大小,降低模型擬合訓練集中存在噪音的概率,從而減輕過擬合。需要注意的是,這兩種正則化在使用時存在兩個主要的區別,首先L1正則化會讓參數變得更稀疏(會有更多的參數變為0),而L2正則化不會;其次,計算L1正則化的公式不可導,而計算L2正則化的公式可導,這就導致了在優化時計算L2正則化損失函數的偏導數要更加簡潔,而計算L1正則化損失函數的偏導數要更加復雜。