概要
Pytroch に実装されているパラメータの初期化方法について解説します。
torch.nn.init.uniform_ – 一様分布
torch.nn.init.uniform_(tensor, a=0.0, b=1.0)
はテンソルを $[a, b]$ の一様分布で初期化する関数です。
import torch
x = torch.empty(10)
torch.nn.init.uniform_(x, a=0, b=5)
print(x)
tensor([0.0789, 2.7473, 3.9215, 3.5201, 3.9573, 4.4034, 1.6722, 2.9046, 4.6709, 2.1375])
torch.nn.init.normal_ – 正規分布
torch.nn.init.normal_(tensor, mean=0.0, std=1.0)
はテンソルを平均 mean
、分散 std**2
の正規分布で初期化する関数です。
import torch
x = torch.empty(10)
torch.nn.init.normal_(x, mean=0, std=1)
print(x)
tensor([-0.8716, 1.1498, -0.9712, 0.0973, -0.6591, 0.4944, 1.1363, -0.5743, -0.2399, 0.1864])
torch.nn.init.constant_ – 定数
torch.nn.init.constant_(tensor, val)
はテンソルを定数 val
で初期化する関数です。
import torch
x = torch.empty(10)
torch.nn.init.constant_(x, 1)
print(x)
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
torch.nn.init.ones_ – 定数1
torch.nn.init.ones_(tensor)
はテンソルを定数1で初期化する関数です。
import torch
x = torch.empty(10)
torch.nn.init.ones_(x)
print(x)
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
torch.nn.init.zeros_ – 定数0
torch.nn.init.zeros_(tensor)
はテンソルを定数0で初期化する関数です。
import torch
x = torch.empty(10)
torch.nn.init.zeros_(x)
print(x)
tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
torch.nn.init.eye_ – 単位行列
torch.nn.init.eye_(tensor)
は2次元のテンソルを単位行列で初期化する関数です。
import torch
x = torch.empty(3, 3)
torch.nn.init.eye_(x)
print(x)
x = torch.empty(5, 7)
torch.nn.init.eye_(x)
print(x)
tensor([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) tensor([[1., 0., 0., 0., 0., 0., 0.], [0., 1., 0., 0., 0., 0., 0.], [0., 0., 1., 0., 0., 0., 0.], [0., 0., 0., 1., 0., 0., 0.], [0., 0., 0., 0., 1., 0., 0.]])
torch.nn.init.dirac_ – ディラックのデルタ関数
torch.nn.init.dirac_(tensor)
は3,4、5次元のテンソルをディラックのデルタ関数で初期化する関数です。
import torch
x = torch.empty(3, 3, 3)
torch.nn.init.dirac_(x)
print(x)
tensor([[[0., 1., 0.], [0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 1., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.], [0., 1., 0.]]])
torch.nn.init.xavieruniform – Xavier の方法 (一様分布)
torch.nn.init.xavier_uniform_(tensor, gain=1.0)
は Xavier の方法 (Glorot 初期化ともいう) の一様分布で初期化する関数です。
としたとき、$[-a, a]$ の一様分布で初期化を行うものです。
fan_in、fan_out について
畳み込み層の重みの形状を (out_channels, in_channels, *kernel_size)
としたとき、fan_in、fan_out とは次のように計算される値です。
ただし、kernel_size
はカーネルのサイズを表すタプルで Conv1d なら (k1,)
、Conv2d なら (k1, k2)
、Conv3d なら (k1, k2, k3)
になります。prod
は累乗 (例: prod((k1, k2, k3)) = k1 * k2 * k3
) を表します。
fan_in = in_channels * prod(kernel_size)
fan_out = out_channels * prod(kernel_size)
import math
def calculate_fan_in_and_fan_out(tensor):
assert tensor.dim() >= 3
in_channels = tensor.size(1)
out_channels = tensor.size(0)
kernel_size = math.prod(tensor.size()[2:])
fan_in = in_channels * kernel_size
fan_out = out_channels * kernel_size
return fan_in, fan_out
conv = nn.Conv1d(in_channels=5, out_channels=10, kernel_size=3)
fan_in, fan_out = calculate_fan_in_and_fan_out(conv.weight)
print(f"Conv1d shape: {conv.weight.shape}, fan_in: {fan_in}, fan_out: {fan_out}")
conv = nn.Conv2d(in_channels=5, out_channels=10, kernel_size=3)
fan_in, fan_out = calculate_fan_in_and_fan_out(conv.weight)
print(f"Conv2d shape: {conv.weight.shape}, fan_in: {fan_in}, fan_out: {fan_out}")
conv = nn.Conv3d(in_channels=5, out_channels=10, kernel_size=3)
fan_in, fan_out = calculate_fan_in_and_fan_out(conv.weight)
print(f"Conv3d shape: {conv.weight.shape}, fan_in: {fan_in}, fan_out: {fan_out}")
Conv1d shape: torch.Size([10, 5, 3]), fan_in: 15, fan_out: 30 Conv2d shape: torch.Size([10, 5, 3, 3]), fan_in: 45, fan_out: 90 Conv3d shape: torch.Size([10, 5, 3, 3, 3]), fan_in: 135, fan_out: 270
import torch.nn as nn
conv = nn.Conv1d(in_channels=3, out_channels=4, kernel_size=3)
torch.nn.init.xavier_uniform_(conv.weight, gain=1.0)
Parameter containing: tensor([[[-0.2460, 0.2175, -0.5319], [-0.3799, -0.4568, 0.2370], [ 0.3525, -0.3530, -0.4080]], [[-0.4691, -0.1311, -0.4520], [ 0.1070, 0.1376, -0.3987], [ 0.3074, 0.2339, 0.3000]], [[-0.2951, -0.3920, 0.1775], [ 0.0544, 0.4971, 0.0906], [-0.5228, -0.0251, 0.3910]], [[-0.4156, -0.0423, 0.0640], [ 0.0202, 0.5138, 0.1344], [ 0.4507, 0.4491, -0.4352]]], requires_grad=True)
torch.nn.init.xaviernormal – Xavier の方法 (正規分布)
torch.nn.init.xavier_normal_(tensor, gain=1.0)
は Xavier の方法 (Glorot 初期化ともいう) の正規分布で初期化する関数です。
としたとき、平均0、分散 std**2
の正規分布で初期化する関数です。
import torch.nn as nn
conv = nn.Conv1d(in_channels=3, out_channels=4, kernel_size=3)
torch.nn.init.xavier_normal_(conv.weight, gain=1.0)
Parameter containing: tensor([[[-0.2056, 0.0869, -0.0975], [ 0.0291, -0.0659, 0.1770], [-0.3691, 0.0374, 0.2935]], [[ 0.2736, 0.0647, 0.2943], [ 0.0235, -0.6853, 0.0501], [-0.0109, -0.1333, -0.1458]], [[ 0.1033, 0.3518, 0.0459], [ 0.2188, 0.3011, 0.9224], [ 0.0318, 0.2838, 0.2632]], [[-0.0945, 0.2279, -0.1813], [ 0.0975, -0.2411, -0.0182], [ 0.4383, -0.1586, -0.2009]]], requires_grad=True)
torch.nn.init.kaiminguniform – He の方法 (一様分布)
torch.nn.init.kaiming_uniform_(tensor, a=0, mode="fan_in", nonlinearity="leaky_relu")
は He の方法の一様分布で初期化する関数です。
としたとき、$[-a, a]$ の一様分布で初期化を行うものです。
import torch.nn as nn
conv = nn.Conv1d(in_channels=3, out_channels=4, kernel_size=3)
torch.nn.init.kaiming_uniform_(conv.weight, mode="fan_in", nonlinearity="relu")
Parameter containing: tensor([[[-0.5564, 0.2750, -0.4595], [ 0.5681, 0.4487, -0.6639], [ 0.1159, 0.2904, 0.4377]], [[-0.5020, 0.1849, 0.5438], [ 0.1629, 0.5750, -0.6051], [-0.5836, -0.0322, 0.0047]], [[ 0.7154, 0.2076, -0.2785], [-0.0636, -0.0628, -0.7857], [ 0.7187, 0.4702, 0.1969]], [[ 0.5643, 0.7418, -0.4367], [-0.2407, -0.3289, -0.6704], [-0.3830, -0.5113, 0.2795]]], requires_grad=True)
torch.nn.init.kaimingnormal – He の方法 (正規分布)
torch.nn.init.kaiming_normal_(tensor, a=0, mode="fan_in", nonlinearity="leaky_relu")
は He の方法の正規分布で初期化する関数です。
としたとき、平均0、分散 std**2
の正規分布で初期化する関数です。
import torch.nn as nn
conv = nn.Conv1d(in_channels=3, out_channels=4, kernel_size=3)
torch.nn.init.kaiming_normal_(conv.weight)
Parameter containing: tensor([[[-0.2056, 0.0869, -0.0975], [ 0.0291, -0.0659, 0.1770], [-0.3691, 0.0374, 0.2935]], [[ 0.2736, 0.0647, 0.2943], [ 0.0235, -0.6853, 0.0501], [-0.0109, -0.1333, -0.1458]], [[ 0.1033, 0.3518, 0.0459], [ 0.2188, 0.3011, 0.9224], [ 0.0318, 0.2838, 0.2632]], [[-0.0945, 0.2279, -0.1813], [ 0.0975, -0.2411, -0.0182], [ 0.4383, -0.1586, -0.2009]]], requires_grad=True)
各モジュールのデフォルトの初期化方法
畳み込み層
nn.Conv1d、nn.Conv2d、nn.Conv3d、nn.ConvTranspose1d、nn.ConvTranspose2d、nn.ConvTranspose3d が該当します。
- weight
- 重み
init.kaiming_uniform_(a=math.sqrt(5))
で初期化 (He の方法)
- bias
- バイアス
- $a = \frac{1}{\sqrt{\text{fan\_in}}}$ としたとき、$[-a, a]$ の一様分布で初期化
全結合層
nn.Linear が該当します。
- weight
- 重み
init.kaiming_uniform_(a=math.sqrt(5))
で初期化 (He の方法)
- bias
- バイアス
- $a = \begin{cases} \frac{1}{\sqrt{\text{fan\_in}}} &\text{if } fan\_in > 0 \\ 0 &\text{if } fan\_in \le 0 \end{cases}$ としたとき、$[-a, a]$ の一様分布で初期化
Batch Normalization
nn.BatchNorm1d、nn.BatchNorm2d、nn.BatchNorm3d が該当します。
- running_mean
- 平均
- 0で初期化
- running_var
- 分散
- 1で初期化
- weight
- 重み
- 1で初期化
- bias
- バイアス
- 0で初期化
コメント