关于神经网络权重初始值的设置的研究
關(guān)于神經(jīng)網(wǎng)絡(luò)權(quán)重初始值的設(shè)置的研究
- 一、權(quán)重初始值
- 二、權(quán)重初始值會(huì)影響隱藏層的激活值分布
- 三、Xavier初始值
- 四、He初始值
- 五、基于MNIST數(shù)據(jù)集的權(quán)重初始值的比較
一、權(quán)重初始值
權(quán)值衰減—抑制過擬合、提高泛化能力。
所謂權(quán)值衰減,即,以減小權(quán)重參數(shù)的值為目的進(jìn)行學(xué)習(xí)。
所以說人們一開始,就想把權(quán)重初始值設(shè)置的比較小。
那如果權(quán)重初始值全設(shè)為0或者一樣的值呢?那可不行,如果輸入層權(quán)重為0,那么第二層神經(jīng)元都到的全是0,如果第二層是乘法節(jié)點(diǎn),拿上圖舉例子,x=y=0,所以返回來的兩個(gè)梯度是一個(gè)樣的。就沒意義了。所有權(quán)重共同進(jìn)退有何意義?權(quán)重共同進(jìn)退,術(shù)語叫做權(quán)重均一化。
二、權(quán)重初始值會(huì)影響隱藏層的激活值分布
先看斯坦福大學(xué)做的一個(gè)實(shí)驗(yàn):
向一個(gè)5層神經(jīng)網(wǎng)絡(luò)傳入隨機(jī)生成的輸入數(shù)據(jù),用直方圖繪制各層激活值的數(shù)據(jù)分布。
實(shí)驗(yàn)?zāi)康氖峭ㄟ^改變標(biāo)準(zhǔn)差,觀察激活值的分布如何變化。
實(shí)驗(yàn)代碼:
這個(gè)實(shí)驗(yàn)各層激活值的結(jié)果保存在activations變量中。
import numpy as np import matplotlib.pyplot as pltdef sigmoid(x):return 1 / (1 + np.exp(-x))def ReLU(x):return np.maximum(0, x)def tanh(x):return np.tanh(x)input_data = np.random.randn(1000, 100) # 1000個(gè)數(shù)據(jù) node_num = 100 # 各隱藏層的節(jié)點(diǎn)(神經(jīng)元)數(shù) hidden_layer_size = 5 # 隱藏層有5層 activations = {} # 激活值的結(jié)果保存在這里x = input_datafor i in range(hidden_layer_size):if i != 0:x = activations[i-1]# 改變初始值進(jìn)行實(shí)驗(yàn)!w = np.random.randn(node_num, node_num) * 1# w = np.random.randn(node_num, node_num) * 0.01# w = np.random.randn(node_num, node_num) * np.sqrt(1.0 / node_num)# w = np.random.randn(node_num, node_num) * np.sqrt(2.0 / node_num)a = np.dot(x, w)# 將激活函數(shù)的種類也改變,來進(jìn)行實(shí)驗(yàn)!z = sigmoid(a)# z = ReLU(a)# z = tanh(a)activations[i] = z# 繪制直方圖 for i, a in activations.items():plt.subplot(1, len(activations), i+1)plt.title(str(i+1) + "-layer")if i != 0: plt.yticks([], [])# plt.xlim(0.1, 1)# plt.ylim(0, 7000)plt.hist(a.flatten(), 30, range=(0,1)) plt.show()首先來看,使用的權(quán)重初始值是標(biāo)準(zhǔn)差為1的高斯分布時(shí),激活值的分布,w = np.random.randn(node_num, node_num) * 1。
再看使用的權(quán)重初始值是標(biāo)準(zhǔn)差為0.01的高斯分布時(shí),激活值的分布:
看到,使用的權(quán)重初始值是標(biāo)準(zhǔn)差為1的高斯分布時(shí),激活值偏向0和1的分布。這會(huì)導(dǎo)致,隨著輸出不斷靠近0或1,導(dǎo)數(shù)的值逐漸接近0,反向傳播中梯度的值不斷變小,最后會(huì)消失。這就是所謂的梯度消失。
使用的權(quán)重初始值是標(biāo)準(zhǔn)差為0.01的高斯分布時(shí),不會(huì)發(fā)生梯度消失,但是激活值分布偏向0.5,說明表現(xiàn)力有大問題。如果100個(gè)神經(jīng)元輸出都幾乎相同,那我可以用1個(gè)神經(jīng)元表達(dá)100個(gè)神經(jīng)元干的事。術(shù)語,所謂的表現(xiàn)力受限問題。
三、Xavier初始值
Xavier提出:如果前一層的節(jié)點(diǎn)數(shù)為n,則初始值使用標(biāo)準(zhǔn)差為根號(hào)n分之一的分布。
代碼里就這句話,w = np.random.randn(node_num, node_num) * np.sqrt(1.0 / node_num)
效果如下:呈現(xiàn)了比之前更有廣度的分布。
Xavier的初始值是以激活函數(shù)是線性函數(shù)為前提而推導(dǎo)得出。
四、He初始值
Kaiming He提出,當(dāng)前一層的節(jié)點(diǎn)數(shù)為n時(shí),He的初始值使用標(biāo)準(zhǔn)差為根號(hào)(n分之2)的高斯分布。
我們研究一下激活函數(shù)用ReLU時(shí),不同權(quán)重初始值下,每一層激活值分布的區(qū)別。
權(quán)重初始值為He初始值時(shí):
權(quán)重初始值為Xavier時(shí):
權(quán)重初始值為標(biāo)準(zhǔn)差為0.01的高斯分布時(shí)
明顯ReLU更適合用He初始值。因?yàn)榉植紡V度好,表現(xiàn)力好。
初始值為Xavier時(shí),隨層次加深,往0那邊偏,我猜,如果加深網(wǎng)絡(luò),會(huì)出現(xiàn)梯度消失現(xiàn)象。
五、基于MNIST數(shù)據(jù)集的權(quán)重初始值的比較
這個(gè)對(duì)比,揭示了,很多時(shí)候,權(quán)重初始值的設(shè)定關(guān)系到神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)能否成功。
代碼:
import os import syssys.path.append(os.pardir) # 為了導(dǎo)入父目錄的文件而進(jìn)行的設(shè)定 import numpy as np import matplotlib.pyplot as plt from dataset.mnist import load_mnist from common.util import smooth_curve from common.multi_layer_net import MultiLayerNet from common.optimizer import SGD# 0:讀入MNIST數(shù)據(jù)========== (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)train_size = x_train.shape[0] batch_size = 128 max_iterations = 2000# 1:進(jìn)行實(shí)驗(yàn)的設(shè)置========== weight_init_types = {'std=0.01': 0.01, 'Xavier': 'sigmoid', 'He': 'relu'} optimizer = SGD(lr=0.01)networks = {} train_loss = {} for key, weight_type in weight_init_types.items():networks[key] = MultiLayerNet(input_size=784, hidden_size_list=[100, 100, 100, 100],output_size=10, weight_init_std=weight_type)train_loss[key] = []# 2:開始訓(xùn)練========== for i in range(max_iterations):batch_mask = np.random.choice(train_size, batch_size)x_batch = x_train[batch_mask]t_batch = t_train[batch_mask]for key in weight_init_types.keys():grads = networks[key].gradient(x_batch, t_batch)optimizer.update(networks[key].params, grads)loss = networks[key].loss(x_batch, t_batch)train_loss[key].append(loss)if i % 100 == 0:print("===========" + "iteration:" + str(i) + "===========")for key in weight_init_types.keys():loss = networks[key].loss(x_batch, t_batch)print(key + ":" + str(loss))# 3.繪制圖形========== markers = {'std=0.01': 'o', 'Xavier': 's', 'He': 'D'} x = np.arange(max_iterations) for key in weight_init_types.keys():plt.plot(x, smooth_curve(train_loss[key]), marker=markers[key], markevery=100, label=key) plt.xlabel("iterations") plt.ylabel("loss") plt.ylim(0, 2.5) plt.legend() plt.show()總結(jié)
以上是生活随笔為你收集整理的关于神经网络权重初始值的设置的研究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RFID 射频 RFID工作流程 自动识
- 下一篇: java rsa算法_求RSA算法JAV