SurnameClassifier ๋ชจ๋ธ
ย
์ด์ ์ฑ์จ๋ฅผ ๋ถ๋ฅํ๋ ๋ชจ๋ธ, SurnameClassifier ๋ชจ๋ธ์ ์์ฑํด๋ด
๋๋ค. ์ด ๋ชจ๋ธ์ ์๋ฒ ๋ฉ ์ธต, ElmanRNN ์ธต, ๊ทธ๋ฆฌ๊ณ Linear์ธต์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. SequenceVocabulary๋ฅผ ํตํด ์ ์๋ก ๋งคํํ ํ ํฐ์ ๋ชจ๋ธ์ ์
๋ ฅ์ ํด์ฃผ๋ฉด, ๋จผ์ ์๋ฒ ๋ฉ ์ธต์ ์ฌ์ฉํด ์ ์๋ฅผ ์๋ฒ ๋ฉํฉ๋๋ค. ๊ทธ ํ, RNN์ผ๋ก ์ํ์ค์ ๋ฒกํฐ ํํ, ์ฆ ์ฑ์จ์ ๊ฐ ๋ฌธ์์ ๋ํ ์๋ ๋ฒกํฐ๋ฅผ ๊ณ์ฐํด์ค๋๋ค. ์ด๋ ์ ์ฒด ์ํ์ค ์
๋ ฅ์ ๊ฑฐ์น ๊ฒฐ๊ณผ๋ฌผ์ ์ฑ์จ์ ๋ง์ง๋ง ๋ฌธ์์ ํด๋นํ๋ ๋ฒกํฐ๊ฐ ๋๊ฒ ์ฃ ? ์ด์ ๋ง์ง๋ง์ผ๋ก, ์ด ์ต์ข
๋ฒกํฐ๋ฅผ Linear์ธต์ผ๋ก ์ ๋ฌํด ์์ธก ๋ฒกํฐ๋ฅผ ๊ณ์ฐํฉ๋๋ค.
ย
SurnameClassifier ๋ชจ๋ธ์ ์๋ 4๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ์ต๋๋ค.
- ๋ฌธ์ ์๋ฒ ๋ฉ ํฌ๊ธฐ(embedding_size ๋ฐ์ดํฐํ int)
- ์๋ฒ ๋ฉํ ๋ฌธ์ ๊ฐ์(num_embeddings ๋ฐ์ดํฐํ int)
- ํด๋์ค ๊ฐ์(num_classes ๋ฐ์ดํฐํ int)
- RNN์ ์๋ ์ํ ํฌ๊ธฐ (rnn_hidden_size ๋ฐ์ดํฐํ int)
ย
์ด๋, ์๋ฒ ๋ฉ ํฌ๊ธฐ์ ํด๋์ค ๊ฐ์๋ ๋ฐ์ดํฐ์ ๋ฐ๋ผ ๊ฒฐ์ ๋๋ ๊ฐ์ด์ง๋ง, ์๋ฒ ๋ฉํ ๋ฌธ์ ๊ฐ์์ RNN ์๋ ์ํ ํฌ๊ธฐ๋ ๊ฐ์ ์ง์ ์ ํด์ฃผ์ด์ผํ๋ ํ์ดํผํ๋ผ๋ฏธํฐ์
๋๋ค.
ย
class SurnameClassifier(nn.module): '''RNN์ผ๋ก ํน์ฑ์ ์ถ์ถํ๊ณ MLP๋ก ๋ถ๋ฅํ๋ ๋ถ๋ฅ ๋ชจ๋ธ''' def __init__(self, embedding_size, num_embeddings, num_classes, rnn_hidden_size, batch_first = True, padding_idx = 0): super(SurnameClassifier, self).__init__() self.emb = nn.Embedding(num_embeddings = num_embeddings, embedding_dim = embedding_size, padding_idx = padding_idx) self.rnn = ElmanRNN(input_size = embedding_size, hidden_size = rnn_hidden_size, batch_first = batch_first) self.fc1 = nn.Linear(in_features = rnn_hidden_size, out_features = rnn_hidden_size) self.fc2 = nn.Linear(in_features = rnn_hidden_size, out_features = num_classes) def forward(self, x_in, x_lengths = None, apply_softmax = False): '''๋ถ๋ฅ๊ธฐ์ ์ ๋ฐฉํฅ ๊ณ์ฐ''' x_embedded = self.emb(x_in) y_out = self.rnn(x_embedded) if x_lengths is not None: y_out = column_gather(y_out, x_lengths) else: y_out = y_out[:, -1, :] y_out = F.dropout(y_out, 0.5) y_out = F.relu(self.fc1(y_out)) y_out = F.dropout(y_out, 0.5) y_out = self.fc2(y_out) if apply_softmax: y_out = F.softmax(y_out, dim = 1) return y_out
ย
forward()
๋ ๋ฐฐ์น ์ ๊ฐ ์ํ์ค์ ๋ง์ง๋ง ๋ฒกํฐ๋ฅผ ์ฐพ์์ฃผ๋ ๋งค์๋์
๋๋ค. column()
ํจ์๋ฅผ ์ด์ฉํ์ฌ ๋ฐฐ์น์ ํ ์ธ๋ฑ์ค๋ฅผ ์ํํ๋ฉด์ ์ํ์ค์ ๋ง์ง๋ง ๋ฒกํฐ๋ฅผ ์ถ์ถํฉ๋๋ค.ย
forward()
๋ฉ์๋๋ 3๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ์
๋ ฅ๋ฐ์ต๋.- ์ ๋ ฅ ๋ฐ์ดํฐ ํ ์ (x_in ๋ฐ์ดํฐํ torch.Tensor)
- ๋ฐฐ์น ์ ๊ฐ ์ํ์ค์ ๊ธธ์ด (x_lengths ๋ฐ์ดํฐํ torch.Tensor)
- ์ํํธ๋งฅ์ค ํ์ฑํ ํจ์๋ฅผ ์ํ ํ๋๊ทธ (apply_softmax ๋ฐ์ดํฐํ bool)
ย
def column_gather(y_out, x_lengths): '''y_out์ ์๋ ๊ฐ ๋ฐ์ดํฐ ํฌ์ธํธ์์ ๋ง์ง๋ง ๋ฒกํฐ๋ฅผ ์ถ์ถํฉ๋๋ค.''' x_lengths = x_lengths.long().detach().cpu().numpy() - 1 out = [] for batch_index, column_index in enumerate(x_lengths): out.append(y_out[batch_index, column_index]) return torch.stack(out) ''' ๋งค๊ฐ๋ณ์: y_out (torch.FloatTensor, torch.cuda.FloatTensor) shape: (batch, sequence, feature) x_lengths (torch.LongTensor, torch.cuda.LongTensor) shape: (batch,) ๋ฐํ๊ฐ: y_out (torch.FloatTensor, torch.cuda.FloatTensor) shape: (batch, feature) '''
ย
๋ชจ๋ธ ํ๋ จ๊ณผ ๊ฒฐ๊ณผ
ย
์ฐ์ ๋ฐฐ์น ํ๋์ ๋ชจ๋ธ์ ์ ์ฉํ๊ณ ์์ธก ๋ฒกํฐ๋ฅผ ๊ณ์ฐํฉ๋๋ค. ๊ทธ ํ, ์์ค์ ๊ณ์ฐํ์ฌ ์์ค๊ฐ๊ณผ ์ตํฐ๋ง์ด์ ๋ก ๊ทธ๋ ์ด๋์ธํธ๋ฅผ ๊ตฌํ๊ณ ์ด๋ฅผ ํ ๋๋ก ๋ชจ๋ธ์ ๊ฐ์ค์น๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค. ์ด ํ๋ จ ๊ณผ์ ์ ๋ชจ๋ ๋ฐฐ์น์ ๋ฐ๋ณตํด์ฃผ๋ฉฐ ๋ชจ๋ธ์ ์ฑ๋ฅ์ ๋์ฌ์ฃผ๋ ์ต์ ์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์ฐพ์์ค๋๋ค.
ย
ย
ย
ย
์ด์ ๊ธ ์ฝ๊ธฐ
ย
ย