Inflearn brand logo image

인프런 커뮤니티 질문&답변

terranysj123님의 프로필 이미지
terranysj123

작성한 질문수

딥러닝을 활용한 자연어 처리 (NLP) 과정 (기초부터 ChatGPT/생성 모델까지)

실습 - Encoder-Decoder 기계 번역 모델 만들기 - part2

Encoder-Decoder 질문 드립니다.

작성

·

33

0

안녕하세요.강사님.
우선 강의 잘 보고 있습니다.

AI 코드에 익숙치 않아서 그런지..

강의 내용을 따라 쳐서 완료를 했는데,
무슨 이유에서 인지, 모델을 훈련 후에 해당 함수를 써서 확인하는 구간에서

def decode_sequence(input_seq):

어떤 문장을 돌려도 <eos> 가 발생해 2~3번째 이상 넘길수가 없는 상태인데요.

코드 내용은 아래와 같습니다.

encoder-decoder.png.webp



강의 영상에선 어느정도 준수한 수준의 Translation 이 되는것 같아보여, 영상이랑 코드 비교도 더해보고, epochs 도 조금 더 올려서 해보기도 했는데 역시나 잘 안되서..

강의 코드를 복붙에서 쳐볼까도 했는데 전체적으로 온전한 코드가 아닌 상태여서 혹시 제가 비정상적으로 동작되는게 원래 맞는건지 문의드리고 싶습니다.

감사합니다.

답변 2

0

YoungJea Oh님의 프로필 이미지
YoungJea Oh
지식공유자

검정색 화면으로 스크립 캡처해서 올리신 코드를 제가 알아보기 힘들어 디버깅하기 어렵습니다. 작성하신 코드를 COPY/PASTE 해서 올려주시면 디버깅해 드리겠습니다. 감사합니다.

terranysj123님의 프로필 이미지
terranysj123
질문자

일부 print함수를 통해서 값을 확인하려고 했던 부분이 있는데, 같이 보시는게 좋을까 해서 그대로 었습니다.

사전에 제가 학습을 잘 못 시킨거라면, 전체적으로 다시 한번 강의를 보면서 새롭게 복습해보겠습니다.

감사합니다.

 

작성코드 :

def decode_sequence(input_seq):
  states_value = encoder_model.predict(input_seq, verbose=0)
  target_seq = np.zeros((1,1))
  target_seq[0,0] = word2idx_kor['<sos>']
  eos = word2idx_kor['<eos>']
  output_sentence = []
  for _ in range(max_len_kor):
    print('----------------------------')
    print( 'target_seq[0,0]: ',target_seq[0,0])
    output_tokens, h, c = decoder_model.predict([target_seq] + states_value, verbose=0)
    idx = np.argmax(output_tokens[0,0, :])
    print( idx, ' vs. ' , eos)
    if eos == idx:
      break;
    if idx > 0:
      word = tokenizer_kor.index_word[idx]
      print( 'word : ',word)
      output_sentence.append(word)
      print( 'output_sentence : ',output_sentence)

    target_seq[0,0] = idx
    states_value = [h,c]
  return ' '.join(output_sentence)

for _ in range(2):
  print('\nSTART\n')
  i = np.random.choice(len(eng_texts))
  input_seq = encoder_inputs[i:i+1]
  print('Input[',i,']:', eng_texts[i])
  translation = decode_sequence(input_seq)
  print('Translation : ', translation)
  print('\nEND')

출력결과 :

image.png


 

YoungJea Oh님의 프로필 이미지
YoungJea Oh
지식공유자

현재 코드만으로는 정확히 원인을 알 수 없고 훈련 과정의 코드를 같이 보아야 할 것 같습니다. 다음의 코드를 추가하면 원인 파악이 거의 될 것 같은데

============== 추가 ====================

print("IDs -> SOS:", SOS_ID, "EOS:", EOS_ID, "PAD:", PAD_ID)

print("First input to decoder:", int(target_seq[0,0]))

print("max_len_kor:", max_len_kor)

=========================================

SOS==EOS거나 SOS가 None이면 바로 원인 확정이고, PAD와 특수토큰이 섞여 있으면 재토크나이징/토크나이저 재생성이 필요할 것 같습니다.

max_len_kor가 1이라면 당연히 한 토큰만 나옵니다. 이 값도 한번 확인 바랍니다. 감사합니다.

terranysj123님의 프로필 이미지
terranysj123
질문자

답변이 좀 늦었습니다.

알려주신데로 추가 프린터 문을 넣었는데, 문제는
print("IDs -> SOS:", SOS_ID, "EOS:", EOS_ID, "PAD:", PAD_ID)
변수에 대한 선언이 없기 때문에 일단 다른 LLM 툴을 통해서 의도하신바를 유추해서 아래와 같이 코드를 넣었습니다.
틀릴지 모르겠지만 확인이 가능하시면 부탁드립니다.
pad_id 의 경우는 어떻게 확인해야 될지 몰라서 일단 넣지 않았습니다.
이번에 혹시 답변을 주시면 마지막으로 확인해보고 제가 공부가 부족해서 그런 부분으로 마무리 하겠습니다.
감사합니다.

작성코드(수정) :

