Pytroch モデルの重みの初期化

目次

1 コンセプト

2 重みの初期化方法

2.1 定数の初期化

2.2 一様分布の初期化

2.3 正規分布の初期化

2.4 ザビエル一様分布

2.5 ザビエル正規分布

2.6 開明一様分布

2.7 開明正規分布

2.8 恒等行列の初期化

2.9 直交初期化

2.10 スパース初期化

2.11 ディラック デルタ関数の初期化

3 つの Python の例


1 コンセプト

        重みの初期化とは、ネットワーク モデルのトレーニング前に各ノードの重みとバイアスを初期化するプロセスを指します。正しく初期化するとモデルの収束が速くなり、モデルのトレーニング速度が向上します。初期化が不適切だと、勾配が消失する可能性があります。または、勾配が爆発的に増加し、最終的にはモデルをトレーニングできなくなります。

        上の図に示す基本的な CNN ネットワーク構造では、データがネットワーク構造内を流れるとき、次の式が成り立ちます (デフォルトではバイアスなし)。

 

        バックプロパゲーションのプロセスでは、合成関数の導出により、連鎖導出ルールに従って 2 つの導関数セットが存在します。1 つは損失関数 Cost から Z への導関数で、もう 1 つは次の導関数です。損失関数を W に、

1. 状態 Z に関する損失関数の勾配:

2. W に関する損失関数の勾配:

        ネットワーク構造では、パラメーターの初期化が、ネットワークが良好な結果をトレーニングできるかどうか、またはネットワークがどれだけ早く収束できるかに関係していることがわかります。したがって、重みの初期化には次の要件があります。

  1. パラメーターをすべて 0 に初期化することも、すべてを 1 に初期化することも、すべてを同じ値に初期化することもできません (バックプロパゲーション中の勾配の更新値は同じです)。
  2. パラメータの初期化値は大きすぎることはできません (活性化関数が sigmoid と Tanh の場合、パラメータが大きすぎると勾配が消えます)。
  3. パラメーターの初期化値は小さすぎることはできません (活性化関数が relu と sigmoid の場合、パラメーターが小さすぎると勾配が消えます)。

1. すべてのパラメータは 0 または同じ数値に初期化されます。

        最も単純な初期化方法は、すべてのパラメータを 0 または定数に初期化することですが、この機能を使用すると、ネットワーク内のすべてのニューロンが同じ機能を学習します。
ニューラル ネットワーク内に 2 つのニューロンを持つ隠れ層が 1 つだけあると仮定すると、バイアス パラメーターはbias=0に初期化され、重み行列は定数 α に初期化されます。ネットワークの入力は (x1, x2) で、隠れ層で使用される活性化関数は ReLU であるため、隠れ層の各ニューロンの出力は relu(αx1+αx2) になります。これは、損失関数の値については、2 つのニューロンの影響が同じであり、バックプロパゲーションのプロセスにおける対応するパラメーターの勾配値も同じであるという事実につながります。トレーニング プロセス、2 つのニューロン パラメーターは常に一貫しており、学習される特徴は同じです。これは、ネットワーク全体で 1 つのニューロンのみに相当します。

2. 初期化が大きすぎるか小さすぎる

        重みの初期値が大きすぎると、勾配が爆発してネットワークが収束しません。重みの初期値が小さすぎると、勾配が消滅し、ネットワークの収束が遅くなります。極小値に収束します。重み値の初期値が大きすぎると、重みパラメータに対する損失関数の勾配値が非常に大きくなり、勾配降下法によりパラメータが更新されるたびにパラメータの更新の大きさも大きくなり、最小値付近の発振における損失関数の値が得られます。一方、初期値が小さすぎると、重みパラメータに対する損失の傾きが非常に小さくなり、パラメータが更新されるたびに更新範囲も非常に小さくなるため、損失が大きくなってしまいます。収束が非常に遅い、または最小値に収束する前に、極小値が収束しました。

2 重みの初期化方法

2.1 定数の初期化

        入力テンソルまたは変数を val の値で埋めます。

torch.nn.init.constant_(tensor, val)

パラメータ:

tensor – n 次元の torch.Tensor または autograd.Variable
val – テンソルを埋める値

使用:

w = torch.empty(3, 5)
nn.init.constant_(w, 0.3)

2.2 一様分布の初期化

        入力テンソルまたは変数を入力して、一様分布 U(a, b) から値を生成します

torch.nn.init.uniform_(テンソル、a=0、b=1)

パラメータ:

テンソル - n 次元トーチ。テンソル
a - 一様分布の下限
b - 一様分布の上限

2.3 正規分布の初期化

        入力テンソルまたは変数を入力して、指定された平均と標準偏差を持つ正規分布 N(mean, std) から値を生成します

torch.nn.init.normal_(テンソル、平均=0、標準=1)

パラメータ:

tensor – n 次元のトーチ。Tensor
means – 正規分布の平均
std – 正規分布の標準偏差

