天天看點

softmax雜談

softmax雜談

在多分類問題中,我們可以使用 softmax 函數,對輸出的值歸一化為機率值。下面舉個例子:

softmax雜談

上圖轉換為表達式:

????(0)=(????(0)0,????(0)1,⋯,????(0)9)????????(1)=(????(1)0,????(1)1,⋯,????(1)6)????????(2)=(????(2)0,????(2)1,⋯,????(2)4)????a(0)=(a0(0),a1(0),⋯,a9(0))Ta(1)=(a0(1),a1(1),⋯,a6(1))Ta(2)=(a0(2),a1(2),⋯,a4(2))T

對于任意的 0≤????≤20≤i≤2, 有前向傳播的表達式:

????(????+1)=????(????)????(????)+????(????)????(????+1)=????(????+1)(????(????+1))z(i+1)=W(i)a(i)+b(i)a(i+1)=f(i+1)(z(i+1))

其中,????(????)f(j) 表示激活函數,除了輸出層外,一般使用 ReLU 函數;????(????),????(????)W(i),b(i) 為模型參數。

如若我們有 ????m 個樣本 {????(????)}????????=1{x(j)}j=1m 組成的資料集 ????D, 稱 ????=(????(1),????(2),⋯,????(????))????X=(x(1),x(2),⋯,x(m))T 為資料集 ????D 的設計矩陣。

這樣,前向傳播可以改寫為:

{????(1+????)=????(????)????(0)+(????(????))????????(1+????)=????(1+????)(????(1+????)){Z(1+i)=Z(i)W(0)+(b(i))TA(1+i)=f(1+i)(Z(1+i))

????(????)=(????(????)1,????(????)2,⋯,????(????)????)????Z(i)=(z1(i),z2(i),⋯,zm(i))T, 這裡對 ????(????)z(i) 添加下标以差別不同的樣本;

這裡對列向量 ????(????)b(i) 進行了 broadcast 操作;

且 ????(0)=????Z(0)=X.

softmax雜談

對于多分類問題,一般輸出層對應的激活函數的 softmax 函數:

求解 ????(2)A(2):

計算 ????????????=exp(????(1))exp=exp⁡(Z(1));

對 ????????????exp 按列做歸一化, 便可得到 softmax(????(1))softmax(A(1)).

但如果輸入值較大或較小時,會出現記憶體溢出的現象:

一種簡單有效避免該問題的方法就是讓 exp(????????)exp⁡(zj) 中的 ????????zj 替換為 ????????−max????{????????}zj−maxi{zi}, 由于 max????maxi 是個固定的常數,是以 exp(????????)exp⁡(zj)的值沒有改變。但是,此時避免了溢出現象的出現。

當然這種做法也不是最完美的,因為 softmax 函數不可能産生 <code>0</code> 值,但這總比出現 <code>nan</code> 的結果好,并且真實的結果也是非常接近 00 的。

除此之外,還有一個問題:如果我們計算 logsoftmax(????????)log⁡softmax(zj) 時,先計算 softmaxsoftmax 再将其傳遞給 loglog,會錯誤的得到 −∞−∞

最簡單的處理方式是直接加一個很小的常數:

為了解決此數值計算的不穩定,MXNet 提供了:

解決計算交叉熵時出現的數值不穩定的問題。