這個代碼片段展示了如何用 PyTorch 初始化神經網絡的權重,具體使用的是截斷正態分布(truncated normal distribution)。截斷正態分布意味著生成的值會在一定范圍內截斷,以防止出現極端值。這里使用 torch.fmod
作為一種變通方法實現這一效果。
詳細解釋
1. 截斷正態分布
截斷正態分布是對正態分布的一種修改,確保生成的值在一定范圍內。具體來說,torch.fmod
函數返回輸入張量除以 2 的余數(即使得生成的值在 -2 到 2 之間)。
2. 權重初始化
代碼中,四個權重張量按不同的標準差(init_sd_first
, init_sd_middle
, init_sd_last
)從截斷正態分布中生成。具體的維度分別是:
- 第一層的權重張量形狀為
(x_dim, width + n_double)
- 中間層的兩個權重張量形狀為
(width, width + n_double)
- 最后一層的權重張量形狀為
(width, 1)
這些權重張量的生成方式如下:
initial_weights = [torch.fmod(torch.normal(0, init_sd_first, size=(x_dim, width + n_double)), 2),torch.fmod(torch.normal(0, init_sd_middle, size=(width, width + n_double)), 2),torch.fmod(torch.normal(0, init_sd_middle, size=(width, width + n_double)), 2),torch.fmod(torch.normal(0, init_sd_last, size=(width, 1)), 2)
]
示例代碼
下面是一個完整的示例,展示如何使用上述權重初始化方式初始化一個簡單的神經網絡:
import torch
import torch.nn as nnclass CustomModel(nn.Module):def __init__(self, x_dim, width, n_double, init_sd_first, init_sd_middle, init_sd_last):super(CustomModel, self).__init__()self.linear1 = nn.Linear(x_dim, width + n_double)self.linear2 = nn.Linear(width + n_double, width + n_double)self.linear3 = nn.Linear(width + n_double, width + n_double)self.linear4 = nn.Linear(width + n_double, 1)self.init_weights(init_sd_first, init_sd_middle, init_sd_last)def init_weights(self, init_sd_first, init_sd_middle, init_sd_last):self.linear1.weight.data = torch.fmod(torch.normal(0, init_sd_first, size=self.linear1.weight.size()), 2)self.linear2.weight.data = torch.fmod(torch.normal(0, init_sd_middle, size=self.linear2.weight.size()), 2)self.linear3.weight.data = torch.fmod(torch.normal(0, init_sd_middle, size=self.linear3.weight.size()), 2)self.linear4.weight.data = torch.fmod(torch.normal(0, init_sd_last, size=self.linear4.weight.size()), 2)def forward(self, x):x = torch.relu(self.linear1(x))x = torch.relu(self.linear2(x))x = torch.relu(self.linear3(x))x = self.linear4(x)return x# 定義超參數
x_dim = 10
width = 20
n_double = 5
init_sd_first = 0.1
init_sd_middle = 0.1
init_sd_last = 0.1# 初始化模型
model = CustomModel(x_dim, width, n_double, init_sd_first, init_sd_middle, init_sd_last)# 打印權重以驗證初始化
for name, param in model.named_parameters():if 'weight' in name:print(f"{name} initialized with values: \n{param.data}\n")
在這個示例中,我們定義了一個簡單的神經網絡 CustomModel
,并在 init_weights
方法中使用截斷正態分布初始化權重。通過打印權重,我們可以驗證它們是否按預期初始化。
說明
- 定義網絡:
CustomModel
包含四個線性層。第一層輸入尺寸為x_dim
,輸出尺寸為width + n_double
。接下來的兩層也是同樣的輸出尺寸,最后一層輸出尺寸為 1。 - 初始化權重:在
init_weights
方法中,我們使用截斷正態分布(通過torch.fmod
)初始化每一層的權重。我們對生成的正態分布取模 2,使得權重在 -2 和 2 之間。 - 打印參數:我們通過
model.named_parameters()
方法遍歷模型的參數,并打印每層參數的名稱、尺寸和前兩個值。
進一步說明
- 截斷正態分布:使用
torch.normal
生成正態分布的隨機數,然后使用torch.fmod
將這些隨機數的范圍限制在 -2 到 2 之間。 - 超參數:
x_dim
是輸入的特征維度,width
是每層的寬度(即神經元數量),n_double
是一個附加參數,用于增加每層的輸出維度。init_sd_first
、init_sd_middle
和init_sd_last
是每層權重初始化的標準差。
這個示例展示了如何使用截斷正態分布初始化神經網絡的權重,并打印每層的參數。如果您有更多問題或需要進一步的幫助,請告訴我!