Week4 Day2

김종영·2021년 2월 16일
0
post-thumbnail

📋 BasicBasic ofof RecurrentRecurrent NeuralNeural NetworksNetworks

📌 RecurrentRecurrent NeuralNeural NetworkNetwork

  • sequentialsequential 한 데이터에 대해서 입력 데이터와 이전 스텝의 statestate를 이용하여 recursiverecursive하게 아웃풋을 출력하는 모델
# B: batch size, L: maximum sequence length
vocab_size = 100
batch = torch.LongTensor(data)  # (B, L)

embedding_size = 256
embedding = nn.Embedding(vocab_size, embedding_size)

# d_w: embedding size
batch_emb = embedding(batch)  # (B, L, d_w)

hidden_size = 512  # RNN의 hidden size
num_layers = 1  # 쌓을 RNN layer의 개수
num_dirs = 1  # 1: 단방향 RNN, 2: 양방향 RNN

rnn = nn.RNN(
    input_size=embedding_size,
    hidden_size=hidden_size,
    num_layers=num_layers,
    bidirectional=True if num_dirs > 1 else False
)

h_0 = torch.zeros((num_layers * num_dirs, batch.shape[0], hidden_size))  # (num_layers * num_dirs, B, d_h)

hidden_states, h_n = rnn(batch_emb.transpose(0, 1), h_0)

num_classes = 2
classification_layer = nn.Linear(hidden_size, num_classes)
# C: number of classes
output = classification_layer(h_n.squeeze(0))  # (1, B, d_h) => (B, C)

📌 BackpropagationBackpropagation throughthrough timetime

  • lossloss를 계산하기 위해서 전체 sequencesequence에 걸쳐서 forwardforward를 하고, 그러고나서 gradientgradient를 계산하기 위해 전체 sequencesequence에 걸쳐서 backwardbackward한다.
  • 훨씬 이전 stepstep의 hiddenhidden statestate값에 대한 updateupdate의한 gradientgradient 전달되기 어렵다. (Vanishing(Vanishing gradient)gradient)
  • 전체sequencesequence 대신 sequencesequence를 잘라서 chunkchunk단위로 forwardforward, backwardbackward
  • (Question)(Question) 동일한 weightweight에 대해서 학습을 sequentialsequential하게 진행하면 앞에 updateupdate한 부분에 대해forgettingforgetting문제 발생하지 않을까??
  • (Question)(Question) 멀리 떨어진 시점에 대한 정보 updateupdate 반영 안되는 것 아닌가?

📌 LongLong ShortShort-TermTerm MemoryMemory

  • sequencesequence내에서 멀이 떨어진 곳의 정보를 더 잘 이용할 수 있도록
    cellcell statestate를 만들어 변형없이 정보를 바로 전달
  • sigmoidsigmoid를 통과하는 ii,ff,oo는 0~1사이 값으로 다른 벡터와 elementelement-wisewise곱을 통해서 원래 가진 값의 일부 퍼센트만 전달할 수 있도록하는 역할
  • tanhtanh를 통과하는 gg의 경우 비선형함수를 통과하여 -1~1사이의 값을 가지며 현재 stepstep에 유의미한 정보를 담고있는 역할을 한다.
class RecurrentNeuralNetworkClass(nn.Module):
    def __init__(self,name='rnn',xdim=28,hdim=256,ydim=10,n_layer=3):
        super(RecurrentNeuralNetworkClass,self).__init__()
        self.name = name
        self.xdim = xdim
        self.hdim = hdim
        self.ydim = ydim
        self.n_layer = n_layer # K

        self.rnn = nn.LSTM(
            input_size=self.xdim,hidden_size=self.hdim,num_layers=self.n_layer,batch_first=True)
        self.lin = nn.Linear(self.hdim,self.ydim)

    def forward(self,x):
        # Set initial hidden and cell states 
        h0 = torch.zeros(self.n_layer, x.size(0), self.hdim).to(device)
        c0 = torch.zeros(self.n_layer, x.size(0), self.hdim).to(device)
        # RNN
        rnn_out,(hn,cn) = self.rnn(x, (h0,c0)) 
        # x:[N x L x Q] => rnn_out:[N x L x D]
        # Linear
        out = self.lin(rnn_out[:,-1 :]).view([-1,self.ydim]) 
        return out 

R = RecurrentNeuralNetworkClass(
    name='rnn',xdim=28,hdim=256,ydim=10,n_layer=2).to(device)
loss = nn.CrossEntropyLoss()
optm = optim.Adam(R.parameters(),lr=1e-3)
print ("Done.")

x_numpy = np.random.rand(2,20,28) # [N x L x Q]
x_torch = torch.from_numpy(x_numpy).float().to(device)
rnn_out,(hn,cn) = R.rnn.forward(x_torch) # forward path
out = R.lin.forward(rnn_out[:,-1:]).view([-1,ydim])

📌 GRUGRU

  • LSTMLSTM의 경량화
  • cellcell statestatehiddenhidden statestate의 일원화
gru = nn.GRU(
    input_size=embedding_size,
    hidden_size=hidden_size,
    num_layers=num_layers,
    bidirectional=True if num_dirs > 1 else False
)
output_layer = nn.Linear(hidden_size, vocab_size)

📌 LanguageLanguage ModelingModeling

  • 단어, 문자 등의 기본단위 값에 대해서 이전 정보를 이용하여 순차적으로 예측해나가는 태스크
  • TeacherTeacher ForcingForcing 없이 이전에 예측값을 입력값으로 이용하여 진행
for t in range(max_len):
  input_emb = embedding(input_id).unsqueeze(0)  # (1, B, d_w)
  output, hidden = gru(input_emb, hidden)  # output: (1, B, d_h), hidden: (1, B, d_h)

  # V: vocab size
  output = output_layer(output)  # (1, B, V)
  probs, top_id = torch.max(output, dim=-1)  # probs: (1, B), top_id: (1, B)

  print("*" * 50)
  print(f"Time step: {t}")
  print(output.shape)
  print(probs.shape)
  print(top_id.shape)

  input_id = top_id.squeeze(0)  # (B)

0개의 댓글

관련 채용 정보