1 數據預處理
關於數據預處理我們有3個常用的符號,數據矩陣\(X\),假設其尺寸是\([N \times D]\)(\(N\)是數據樣本的數量,\(D\)是數據的維度)。
1.1 均值減去
均值減法(Mean subtraction)是預處理最常用的形式。它對數據中每個獨立特征減去平均值,從幾何上可以理解為在每個維度上都將數據雲的中心都遷移到原點。
在numpy中,該操作可以通過代碼\(X-=n p \cdot \operatorname{mean}(X, \text { axis }=0)\)實現。
而對於圖像,更常用的是對所有像素都減去一個值,可以用\(\mathrm{X}-=\mathrm{np} \cdot \operatorname{mean}(\mathrm{X})\)實現,也可以在3個顏色通道上分別操作。
1.2 歸一化
歸一化(Normalization)是指將數據的所有維度都歸一化,使其數值范圍都近似相等。
有兩種常用方法可以實現歸一化。
第一種是先對數據做零中心化(zero-centered)處理,然后每個維度都除以其標准差,實現代碼為\(\mathrm{X} /=\mathrm{np} . \mathrm{std}(\mathrm{X}, \mathrm{axis}=0)\)。
第二種是對每個維度都做歸一化,使得每個維度的最大和最小值是1和-1。這個預處理操作只有在確信不同的輸入特征有不同的數值范圍(或計量單位)時才有意義,但要注意預處理操作的重要性幾乎等同於學習算法本身。在圖像處理中,由於像素的數值范圍幾乎是一致的(都在0-255之間),所以進行這個額外的預處理步驟並不是很必要。
下面直觀的看一下均值減法與歸一化的效果:

上圖也是一般數據預處理流程:
左邊:原始的2維輸入數據。
中間:在每個維度上都減去平均值后得到零中心化數據,現在數據雲是以原點為中心的。
右邊:每個維度都除以其標准差來調整其數值范圍。
紅色的線指出了數據各維度的數值范圍,在中間的零中心化數據的數值范圍不同,但在右邊歸一化數據中數值范圍相同。
1.3 PCA和白化(Whitening)
PCA和白化(Whitening)是另一種預處理形式。
1.3.1 PCA
在這種處理中,先對數據進行零中心化處理,然后計算協方差矩陣,它展示了數據中的相關性結構。
# 假設輸入數據矩陣X的尺寸為[N x D]
X -= np.mean(X, axis = 0) # 對數據進行零中心化(重要)
cov = np.dot(X.T, X) / X.shape[0] # 得到數據的協方差矩陣
數據協方差矩陣的第(i, j)個元素是數據第i個和第j個維度的協方差。具體來說,該矩陣的對角線上的元素是方差。
還有,協方差矩陣是對稱和半正定的。我們可以對數據協方差矩陣進行SVD(奇異值分解)運算。
U,S,V = np.linalg.svd(cov)
U的列是特征向量,S是裝有奇異值的1維數組(因為cov是對稱且半正定的,所以S中元素是特征值的平方)。
為了去除數據相關性,將已經零中心化處理過的原始數據投影到特征基准上:
Xrot = np.dot(X,U) # 對數據去相關性
注意U的列是標准正交向量的集合(范式為1,列之間標准正交),所以可以把它們看做標准正交基向量。
因此,投影對應x中的數據的一個旋轉,旋轉產生的結果就是新的特征向量。如果計算Xrot的協方差矩陣,將會看到它是對角對稱的。
np.linalg.svd的一個良好性質是在它的返回值U中,特征向量是按照特征值的大小排列的。
我們可以利用這個性質來對數據降維,只要使用前面的小部分特征向量,丟棄掉那些包含的數據沒有方差的維度。 這個操作也被稱為主成分分析( Principal Component Analysis 簡稱PCA)降維:
Xrot_reduced = np.dot(X, U[:,:100]) # Xrot_reduced 變成 [N x 100]
經過上面的操作,將原始的數據集的大小由[N x D]降到了[N x 100],留下了數據中包含最大方差的100個維度。
通常使用PCA降維過的數據訓練線性分類器和神經網絡會達到非常好的性能效果,同時還能節省時間和存儲器空間。
1.3.2 白化(Whitening)
白化操作的輸入是特征基准上的數據,然后對每個維度除以其特征值來對數值范圍進行歸一化。
該變換的幾何解釋是:如果數據服從多變量的高斯分布,那么經過白化后,數據的分布將會是一個均值為零,且協方差相等的矩陣。
該操作的代碼如下:
# 對數據進行白化操作:
# 除以特征值
Xwhite = Xrot / np.sqrt(S + 1e-5)
注意分母中添加了1e-5(或一個更小的常量)來防止分母為0。
該變換的一個缺陷是在變換的過程中可能會誇大數據中的噪聲,這是因為它將所有維度都拉伸到相同的數值范圍,這些維度中也包含了那些只有極少差異性(方差小)而大多是噪聲的維度。
在實際操作中,這個問題可以用更強的平滑來解決(例如:采用比1e-5更大的值)。
1.3.3 PCA與白化的差異性

