PyTorch-순환 신경망

순환 신경망은 순차적 접근 방식을 따르는 딥 러닝 지향 알고리즘의 한 유형입니다. 신경망에서 우리는 항상 각 입력과 출력이 다른 모든 계층과 독립적이라고 가정합니다. 이러한 유형의 신경망은 하나의 작업을 차례로 완료하는 순차적 인 방식으로 수학적 계산을 수행하기 때문에 반복이라고합니다.

아래 다이어그램은 순환 신경망의 완전한 접근 방식과 작동 방식을 지정합니다.

위 그림에서 c1, c2, c3 및 x1은 o1의 각 출력을 전달하는 h1, h2 및 h3과 같은 일부 숨겨진 입력 값을 포함하는 입력으로 간주됩니다. 이제 반복 신경망의 도움으로 사인파를 생성하기 위해 PyTorch를 구현하는 데 중점을 둘 것입니다.

훈련 중에는 한 번에 하나의 데이터 포인트를 사용하여 모델에 대한 훈련 방식을 따릅니다. 입력 시퀀스 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 단계

가중치는 평균이 0 인 정규 분포를 사용하여 순환 신경망에서 초기화됩니다. 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 단계

다음 단계는 순환 신경망의 사인파 구현 훈련 절차를 시작하는 것입니다. 외부 루프는 각 루프를 반복하고 내부 루프는 시퀀스 요소를 반복합니다. 여기에서는 연속 변수의 예측에 도움이되는 평균 제곱 오차 (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()

산출

위 프로세스의 출력은 다음과 같습니다.