Pytorch-recurrent-neural-network
PyTorch-リカレントニューラルネットワーク
リカレントニューラルネットワークは、シーケンシャルアプローチに従う深層学習指向のアルゴリズムの一種です。 ニューラルネットワークでは、各入力と出力が他のすべてのレイヤーから独立していることを常に想定しています。 これらのタイプのニューラルネットワークは、次々にタスクを完了する逐次的な方法で数学的計算を実行するため、リカレントと呼ばれます。
以下の図は、リカレントニューラルネットワークの完全なアプローチと動作を指定しています-
上記の図では、c1、c2、c3、およびx1は、o1のそれぞれの出力を提供するいくつかの隠された入力値、つまりh1、h2、およびh3を含む入力と見なされます。 PyTorchの実装に焦点を当てて、リカレントニューラルネットワークを使用して正弦波を作成します。
トレーニング中、一度に1つのデータポイントを使用して、モデルへのトレーニングアプローチに従います。 入力シーケンスxは20個のデータポイントで構成され、ターゲットシーケンスは入力シーケンスと同じと見なされます。
ステップ1
以下のコードを使用して、リカレントニューラルネットワークを実装するために必要なパッケージをインポートします-
import torch
from torch.autograd import Variable
import numpy as np
import pylab as pl
import torch.nn.init as init
ステップ2
入力レイヤーのサイズを7に設定して、モデルのハイパーパラメーターを設定します。 ターゲットシーケンスを作成するために、6つのコンテキストニューロンと1つの入力ニューロンがあります。
dtype = torch.FloatTensor
input_size, hidden_size, output_size = 7, 6, 1
epochs = 300
seq_length = 20
lr = 0.1
data_time_steps = np.linspace(2, 10, seq_length + 1)
data = np.sin(data_time_steps)
data.resize((seq_length + 1, 1))
x = Variable(torch.Tensor(data[:-1]).type(dtype), requires_grad=False)
y = Variable(torch.Tensor(data[1:]).type(dtype), requires_grad=False)
トレーニングデータを生成します。xは入力データシーケンス、yは必須のターゲットシーケンスです。
ステップ3
重みは、平均がゼロの正規分布を使用して、リカレントニューラルネットワークで初期化されます。 W1は入力変数の受け入れを表し、w2は以下に示すように生成される出力を表します-
w1 = torch.FloatTensor(input_size,
hidden_size).type(dtype)
init.normal(w1, 0.0, 0.4)
w1 = Variable(w1, requires_grad = True)
w2 = torch.FloatTensor(hidden_size, output_size).type(dtype)
init.normal(w2, 0.0, 0.3)
w2 = Variable(w2, requires_grad = True)
ステップ4
ここで、ニューラルネットワークを一意に定義するフィードフォワード用の関数を作成することが重要です。
def forward(input, context_state, w1, w2):
xh = torch.cat((input, context_state), 1)
context_state = torch.tanh(xh.mm(w1))
out = context_state.mm(w2)
return (out, context_state)
ステップ5
次のステップは、リカレントニューラルネットワークの正弦波実装のトレーニング手順を開始することです。 外側のループは各ループを反復し、内側のループはsequenceの要素を反復します。 ここでは、連続変数の予測に役立つ平均二乗誤差(MSE)も計算します。
for i in range(epochs):
total_loss = 0
context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = True)
for j in range(x.size(0)):
input = x[j:(j+1)]
target = y[j:(j+1)]
(pred, context_state) = forward(input, context_state, w1, w2)
loss = (pred - target).pow(2).sum()/2
total_loss += loss
loss.backward()
w1.data -= lr *w1.grad.data
w2.data -= lr* w2.grad.data
w1.grad.data.zero_()
w2.grad.data.zero_()
context_state = Variable(context_state.data)
if i % 10 == 0:
print("Epoch: {} loss {}".format(i, total_loss.data[0]))
context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = False)
predictions = []
for i in range(x.size(0)):
input = x[i:i+1]
(pred, context_state) = forward(input, context_state, w1, w2)
context_state = context_state
predictions.append(pred.data.numpy().ravel()[0])
ステップ6
さて、サイン波を必要に応じてプロットします。
pl.scatter(data_time_steps[:-1], x.data.numpy(), s = 90, label = "Actual")
pl.scatter(data_time_steps[1:], predictions, label = "Predicted")
pl.legend()
pl.show()
出力
上記のプロセスの出力は次のとおりです-