左邊是二維的原始數據。
中間:經過PCA操作的數據。可以看出數據首先是零中心的,然后變換到了數據協方差矩陣的基准軸上。這樣就對數據進行了解相關(協方差矩陣變成對角陣)。
右邊:每個維度都被特征值調整數值范圍,將數據協方差矩陣變為單位矩陣。從幾何上看,就是對數據在各個方向上拉伸壓縮,使之變成服從高斯分布的一個數據點分布。
我們可以使用CIFAR-10數據將這些變化可視化出來。
CIFAR-10訓練集的大小是50000x3072,其中每張圖片都可以拉伸為3072維的行向量。
我們可以計算[3072 x 3072]的協方差矩陣然后進行奇異值分解(比較耗費計算性能),那么經過計算的特征向量看起來是什么樣子呢?

最左:一個用於演示的集合,含49張圖片。
左二:3072個特征值向量中的前144個。靠前面的特征向量解釋了數據中大部分的方差,可以看見它們與圖像中較低的頻率相關。
第三張是49張經過了PCA降維處理的圖片,展示了144個特征向量。
這就是說,展示原始圖像是每個圖像用3072維的向量,向量中的元素是圖片上某個位置的像素在某個顏色通道中的亮度值。而現在每張圖片只使用了一個144維的向量,其中每個元素表示了特征向量對於組成這張圖片的貢獻度。
為了讓圖片能夠正常顯示,需要將144維度重新變成基於像素基准的3072個數值。因為U是一個旋轉,可以通過乘以U.transpose()[:144,:]來實現,然后將得到的3072個數值可視化。
可以看見圖像變得有點模糊了,這正好說明前面的特征向量獲取了較低的頻率。然而,大多數信息還是保留了下來。
最右:將“白化”后的數據進行顯示。
其中144個維度中的方差都被壓縮到了相同的數值范圍。然后144個白化后的數值通過乘以U.transpose()[:144,:]轉換到圖像像素基准上。
現在較低的頻率(代表了大多數方差)可以忽略不計了,較高的頻率(代表相對少的方差)就被誇大了。
1.4 補充
在這里提到PCA和白化主要是為了介紹的完整性,實際上在卷積神經網絡中並不會采用這些變換。然而對數據進行零中心化操作還是非常重要的,對每個像素進行歸一化也很常見。
進行預處理很重要的一點是:任何預處理策略(比如數據均值)都只能在訓練集數據上進行計算,算法訓練完畢后再應用到驗證集或者測試集上。
例如,如果先計算整個數據集圖像的平均值然后每張圖片都減去平均值,最后將整個數據集分成訓練/驗證/測試集,那么這個做法是錯誤的。
正確的做法是應該先分成訓練/驗證/測試集,只是從訓練集中求圖片平均值,然后各個集(訓練/驗證/測試集)中的圖像再減去這個平均值。
2 權重初始化
我們已經看到如何構建一個神經網絡的結構並對數據進行預處理,但是在開始訓練網絡之前,還需要初始化網絡的參數。
讓我們從應該避免的錯誤開始。
在訓練完畢后,雖然不知道網絡中每個權重的最終值應該是多少,但如果數據經過了恰當的歸一化的話,就可以假設所有權重數值中大約一半為正數,一半為負數。
這樣,一個聽起來蠻合理的想法就是把這些權重的初始值都設為0吧,因為在期望上來說0是最合理的猜測。
這個做法錯誤的!因為如果網絡中的每個神經元都計算出同樣的輸出,然后它們就會在反向傳播中計算出同樣的梯度,從而進行同樣的參數更新。
換句話說,如果權重被初始化為同樣的值,神經元之間就失去了不對稱性的源頭。
2.1 小隨機數初始化
因此,權重初始值要非常接近0又不能等於0。解決方法就是將權重初始化為很小的數值,以此來打破對稱性。
其思路是:如果神經元剛開始的時候是隨機且不相等的,那么它們將計算出不同的更新,並將自身變成整個網絡的不同部分。
小隨機數權重初始化的實現方法是:W = 0.01 * np.random.randn(D,H)。
其中randn函數是基於零均值和標准差的一個高斯分布來生成隨機數的。
根據這個式子,每個神經元的權重向量都被初始化為一個隨機向量,而這些隨機向量又服從一個多變量高斯分布,這樣在輸入空間中,所有的神經元的指向是隨機的。
也可以使用均勻分布生成的隨機數,但是從實踐結果來看,對於算法的結果影響極小。
注意:並不是小數值一定會得到好的結果。例如,一個神經網絡的層中的權重值很小,那么在反向傳播的時候就會計算出非常小的梯度(因為梯度與權重值是成比例的)。這就會很大程度上減小反向傳播中的“梯度信號”,在深度網絡中,就會出現問題。
除了上述所提到的,上面做法還存在一個問題,即:隨着輸入數據量的增長,隨機初始化的神經元的輸出數據的分布中的方差也在增大。
我們可以除以輸入數據量的平方根來調整其數值范圍,這樣神經元輸出的方差就歸一化到1了。
也就是說,建議將神經元的權重向量初始化為:w = np.random.randn(n) / sqrt(n)。其中n是輸入數據的數量。
這樣就保證了網絡中所有神經元起始時有近似同樣的輸出分布。實踐經驗證明,這樣做可以提高收斂的速度。
Glorot等在論文"Understanding the difficulty of training deep feedforward neural networks"中作出了類似的分析。
在論文中,作者推薦初始化公式為\(\operatorname{Var}(w)=2 /\left(n_{i n}+n_{o u t}\right)\),其中\(n_{i n}, n_{o u t}\)是在前一層和后一層中單元的個數。
這是基於妥協和對反向傳播中梯度的分析得出的結論。
該主題下最新的一篇論文是:"Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification",作者是He等人。
文中給出了一種針對ReLU神經元的特殊初始化,並給出結論:網絡中神經元的方差應該是2.0\(/ n\)。代碼為w = np.random.randn(n) * sqrt(2.0/n)。這個形式是神經網絡算法使用ReLU神經元時的當前最佳推薦。
2.2 稀疏初始化
另一個處理非標定方差的方法是將所有權重矩陣設為0,但是為了打破對稱性,每個神經元都同下一層固定數目的神經元隨機連接(其權重數值由一個小的高斯分布生成)。
一個比較典型的連接數目是10個。
2.3 偏置初始化
通常將偏置初始化為0,這是因為隨機小數值權重矩陣已經打破了對稱性。
對於ReLU非線性激活函數,有研究人員喜歡使用如0.01這樣的小數值常量作為所有偏置的初始值,這是因為他們認為這樣做能讓所有的ReLU單元一開始就激活,這樣就能保存並傳播一些梯度。
然而,這樣做是不是總是能提高算法性能並不清楚(有時候實驗結果反而顯示性能更差),所以通常還是使用0來初始化偏置參數。
2.4 批量歸一化
批量歸一化是loffe和Szegedy最近才提出的方法,該方法減輕了如何合理初始化神經網絡這個棘手問題帶來的頭痛。
其做法是讓激活數據在訓練開始前通過一個網絡,網絡處理數據使其服從標准高斯分布。
因為歸一化是一個簡單可求導的操作,所以上述思路是可行的。
在實現層面,應用這個技巧通常意味着全連接層(或者是卷積層,后續會講)與激活函數之間添加一個BatchNorm層。
在實踐中,使用了批量歸一化的網絡對於不好的初始值有更強的魯棒性。
最后一句話總結:批量歸一化可以理解為在網絡的每一層之前都做預處理,只是這種操作以另一種方式與網絡集成在了一起。搞定!
3 正則化
3.1 L2正則化
L2正則化可能是最常用的正則化方法了。可以通過懲罰目標函數中所有參數的平方將其實現。
即對於網絡中的每個權重\(w\),向目標函數中增加一個\(\frac{1}{2} \lambda w^{2}\),其中\(\lambda\)是正則化強度。
前面這個\(\frac{1}{2}\)很常見,是因為加上\(\frac{1}{2}\)后,該式子關於\(w\)梯度就是\(\lambda w\)而不是2\(\lambda w\)了。
L2正則化可以直觀理解為它對於大數值的權重向量進行嚴厲懲罰,傾向於更加分散的權重向量。
在線性分類章節中討論過,由於輸入和權重之間的乘法操作,這樣就有了一個優良的特性:使網絡更傾向於使用所有輸入特征,而不是嚴重依賴輸入特征中某些小部分特征。
最后需要注意在梯度下降和參數更新的時候,使用L2正則化意味着所有的權重都以w += -lambda * W向着0線性下降。
3.2 L1正則化
L1正則化是另一個相對常用的正則化方法。
對於每個w我們都向目標函數增加一個\(\lambda|w|\)。
L1和L2正則化也可以進行組合:\(\lambda_{1}|w|+\lambda_{2} w^{2}\),這也被稱作Elastic net regularizaton。
L1正則化有一個有趣的性質,它會讓權重向量在最優化的過程中變得稀疏(即非常接近0)。
也就是說,使用L1正則化的神經元最后使用的是它們最重要的輸入數據的稀疏子集,同時對於噪音輸入則幾乎是不變的了。
相較L1正則化,L2正則化中的權重向量大多是分散的小數字。
在實踐中,如果不是特別關注某些明確的特征選擇,一般說來L2正則化都會比L1正則化效果好。
3.3 最大范式約束
最大范式約束(Max norm constraints)是給每個神經元中權重向量的量級設定上限,並使用投影梯度下降來確保這一約束。
在實踐中,與之對應的是參數更新方式不變,然后要求神經元中的權重向量\(\vec{w}\)必須滿足\(\|\vec{w}\|_{2}<c\)這一條件,一般\(c\)值為3或者4。
有研究者發文稱在使用這種正則化方法時效果更好。這種正則化還有一個良好的性質,即使在學習率設置過高的時候,網絡中也不會出現數值“爆炸”,這是因為它的參數更新始終是被限制着的。
3.4 隨機失活
隨機失活(Dropout)是一個簡單又極其有效的正則化方法。
該方法由Srivastava在論文"Dropout: A Simple Way to Prevent Neural Networks from Overfitting"中提出的,與L1正則化,L2正則化和最大范式約束等方法互為補充。
在訓練的時候,隨機失活的實現方法是讓神經元以超參數\(\mathcal{P}\)的概率被激活或者被設置為0。
<img src="https://img2018.cnblogs.com/blog/1414369/201906/1414369-20190613101957588-1259315751.png"width="440" align=center />
上圖來源自論文,展示其核心思路。
在訓練過程中,隨機失活可以被認為是對完整的神經網絡抽樣出一些子集,每次基於輸入數據只更新子網絡的參數(然而,數量巨大的子網絡們並不是相互獨立的,因為它們都共享參數)。
在測試過程中不使用隨機失活,可以理解為是對數量巨大的子網絡們做了模型集成(model ensemble),以此來計算出一個平均的預測。
一個3層神經網絡的普通版隨機失活可以用下面代碼實現:
""" 普通版隨機失活: 不推薦實現 (看下面筆記) """
p = 0.5 # 激活神經元的概率. p值更高 = 隨機失活更弱
def train_step(X):
""" X中是輸入數據 """
# 3層neural network的前向傳播
H1 = np.maximum(0, np.dot(W1, X) + b1)
#np.random.rand()括號里加的是個int型的數,
#而a.shape結果並不是一個int型的數,
#這時候就要在a.shape前面加個*號了。
U1 = np.random.rand(*H1.shape) < p # 第一個隨機失活遮罩
H1 *= U1 # drop!
H2 = np.maximum(0, np.dot(W2, H1) + b2)
U2 = np.random.rand(*H2.shape) < p # 第二個隨機失活遮罩
H2 *= U2 # drop!
out = np.dot(W3, H2) + b3
# 反向傳播:計算梯度... (略)
# 進行參數更新... (略)
def predict(X):
# 前向傳播時模型集成
H1 = np.maximum(0, np.dot(W1, X) + b1) * p # 注意:激活數據要乘以p
H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # 注意:激活數據要乘以p
out = np.dot(W3, H2) + b3
在上面的代碼中,train_step函數在第一個隱層和第二個隱層上進行了兩次隨機失活。
在輸入層上面進行隨機失活也是可以的,為此需要為輸入數據\(X\)創建一個二值的遮罩。
反向傳播保持不變,但是肯定需要將遮罩U1和U2加入進去。
注意:在predict函數中不進行隨機失活,但是對於兩個隱層的輸出都要乘以\(p\),調整其數值范圍。
這一點非常重要,因為在測試時所有的神經元都能看見它們的輸入,因此我們想要神經元的輸出與訓練時的預期輸出是一致的。
以\(p=0.5\)為例,在測試時神經元必須把它們的輸出減半,這是因為在訓練的時候它們的輸出只有一半。
為了理解這點,先假設有一個神經元\(x\)的輸出,那么進行隨機失活的時候,該神經元的輸出就是\(p x+(1-p) 0\),這是有\(1-p\)的概率神經元的輸出為0。
在測試時神經元總是激活的,就必須調整\(x \rightarrow p x\)來保持同樣的預期輸出。
在測試時會在所有可能的二值遮罩(也就是數量龐大的所有子網絡)中迭代並計算它們的協作預測,進行這種減弱的操作也可以認為是與之相關的。
上述操作不好的性質是必須在測試時對激活數據要按照\(p\)進行數值范圍調整。
既然測試性能如此關鍵,實際更傾向使用反向隨機失活(inverted dropout),它是在訓練時就進行數值范圍調整,從而讓前向傳播在測試時保持不變。
這樣做還有一個好處,無論你決定是否使用隨機失活,預測方法的代碼可以保持不變。反向隨機失活的代碼如下:
"""
反向隨機失活: 推薦實現方式.
在訓練的時候drop和調整數值范圍,測試時不做任何事.
"""
p = 0.5 # 激活神經元的概率. p值更高 = 隨機失活更弱
def train_step(X):
# 3層neural network的前向傳播
H1 = np.maximum(0, np.dot(W1, X) + b1)
U1 = (np.random.rand(*H1.shape) < p) / p # 第一個隨機失活遮罩. 注意/p!
H1 *= U1 # drop!
H2 = np.maximum(0, np.dot(W2, H1) + b2)
U2 = (np.random.rand(*H2.shape) < p) / p # 第二個隨機失活遮罩. 注意/p!
H2 *= U2 # drop!
out = np.dot(W3, H2) + b3
# 反向傳播:計算梯度... (略)
# 進行參數更新... (略)
def predict(X):
# 前向傳播時模型集成
H1 = np.maximum(0, np.dot(W1, X) + b1) # 不用數值范圍調整了
H2 = np.maximum(0, np.dot(W2, H1) + b2)
out = np.dot(W3, H2) + b3
3.5 偏置正則化
在線性分類器的章節中介紹過,對於偏置參數的正則化並不常見,因為它們在矩陣乘法中和輸入數據並不產生互動,所以並不需要控制其在數據維度上的效果。
然而在實際應用中(使用了合理數據預處理的情況下),對偏置進行正則化也很少會導致算法性能變差。
這可能是因為相較於權重參數,偏置參數實在太少,所以分類器需要它們來獲得一個很好的數據損失,那么還是能夠承受的。
3.6 每層正則化
對於不同的層進行不同強度的正則化很少見(可能除了輸出層以外),關於這個思路的相關文獻也很少。
在實際中,通過交叉驗證獲得一個全局使用的L2正則化強度是比較常見的。在使用L2正則化的同時在所有層后面使用隨機失活也很常見。
\(p\)值一般默認設為0.5,也可能在驗證集上調參。
4 損失函數
我們已經討論過損失函數的正則化損失部分,它可以看做是對模型復雜程度的某種懲罰。
損失函數的第二個部分是數據損失,它是一個有監督學習問題,用於衡量分類算法的預測結果(即分類評分)和真實標簽結果之間的一致性。
數據損失是對所有樣本的數據損失求平均。也就是說,\(L=\frac{1}{N} \sum_{i} L_{i}\)中,\(N\)是訓練集數據的樣本數。
讓我們把神經網絡中輸出層的激活函數簡寫為\(f=f\left(x_{i} ; W\right)\)。
4.1 分類問題
分類問題是我們一直討論的。
在該問題中,假設有一個裝滿樣本的數據集,每個樣本都有一個唯一的正確標簽(是固定分類標簽之一)。
在這類問題中,一個最常見的損失函數就是SVM(是Weston Watkins 公式):
之前簡要提起過,有些學者的論文中指出平方折葉損失(即使用\(\max \left(0, f_{j}-f_{y_{i}}+1\right)^{2}\))算法的結果會更好。
第二個常用的損失函數是Softmax分類器,它使用交叉熵損失:
當標簽集非常龐大(例如字典中的所有英語單詞,或者ImageNet中的22000種分類),就需要使用分層Softmax(Hierarchical Softmax)了。
分層softmax將標簽分解成一個樹。每個標簽都表示成這個樹上的一個路徑,這個樹的每個節點處都訓練一個Softmax分類器來在左和右分枝之間做決策。
樹的結構對於算法的最終結果影響很大,而且一般需要具體問題具體分析。
上面兩個損失公式的前提,都是假設每個樣本只有一個正確的標簽\(\mathcal{y}_{i}\)。但是如果\(\mathcal{y}_{i}\)是一個二值向量,每個樣本可能有,也可能沒有某個屬性,而且屬性之間並不相互排斥呢?
比如在Instagram上的圖片,就可以看成是被一個巨大的標簽集合中的某個子集打上標簽,一張圖片上可能有多個標簽。
在這種情況下,一個明智的方法是為每個屬性創建一個獨立的二分類的分類器。
例如,針對每個分類的二分類器會采用下面的公式:
上式中,求和是對所有分類\(j\),\(y_{i j}\)的值為1或者-1,具體根據第i個樣本是否被第j個屬性打標簽而定,當該類別被正確預測並展示的時候,分值向量\(f_{j}\)為正,其余情況為負。
可以發現,當一個正樣本的得分小於+1,或者一個負樣本得分大於-1的時候,算法就會累計損失值。
另一種方法是對每種屬性訓練一個獨立的邏輯回歸分類器。
二分類的邏輯回歸分類器只有兩個分類(0,1),其中對於分類1的概率計算為:
因為類別0和類別1的概率和為1,所以類別0的概率為:
這樣,如果\(\sigma\left(w^{T} x+b\right)>0.5\)或者\(w^{T} x+b>0\),那么樣本就要被分類成為正樣本(y=1)。
然后損失函數最大化這個對數似然函數,問題可以簡化為:
上式中,假設標簽\(y_{i j}\)非0即1,\(\sigma( .)\)就是sigmoid函數。上面的公式看起來嚇人,但是\(f\)的梯度實際上非常簡單:\(\frac{\partial L_{i}}{\partial f_{j}}=y_{i j}-\sigma\left(f_{j}\right)\)。
4.2 回歸問題
回歸問題是預測實數的值的問題,比如預測房價,預測圖片中某個東西的長度等。
對於這種問題,通常是計算預測值和真實值之間的損失。然后用L2平方范式或L1范式度量差異。
對於某個樣本,L2范式計算如下:
之所以在目標函數中要進行平方,是因為梯度算起來更加簡單。因為平方是一個單調運算,所以不用改變最優參數。
L1范式則是要將每個維度上的絕對值加起來:
在上式中,如果有多個數量被預測了,就要對預測的所有維度的預測求和,即\(\sum_{j}\)。
觀察第i個樣本的第j維,用\(\delta_{i j}\)表示預測值與真實值之間的差異。
關於該維度的梯度(也就是\(\partial L_{i} / \partial f_{j}\))能夠輕松地通過被求導為L2范式的\(\delta_{i j}\)或者\(\operatorname{sign}\left(\delta_{i j}\right)\)。
這就是說,評分值的梯度要么與誤差中的差值直接成比例,要么是固定的並從差值中繼承sign。
注意:L2損失比起較為穩定的Softmax損失來,其最優化過程要困難很多。
直觀而言,它需要網絡具備一個特別的性質,即對於每個輸入(和增量)都要輸出一個確切的正確值。
而在Softmax中就不是這樣,每個評分的准確值並不是那么重要:只有當它們量級適當的時候,才有意義。
還有,L2損失魯棒性不好,因為異常值可以導致很大的梯度。所以在面對一個回歸問題時,先考慮將輸出變成二值化是否真的不夠用。
例如,如果對一個產品的星級進行預測,使用5個獨立的分類器來對1-5星進行打分的效果一般比使用一個回歸損失要好很多。
分類還有一個額外優點,就是能給出關於回歸的輸出的分布,而不是一個簡單的毫無把握的輸出值。
如果確信分類不適用,那么使用L2損失吧,但是一定要謹慎:L2非常脆弱,在網絡中使用隨機失活(尤其是在L2損失層的上一層)不是好主意。
4.3 結構化損失
結構化損失是指標簽可以是任意的結構,例如圖表、樹或者其他復雜物體的情況。
通常這種情況還會假設結構空間非常巨大,不容易進行遍歷。
結構化SVM背后的基本思想就是在正確的結構\(\mathcal{y}_{i}\)和得分最高的非正確結構之間畫出一個邊界。
解決這類問題,並不是像解決一個簡單無限制的最優化問題那樣使用梯度下降就可以了,而是需要設計一些特殊的解決方案,這樣可以有效利用對於結構空間的特殊簡化假設。