%matplotlib inline
神経回路網
torch.nnパッケージを使用してニューラルネットワークを構築します。
すでに述べた話ではautograd
、nn
パッケージが依存autograd
袋をし、モデル導出を定義します。それぞれの層が含ま返す方法。nn.Module
forward(input)
output
例えば:
これは、入力を受け付ける簡単なフィードフォワードニューラルネットワークであり、その後、層ごとに転送され、最終的に計算された結果を出力します。
次のように典型的なニューラルネットワークのトレーニングプロセスは、次のとおりです。
- 定義はパラメータの数が学習(または重みと呼ばれる)することができます含まれているニューラルネットワークモデル。
- データセットを反復処理します。
- ニューラルネットワークによる入力を処理。
- 損失の計算(正しい値と出力の大きさとの差)。
- 勾配は、伝播ネットワークパラメータを逆にします。
- ネットワークの更新パラメータは、主に次のような単純な更新の原則を使用しました:
weight = weight - learning_rate * gradient
ネットワークの定義
ネットワークを定義するために開始します。
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 1 input image channel, 6 output channels, 5x5 square convolution
# kernel
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# an affine operation: y = Wx + b
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # all dimensions except the batch dimension
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
print(net)
Net(
(conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
(fc1): Linear(in_features=400, out_features=120, bias=True)
(fc2): Linear(in_features=120, out_features=84, bias=True)
(fc3): Linear(in_features=84, out_features=10, bias=True)
)
モデルで定義する必要がありforward
、関数backward
(勾配を計算するために使用される)関数はさautograd
自動的に作成。
あなたはできるforward
機能のテンソルのためのいずれかの操作を使用します。
net.parameters()
リターン・パラメータ(重み)と値のリストを学ぶことができます
params = list(net.parameters())
print(len(params))
print(params[0].size()) # conv1's .weight
10
torch.Size([6, 1, 5, 5])
試験の確率的入力32×32。
注:このネットワーク(LeNet)入力所望のサイズ32×32、MNISTを使用してデータセットはネットワーク、32×32にリサイズ画像を訓練する場合。
input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)
tensor([[ 0.1470, -0.0240, 0.0103, 0.0705, 0.0650, -0.0010, -0.0083, 0.0556,
-0.0686, -0.0675]], grad_fn=<AddmmBackward>)
勾配バッファのすべてのパラメータがクリアされ、その後、確率的勾配バックプロパゲーション:
net.zero_grad()
out.backward(torch.randn(1, 10))
注意
`` Torch.nn``支持少量のみ入力。`` Torch.nn``パッケージ全体は、単一のサンプルのサポートなしで少量のサンプルをサポートしています。例えば、 `` nn.Conv2d``は4次元テンソル、 `各寸法はsSamplesあるを受け入れる* nChannels *高さ*幅(サンプル数* H * Wチャネル)` `。あなたは、単一のサンプルを持っている場合は、単にinput.unsqueeze(0) ``別の次元を追加するために ``使用
先に進む前に、我々はこれまでのクラスで使用振り返ります。
レビュー:
torch.Tensor
:使用される自動コールbackward()
実装は自動勾配計算サポート多次元配列、
およびベクターを節約勾配 WRTnn.Module
:ニューラルネットワークモジュール。カプセル化パラメータ、移動するためにGPU上で実行する、エクスポート、ロードなどが挙げられます。nn.Parameter
:に割り当てる方法の一つの分散、Module
時間が、されて自動的にパラメータとして登録します。autograd.Function
:前方の自動導出を実装し、逆動作は、定義された各変数ノードの動作は、それぞれ、少なくとも1つの機能を作成しているTensor
操作のが作成に戻って作成するTensor
と、その履歴符号化の機能Function
ノード。
それは次のように焦点を当てました:
- ネットワークの定義
- 処理入力、backword呼び出します
左:
- 損失の計算
- ネットワークの重みを更新
損失関数
損失関数は、入力として一組(出力、ターゲット)を受け付ける目標値とネットワークの出力との間のどのくらいの差を推定するための値を算出します。
翻訳者注:ネットワークの出力のための出力は、実際の値をターゲット
nnのパッケージ、多くの異なった損失関数。
nn.MSELoss
損失は、出力とターゲットとの間に算出する比較的単純な関数である平均二乗誤差、
例えば:
output = net(input)
target = torch.randn(10) # 随机值作为样例
target = target.view(1, -1) # 使target和output的shape相同
criterion = nn.MSELoss()
loss = criterion(output, target)
print(loss)
tensor(0.7241, grad_fn=<MseLossBackward>)
あなたはそれを使用している場合今、.grad_fn
一緒にプロパティをloss
後方へ移動方向下図のように、あなたは、計算マップが表示されます。
::
input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d
-> view -> linear -> relu -> linear -> relu -> linear
-> MSELoss
-> loss
だから、私たちが呼ぶときloss.backward()
、全体のグラフが区別され
WRTに損失を、としているグラフのすべてのテンソルrequires_grad=True
自分のしているだろう.grad
テンソルは、勾配で蓄積しました。
説明のため、私たちは後方にいくつかの手順に従ってみましょう:
print(loss.grad_fn) # MSELoss
print(loss.grad_fn.next_functions[0][0]) # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0]) # ReLU
<MseLossBackward object at 0x0000001FCC3CEEB8>
<AddmmBackward object at 0x0000001FCC3CEBE0>
<AccumulateGrad object at 0x0000001FCC3CEEB8>
逆伝搬
伝播を、エラーが戻って取得するために)(loss.backward呼び出します。
しかし、既存の勾配、または勾配をクリアする必要性を呼び出す前に、既存のグラデーションに蓄積されます。
今、我々は)(loss.backward呼び出し、バックプロパゲーションの前と後の偏差(バイアス)CONV1アイテム勾配層を表示します。
net.zero_grad() # 清除梯度
print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)
loss.backward()
print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)
conv1.bias.grad before backward
tensor([0., 0., 0., 0., 0., 0.])
conv1.bias.grad after backward
tensor([-0.0024, 0.0044, -0.0027, 0.0066, -0.0034, 0.0067])
損失関数を使用する方法
後で読みます
nn
パケットは、ビルディングブロックと損失の機能ブロックを構成するニューラルネットワークのためのさまざまな深さが含まれている、完全なドキュメントを参照してくださいここに壁紙を。
最後に残った一つのこと:
- 再新しいネットワークへの権利
更新重み
実際には、最も単純な重み更新規則は、確率的勾配降下法(SGD)です。
``weight = weight - learning_rate * gradient``
私たちは、この規則を実装する簡単なPythonコードを使用することができます。
learning_rate = 0.01
for f in net.parameters():
f.data.sub_(f.grad.data * learning_rate)
あなたは、ニューラルネットワークを使用する場合でも、このようなSGD、ネステロフ-SGD、アダム、など、さまざまなルール、さまざまな使用して更新され RMSPROP パッケージを構築するなど、PyTorchをtorch.optim
これらのルールのすべてを実装しています。
彼らは使用し非常に簡単です:
import torch.optim as optim
# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)
# in your training loop:
optimizer.zero_grad() # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # Does the update
.. 注意::
Observe how gradient buffers had to be manually set to zero using
``optimizer.zero_grad()``. This is because gradients are accumulated
as explained in `Backprop`_ section.