2.4 ザビエル一様分布

        一様分布から値を生成して、入力テンソルまたは変数を埋めます。結果として得られるテンソルの値は、U(-a, a) からサンプリングされます (a= ゲイン * sqrt( 2/(fan_in + fan_out))* sqrt(3)。このメソッドは、Glorot 初期化とも呼ばれます。

torch.nn.init.xavier_uniform_(テンソル、ゲイン=1)

パラメータ:

テンソル – n 次元トーチ。テンソル
ゲイン – オプションのスケーリング係数

2.5 ザビエル正規分布

        入力テンソルまたは変数を満たすために正規分布から値を生成します。結果として得られるテンソルの値は、平均 0 および標準偏差ゲイン * sqrt(2/(fan_in + fan_out)) の正規分布からサンプリングされます。Glorot 初期化とも呼ばれます。

torch.nn.init.xavier_normal_(テンソル、ゲイン=1)

パラメータ:

テンソル – n 次元トーチ。テンソル
ゲイン – オプションのスケーリング係数

2.6 開明一様分布

        一様分布から値を生成して、入力テンソルまたは変数を埋めます。結果のテンソルの値は U(-bound,bound) からサンプリングされます。

torch.nn.init.kaiming_uniform_(tensor、a=0、mode='fan_in'、nonlinearity='leaky_relu')

パラメータ:

tensor – n 次元の torch.Tensor
a – この層の後に使用される整流器の負の傾斜係数 (ReLU のデフォルト値は 0)
モード – fan_in は順伝播中の重み分散のサイズを保持し、fan_out は順伝播中の重み分散のサイズを保持します。バックプロパゲーション。デフォルト: fan_in
nonlinearity – 非線形関数、relu および Leaky_relu が推奨、デフォルトは Leaky_relu

2.7 開明正規分布

        入力テンソルまたは変数を満たすために正規分布から値を生成します。結果として得られるテンソルの値がサンプリングされる正規分布。

torch.nn.init.kaiming_normal_(tensor、a=0、mode='fan_in'、nonlinearity='leaky_relu')

パラメータ:

tensor – n 次元の torch.Tensor
a – この層の後に使用される整流器の負の傾斜係数 (ReLU のデフォルト値は 0)
モード – fan_in は順伝播中の重み分散のサイズを保持し、fan_out は順伝播中の重み分散のサイズを保持します。バックプロパゲーション。デフォルト: fan_in
nonlinearity – 非線形関数、relu および Leaky_relu が推奨、デフォルトは Leaky_relu

2.8 恒等行列の初期化

        2D 入力テンソルまたは変数に単位行列を入力します。線形レイヤーにできるだけ多くの入力フィーチャを保存します。

torch.nn.init.eye_(テンソル)

パラメータ:

tensor – 2D トーチ.Tensor

2.9 直交初期化

        入力テンソルまたは変数を (半) 直交行列で満たします。

torch.nn.init.orthogonal_(テンソル、ゲイン=1)

パラメータ:

tensor – n 次元の torch.Tensor または autograd.Variable、n>=2
ゲイン – オプション

2.10 スパース初期化

        2 次元の入力テンソルまたは変数を疎行列として入力します。ここで、非ゼロ要素は、平均 0 および標準偏差 std の正規分布に従って生成されます。

torch.nn.init.sparse_(テンソル、スパース性、std=0.01)

パラメータ:

tensor – n 次元の torch.Tensor または autograd.Variable
sparsity – ゼロに設定する必要がある各列の要素の割合
std – ゼロ以外の値を生成するために使用される正規分布の標準偏差

2.11 ディラック デルタ関数の初期化

入力 torch.Tensor にディラック デルタ関数を埋めます。

torch.nn.init.dirac_(テンソル)

パラメータ:

tensor – {3, 4, 5} 次元の torch.Tensor

3 つの Python の例

import torch.nn as nn
import torch

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 3, (3, 3), stride=(1, 1), padding=1)
        self.bn1 = nn.BatchNorm2d(3)
        self.relu = nn.ReLU()
    def forward(self, x):
        x = self.relu(self.bn1(self.conv1(x)))

        return x
# init.uniform  a, b均值分布的上下限
class model_param_init(nn.Module):
    def __init__(self, model):
        super().__init__()
        assert isinstance(model, nn.Module), 'model not a class nn.Module'
        self.net = model
        self.initParam()
    def initParam(self):
        for param in self.net.parameters():
            # nn.init.zeros_(param)
            # nn.init.ones_(param)
            # nn.init.normal_(param, mean=0, std=1)
            # nn.init.uniform_(param, a=0, b=1)
            # nn.init.constant_(param, val=1)   # 将所有权重初始化为1
            # nn.init.eye_(param)  # 只能将二维的tensor初始化为单位矩阵
            # nn.init.xavier_uniform_(param, gain=1)  # Glorot初始化  得到的张量是从-a——a中采用的
            # nn.init.xavier_normal_(param, gain=1)   # 得到的张量是从0-std采样的
            nn.init.kaiming_normal_(param, a=0, mode='fan_in', nonlinearity='leaky_relu') # he初始化方法
            # nn.init.kaiming_uniform_(param)

if __name__ == '__main__':
    net = Net()
    net = model_param_init(net)
    for param in net.parameters():
        print(param)
    # 按照参数更改权重
    for name, param in net.named_parameters():
        if name == net.conv1.weight:  # 指定更改某层的权重值
            nn.init.dirac_(param, groups=1) # 保留卷积层通道的值
        print(param)

PyTorch 学習のための 11 の重み初期化メソッド_51CTO Blog_pytorch 重みの初期化

 Pytroch はモデルの重みの初期化を実行します_pytorch の重みの初期化_Xiao Zhou のブログ、wind-CSDN ブログと同じくらい無料

 Pytorch 研究ノート 9: 重みの初期化_Dear_Lin のブログ-CSDN ブログ

おすすめ

転載: blog.csdn.net/weixin_39910711/article/details/130743178