4rldur0

4rldur0

Posted on December 28, 2023

댑덥딥 9주차 정리

'모두를 위한 딥러닝 시즌 2' 강의를 듣고 공부하는 스터디 입니다. https://deeplearningzerotoall.github.io/season2/lec_tensorflow.html


비대면 7 June, 2023

11-4 RNN time series

time series data? =serial data, 일정한 시간 간격으로 배치된 데이터 ex) 주가 데이터

apply RNN: many-to-one

hidden state에 충분한 dimesion을 주고 마지막 output에 fc layer

#스케일링: 0부터 1사이의 상대값으로 변환하여 사용→부담이 줄어듦
def minmax_scaler(data):
    numerator = data - np.min(data, 0)
    denominator = np.max(data, 0) - np.min(data, 0)
    return numerator / (denominator + 1e-7)
Enter fullscreen mode Exit fullscreen mode
#Neural Net setting
class Net(torch.nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim, layers):
        super(Net, self).__init__()
        self.rnn = torch.nn.LSTM(input_dim, hidden_dim, num_layers=layers, batch_first=True)
        self.fc = torch.nn.Linear(hidden_dim, output_dim, bias=True)

    def forward(self, x):
        x, _status = self.rnn(x)
        x = self.fc(x[:, -1])
        return x

net = Net(data_dim, hidden_dim, output_dim, 1)
Enter fullscreen mode Exit fullscreen mode

11-5 RNN Seq2seq

Seq2seq model

? sequence를 입력받고 sequence를 출력. 번역/챗봇 분야에서 많이 활용

Image description

RNN은 문장이 끝나기 전 답변을 만듦. 끝까지 듣고 답하기 위해 seq2seq 모델이 나옴

  • encoder와 decoder이라는 두 개의 RNN으로 구성됨

    encoder: input을 벡터의 형태로 압축하여 decoder에 전달

    decoder: 첫 셀에 전달된 벡터

Image description

# 전체적인 흐름

SOURCE_MAX_LENGTH = 10
TARGET_MAX_LENGTH = 12
#data setting
load_pairs, load_source_vocab, load_target_vocab = preprocess(raw, SOURCE_MAX_LENGTH, TARGET_MAX_LENGTH)
print(random.choice(load_pairs))

#define encoder, decoder
enc_hidden_size = 16
dec_hidden_size = enc_hidden_size
enc = Encoder(load_source_vocab.n_vocab, enc_hidden_size)
dec = Decoder(dec_hidden_size, load_target_vocab.n_vocab)

train(load_pairs, load_source_vocab, load_target_vocab, enc, dec, 5000, print_every=1000)
evaluate(load_pairs, load_source_vocab, load_target_vocab, enc, dec, TARGET_MAX_LENGTH)
Enter fullscreen mode Exit fullscreen mode
#data setting-convert sentence to one-hot vector
def tensorize(vocab, sentence):
indexes = [vocab.vocab2index[word] for word in sentence.split(" ")]
indexes.append(vocab.vocab2index["<EOS>"])
return torch.Tensor(indexes).long().to(device).view(-1, 1)
Enter fullscreen mode Exit fullscreen mode
# fix token for "start of sentence" and "end of sentence"
SOS_token = 0
EOS_token = 1

# class for vocabulary related information of data
class Vocab:
    def __init__(self):
        self.vocab2index = {"<SOS>": SOS_token, "<EOS>": EOS_token}
        self.index2vocab = {SOS_token: "<SOS>", EOS_token: "<EOS>"}
        self.vocab_count = {}
        self.n_vocab = len(self.vocab2index)

    def add_vocab(self, sentence):
        for word in sentence.split(" "):
            if word not in self.vocab2index:
                self.vocab2index[word] = self.n_vocab
                self.vocab_count[word] = 1
                self.index2vocab[self.n_vocab] = word
                self.n_vocab += 1
            else:
                self.vocab_count[word] += 1
Enter fullscreen mode Exit fullscreen mode
# declare simple encoder
class Encoder(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(Encoder, self).__init__()
        self.hidden_size = hidden_size
        self.embedding = nn.Embedding(input_size, hidden_size)
        self.gru = nn.GRU(hidden_size, hidden_size)

    def forward(self, x, hidden):
        x = self.embedding(x).view(1, 1, -1)
        x, hidden = self.gru(x, hidden)
        return x, hidden

# declare simple decoder
class Decoder(nn.Module):
    def __init__(self, hidden_size, output_size):
        super(Decoder, self).__init__()
        self.hidden_size = hidden_size
        self.embedding = nn.Embedding(output_size, hidden_size)
        self.gru = nn.GRU(hidden_size, hidden_size)
        self.out = nn.Linear(hidden_size, output_size)    #압축된 데이터를 원래 크기로 복원시킴
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, x, hidden):
        x = self.embedding(x).view(1, 1, -1)
        x, hidden = self.gru(x, hidden)
        x = self.softmax(self.out(x[0]))
        return x, hidden
