【tensorflow】神經網路的優化
神經網路的複雜度
1.空間複雜度
層數 = 隱藏層的層數 + 1個輸出層
總引數 = 總w + 總b
2.時間複雜度
乘加運算次數 = 總w
指數衰減學習率
指數衰減學習率 = 初始學習率 * 學習率衰減率^(當前輪數/多少輪衰減一次)
- 初始學習率:最初的學習率
- 學習率衰減率:學習率按照這個比例指數衰減
- 當前輪數:可以用當前迭代了多少次資料集也就是epoch表示,也可以用當前迭代了多少次batch表示
- 多少輪衰減一次:迭代多少次更新一次學習率,決定了學習率更新的頻率
例: poch = 50 r_base = 0.2 r_decay = 0.99 r_step = 1 or epoch inrange(epoch): lr = lr_base * lr_decay ** (epoch/lr_step) with tf.GradientTape() as tape: loss = tf.square(w + 1) grads = tape.gradient(loss, w) w.assign_sub(lr * grads)
啟用函式
線性函式表達力不夠
加入非線性函式(啟用函式)大大提升了模型的表達力
優秀的啟用函式:
非線性:只有啟用函式是非線性時,
才不會被單層網路所替代,
使得多層網路有了意義,
而多層網路可逼近所有函式
可微性:優化器大多使用梯度下降法更新引數,
若啟用函式不可微,就不能更新引數
單調性:當啟用函式是單調的,能保證單層網路的損失函式是凸函式,更容易收斂
近似恆等性:f(x) ≈ x
當引數初始值為隨機小數時,神經網路更穩定
啟用函式輸出值的範圍:
啟用函式輸出為有限值時,基於梯度的優化方法更穩定
啟用函式輸出為無限值時,建議調小學習率
igmoid函式
f.nn.sigmoid(x)
anh函式
f.nn.tanh(x)
elu函式
f.nn.relu(x)
eaky Relu函式
f.nn.leaky_relu(x)
對初學者的建議:
首選relu啟用函式
學習率設定較小值
輸入特徵標準化,即讓輸入特徵滿足以0為均值,1為標準差的正態分佈
初始引數中心化,即讓隨機生成的引數滿足以0為均值,√(2/當前層輸入特徵個數)為標差的正態分佈
損失函式loss:
前向傳播預測結果y與已知標準答案y_的差距
神經網路的優化目標就是找到某套引數,
使得預測結果與標準答案無限接近,即loss值最小
主流loss有三種:
均方誤差
oss_mse = tf.reduce_mean(tf.square(y_ - y))
自定義
交叉熵
交叉熵越大,兩個概率分佈越遠
交叉熵越小,兩個概率分佈越近
f.losses.categorical_crossentropy(y_, y)
執行分類問題時,
通常先用softmax函式使輸出結果符合概率分佈
再求交叉熵損失函式
ensorflow給出了同時計算概率分佈和交叉熵的函式
f.nn.softmax_cross_entropy_with_logits(y_, y)
欠擬合與過擬合
欠擬合:模型不能有效擬合數據集
過擬合:模型對資料擬合太好,
但缺乏泛化力,對新資料難以做出判斷
欠擬合的解決方法:
增加輸入特徵項
增加網路引數
減少正則化引數
過擬合的解決方法:
資料清洗
增大訓練集
採用正則化
增大正則化引數
正則化減少過擬合:
給w加權重,抑制訓練中的噪聲
通常只對w使用,不對b使用
oss = loss(y_, y) + regularizer * loss(w)
oss(y_, y):原loss值
egularizer:引數w在總loss中的比重
oss(w):對所有w求和(L1正則化)
對所有w的平方求和(L2正則化)
1正則化大概率會使很多引數變為0
可用來稀疏引數,降低模型複雜度
2正則化會使引數接近0但不等於0
可用來減小引數的數值
有效緩解資料集中因噪聲引起的過擬合
例:
with tf.GradientTape() as tape:
。。。
# 寄存所有w L2正則化後的結果
loss_regularization = []
# 將w 做L2正則化處理,並即存在loss_regularization中
loss_regularization.append(tf.nn.l2_loss(w1))
loss_regularization.append(tf.nn.l2_loss(w2))
# 計算引數w L2正則化後的總和
loss_regularization = tf.reduce_sum(loss_regularization)
loss = loss + 0.03 * loss_regularization
優化器更新網路引數