이 포스트는 "밑바닥부터 시작하는 딥러닝2 - 파이썬으로 직접 구현하며 배우는 순환 신경망과 자연어 처리 (한빛미디어, 사이토 고키 지음)" 책을 기반으로 공부해서 정리한 내용이다.
Chapter7: RNN을 사용한 문장 생성
7.1 언어 모델을 사용한 문장 생성
- 언어 모델: 지금까지 주어진 단어들에서 다음에 출현하는 단어의 확률분포를 출력
- 다음 단어를 생성하기 위해서는?
- 결정적 방법: 확률이 가장 높은 단어를 선택
- 확률적 방법: 각 후보 단어의 확률에 맞게 선택 -> 매번 선택되는 단어가 달라질 수 있음 - 이렇게 학습된 단어의 정렬 패턴을 이용해(학습이 끝난 가중치를 통해) 새로운 문장을 생성하는 것이 가능
- 더 좋은 언어 모델로 더 자연스러운 문장을 생성
7.2 seq2seq
- 시계열 데이터 ex) 언어 데이터, 음성 데이터, 동영상 데이터
- 시계열 데이터 -> 시계열 데이터 ex) 기계 번역, 음성 인식, 챗봇, 컴파일러
- seq2seq: 시계열 데이터를 다른 시계열 데이터로 변환하는 보델(여기서는 2개의 RNN 사용)
- Encoder: 입력 데이터를 인코딩, Decoder: 인코딩된 데이터를 디코딩
- 인코딩된 정보에는 번역에 필요한 정보가 조밀하게 응축되어 있음
- 디코더는 이러한 응축된 정보를 바탕으로 도착어 문장 생성
- Encoder에서 출력되는 벡터는 마지막 은닉 상태 h: 번역하는 데 필요한 정보가 인코딩, 고정 길이 벡터
- 즉 인코딩 == 임의 길이의 문장을 고정 길이 벡터로 변환하는 것
- 이 h가 encoder, decoder를 이어주는 가교 역할, 순전파 때는 인코딩된 정보가 전해지고, 역전파일 때는 기울기가 전해짐 - 장난감 문제 테스트(머신러닝을 평가하고자 만든 간단한 문제, 덧셈 테스트)
- 문장을 단어가 아닌 문자 단위로 분할
- 가변 길이 시계열 데이터가 입력으로 -> 패딩 필요(정확도를 높이기 위해서는 패딩값이 결과에 반영되지 않도록 softmax with loss 계층에 마스크 기능을 추가하거나 lstm 계층에서 패딩 값이 들어오면 이전 시각의 입력을 그대로 출력하거나 등등의 작업이 필요)
++ 정석적인 방식으로는 데이터셋 3개 필요(훈련용, 검증용-하이퍼파라미터 튜닝, 테스트용)
7.3 seq2seq 구현
- Encoder: Time embedding + Time LSTM -> 마지막 은닉 벡터 h decoder로 전달
- Decoder: Time embedding + Time LSTM + Time Affine
- 학습: + Time softmax with loss
- 문장 생성: + argmax 노드(affine 계층의 출력 중 값이 가장 큰 원소의 인덱스를 반환) - 학습: 미니배치 선택 -> 기울기 계산 -> 매개변수 갱신
- 평가: 현재 모델로는 덧셈 테스트에서 그다지 좋은 정답률을 보이지는 않음
7.4 seq2seq 개선
- 입력 데이터 반전(reverse)
- 직관적으로 기울기 전파가 원활해지기 때문(문장의 앞쪽 단어는 반전하게 되면 대응하는 변환 후 단어와 가까워지므로 기울기가 더 잘 전해져 학습 효율이 좋아진다)
- 많은 경우 학습 진행이 빨라짐, 결과적으로 최종 정확도도 좋아짐 - 엿보기(peeky)
- Decoder에게 있어 h는 매우 중요한 정보
- h를 여러 계층에 공유해서 집단지성과 같은 효과
- 하지만 가중치 매개변수가 커지므로 계산량이 늘어남
- seq2seq의 정확도는 파이퍼파라미터에 영향을 크게 받음
7.5 RNNLM 추가 개선
- 기계번역, 자동 요약, 질의응답, 메일 자동 응답
- 챗봇, 알고리즘 학습, 이미지 캡셔닝(이미지 -> 문장, encoder를 합성곱 신경망[CNN]으로 대체)
++CNN: 최종 출력은 특징 맵(높이, 폭, 채널) -> decoder의 LSTM이 처리할 수 있도록 1차원으로 flattening 후 affine 계층에서 변환, VGG,ResNet 등의 입증된 신경망 사용, 가중치로는 다른 이미지 데이터셋으로 학습을 끝낸 것을 이용
Chapter8: 어텐션
8.1 어텐션의 구조
- seq2seq의 근본적인 문제를 해결하고 크게 개선시킬 수 있는 어텐션 메커니즘
- seq2seq의 문제점: encoder의 출력이 고정 길이 벡터 -> 아무리 긴 문장이 입력되더라도 항상 같은 길이의 벡터로 출력해야 함 -> 필요한 정보가 벡터에 다 담기지 못하게 된다
- Encoder 개선
- 출력 길이를 입력 문장의 길이에 따라 바꾸기
- 시각별 LSTM 계층의 은닉 상태 벡터를 모두 사용
- 결국 이 hs의 각 행은 직전에 입력된 단어에 대한 정보가 많이 포함, 즉 각 단어에 해당하는 벡터들의 집합이라 할 수 있음
++ 많은 딥러닝 프레임워크에서 RNN(LSTM, GRU) 계층을 초기화할 때 모든 시각의 은닉 상태 벡터 반환/마지막 은닝 상태 벡터만 반환 선택 가능 - Decoder 개선
- 입력과 출력의 여러 단어 중 어떤 단어끼리 서로 관련되어 있는지, 즉 고양이와 cat이 대응관계에 있는 것처럼 이러한 대응 관계를 seq2seq에 학습시켜야 한다(단어 또는 문구의 대응 관계를 나타내는 alignment 자동화)
- 필요한 정보에만 주목하여 도착어 단어와 대응 관계에 있는 출발어 단어의 정보를 골라내기
- 각 시각에서 decoder에 입력된 단어와 대응 관계인 단어의 벡터를 hs(encoder 출력값)에서 선택하기 -> 선택 과정을 미분 가능한 연산으로 바꾸기(오차역전파법 가능)
- Attention Weight 계층: encoder가 출력하는 각 단어의 벡터 hs에 주목하여 해당 단어의 가중치 a 구함 - 은닉 벡터 h와 hs의 각 행의 유사도를 내적을 이용해 산출 -> softmax를 통한 정규화 -> 가중치 값으로 사용
- Weight Sum 계층: a와 hs의 가중합을 구하고 그 결과를 맥락 벡터 c로 출력
- 선택하는 작업을 이 가중합으로 대체, 만약 하나의 가중치가 1이고 나머지가 0이라면 그 벡터를 선택하는 것과 똑같은 효과 - 최종
- affine 계층에는 은닉 상태 벡터뿐만 아니라 맥락 벡터가 추가적으로 입력된다
8.2 어텐션을 갖춘 seq2seq 구현
- encoder: 모든 은닉 상태 반환
- decoder: 순전파, 역전파, 새로운 문장 생성 / attention 계층 연결
8.3 어텐션 평가
- 날짜 형식 변경하는 문제 테스트
- 간단하지 않음, 입력과 출력에 년,월,일 대응 관계 존재 -> 어텐션이 올바르게 주목하는지 확인 가능 - 학습 결과 및 어텐션 시각화
- 어텐션에서는 모델의 처리 논리가 인간의 논리를 따르는지를 판단 가능
8.4 어텐션에 관한 남은 이야기
- 양방향 RNN
- 단어의 주변 정보를 균형있게
-구현 방법 중 한 가지는 2개의 LSTM 계층을 준비한 후 입력 단어의 순서를 조정 - attention 계층의 위치
- 앞 절에서 본 계층 구성이 좀 더 구현하기 쉬움, 쉽게 모듈화 가능 - seq2seq 심층화
- LSTM 계층을 깊게 쌓으면 표현력 높은 모델 쌓을 수 있음
- 일반적으로 encoder와 decoder에서 같은 층수의 lstm 사용
- 계층을 깊게 할 때는 일반화 성능을 떨어뜨리기 않기 위해 드롭아웃, 가중치 공유 등 사용 - skip 연결(잔차 연결, 숏컷)
- 층을 깊게 할 때 사용되는 중요한 기법
- 계층을 넘어 선을 연결, 계층을 건너뛴다
- 접속부에서 원소별 덧셈 -> 역전파 시 기울기를 그대로 흘려보내므로 기울기 손실/폭발 위험성 줄여 좋은 학습 가능
- RNN 시간 방향에서 기울기 소실: 게이트 달린 RNN, 기울기 폭발: 기울기 클리핑, RNN 깊이 방향 기울기 소실: skip 연결 효과적
8.5 어텐션 응용
- 구글 신경망 기계 번역(GNMT)
- LSTM 계층 다층화, 양방향 LSTM, skip 연결, GPU 분산 학습 - 트랜스포머
- 딥러닝 학습은 GPU를 이용한 병렬 계산 환경에서 이루어짐, 하지만 RNN은 시간방향으로 병력적 계산이 불가능함
-> RNN을 없애거나 병렬 계산할 수 있는 RNN 연구 활발
-> 트랜스포머 모델: RNN이 아닌 어텐션을 사용해 처리
- self-attention: 하나의 시계열 데이터 내에서 각 원소가 다른 원소들과 어떻게 관련되어있는지
- 하나의 시계열 데이터 내에서 원소 간 대응 관계 구해짐
- 피드포워드 신경망: 시간 방향으로 독립적으로 처리
- GNMT보다 학습 시간을 큰 폭으로 줄이고 번역 품질도 상당히 올릴 수 있음
-> 어텐션은 RNN을 대체하는 모듈로도 사용 가능하다 - 뉴럴 튜링 머신(NTM)
- 외부 메모리를 통한 혹장
- encoder가 필요한 정보를 메모리에 적고, decoder가 메모리로부터 필요한 정보를 읽어 들인다
- 이러한 메로리 조작을 미분 가능한 계산으로 구축 -> 학습 가능
- LSTM 계층이 컨트롤러 역할
- 콘텐츠 기반 어텐션(입력 벡터와 비슷한 벡터를 메모리로부터 찾아냄), 위치 기반 어텐션(이전 시각에서 주목한 메모리의 위치를 기준으로 그 전후로 이동, 1차원의 합성곱 연산으로 구현) - 외부 메모리를 사용함으로써 알고리즘을 학습하는 능력, 긴 시계열 기억 문제와 정렬 문제 해결 가능
학습한 코드는 여기에서
https://github.com/syi07030/NLP_study
위 코드는 이 책의 코드와 아래의 코드를 바탕으로 작성했습니다.
https://github.com/WegraLee/deep-learning-from-scratch-2
사진 출처 또한 여기에서: https://github.com/WegraLee/deep-learning-from-scratch-2
'3-2기 스터디 > NLP 입문' 카테고리의 다른 글
[8주차] 딥러닝을 이용한 자연어처리 입문 Chap.16 Transformer (0) | 2022.05.30 |
---|---|
[9주차] 딥러닝을 이용한 자연어처리 입문 Chap.17 BERT (0) | 2022.05.30 |
[7주차] 딥러닝을 이용한 자연어처리 입문 Chap.2 텍스트 전처리 (0) | 2022.05.30 |
[5주차] NLP Chapter 5.2 RNN이란 ~ 6. 게이트가 추가된 RNN (0) | 2022.05.02 |
[4주차] NLP Chapter 4. word2vec 속도 개선 ~ 5.2 RNN이란 (0) | 2022.05.02 |
댓글