臨西網(wǎng)站建設(shè)住房和城鄉(xiāng)建設(shè)部官網(wǎng)
神經(jīng)網(wǎng)絡(luò)基礎(chǔ)
- 前言
- 一、神經(jīng)網(wǎng)絡(luò)
- 1.1 基本概念
- 1.2 工作原理
- 二、激活函數(shù)
- 2.1 sigmoid激活函數(shù)
- 2.1.1 公式
- 2.1.2 注意事項(xiàng)
- 2.2 tanh激活函數(shù)
- 2.2.1 公式
- 2.2.2 注意事項(xiàng)
- 2.3 ReLU激活函數(shù)
- 2.3.1 公式
- 2.3.2 注意事項(xiàng)
- 2.4 SoftMax激活函數(shù)
- 2.4.1 公式
- 2.4.2 Softmax的性質(zhì)
- 2.4.3 Softmax的應(yīng)用
- 2.4.4 代碼演示
- 2.4.5 數(shù)學(xué)計(jì)算舉例
- 2.4.6 Softmax的注意事項(xiàng)
- 三、參數(shù)初始化
- 3.1 均勻分布初始化
- 3.2 正態(tài)分布初始化
- 3.3 全0初始化
- 3.4 全1初始化
- 3.5 固定值初始化
- 3.6 Kaiming 初始化,也叫做 HE 初始化
- 3.6.1 正態(tài)化的Kaiming 初始化
- 3.6.2 均勻分布的Kaiming 初始化
- 3.7 Xavier 初始化,也叫做 Glorot初始化
- 3.7.1 正態(tài)化的Xavier初始化
- 3.7.2 均勻分布的Xavier初始化
- 四、構(gòu)建簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)
- 總結(jié)
前言
- 前面我們學(xué)習(xí)了深度學(xué)習(xí)當(dāng)中的基礎(chǔ)——張量,接下來我們了解神經(jīng)網(wǎng)絡(luò)中的知識(shí)。
一、神經(jīng)網(wǎng)絡(luò)
- 神經(jīng)網(wǎng)絡(luò)是一種模擬人腦神經(jīng)元結(jié)構(gòu)和功能的計(jì)算模型,旨在解決復(fù)雜的模式識(shí)別和預(yù)測(cè)問題
1.1 基本概念
-
神經(jīng)元:神經(jīng)元是神經(jīng)網(wǎng)絡(luò)的基本組成單元,它接收輸入信號(hào),通過對(duì)輸入信號(hào)的處理產(chǎn)生輸出信號(hào)。每個(gè)神經(jīng)元都有多個(gè)輸入和一個(gè)輸出,輸入可以是其他神經(jīng)元的輸出,也可以是外部輸入信號(hào)。
-
層級(jí)結(jié)構(gòu):神經(jīng)網(wǎng)絡(luò)由多個(gè)層級(jí)結(jié)構(gòu)組成,包括輸入層、隱藏層和輸出層。輸入層接收來自外部環(huán)境的數(shù)據(jù),每個(gè)神經(jīng)元代表一個(gè)輸入特征;隱藏層負(fù)責(zé)對(duì)輸入數(shù)據(jù)進(jìn)行非線性變換,提取特征;輸出層輸出預(yù)測(cè)結(jié)果,每個(gè)神經(jīng)元代表一個(gè)輸出值。
-
-
連接權(quán)重:連接不同神經(jīng)元之間的權(quán)重,決定信號(hào)的傳遞強(qiáng)度。這些權(quán)重在神經(jīng)網(wǎng)絡(luò)的訓(xùn)練過程中不斷調(diào)整,以實(shí)現(xiàn)更好的預(yù)測(cè)性能。
-
-
激活函數(shù):激活函數(shù)用于對(duì)神經(jīng)元輸出進(jìn)行非線性變換,引入非線性特性。常見的激活函數(shù)包括sigmoid函數(shù)、ReLU函數(shù)、tanh函數(shù)等。不同的激活函數(shù)有不同的性質(zhì),可以根據(jù)具體的任務(wù)需求選擇不同的激活函數(shù)。
1.2 工作原理
- 層級(jí)傳播:信號(hào)通過逐層傳遞,最終到達(dá)輸出層。
- 輸出預(yù)測(cè):輸出層的神經(jīng)元輸出預(yù)測(cè)結(jié)果。
- 誤差反向傳播:根據(jù)預(yù)測(cè)結(jié)果與真實(shí)值的誤差,通過反向傳播算法更新連接權(quán)重。反向傳播算法通過從輸出層向輸入層反向傳播誤差,依次更新權(quán)重和偏置,使得網(wǎng)絡(luò)的預(yù)測(cè)能力逐漸提高。
二、激活函數(shù)
- 用于對(duì)每層的輸出數(shù)據(jù)進(jìn)行變換,從而為整個(gè)網(wǎng)絡(luò)注入了非線性因素,此時(shí)的神經(jīng)網(wǎng)絡(luò)就可以擬合各種曲線,提高應(yīng)對(duì)復(fù)雜問題的擬合能力。
2.1 sigmoid激活函數(shù)
2.1.1 公式
f ( x ) = 1 1 + e ? x f(x)=\frac{1}{1+e^{-x}} f(x)=1+e?x1?
- 求導(dǎo)后的公式:
- f ′ ( x ) = ( 1 1 + e ? x ) ′ = 1 1 + e ? x ( 1 ? 1 1 + e ? x ) = f ( x ) ( 1 ? f ( x ) ) f'(x)=(\frac{1}{1+e^{-x}})'=\frac{1}{1+e^{-x}}(1-\frac{1}{1+e^{-x}})=f(x)(1-f(x)) f′(x)=(1+e?x1?)′=1+e?x1?(1?1+e?x1?)=f(x)(1?f(x))
代碼演示:
import torch
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負(fù)號(hào)# 創(chuàng)建畫布和坐標(biāo)軸
_, axes = plt.subplots(1, 2)
# sigmoid函數(shù)圖像
x = torch.linspace(-20, 20, 1000)
# 輸入值x通過sigmoid函數(shù)轉(zhuǎn)換成激活值y
y = torch.sigmoid(x)
axes[0].plot(x, y)
axes[0].grid()
axes[0].set_title('Sigmoid 函數(shù)圖像')# sigmoid導(dǎo)數(shù)圖像
x = torch.linspace(-20, 20, 1000, requires_grad=True)
torch.sigmoid(x).sum().backward()# y = 2 * torch.dot(x, x)
# y.backward()
# x.detach():輸入值x的數(shù)值
# x.grad:計(jì)算梯度,求導(dǎo)
axes[1].plot(x.detach(), x.grad)
axes[1].grid()
axes[1].set_title('Sigmoid 導(dǎo)數(shù)圖像')
plt.show()
- 函數(shù)圖像如下
2.1.2 注意事項(xiàng)
- sigmoid函數(shù)可以將任意值的輸入映射到(0,1)之間,從圖中我們可以看出,當(dāng)輸入的值大致在 < -6 或者 >6 的時(shí)候,此時(shí)輸入任何值得到的激活值都差不多,這樣就會(huì)導(dǎo)致丟失部分信息。
- 對(duì)于sigmoid函數(shù)而言,輸入值在[-6,6]之間才會(huì)有明顯差異,輸入值在[-3,3]之間才會(huì)有比較好的結(jié)果。
- 由導(dǎo)函數(shù)的圖像,導(dǎo)數(shù)的數(shù)值范圍是(0,025),當(dāng)輸入*< -6 或者 >6 的時(shí)候,sigmoid激活函數(shù)圖像的導(dǎo)數(shù)接近于0,此時(shí)網(wǎng)絡(luò)參數(shù)將更新緩慢或者無法更新。
- 一般來說,sigmoid的網(wǎng)絡(luò)在五層之內(nèi)就會(huì)產(chǎn)生梯度消失的現(xiàn)象,而且該激活函數(shù)不以0為中心,所以在實(shí)踐中,使用很少。一般只用于二分類的輸出層。
2.2 tanh激活函數(shù)
2.2.1 公式
f ( x ) = 1 ? e ? 2 x 1 + e ? 2 x f(x)=\frac{1-e^{-2x}}{1+e^{-2x}} f(x)=1+e?2x1?e?2x?
- 求導(dǎo)后的公式:
f ′ ( x ) = ( 1 ? e ? 2 x 1 + e ? 2 x ) ′ = 1 ? f 2 ( x ) f'(x)=(\frac{1-e^{-2x}}{1+e^{-2x}})'=1-f^2(x) f′(x)=(1+e?2x1?e?2x?)′=1?f2(x)
代碼演示:
import torch
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負(fù)號(hào)# 創(chuàng)建畫布和坐標(biāo)軸
_, axes = plt.subplots(1, 2)
# 函數(shù)圖像
x = torch.linspace(-20, 20, 1000)
y = torch.tanh(x)
axes[0].plot(x, y)
axes[0].grid()
axes[0].set_title('Tanh 函數(shù)圖像')# 導(dǎo)數(shù)圖像
x = torch.linspace(-20, 20, 1000, requires_grad=True)
torch.tanh(x).sum().backward()
axes[1].plot(x.detach(), x.grad)
axes[1].grid()
axes[1].set_title('Tanh 導(dǎo)數(shù)圖像')
plt.show()
2.2.2 注意事項(xiàng)
- Tanh函數(shù)將輸入映射在(-1,1)之間,圖像以0為中心,在0點(diǎn)對(duì)稱,當(dāng)輸入 < -3 或者 >3 的時(shí)會(huì)被映射成 -1 或者 1 。導(dǎo)函數(shù)的取值范圍(0,1),當(dāng)輸入的值 < -3 或者 >3 的時(shí),其導(dǎo)函數(shù)近似0。
- 與sigmoid相比,它是以0為中心,并且梯度相對(duì)于sigmoid大,使得其收斂速度要比sigmoid快,減少迭代刺水。然而,從圖中可以看出,Tanh兩側(cè)的導(dǎo)數(shù)也為0,同樣會(huì)出現(xiàn)梯度消失的情況。
- 若使用的時(shí)候,可以再隱藏層使用Tanh函數(shù),在輸出層使用sigmoid函數(shù)。
2.3 ReLU激活函數(shù)
2.3.1 公式
f ( x ) = m a x ( 0 , x ) f(x)=max(0, x) f(x)=max(0,x)
- 求導(dǎo)后的公式:
f ′ ( x ) = 0 或者 1 f'(x)=0或者1 f′(x)=0或者1
代碼演示:
# 創(chuàng)建畫布和坐標(biāo)軸
import torch
from matplotlib import pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負(fù)號(hào)_, axes = plt.subplots(1, 2)
# 函數(shù)圖像
x = torch.linspace(-20, 20, 1000)
y = torch.relu(x)
axes[0].plot(x, y)
axes[0].grid()
axes[0].set_title('ReLU 函數(shù)圖像')
# 導(dǎo)數(shù)圖像
x = torch.linspace(-20, 20, 1000, requires_grad=True)
torch.relu(x).sum().backward()
axes[1].plot(x.detach(), x.grad)
axes[1].grid()
axes[1].set_title('ReLU 導(dǎo)數(shù)圖像')
plt.show()
2.3.2 注意事項(xiàng)
- ReLU 激活函數(shù)將小于0的值映射為 0,而大于 0 的值則保持不變,它更加重視正信號(hào),而忽略負(fù)信號(hào),這種激活函數(shù)運(yùn)算更為簡(jiǎn)單,能夠提高模型的訓(xùn)練效率。
- 當(dāng)x<0時(shí),ReLU導(dǎo)數(shù)為0,而當(dāng)x>0時(shí),則不存在飽和問題。所以,ReLU能夠在x>0時(shí)保持梯度不衰減,從而緩解梯度消失問題。然而,隨著訓(xùn)練的推進(jìn),部分輸入會(huì)落入小于0區(qū)域,導(dǎo)致對(duì)應(yīng)權(quán)重?zé)o法更新。這種現(xiàn)象被稱為“神經(jīng)元死亡”
- ReLU是目前最常用的激活函數(shù)。
- 與sigmoid相比,RELU的優(yōu)勢(shì)是:采用sigmoid函數(shù),計(jì)算量大(指數(shù)運(yùn)算),反向傳播求誤差梯度時(shí),計(jì)算量相對(duì)大,而采用Relu激活函數(shù),整個(gè)過程的計(jì)算量節(jié)省很多。
- siqmoid函數(shù)反向傳播時(shí),很容易就會(huì)出現(xiàn)梯度消失的情況,從而無法完成深層網(wǎng)絡(luò)的訓(xùn)練。
- Relu會(huì)使一部分神經(jīng)元的輸出為0,這樣就造成了網(wǎng)絡(luò)的稀疏性,并且減少了參數(shù)的相互依存關(guān)系,緩解了過擬合問題的發(fā)生。
2.4 SoftMax激活函數(shù)
2.4.1 公式
-
Softmax函數(shù)的本質(zhì)是一種歸一化函數(shù),它將一個(gè)數(shù)值向量歸一化為一個(gè)概率分布向量,且各個(gè)概率之和為1。對(duì)于一個(gè)給定的實(shí)數(shù)向量z,Softmax函數(shù)首先計(jì)算每一個(gè)元素的指數(shù)(e的冪),然后每個(gè)元素的指數(shù)與所有元素指數(shù)總和的比值,就形成了Softmax函數(shù)的輸出。
Softmax ( z i ) = e z i ∑ j = 1 K e z j \text{Softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}} Softmax(zi?)=∑j=1K?ezj?ezi?? -
其中, z i z_i zi? 表示輸入向量 z z z 的第 i i i 個(gè)分量, K K K 是類別總數(shù),即向量 z z z 的維度, e e e 是自然對(duì)數(shù)的底數(shù)。
-
實(shí)際計(jì)算的時(shí)候需要輸入向量減去向量中的最大值
- 在實(shí)際應(yīng)用中,直接計(jì)算 e z i e^{z_i} ezi? 可能會(huì)導(dǎo)致數(shù)值溢出,特別是當(dāng)輸入值很大時(shí)。為了防止這種情況,可以在計(jì)算前減去向量中的最大值。
2.4.2 Softmax的性質(zhì)
- 歸一化:Softmax保證所有輸出值的和為1,使其可以被解釋為概率。
- 可微性:Softmax函數(shù)在整個(gè)定義域內(nèi)可微,這使得它可以在基于梯度的優(yōu)化算法中使用,例如反向傳播。
- 敏感性:Softmax對(duì)輸入值非常敏感,尤其是當(dāng)有一個(gè)輸入遠(yuǎn)大于其他輸入時(shí)。
2.4.3 Softmax的應(yīng)用
- 多類別分類問題:Softmax函數(shù)常用于多類別分類問題中,將輸入向量映射為各個(gè)類別的概率。在神經(jīng)網(wǎng)絡(luò)中,Softmax通常作為輸出層的激活函數(shù),將網(wǎng)絡(luò)的輸出轉(zhuǎn)換為類別概率。
- 交叉熵?fù)p失函數(shù):在訓(xùn)練神經(jīng)網(wǎng)絡(luò)時(shí),Softmax函數(shù)通常與交叉熵?fù)p失函數(shù)結(jié)合使用。交叉熵?fù)p失函數(shù)用于衡量預(yù)測(cè)概率分布與真實(shí)標(biāo)簽之間的差異,從而進(jìn)行模型的訓(xùn)練和優(yōu)化。
2.4.4 代碼演示
代碼演示:
import torchscores = torch.tensor([0.2, 0.02, 0.15, 0.15, 1.3, 0.5, 0.06, 1.1, 0.05, 3.75])
# dim = 0,按行計(jì)算
probabilities = torch.softmax(scores, dim=0)
print(probabilities)
2.4.5 數(shù)學(xué)計(jì)算舉例
- 0、背景:
- 假設(shè)我們有一個(gè)神經(jīng)網(wǎng)絡(luò),用于識(shí)別手寫數(shù)字(0 到 9)。神經(jīng)網(wǎng)絡(luò)的輸出層有 10 個(gè)神經(jīng)元,每個(gè)神經(jīng)元對(duì)應(yīng)一個(gè)數(shù)字類別。在訓(xùn)練完成后,對(duì)于一個(gè)新的輸入圖像,神經(jīng)網(wǎng)絡(luò)的輸出層會(huì)產(chǎn)生一個(gè) 10 維的實(shí)數(shù)向量。我們需要將這個(gè)向量轉(zhuǎn)換為一個(gè)概率分布,以便確定哪個(gè)數(shù)字最有可能是正確的。
- 1、輸入向量
- z = [ 1.0 , 2.0 , 3.0 , 4.0 , 1.0 , 0.5 , 0.0 , ? 1.0 , ? 2.0 , ? 3.0 ] z = [1.0,2.0,3.0,4.0,1.0,0.5,0.0,?1.0,?2.0,?3.0] z=[1.0,2.0,3.0,4.0,1.0,0.5,0.0,?1.0,?2.0,?3.0]
- 2、減去最大值
- 為了防止數(shù)值溢出,我們先減去向量中的最大值(4.0)
- z ′ = [ 1.0 ? 4.0 , 2.0 ? 4.0 , 3.0 ? 4.0 , 4.0 ? 4.0 , 1.0 ? 4.0 , 0.5 ? 4.0 , 0.0 ? 4.0 , ? 1.0 ? 4.0 , ? 2.0 ? 4.0 , ? 3.0 ? 4.0 ] z'=[1.0?4.0,2.0?4.0,3.0?4.0,4.0?4.0,1.0?4.0,0.5?4.0,0.0?4.0,?1.0?4.0,?2.0?4.0,?3.0?4.0] z′=[1.0?4.0,2.0?4.0,3.0?4.0,4.0?4.0,1.0?4.0,0.5?4.0,0.0?4.0,?1.0?4.0,?2.0?4.0,?3.0?4.0]
- z ′ = [ ? 3.0 , ? 2.0 , ? 1.0 , 0.0 , ? 3.0 , ? 3.5 , ? 4.0 , ? 5.0 , ? 6.0 , ? 7.0 ] z' = [?3.0,?2.0,?1.0,0.0,?3.0,?3.5,?4.0,?5.0,?6.0,?7.0] z′=[?3.0,?2.0,?1.0,0.0,?3.0,?3.5,?4.0,?5.0,?6.0,?7.0]
- 3、計(jì)算指數(shù)
- e z ′ = [ e ? 3.0 , e ? 2.0 , e ? 1.0 , e 0.0 , e ? 3.0 , e ? 3.5 , e ? 4.0 , e ? 5.0 , e ? 6.0 , e ? 7.0 ] e^{z'} = [e^{-3.0},e^{-2.0},e^{-1.0},e^{0.0},e^{-3.0},e^{-3.5},e^{-4.0},e^{-5.0},e^{-6.0},e^{-7.0}] ez′=[e?3.0,e?2.0,e?1.0,e0.0,e?3.0,e?3.5,e?4.0,e?5.0,e?6.0,e?7.0]
import numpy as npz_prime = np.array([-3.0, -2.0, -1.0, 0.0, -3.0, -3.5, -4.0, -5.0, -6.0, -7.0]) exp_z_prime = np.exp(z_prime) print(exp_z_prime)
- [‘0.0497870684’, ‘0.1353352832’, ‘0.3678794412’, ‘1.0000000000’, ‘0.0497870684’, ‘0.0301973834’, ‘0.0183156389’, ‘0.0067379470’, ‘0.0024787522’, ‘0.0009118820’]
- 4、計(jì)算分母
- ∑ i = 1 10 e z ′ = 0.0497870684 + 0.1353352832 + 0.3678794412 + 1.0000000000 + 0.0497870684 + 0.0301973834 + 0.0183156389 + 0.0067379470 + 0.0024787522 + 0.0009118820 \sum_{i=1}^{10}e^{z'}= 0.0497870684+0.1353352832+0.3678794412+1.0000000000+0.0497870684+0.0301973834+0.0183156389+0.0067379470+0.0024787522+0.0009118820 ∑i=110?ez′=0.0497870684+0.1353352832+0.3678794412+1.0000000000+0.0497870684+0.0301973834+0.0183156389+0.0067379470+0.0024787522+0.0009118820
- ∑ i = 1 10 e z ′ = 1.6614304647 \sum_{i=1}^{10}e^{z'}= 1.6614304647 ∑i=110?ez′=1.6614304647
- 5、計(jì)算Softmax
- 將每個(gè)指數(shù)除以總和,得到概率分布
- s o f t m a x ( z i ) = e z ′ ∑ i = 1 10 e z ′ softmax(z_i) = \frac{e^{z'}}{\sum_{i=1}^{10}e^{z'}} softmax(zi?)=∑i=110?ez′ez′?
sum_exp_z_prime = np.sum(exp_z_prime)
softmax_output = exp_z_prime / sum_exp_z_prime
print(softmax_output)
- 輸出結(jié)果為:[0.0299663871,0.0814570854,0.2214233150,0.6018909737,0.0299663871,0.0181755325,0.0110240177,0.0040555095,0.0014919386,0.0005488535]
- 6、結(jié)果解釋
- 第四個(gè)元素的概率最高為0.6018909737,所以預(yù)測(cè)為 數(shù)字 3
- 其他數(shù)字概率較小,所以表示其他數(shù)字的可能性較小
2.4.6 Softmax的注意事項(xiàng)
- 輸入值范圍:Softmax函數(shù)的輸入值可以是任意實(shí)數(shù),但通常在實(shí)際應(yīng)用中,輸入值是經(jīng)過神經(jīng)網(wǎng)絡(luò)計(jì)算得到的logits(即未歸一化的得分或置信度)。
- 數(shù)值穩(wěn)定性:在計(jì)算Softmax函數(shù)時(shí),由于涉及到指數(shù)運(yùn)算,可能會(huì)出現(xiàn)數(shù)值溢出或下溢的問題。為了解決這個(gè)問題,通常會(huì)對(duì)輸入值進(jìn)行適當(dāng)?shù)目s放或平移處理。
- 互斥類別:Softmax函數(shù)適用于類別互斥的情況,即每個(gè)樣本只能屬于一個(gè)類別。如果問題是多標(biāo)簽分類(即一個(gè)樣本可能屬于多個(gè)類別),則需要使用其他方法,如sigmoid函數(shù)或其他多標(biāo)簽分類算法。
三、參數(shù)初始化
導(dǎo)包:
import torch
import torch.nn.functional as F
import torch.nn as nn
3.1 均勻分布初始化
- 權(quán)重參數(shù)初始化從區(qū)間均勻隨機(jī)取值。即在( ? 1 d , 1 d \frac{-1}{\sqrtieo6y2aa},\frac{1}{\sqrtieo6y2aa} d??1?,d?1? )均勻分布中生成當(dāng)前神經(jīng)元的權(quán)重,其中 d d d 為每個(gè)神經(jīng)元的輸入數(shù)量
代碼演示:
linear = nn.Linear(5, 3)
# 從0-1均勻分布產(chǎn)生參數(shù)
nn.init.uniform_(linear.weight)
print(linear.weight.data)
3.2 正態(tài)分布初始化
- 隨機(jī)初始化從均值為0,標(biāo)準(zhǔn)差是1的高斯分布中取樣,使用一些很小的值對(duì)參數(shù) W W W 進(jìn)行初始化
代碼演示:
linear = nn.Linear(5, 3)
nn.init.normal_(linear.weight, mean=0, std=1)
print(linear.weight.data)
3.3 全0初始化
- ? 將神經(jīng)網(wǎng)絡(luò)中的所有權(quán)重參數(shù)初始化為 0
代碼演示:
linear = nn.Linear(5, 3)
nn.init.zeros_(linear.weight)
print(linear.weight.data)
3.4 全1初始化
- ? 將神經(jīng)網(wǎng)絡(luò)中的所有權(quán)重參數(shù)初始化為 1
代碼演示:
linear = nn.Linear(5, 3)
nn.init.ones_(linear.weight)
print(linear.weight.data)
3.5 固定值初始化
- 將神經(jīng)網(wǎng)絡(luò)中的所有權(quán)重參數(shù)初始化為某個(gè)固定值
代碼演示:
linear = nn.Linear(5, 3)
nn.init.constant_(linear.weight, 5) # 里邊寫 幾 就是 用哪個(gè)值初始化
print(linear.weight.data)
3.6 Kaiming 初始化,也叫做 HE 初始化
3.6.1 正態(tài)化的Kaiming 初始化
- s t d d e v = 2 f a n i n stddev = \sqrt{\frac{2}{fan_{in}}} stddev=fanin?2??
- f a n i n fan_{in} fanin? 輸入神經(jīng)元的個(gè)數(shù)
代碼演示:
# kaiming 正態(tài)分布初始化
linear = nn.Linear(5, 3)
nn.init.kaiming_normal_(linear.weight)
print(linear.weight.data)
3.6.2 均勻分布的Kaiming 初始化
- f a n i n fan_{in} fanin? 輸入神經(jīng)元的個(gè)數(shù)
- 它從 [ ? l i m i t , l i m i t ] [-limit,limit] [?limit,limit] 中的均勻分布中抽取樣本, l i m i t limit limit 是 6 f a n i n \sqrt{\frac{6}{fan_{in}}} fanin?6??
代碼演示:
# kaiming 均勻分布初始化
linear = nn.Linear(5, 3)
nn.init.kaiming_uniform_(linear.weight)
print(linear.weight.data)
3.7 Xavier 初始化,也叫做 Glorot初始化
3.7.1 正態(tài)化的Xavier初始化
- s t d d e v = 2 f a n i n + f a n o u t stddev = \sqrt{\frac{2}{fan_{in}+fan_{out}}} stddev=fanin?+fanout?2??
- f a n i n fan_{in} fanin? 輸入神經(jīng)元的個(gè)數(shù)
- f a n o u t fan_{out} fanout? 輸出的神經(jīng)元個(gè)數(shù)
代碼演示:
# xavier 正態(tài)分布初始化
linear = nn.Linear(5, 3)
nn.init.xavier_normal_(linear.weight)
print(linear.weight.data)
3.7.2 均勻分布的Xavier初始化
- 它從 [ ? l i m i t , l i m i t ] [-limit,limit] [?limit,limit] 中的均勻分布中抽取樣本, l i m i t limit limit 是 6 f a n i n + f a n o u t \sqrt{\frac{6}{fan_{in}+fan_{out}}} fanin?+fanout?6??
代碼演示:
# xavier 均勻分布初始化
linear = nn.Linear(5, 3)
nn.init.xavier_uniform_(linear.weight)
print(linear.weight.data)
四、構(gòu)建簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)
- 案例:我們構(gòu)建如下網(wǎng)絡(luò)
- 要求如下:
- 第1個(gè)隱藏層:權(quán)重初始化采用標(biāo)準(zhǔn)化的xavier初始化 激活函數(shù)使用sigmoid
- 第2個(gè)隱藏層:權(quán)重初始化采用標(biāo)準(zhǔn)化的He初始化 激活函數(shù)采用relu
- out輸出層線性層,采用 softmax 做數(shù)據(jù)分類輸出
代碼演示:
"""
在pytorch中定義深度神經(jīng)網(wǎng)絡(luò)其實(shí)就是層堆疊的過程,繼承自nn.Module,實(shí)現(xiàn)兩個(gè)方法:1、__init__方法中定義網(wǎng)絡(luò)中的層結(jié)構(gòu),主要是全連接層,并進(jìn)行初始化2、forward方法,在實(shí)例化模型的時(shí)候,底層會(huì)自動(dòng)調(diào)用該函數(shù)。該函數(shù)中可以定義學(xué)習(xí)率,為初始化定義的layer傳入數(shù)據(jù)等。
"""
import torch
import torch.nn as nn
from torchsummary import summary # 計(jì)算模型參數(shù),查看模型結(jié)構(gòu), pip install torchsummary# 創(chuàng)建神經(jīng)網(wǎng)絡(luò)模型類
class Model(nn.Module):# 初始化屬性值def __init__(self):super(Model, self).__init__() # 調(diào)用父類的初始化屬性值self.linear1 = nn.Linear(3, 3) # 創(chuàng)建第一個(gè)隱藏層模型, 3個(gè)輸入特征,3個(gè)輸出特征nn.init.xavier_normal_(self.linear1.weight) # 初始化權(quán)# 創(chuàng)建第二個(gè)隱藏層模型, 3個(gè)輸入特征(上一層的輸出特征),2個(gè)輸出特征self.linear2 = nn.Linear(3, 2)# 初始化權(quán)重nn.init.kaiming_normal_(self.linear2.weight)# 創(chuàng)建輸出層模型self.out = nn.Linear(2, 2)# 創(chuàng)建前向傳播方法,自動(dòng)執(zhí)行forward()方法def forward(self, x):# 數(shù)據(jù)經(jīng)過第一個(gè)線性層x = self.linear1(x)# 使用sigmoid激活函數(shù)x = torch.sigmoid(x)# 數(shù)據(jù)經(jīng)過第二個(gè)線性層x = self.linear2(x)# 使用relu激活函數(shù)x = torch.relu(x)# 數(shù)據(jù)經(jīng)過輸出層x = self.out(x)# 使用softmax激活函數(shù)# dim=-1:每一維度行數(shù)據(jù)相加為1x = torch.softmax(x, dim=-1)return xif __name__ == "__main__":# 實(shí)例化model對(duì)象my_model = Model()# 隨機(jī)產(chǎn)生數(shù)據(jù)my_data = torch.randn(5, 3)print("mydata shape", my_data.shape)# 數(shù)據(jù)經(jīng)過神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練output = my_model(my_data)print("output shape-->", output.shape)# 計(jì)算模型參數(shù)# 計(jì)算每層每個(gè)神經(jīng)元的w和b個(gè)數(shù)總和summary(my_model, input_size=(3,), batch_size=5) # 查看模型參數(shù)print("======查看模型參數(shù)w和b======")for name, parameter in my_model.named_parameters():print(name, parameter)
總結(jié)
- 我們通過學(xué)習(xí)了激活函數(shù)和參數(shù)初始化后,我們能實(shí)現(xiàn)搭建一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)。