pytorch勾配蓄積逆伝播

従来のトレーニング機能であるバッチは、次のようにトレーニングされます。

for i,(images,target) in enumerate(train_loader):
    # 1. input output
    images = images.cuda(non_blocking=True)
    target = torch.from_numpy(np.array(target)).float().cuda(non_blocking=True)
    outputs = model(images)
    loss = criterion(outputs,target)

    # 2. backward
    optimizer.zero_grad()   # reset gradient
    loss.backward()
    optimizer.step()            
  1. 損失の取得:画像とラベルを入力し、推論によって予測値を計算し、損失関数を計算します。
  2. オプティマイザー.zero_grad()は過去の勾配をクリアします。
  3. loss.backward()逆伝播、現在の勾配を計算します。
  4. オプティマイザー.step()は、勾配に従ってネットワークパラメーターを更新します

簡単に言えば、データのバッチで提供され、勾配を1回計算し、ネットワークを1回更新します。

 

勾配累積の使用は次のように記述されます。

for i,(images,target) in enumerate(train_loader):
    # 1. input output
    images = images.cuda(non_blocking=True)
    target = torch.from_numpy(np.array(target)).float().cuda(non_blocking=True)
    outputs = model(images)
    loss = criterion(outputs,target)

    # 2.1 loss regularization
    loss = loss/accumulation_steps   
    # 2.2 back propagation
    loss.backward()
    # 3. update parameters of net
    if((i+1)%accumulation_steps)==0:
        # optimizer the net
        optimizer.step()        # update parameters of net
        optimizer.zero_grad()   # reset gradient
  1. 損失の取得:画像とラベルを入力し、推論によって予測値を計算し、損失関数を計算します。
  2. loss.backward()逆伝播、現在の勾配を計算します。
  3. 勾配をクリアせずに、手順1〜2を複数回繰り返して、勾配が既存の勾配に累積されるようにします。
  4. 勾配が特定の回数蓄積された後、最初にoptimizer.step()は蓄積された勾配に従ってネットワークパラメータを更新し、次にoptimizer.zero_grad()は過去の勾配をクリアして次の勾配蓄積の波に備えます。

要約:勾配累積とは、1バッチのデータを取得するたびに、勾配を1回計算し、勾配がクリアされず、継続的に累積されることを意味します。一定の回数が経過すると、ネットワークパラメータが累積勾配に従って更新され、次に勾配がクリアされ、次のサイクル。

特定の条件下では、バッチサイズが大きいほど、トレーニング効果が高くなります。グラデーションの累積により、バッチサイズの偽装拡張が実現されます。accumulation_stepsが8の場合、バッチサイズ「偽装」は8倍に拡張されます。これは、ビデオメモリの制限を解決するための乞食ラボの1つです。良いトリックです。使用するときは注意が必要であり、学習率を適切に拡大する必要があります。

おすすめ

転載: blog.csdn.net/wi162yyxq/article/details/106054613