iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0
AI & Data

30天深度學習-從零到英雄系列 第 18

權重初始化

  • 分享至 

  • xImage
  •  

前言:
今天要跟大家介紹權重初始化(Weight Initialization),並且嘗試用不同權重初始化方式來大帶大家認識。


權重初始化

權重初始化通常會是解決神經元飽和的方法之一。當神經元使用某些激活函數(如Sigmoid或Tanh)時,它們在輸入值較高或較低(極端值)的情況下容易飽和(這部分我們在第十天Sigmoid 函數有稍微提到,忘記的話可以再回去複習),這可能導致梯度消失問題(梯度消失的問題我們也會在之後跟大家說明如何解決),使得神經網路難以訓練。

值得注意的地方是,選擇權重初始化方法應該根據模型結構和所使用的激活函數來考慮。當使用Sigmoid或Tanh激活函數時,不建議將權重初始化設置得很大,因為這樣做可能會在初始階段使神經元的輸出超出激活函數的飽和區域,進而導致梯度爆炸問題(梯度變得非常大,導致權重更新極端,訓練變得不穩定)。

這邊會帶大家用兩種分布去設定權重初始值,一種是標準常態分佈,另一種是Glorot分佈(明天會跟大家介紹),話不多說直接看程式碼!


有寫註解的地方為有新增程式碼的地方,記得補上喔!

from tensorflow.keras.datasets import mnist  
from tensorflow.keras.layers import Dense,Activation #Activation(激活函數層)
from tensorflow.keras.models import Sequential
from tensorflow.keras import optimizers    
from tensorflow.keras.utils import plot_model  
from tensorflow.keras.utils import to_categorical  
from tensorflow.keras.initializers import Zeros,RandomNormal #用於初始化神經網絡層權重的初始化器
import numpy as np 
import matplotlib.pyplot as plt 


這邊開始設定我們的權重

b_init=Zeros() #我們將密集層的偏值(bias)設為0,Zeros()初始化器將偏差初始化為0。
w_init=RandomNormal(stddev=1.0) #設標準差為1,用標準常態分佈來初始化權重

#建立輸入資料跟密集層的神經元
n_dense=256
n_input=784

建構神經網路

model=Sequential()
model.add(Dense(n_dense,
                input_shape=(784,),
#這邊也可以寫input_dim=n_input,它們的作用是相同的,用於指定輸入層的特徵數量
                kernel_initializer=w_init 
#kernel_initializer : 指定權重參數 w 初始值,前面我們設定為標準常態分佈
                bias_initializer=b_init))
#bias_initializer : 指定偏值參數 b 初始值,前面我們設定為0
model.add(Activation('sigmoid'))

補充說明:model.add(Dense(10, activation='sigmoid'))model.add(Activation('sigmoid'))

  1. model.add(Dense(10, activation='sigmoid'))

    • 添加了一個全連接層(Dense層)到模型中,該層具有10個神經元。
    • activation='sigmoid' 參數指定了該層使用Sigmoid激活函數。該層的神經元將使用Sigmoid函數來計算其輸出。
  2. model.add(Activation('sigmoid'))

    • 這個語句添加了一個獨立的激活函數層(Activation層)到模型中。
    • Activation('sigmoid') 指定了該激活層使用Sigmoid激活函數,但它不包含神經元。它只是將前一層的輸出通過Sigmoid函數進行轉換。

第一行我們把隨機產生的浮點數當作輸入資料,第二行為資料傳入密集層

x=np.random.random((1,n_input)) #n_input=784,生成784個隨機數,每個數字都是在0到1之間的隨機浮點數
a=model.predict(x) #執行神經網絡模型的預測操作,模型對 x 的預測結果存在變數a

可以從圖片看出來大部分的數值都會0跟1兩端靠攏,說明神經層中大部分的神經元都已經飽和,言外之意這會使得我們訓練變得困難,明天就來帶大家看不同權重初始化的結果。

_=plt.hist(np.transpose(a)) #直方圖呈現,統計數值分佈

https://ithelp.ithome.com.tw/upload/images/20230930/20161909teCr6boup6.png


最後我們來看用這個權重初始化跑MNIST手寫資料集的結果,這次設定訓練20次,跑出來成效蠻差的正確率只有42%

#匯入套件
from tensorflow.keras.datasets import mnist     
from tensorflow.keras.models import Sequential     
from tensorflow.keras.layers import Dense, Activation   
from tensorflow.keras import optimizers    
from tensorflow.keras.utils import plot_model    
from tensorflow.keras.utils import to_categorical    
import matplotlib.pyplot as plt    
import numpy as np       
from tensorflow.keras.initializers import Zeros, RandomNormal   

#下載mnist資料集
(X_train, y_train), (X_test, y_test)=mnist.load_data()

#資料預處理
X_train=X_train.reshape(60000, 784).astype('float32')   
X_test=X_test.reshape(10000, 784).astype('float32')         
X_train /= 255            
X_test /= 255               
y_train=to_categorical(y_train, 10)    
y_test=to_categorical(y_test, 10)        

#建構神經網路
b_init=Zeros()                 
w_init=RandomNormal()    
model=Sequential()   
model.add(Dense(64,input_dim=784,kernel_initializer=w_init,bias_initializer=b_init))   
model.add(Activation('sigmoid'))                  
model.add(Dense(10, activation='softmax'))    

#編譯模型
model.compile(loss='mean_squared_error',    
                        optimizer=optimizers.SGD(learning_rate=0.01),      
                        metrics='accuracy') 

#訓練模型
model.fit(X_train, y_train, batch_size=128, epochs=20, verbose=1,validation_data=(X_test, y_test))   

上一篇
升級吧!神經網路模型
下一篇
Glorot分佈
系列文
30天深度學習-從零到英雄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言