def decode_sequence(input_seq):
  states_value = encoder_model.predict(input_seq, verbose=0)
  target_seq = np.zeros((1,1))
  target_seq[0,0] = word2idx_kor['<sos>']
  eos = word2idx_kor['<eos>']


  # 필요한 ID 값들을 미리 변수로 받아오기 (가독성 및 확인 용이)
  sos_id = word2idx_kor['<sos>']
  eos_id = word2idx_kor['<eos>']
  # ==================== 강사님 의도에 맞게 수정한 코드 ====================
  # 루프 시작 전에 특수 토큰 ID들이 올바른지 한 번만 출력해서 확인
  print(f"IDs -> SOS: {sos_id}, EOS: {eos_id}") 
  print(f"First input to decoder: {int(target_seq[0, 0])}")
  print(f"max_len_kor: {max_len_kor}")
  print('----------------------------')
  # ======================================================================

  output_sentence = []
  for _ in range(max_len_kor):
    print('----------------------------')
    print( 'target_seq[0,0]: ',target_seq[0,0])
    output_tokens, h, c = decoder_model.predict([target_seq] + states_value, verbose=0)
    idx = np.argmax(output_tokens[0,0, :])
    print( idx, ' vs. ' , eos)
    if eos == idx:
      break;
    if idx > 0:
      word = tokenizer_kor.index_word[idx]
      print( 'word : ',word)
      output_sentence.append(word)
      print( 'output_sentence : ',output_sentence)

    target_seq[0,0] = idx
    states_value = [h,c]  
  return ' '.join(output_sentence)

for _ in range(2):
  print('\nSTART\n')
  i = np.random.choice(len(eng_texts))
  input_seq = encoder_inputs[i:i+1]
  print('Input[',i,']:', eng_texts[i])
  translation = decode_sequence(input_seq)
  print('Translation : ', translation)
  print('\nEND')


출력결과 :

image.png


YoungJea Oh님의 프로필 이미지
YoungJea Oh
지식공유자

작성하신 코드 말고 교재 원본 파일을 돌려도 동일한 결과가 나오시나요? 만약 교재 원본과 작성하신 코드의 결과가 다르게 나온다면 두 코드 간에 다른 부분을 찾으시면 그 것이 원인이겠고, 교재 원본을 돌려도 마찬가지로 한글자 나오고 끝나는 결과가 나오시면 환경 문제가 아닌가 생각합니다. 혹시나 하여 방금 Google Colab 에서 다시 작업을 돌려 보았는데 정상적으로 출력되는 것을 확인하였습니다. 혹시 차이점을 발견 못하시겠다면 전체 코드 파일을 제 이메일로 보내 주시면 제가 도와드리겠습니다. trimurti@naver.com 으로 전체 노트북 코드 파일 보내주세요.

terranysj123님의 프로필 이미지
terranysj123
질문자

아 네, 댓글로 알려주신 대로 교재 원본 파일에는 정상적으로 동작하네요..
아무래도 제가 코드를 잘 못 적은 것이나 착각을 한 것 같습니다.
다시 한 번 재검토해보고 아무래도 모르겠으면, 알려주신 메일로 코드와 문의 드리겠습니다.
적극적으로 확인 해주셔서 너무 감사드립니다! 😊

0

안녕하세요, 인프런 AI 인턴입니다.
딥러닝을 활용한 자연어 처리 강의에 대한 질문을 주셨군요. 인코더-디코더 모델을 사용하여 시퀀스 예측을 수행할 때, 예상보다 결과가 좋지 않아 고민이 되시는 것 같습니다.

모델이 <eos> 토큰 때문에 충분한 번역을 못하는 경우는 여러 원인이 있을 수 있습니다. 주된 이유로는 훈련 데이터의 불균형, 모델 파라미터 설정, 또는 태그 및 시퀀스 길이 관련 설정 문제 등이 있습니다.

  1. 데이터 사전 처리 및 토크나이저 확인:

    • <sos><eos> 토큰을 정확히 설정했는지 확인해 보세요.
    • 토크나이저가 올바르게 설정되어 있는지 다시 한 번 점검해 보시면 좋을 것 같습니다.
  2. 모델 설정 및 파라미터 확인:

    • 모델의 레이어 구성 및 활성화 함수, 손실 함수가 적절히 설정되어 있는지 확인해 보세요.
    • decode_sequence 함수의 로직과 파라미터 전달이 제대로 이루어졌는지 검토해 보세요.
  3. 에포크 수 및 학습률 조절:

    • 학습이 충분히 이루어졌는지 확인하고, 학습률과 에포크 수를 적절히 조절하여 재학습해 보시는 것도 방법입니다.

비슷한 사례에 대한 질문이 커뮤니티에 올라와 있는 것이 있으면 참조할 수 있으니 확인해 보세요:

위 질문들은 인코더-디코더 모델과 관련된 teacher forcing, 문장의 입력 및 출력 예측과 관련된 이슈들에 대한 답변과 토론이 포함되어 있습니다. 이와 비슷하게 문제를 해결하는 데 도움이 될 수 있을 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

terranysj123님의 프로필 이미지
terranysj123

작성한 질문수

질문하기