見出し画像

PyTorch - Neural Networks! - 2

ネットワークができたのであとは精度を上げていきます。

ここから「学習」です。ネットワークで正解と比べ、間違わないように最適化していきます。ネットワークから出力されるデータと、正解データとを見合わせながらパラメータを調整していきます。

まず最初に全てのパラメータを"0"にして次のステップの準備します。総てのパラメータの勾配バッファをゼロにして勾配を初期化し, 逆誤差伝播法でパラメータの値の最適な勾配を求めます。

net.zero_grad()
out.backward(torch.randn(1, 10))


Loss Function:損失関数

損失関数はネットワークで出力された値outputと正解値 targetと2つの値を使います。、output が target からどのくらい遠く離れているかを推定する値を計算します。

"nn package"には数種類ありますが、今回はnn.MSELoss とい損失関数を使っています。これは入力とターゲット間の平均二乗誤差を計算します。

output = net(input)
target = torch.randn(10)  # a dummy target, for example
target = target.view(1, -1)  # make it the same shape as output
criterion = nn.MSELoss()
loss = criterion(output, target)
print(loss)

Out:

Out:
tensor(1.4711, grad_fn=<MseLossBackward>)

と出力されました。

計算の流れは、


input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d
-> view -> linear -> relu -> linear -> relu -> linear
-> MSELoss
-> loss

データがinputで入ってきて、ニューラルネットワークを通り、MSLoss損失関数へ入って微分され、loss差分値が出ます。

以下はloss.backward()の計算順を書き出しています。実行すると、

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
Out:
<MseLossBackward object at 0x7f9b675d4d68>
<AddmmBackward object at 0x7f9b675d4160>
<AccumulateGrad object at 0x7f9b675d4d68>

と出力されました。


Backprop: 誤差逆伝播

勾配を求める時の流れの確認です。

net.zero_grad()     # zeroes the gradient buffers of all parameters
print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)
loss.backward()
print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)

Out:

conv1.bias.grad before backward
tensor([0., 0., 0., 0., 0., 0.])
conv1.bias.grad after backward
tensor([-0.0037, 0.0010, 0.0152, -0.0221, 0.0205, 0.0080])

conv1の勾配の出力される前と後のデータです。


Update the weights:パラメータの更新

まずシンプルなものとして一例として、Stochastic Gradient Descent (SGD)の実装の例示です。

weight = weight - learning_rate * gradient
learning_rate = 0.01
for f in net.parameters():
   f.data.sub_(f.grad.data * learning_rate)

とすることができます。

Pytorchではパッケージ torch.optim を使います。

import torch.optim as optim

optimizer = optim.SGD(net.parameters(), lr=0.01)

optimizer.zero_grad() 

output = net(input)

loss = criterion(output, target)
loss.backward()

optimizer.step()   
optimizer = optim.SGD(net.parameters(), lr=0.01)

確率的勾配降下法を使います。

optimizer.zero_grad()

"0"に初期化。

output = net(input)
loss = criterion(output, target)
loss.backward()

ネットワークから出力された値の損失関数を導きます。

optimizer.step()

そして最適化です。

この記事が気に入ったらサポートをしてみませんか?