2021. 8. 14. 20:48ㆍIT Study/Ai
이번 장에서는 앞에서 설명한 seq2seq의 구조를 살짝 변경해 성능을 올리는 기술을 설명 하겠다.
구조자체는 간단한 기술이라서 설명할 것이 많지 않기에 가볍게 봐주었으면 좋겠다.
하지만 이장 마지막에 나올 어텐션 기술을 위한 고정길이 벡터 개선 부분은 매우 중요한 기술이니 정확이 이해하는 것을 추천한다.
입력 데이터 반전(Reverse)
제목그대로 우리가 시계열 데이터 xs를 모델에 입력을 할 때 그 입력데이터의 순서를 반전 시켜 주는 것이 하나의 방법이 될 수 있다.
반전의 형식은 모든 행마다 열부분을 반전 시켜주는 것인데
예를들어 "나는 밥을 먹는다."가 입력이 되면 ".먹는다 밥을 나는" 가 입력값이 되는 것이다.
아이디어 자체는 어려운게 없어서 구현부는 설명을 패스 하겠지만 왜 이 기술이 효과 있는 것인가가 제일 중요한 부분일 것이다.
가장 이해하기 쉬운 예시가 번역작업을 들 수 있는데
".먹는다 밥을 나는"이라는 입력데이터가 들어오면 그에대한 출력 값은 "i eat lunch."가 될 것이다. 이는 시계열 데이터 입력의 대한 특징으로 왼쪽에서 오른쪽으로 순차적으로 입력되는 것을 생각해보면 "나는"에 대응하는 "i"가 반전을 하지 않았을 때보다 구조적으로 가까워짐을 확인 할 수있다.
이는 결국 오차의 역전파시 오차가 기존보다 더욱 강력하게, 효과적으로 전달이 가능함을 의미하는 것이다.
참고로 행렬의 데이터 반전은 arr[::-1]을 통해 가능하다. 이 경우에는 arr[ : , ::-1]이 될 것이다.
엿보기(Peeky)
Peeky라는 기술은 Encoder에서 넘어오는 은닉상태 벡터 h의 역할을 확장하는 기술이다.
지금까지의 seq2seq는 Decoder부분에서 처음 Lstm만 Encoder의 은닉상태 벡터를 받게 된다. 하지만 전 포스팅에도 기술했듯이 대부분의 중요한 정보는 Encoder에서 연산이 되어 은닉상태 벡터로 저장되어 오게 된다. 즉 seq2seq의 핵심 정보는 은닉상태 벡터에 있다고 봐도 과언이 아니다.
그러한 정보가 단 한번만 쓰이는 것은 효율이 나쁘다고 충분히 생각할 수 있는 것이다. 필자도 이부분을 공부하기전 이 h가 한부분에만 사용 되는 것에 궁금증을 느꼈고 게이트를 활용해서 모든 부분에 추가하면 더 좋게 모델이 만들어 지지 않을까? 생각까지 하였다.
책에서 기술하고있는 Peeky의 구조는 은닉상태 벡터 h를 Decoder의 모든 Lstm과 Affine계층에 전달을 해주는 모습을 띄고 있다.
구조자체는 역시 여려운 부분이 없다. 하지만 하나 짚고 넘어가야 할점은 Lstm과 Affine 계층에서 입력값이 두개가 됬다는 점이다. 지금까지 우리가 구현한 Lstm과 Affine계층을 생각해보면 입력값을 전처리 해줘야 하는 것이다.
그 방법이 ConCat노드를 사용하는 것이다.
이렇게 두방향에서 오는 입력값을 하나로 모아 전달을 해주는 것이다.
참고로 이 Peeky기술 구현부에서 한가지 헷갈릴수 있는점을 써두고 싶은데 자연어처리 모델들의 대부분구현은 모두 Time으로 묶어서 처리하는 것을 잊으면 안된다. 이 Concat기술또한 묶어서 처리해 TimeConcat처럼 사용을 한다. 그렇게 시계열 데이터인 xs를 만들어 입력을 하는 것이다.
고정길이 벡터 개선
지금부터는 어텐션 기술의 영역이다. 이번 장에서는 Encoder의 역할을 위주로 설명하고 Decoder의 역할은 다음 포스팅에 후술 하겠다.
기존 Seq2Seq는 Encoder에서 은닉상태 벡터 h를 넘길 때 고정길이 벡터로 넘기게 된다.
이 고정길이 벡터라는 것은 구현 할 때는 간단하지만 결국 Ai의 융통성을 떨어트리는데 예를 한번 들어보자
"i am korean"
"i am korean and i can't speak english well, so i will study english everyday because i want to talk to foriner.
이 두개의 문장을 보자. 만약 고정길이 벡터가 4의 크기를 가지고 있다면 위 짧은 문장은 문제가 되지않을 것이다. 하지만 아래의 문장을 처리 한다고 가정했을 때 고정길이 벡터의 크기가 작다면 충분히 문장의 내용을 내포하지 못하게 되는 문제점이 생긴다.
그렇다면 먼저 생각해 낼 수 있는 아이디어는 처음부터 고정길이 벡터를 크게 잡는 것이다.
물론 이 글을 읽고있는 개발자분들은 이 방법이 매우 좋지않은 아이디어임을 알 수있을 것이다.
그렇다면 고정길이 벡터가아닌 가변길이 벡터로 전환 하면 이 문제는 해결 될 것이다. 정확히는 입력데이터의 크기에 따라 은닉상태 h가 변화되면 될 것이다.
가장 쉬운방법이자 책에서 구현하고 있는 방법은 Encoder에서 출력되는 h모두를 hs라는 변수에다가 차곡차곡 저장하는 것이다 그렇게 되면 hs의 행의 갯수는 시계열 데이터의 크기가 될 것이고 열의 갯수는 고정길이가 될 것이다.
이렇게되면 입력데이터가 아무리 길어져도 충분히 은닉상태 벡터h가 그 특징을 다 받아낼 수 있을 것이다.
이제 이 벡터를 Decoder에넘기면 Encoder의 역할은 끝이난다. 이제 Decoder의 역할만 남았는데 그 것은 다음 포스팅에 후술하겠다.
본 포스팅은 밑바닥부터 시작하는 딥러닝2에 기초하여 작성되었습니다.
'IT Study > Ai' 카테고리의 다른 글
Attention(어텐션) (0) | 2021.08.17 |
---|---|
seq2seq(Sequence to Sequence) (0) | 2021.08.04 |
LSTM(Long Short-Term Memory) (0) | 2021.07.30 |
RNNLM(RNN Language Model) (0) | 2021.07.28 |
RNN, Truncated BPTT, Time RNN (0) | 2021.07.27 |