1. 程式人生 > 其它 >Improving the Learning Speed of 2-Layer Neural Networks by Choosing Initial Values of the Adaptive Weights

Improving the Learning Speed of 2-Layer Neural Networks by Choosing Initial Values of the Adaptive Weights

目錄

Nguyen D. and Widrow B. Improving the learning speed of 2-layer neural networks by choosing initial values of the adaptive weights. In International Joint Conference on Neural Networks (IJCNN), 1990.

本文提出了一種關於兩層網路的權重初始化方法.

主要內容

假設我們想通過一個兩層的網路

\[f(\bm{x}) = \sum_{i=1}^{H} v_i \tanh (\bm{w}_i^T \bm{x} + b_i), \]

擬合一個函式\(g(\bm{x})\)

.
其中 \(\bm{x}, \bm{w}_i \in \mathbb{R}^{d}\).

\[\tanh (x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}, \]

\([-1, 1]\)之前是近似線性的.

為了方便討論, 令\(f_i(\bm{x}) := v_i \tanh (\bm{w}_i^T \bm{x} + b_i)\).

一維情形

\[f(x) = \sum_{i=1}^{H} v_i \tanh (w_i x + b_i), \\ f_i(x) = v_i \tanh (w_i x + b_i). \]

不考慮\(\tanh\), 當\(x \in [-1, 1]\)

時, 每個\(f_i(x)\)(近似)落在區間

\[[b_i - |w_i|, b_i + |w_i|] \]

之中. 該區間以\(b_i\)為中心, 大小為\(2|w_i|\).
所以總的網路可以看成是在每個區間內取樣\(\xi_i\), 然後求和

\[f(x) = \sum_{i=1}^H v_i \xi_i. \]

倘若每個區間是差不離一致的, 那麼就容易導致\(f(x)\)本身是很平坦的,

注: 文中還要平坦, 這個和初始化有關係, 不過既然都是近似線性的, 所以直線是正常的.

如何加速

上面是的情況是權重 \(w_i, b_i\)取樣自 \(\mathcal{U}[-1, 1]\)

\(\mathcal{U}[-5, 5]\)的結果. 我們希望輸出\(f(x)\)是不平坦的, 但是也希望其不會偏向任意一些值, 顯然取樣自 \(\mathcal{U}[-5, 5]\)的較小的值佔據了很大部分.

\(f(x)\)總共有\(H\)個結點, 滿足

\[-1 < w_ix + b_i < 1, \]

\(x\)區間為

\[-1/|w_i| - b_i/ w_i < x < 1 / |w_i| - b_i / w_i, \]

該區間長度為 \(2 / |w_i|\),
倘若不同結點

\[2 / |w_i| = 2 / H \rightarrow |w_i| = H. \]

即每個區間所對應的\(x\)的大小是一致的, 均為 \(2 / H\). 那麼最後的輸出也就很有可能是均勻的且並不完全平坦的.

注: 在這種情況下, 對於任意\(x \in [-1, 1]\), 只有一個區間 \(f_i(x)\)是落在\([-1, 1]\)的, 其餘的都將表現出非線性, 從而導致不平坦?

為了讓區間有所重疊, 實際上我們採用\(|w_i| = 0.7H\).

區間的中心 \(-b_i / w_i\)將從 \([-1, 1]\)從取樣, 實際上

\[b_i \sim \mathcal{U}[-|w_i|, |w_i|]. \]

最後 \(v_i\) 均勻取樣自 \(\mathcal{U}[-0.5, 0.5]\).

下面是幾個示例:



多維情形

作者給出的是從\(f_i(x)\)到其傅立葉變換表示的解釋, 但是說實話
我不是很理解其中的具體思路 (可能是傅立葉變換了解得不是很透徹).
我這裡勉強給個自己的解釋吧.

首先,

\[f_i(\bm{x}) = v_i \tanh (\bm{w}_i^T \bm{x} + b_i). \]

倘若\(\bm{x} \in [-1, 1]^d\), 那麼

\[-\|\bm{w}_i\|_1 + b_i \le \bm{w}_i^T\bm{x} + b_i \le \|\bm{w}_i\|_1 + b_i, \]

最大區間長度為\(2\|\bm{w}_i\|_1\). 和之前一維一樣, 我們希望不同的區間長度是一致的, 即\(\|\bm{w}_i\|_1\)對於不同的\(i\)的大小也是一致的.

文中給出的是

\[\|\bm{w}\|_1 = H^{\frac{1}{d}}. \]

類似地, 在實際中, 採用

\[\|\bm{w}\|_1 = 0.7 * H^{\frac{1}{d}}. \]

並且, \(b_i\)取樣自\(\mathcal{U}[-\|\bm{w}_i\|_1, \|\bm{w}_i\|_1]\).

注: 該係數是通過傅立葉變換, slices之類的推匯出來的, 但是我沒有搞清楚其中的關係;
注: 文中用的\(|\cdot|\)來表示大小, 我沒法保證這就是\(\ell_1\)範數.

程式碼

import torch.nn as nn
import torch.nn.functional as F

def nguyen_widrow_init(weight, bias, scale: float = 0.7):
    out_channels, in_channels = weight.size()
    nn.init.uniform_(weight, -0.5, 0.5)
    scale = scale * out_channels ** (1 / in_channels)
    weight.data.copy_(scale * F.normalize(weight.data, p=1, dim=-1))
    nn.init.uniform_(bias, -scale, scale)

# test

import torch
import torch.nn as nn
import torch.nn.functional as F

from freeplot.base import FreePlot

class Net(nn.Module):

    def __init__(self) -> None:
        super().__init__()

        self.linear1 = nn.Linear(1, 4)
        self.linear2 = nn.Linear(4, 1)


        nguyen_widrow_init(self.linear1.weight, self.linear1.bias)
        nn.init.uniform_(self.linear2.weight, -0.5, 0.5)
        nn.init.uniform_(self.linear2.bias, -0.5, 0.5)

    def forward(self, x):
        z = torch.tanh(self.linear1(x))
        y = self.linear2(z)
        return z, y


model = Net()
x = torch.linspace(-1, 1, 100).view(-1, 1)
z, y = model(x)

x = x.flatten().detach().clone().numpy()
y = y.flatten().detach().clone().numpy()
z = z.transpose(0, 1).detach().clone().numpy()


fp = FreePlot((1, 2), (5, 2), sharey=False)
for i in range(4):
    fp.lineplot(x, z[i], label=str(i))
fp.lineplot(x, y, label='ALL', index=(0, 1), color='black')
fp.set_label(r"$f_i(x)$", index=(0, 0))
fp.set_label(r"$f(x)$", index=(0, 1))
fp.show()