2020. 2. 8. 01:04ㆍnlp
https://www.deeplearningwizard.com/deep_learning/practical_pytorch/pytorch_lstm_neuralnetwork/
Model A : 1 Hidden Layer
- 입력 데이터는 MNIST 손글씨 데이터
- 입력 사이즈 (28,1)
- 반복 횟수는 28
Create Model Class
class LSTMModel(nn.Module):
def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):
super(LSTMModel, self).__init__()
self.hidden_dim = hidden_dim
self.layer_dim = layer_dim # 은닉층 개수
# LSTM
# batch_first : input/output 텐서가 (batch_dim, seq_dim, feature_dim) 형태가 됨
# batch_dim = batch_size, seq_dim = 반복 횟수, feature_dim = ?
self.lstm = nn.LSTM(input_dim, hidden_dim, layer_dim, batch_first=True)
# Readout layer
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
# 은닉상태를 0으로 초기화
h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()
# cell state를 0으로 초기화
c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()
# 28 time steps (28번 반복)
# truncated BPTT
# detach 안 하면 다음 배치로 넘어가서도 맨 앞까지 오차역전파함
out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
# out.size() -> 100, 28, 100
# out[:, -1, :] -> 100, 100 (마지막 반복의 은닉 상태만)
out = self.fc(out[:, -1, :])
# 100,100 을 FC에 넣어서 이제 100,10
# out.size() -> 100,10
return out
Instantiate Model Class
input_dim = 28
hidden_dim = 100
layer_dim = 1
output_dim = 10
model = LSTMModel(input_dim, hidden_dim, layer_dim, output_dim)
Parameter 살펴보기
전체 파라미터 개수 = 6개
• input -> forget/input/new candidate/output gates로 가는 W, b
- 3개의 gate + new candidate = 총 4개로 보내는 걸 하나의 큰 가중치 행렬로 만듦
- 각 가중치는 [100,28] * input(x) [28,1] + 편향 [100,1] = [100,1]
- 그런데 총 4개를 합쳐서 100 -> 400
- 전체 가중치 [400,28] * input(x) [28,1] + 편향 [400,1] = [400,1]
• 은닉 상태(h) -> forget/input/new candidate/output gates로 가는 W, b
- 3개의 gate + new candidate = 총 4개로 보내는 걸 하나의 큰 가중치 행렬로 만듦
- 각 가중치는 [100,100] * 은닉상태(h) [100,1] + 편향 [100,1] = [100,1]
- 그런데 총 4개를 합쳐서 100 -> 400
- 전체 가중치 [400,100] * 은닉상태(h) [100,1] + 편향 [400,1] = [400,1]
• 은닉 상태 (h) -> output으로 가는 W, b
- FC 가중치 [10,100] * 은닉상태(h) [100,1] + 편향 [10,1] = [10,1]
Train/Test Model
images = images.view(-1, seq_dim, input_dim).requires_grad_()
images = images.view(-1, seq_dim, input_dim)
# 반복횟수
seq_dim = 28
iter = 0
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
# images = (batch_size, seq_dim, input_dim) = (100, 28, 28)
images = images.view(-1, seq_dim, input_dim).requires_grad_()
# Clear gradients
optimizer.zero_grad()
# outputs.size() --> 100, 10
outputs = model(images)
# Calculate Loss: softmax --> cross entropy loss
loss = criterion(outputs, labels)
# Getting gradients w.r.t. parameters
loss.backward()
# Updating parameters
optimizer.step()
iter += 1
if iter % 500 == 0:
# Calculate Accuracy
correct = 0
total = 0
# Iterate through test dataset
for images, labels in test_loader:
# Resize images
images = images.view(-1, seq_dim, input_dim)
# Forward pass only to get logits/output
outputs = model(images)
# Get predictions from the maximum value
_, predicted = torch.max(outputs.data, 1)
# Total number of labels
total += labels.size(0)
# Total correct predictions
correct += (predicted == labels).sum()
accuracy = 100 * correct / total
# Print Loss
print('Iteration: {}. Loss: {}. Accuracy: {}'.format(iter, loss.item(), accuracy))
cf. 은닉층 2개 (layer_dim=2) 로 변경했을 때 Parameter 변화
'nlp' 카테고리의 다른 글
seq2seq 모델 PyTorch로 구현하기 번역 및 정리 (9) | 2020.02.09 |
---|---|
Intro to Encoder-Decoder LSTM(=seq2seq) 번역 및 정리 (2) | 2020.02.08 |
[DL Wizard] Recurrent Neural Network with PyTorch 번역 및 정리 (0) | 2020.02.08 |
그림으로 보는 RNN/LSTM과 GRU 번역 및 정리 (0) | 2020.02.07 |
[DL Wizard] Convolutional Neural Network with PyTorch 번역 및 정리 (0) | 2020.02.06 |