파이토치 통한 RNNcell 구현
import torch
import torch.nn as nn
torch.manual_seed(42);
# 입력 𝑋𝑡 생성
d = 4 # 입력 x_t (1차원 벡터)의 크기
x_t = torch.randn(d) # 현재 시점 t의 입력
# 초기 은닉 상태 ℎ𝑡−1 설정
# 은닉 상태의 크기를 설정합니다.
Dh = 6
# 이전 타임 스텝의 은닉 상태를 초기화
h_t_minus_1 = torch.zeroes(1, Dh)
#입력에 대한 가중치 (𝑊𝑥)설정
# 𝑊𝑥는 입력 데이터의 차원 𝑑와 은닉 상태의 차원 𝐷ℎ에 따라 결정되는 𝐷ℎ×𝑑 크기의 행렬
Wx = torch.randn(Dh, d)
#은닉 상태에 대한 가중치 (𝑊ℎ)설정
# 𝑊ℎ의 차원은 은닉 상태의 크기 𝐷ℎ에 따라 𝐷ℎ×𝐷ℎ로 설정.
Wh = torch.randn(Dh, Dh)
#편향(b) 설정
b = torch.randn(Dh)
#현시점 은닉 상태 계산
h_t = torch.tanh(torch.matmul(x_t.unsqueeze(0), Wx.t()) + torch.matmul(h_t_minus_1, Wh.Wh.t()) + b.unsqueeze(0))
# 출력 가중치 𝑊𝑦 및 출력 𝑌𝑡 계산
Dy = 2
Wy = torch.randn(Dh,Dy) # 출력 가중치
y_t = torch.sigmoid(torch.matmul(h_t, wy))
RNN 클래스구현과 Sequence 데이터 처리
1. MyRNNcell 클래스 구현하기
# 1.1 클래스 정의하기 : init 함수 구현
import torch
import torch.nn as nn
class MyRNNcell(nn.Module):
def __init__(self, input_size, hidden_size):
super(MyRNNcell, self).__init__()
self.hidden_size = hidden_size
# 가중치와 편향을 nn.Parameter로 자동 초기화
self.Wx = nn.Parameter(torch.randn(hidden_size, input_size))
self.Wh = nn.Parameter(torch.randn(hidden_size, hidden_size))
self.b = nn.Parameter(torch.randn(hidden_size))
## 확인하기
model_rnn = MyRNNcell(input_size=4, hidden_size=6)

1.2 클래스 정의하기 : forward 함수 구현
import torch
import torch.nn as nn
# SimpleRNN 클래스 정의
class MyRNNcell(nn.Module):
def __init__(self, input_size, hidden_size):
super(MyRNNcell, self).__init__()
self.hidden_size = hidden_size
self.Wx = nn.Parameter(torch.randn(hidden_size, input_size))
self.Wh = nn.Parameter(torch.randn(hidden_size, hidden_size))
self.b = nn.Parameter(torch.randn(hidden_size))
def forward(self, x, hidden):
hidden = torch.tanh(torch.matmul(x,self.Wx.t()) + torch.matmul(hidden, self.Wh.t()) + self.b)
return hidden
# 모델 인스턴스 생성
model_rnn = MyRNNcell(input_size=4, hidden_size=6)
model_rnn

2.MyRNNcell 인스턴스를 통한 새로운 은닉 상태 계산
torch.manual_seed(42)
# 랜덤 입력 데이터 생성
x_t = torch.randn(1, 4) # Input size = 4
# 초기 은닉 상태 생성
initial_hidden = torch.randn(1, 6) # Hidden size = 6
# 모델 실행
new_h_t = model_rnn(x_t , initial_hidden)
print("새로운 은닉 상태:", new_h_t)
3.시퀀스 데이터 처리를 위한 MyRNN 클래스 구현
import torch
import torch.nn as nn
# MyRNN 클래스 정의
class MyRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(MyRNN, self).__init__()
self.hidden_size = hidden_size
self.rnn_cell = MyRNNcell(input_size, hidden_size)
self.Wy = nn.Parameter(torch.randn(output_size, hidden_size))
def init_hidden(self, batch_size=1):
return torch.zeros(batch_size, self.hidden_size)
def forward(self, x):
h_t = self.init_hidden(x.size(0))
for i in range(x.size(1)): # Iterate over sequence
h_t = self.rnn_cell(x[:, i], h_t)
output = torch.sigmoid(torch.matmul(h_t, self.Wy.t())) # Sigmoid activation
return output, h_t
# 모델 초기화 통한 인스턴스 생성 예시
model_myrnn = MyRNN(input_size=4, hidden_size=6, output_size=2)
model_myrnn
# Sequence 입력 데이터와 MyRNN을 통한 출력 계산
sequence_data = torch.tensor([
[0.1, 0.2, 0.3, 0.4],
[0.2, 0.3, 0.4, 0.5],
[0.3, 0.4, 0.5, 0.6],
[0.4, 0.5, 0.6, 0.7],
[0.5, 0.6, 0.7, 0.8],
])
# MyRNN 모델 인스턴스화
input_size = 4 # 입력 피처의 개수
hidden_size = 6 # 은닉 상태의 크기
output_size = 1 # 출력 크기
model_myrnn1 = MyRNN(input_size, hidden_size, output_size)
# 모델을 통해 시퀀스 데이터 처리
output, ht = model_myrnn1(sequence_data.unsquezze(0))
print("입력 시퀀스:", sequence_data)
print(f"모델 출력:, {output} {ht}")
| 기능 | MyRNNcell | MyRNN |
|---|
| 처리 단위 | 한 시점만 처리 | 전체 시퀀스 반복 처리 |
| 내부 구성 | Wx,Wh,b | RNNCell + 출력 가중치 |
| 출력 | 새로운 은닉 상태 ht | 최종 결과 (예: 분류 결과) |
| 사용 방식 | 수동 반복(for문으로 여러 번 호출) | 자동 반복 구조(한 번에 시퀀스 처리 가능) |