변수 값을 지정합니다. vocab_size에는 영화 리뷰에 대한 텍스트 길이를, n_classes에는 레이블(긍정, 부정) 값을 지정합니다.
코드 7-22 변수 값 지정
vocab_size = len(TEXT.vocab)
n_classes = 2 ------ pos(긍정), neg(부정)
이제 모델에 대한 네트워크를 정의합니다.
코드 7-23 RNN 계층 네트워크
class BasicRNN(nn.Module):
def __init__(self, n_layers, hidden_dim, n_vocab, embed_dim, n_classes, dropout_p=0.2):
super(BasicRNN, self).__init__()
self.n_layers = n_layers ------ RNN 계층에 대한 개수
self.embed = nn.Embedding(n_vocab, embed_dim) ------ 워드 임베딩 적용
self.hidden_dim = hidden_dim
self.dropout = nn.Dropout(dropout_p) ------ 드롭아웃 적용
self.rnn = nn.RNN(embed_dim, self.hidden_dim, num_layers=self.n_layers, batch_first=True) ------ ①
self.out = nn.Linear(self.hidden_dim, n_classes)
def forward(self, x):
x = self.embed(x) ------ 문자를 숫자/벡터로 변환
h_0 = self._init_state(batch_size=x.size(0)) ------ 최초 은닉 상태의 값을 0으로 초기화
x, _ = self.rnn(x, h_0) ------ RNN 계층을 의미하며, 파라미터로 입력과 이전 은닉 상태의 값을 받습니다.
h_t = x[:, -1, :] ------ 모든 네트워크를 거쳐서 가장 마지막에 나온 단어의 임베딩 값(마지막 은닉 상태의 값)
self.dropout(h_t)
logit = torch.sigmoid(self.out(h_t))
return logit
def _init_state(self, batch_size=1):
weight = next(self.parameters()).data ------ 모델의 파라미터 값을 가져와서 weight 변수에 저장
return weight.new(self.n_layers, batch_size, self.hidden_dim).zero_() ------ 크기가 (계층의 개수, 배치 크기, 은닉층의 뉴런/유닛 개수)인 은닉 상태(텐서)를 생성하여 0으로 초기화한 후 반환