약간 디테일한 부분은 본 페이지의 코드 내에 주석 참고 요망.
•
임베딩 → 임베딩 레이어가 아니라 linear layer를 추가해서
◦
batch, seq, data ⇒ data * w 임베딩이 되는 것처럼 구성이됩니다.
•
PositionalEncoding Class 추가
class PositionalEncoding(nn.Module):
def __init__(self, d_model: int, dropout: float = 0.1, max_len: int = 5000):
super().__init__()
self.dropout = nn.Dropout(p=dropout)
position = torch.arange(max_len).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model))
pe = torch.zeros(max_len, 1, d_model)
pe[:, 0, 0::2] = torch.sin(position * div_term)
pe[:, 0, 1::2] = torch.cos(position * div_term)
self.register_buffer('pe', pe)
def forward(self, x):
x = x + self.pe[:x.size(0)]
return self.dropout(x)
Python
•
모든 트랜스포머 인코더에서 마스킹 제거.
◦
GPU 메모리가 작아서 batch를 1로 줄여서 사용중
•
트랜스포머 인코더 구현
class EncoderMel(nn.Module):
def __init__(self, config):
super().__init__()
self.config = config
#임베딩
self.enc_emb = nn.Linear(128, self.config.d_hidn)
#포지셔널
self.pos_emb = PositionalEncoding(self.config.d_hidn, 0)
self.layers = nn.ModuleList([EncoderLayer(self.config) for _ in range(self.config.n_layer)])
def forward(self, inputs):
# 참고한 코드에서 math.sqrt(128)를 곱해주어 별 의미없이 따라해줌.
x = self.enc_emb(inputs) * math.sqrt(128)
# 임베딩한 값 + 포지셔널한 값
x = x + self.pos_emb(x)
....
Python
•
뒤쪽 트랜스포머 인코더 수정사항.
class EncoderKeysTar(nn.Module):
def __init__(self, config):
super().__init__()
self.config = config
# 트랜스포머 출력이 input/output이 동일한데, 앞쪽 인코더에서 각각의 값을 이어붙여 2배의 값이 인풋으로 들어와서 그냥 Linear 임베딩으로 반으로 줄여줌.
self.enc_emb = nn.Linear(self.config.d_hidn*2, self.config.d_hidn)
self.pos_emb = PositionalEncoding(self.config.d_hidn, 0)
self.layers = nn.ModuleList([EncoderLayer(self.config) for _ in range(self.config.n_layer_multimodal)])
def forward(self, inputs):
x = self.enc_emb(inputs) * math.sqrt(128)
x = x + self.pos_emb(x)
```
Python
•
Transformer 전체 구조
class Transformer(nn.Module):
def __init__(self, config):
super().__init__()
self.config = config
self.encoder_mel = EncoderMel(self.config)
self.encoder_keys = EncoderKeys(self.config)
self.encoder_keys_tar = EncoderKeysTar(self.config)
def forward(self, enc_mel_inputs, enc_key_inputs):
enc_mel_outputs, enc_mel_self_attn_probs = self.encoder_mel(enc_mel_inputs)
enc_keys_outputs, enc_keys_self_attn_probs = self.encoder_keys(enc_key_inputs)
# dim = 0이라 batch_size가 합쳐졌는데, dim=1은 시퀀스니 dim=2로 합쳐줌.
enc_mel_keys = torch.cat([enc_mel_outputs, enc_keys_outputs], dim=2)
enc_keys_tar_outputs, enc_keys_tar_self_attn_probs = self.encoder_keys_tar(enc_mel_keys)
return enc_keys_tar_outputs, enc_keys_tar_self_attn_probs
Python
•
KeypointsPred : 주석처리
class KeypointsPred(nn.Module):
self.config = config
self.transformer = Transformer(self.config)
self.projection = nn.Linear(self.config.d_hidn, self.config.n_enc_keys_vocab, bias=False)
def forward(self, enc_inputs, dec_inputs):
dec_outputs, enc_self_attn_probs = self.transformer(enc_inputs, dec_inputs)
# 주석처리 dec_outputs, _ = torch.max(dec_outputs, dim=1)
logits = self.projection(dec_outputs)
return logits, enc_self_attn_probs
Python
•
모델 학습 :
...
# 학습시 데이터 float()
tk = tk.float().to(device)
m = m.float().to(device)
k = k.float().to(device)
...
...
#eval 함수가 아직 구현되지 않아 loss 값 기준으로 best epoch 및 loss 값 설정
if best_loss > loss:
best_epoch, best_loss = epoch, loss
Python
•
Loss function : 그냥 MSELoss 사용
모델 학습 1차 결과
•
1000에폭 1408 스텝 진행
•
학습이 진행이 되는지 파악 ⇒ 모델 자체가 학습은 잘 진행하는 것을 확인
◦
loss 0.3 정도
•
학습, 정답, output결과 확인
•
데이터셋 구성에 오류가 있어 재학습이 필요한 상태
◦
Tar 데이터 수정해서 재학습 필요
•
2차 학습 진행 예정