Enter fullscreen mode Exit fullscreen mode
  • nn.Embedding: input에 one-hot으로 표현된 vector를 곱하여 거대한 matrix(mxn)를 mx1 vector로 변환함
  • GRU: LSTM과 같은 advanced RNN model.

    LSTM: RNN보다 성능이 좋다고 알려져 있다.(gradient vanishing문제 일부 해소)

    GRU: LSTM보다 빠르다고 알려져 있다.

Image description

Q. encoder에서 embedding 했는데 decoder에서 왜 또 embedding 하지? 이미 압축된 형태로 들어오는 거 아닌가?
A. hidden state의 사이즈를 gru input 사이즈에 맞춰주기 위해서

# training seq2seq
def train(pairs, source_vocab, target_vocab, encoder, decoder, n_iter, print_every=1000, learning_rate=0.01):
    loss_total = 0

    encoder_optimizer = optim.SGD(encoder.parameters(), lr=learning_rate)
    decoder_optimizer = optim.SGD(decoder.parameters(), lr=learning_rate)

    training_batch = [random.choice(pairs) for _ in range(n_iter)]
    training_source = [tensorize(source_vocab, pair[0]) for pair in training_batch]
    training_target = [tensorize(target_vocab, pair[1]) for pair in training_batch]

    criterion = nn.NLLLoss()    #crossentropy를 사용하기도 함

    for i in range(1, n_iter + 1):
        source_tensor = training_source[i - 1]
        target_tensor = training_target[i - 1]

        encoder_hidden = torch.zeros([1, 1, encoder.hidden_size]).to(device)

        encoder_optimizer.zero_grad()
        decoder_optimizer.zero_grad()

        source_length = source_tensor.size(0)
        target_length = target_tensor.size(0)

        loss = 0

        for enc_input in range(source_length):
            _, encoder_hidden = encoder(source_tensor[enc_input], encoder_hidden)

        decoder_input = torch.Tensor([[SOS_token]]).long().to(device) #decoder의 첫 셀의 입력값은 start token
        decoder_hidden = encoder_hidden # connect encoder output to decoder input

        for di in range(target_length):
            decoder_output, decoder_hidden = decoder(decoder_input, decoder_hidden)
            loss += criterion(decoder_output, target_tensor[di])
            decoder_input = target_tensor[di]  # teacher forcing

        loss.backward()

        encoder_optimizer.step()
        decoder_optimizer.step()

        loss_iter = loss.item() / target_length
        loss_total += loss_iter

        if i % print_every == 0:
            loss_avg = loss_total / print_every
            loss_total = 0
            print("[{} - {}%] loss = {:05.4f}".format(i, i / n_iter * 100, loss_avg))
Enter fullscreen mode Exit fullscreen mode
  • nn.NLLLoss: CrossEntropyLoss와 같이 cross-entropy 손실을 구하는 함수이고, 분류문제에서 출력이 확률값일 때 사용. CrossEntropyLoss = LogSoftmax + NLLLoss
  • teacher forcing: 실제 정답을 다음 셀에 넣어주는 것.

-일부는 teacher forcing, 일부는 gru의 예측값을 다음 셀에 전달하는 방법을 사용할 수도 있음

11-6 RNN PackedSequence

sequential data는 길이가 정해져 있지 않음 → 하나로 tensor로 묶어서 학습시켜야 함

cf) 이미지는 fixed size(예를 들어 32x32)

padding method

? 가장 긴 sequence의 길이에 맞추어 나머지 sequence의 뒤를 pad라는 토큰으로 채음

packing method

? seqence 길이의 정보를 저장하여 사용. batch는 길이 내림차순으로 정렬되어야 함. padding method에 비해 효율적이고 pad tocken을 사용하지 않아도 됨.

Image description


대면 8 April, 2023

RNN-timeseries, seq2seq, packedsequence

💖 💪 🙅 🚩
4rldur0
4rldur0

Posted on December 28, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

댑덥딥 7주차 정리
ai 댑덥딥 7주차 정리

December 28, 2023

댑덥딥 6주차 정리
ai 댑덥딥 6주차 정리

December 28, 2023

댑덥딥 8주차 정리
ai 댑덥딥 8주차 정리

December 28, 2023

댑덥딥 9주차 정리
ai 댑덥딥 9주차 정리

December 28, 2023

댑덥딥 2주차 정리
ai 댑덥딥 2주차 정리

December 28, 2023