어텐션 메커니즘이란, 트랜스포머의 기반이 되는 모델이자, seq2seq의 단점을 보완할 수 있는 개념이다.

 

멀수록 잊혀진다(decoder) --- >  갈수록 흐려지는 정보에 ATTNETION하자!!

 

seq2seq 모델은 기존 RNN과 같이 고정된 길이의 벡터를 입력으로 받아 고정된 길이의 벡터를 출력하는 구조를 갖고 있음

이 구조는 시퀀스 길이가 길어질수록 정보 손실이 발생함!

 

이러한 한계를 보완하기 위해 Attention Mechanism이 도입되었다. 

어텐션 메커니즘은 입력 문장의 모든 단어를 동일한 가중치로 취급하지 않고, 출력 문장에서 특정 위치에 대응하는 입력 단어들에 더 많은 가중치를 부여하는 원리로 만들어졌다.

이를 통해 입/출력의 길이가 달라도 모델이 상대적으로 더 정확하고 유연하다고 볼 수 있다.

 

seq2seq

인코더: 입력 시퀀스를 context vector라는 하나의 고정된 크기의 벡터 표현으로 압축

디코더: 이 context vector를 통해서 출력 시퀀스를 만들어냄

문제점: 1 - 하나의 고정된 크기의 벡터에 모든 정보를 압축하려고 하다보니 정보 손실 발생!

             2 - RNN의 고질적인 문제인 기울기 소실이 존재!\

 

 

1. 어텐션의 기본 아이디어

어텐션의 기본 아이디어는 디코더에서 출력 단어를 예측하는 매 시점(time step)마다, 인코더에서의 전체 입력 문장을 다시 한 번 참고한다는 점이다.

단, 전체 입력 문장을 전부 다 동일한 비율로 참고하는 것이 아니라, 해당 시점에서 예측해야할 단어와 연관이 있는 입력 단어 부분을 좀 더 집중(attention)해서 보는 것이다.

 

중요하니까 자세히..!!

디코더(Decoder)에서 출력 단어 예측하는 매 시점(time step)마다 인코더(Encoder)에서의 전체 입력 문장(sequence)을 다시 한 번 참고한다는 것..

단, 전체 입력 sequence 참고하는게 아니라 해당 시점에서 예측해야할 단어 연관이 있는 입력 단어 부분을 좀 더 집중해서 보겠다는 것이다.

 

2. 어텐션 함수(Attention Function)

파이썬의 딕셔너리 함수를 떠올려보자. key-value, 쌍으로 이루어진 자료형이다.

이 딕셔너리 자료형은 키를 통해서 매핑된 값을 바로 찾아낼 수 있다는 특징을 갖고 있다.

 

dict = {"2017" : "Transformer", "2018" : "BERT"}의 경우, 2017은 키, Transformer은 값(value)에 해당한다.

이 개념을 통해서 어텐션 함수에 대해서 그림을 통해 알아보자.

 

어텐션을 함수로 표현하면 주로 다음과 같이 표현할 수 있다.
Attention(Q, K, V) = Attention Value

 

어텐션 함수는 주어진 '쿼리(Query)'에 대해서 모든 '키(Key)'와의 유사도를 각각 구한다. ★

그리고 구해낸 이 유사도를 키와 매핑되어있는 각각의 값에 반영하고 유사도가 반영된 값을 모두 더해서 리턴.

여기서는 이를 어텐션 값(Attention Value)이라고 하고, 지금부터 배우게 되는 seq2seq + 어텐션 모델에서 Q, K, V에 해당되는 각각의 Query, Keys, Values는 각각 다음과 같다.

Q = Query : t 시점의 디코더 셀에서의 은닉 상태
K = Keys : 모든 시점의 인코더 셀의 은닉 상태들
V = Values : 모든 시점의 인코더 셀의 은닉 상태들

 

Attention 모델은 인코더 층 seq2seq층 동일하지만 디코더 층에서 차이가 남.

디코더 층에서는 RNN계열 층을 지나고 Attention 층을 지나는데 이때 Attention층에서는 시점마다 RNN계열층 은닉상태(Quary)와 인코더에서의 전체 입력 시퀀스 정보(Key, Value)를 다시 한번 참고한다.

 

 

 

 

 

✅ 쿼리 (Query)
• 쿼리는 어텐션 메커니즘에서 주목할 대상을 나타내는 정보
• 쿼리는 보통 출력 시퀀스의 현재 위치 또는 상태와 관련이 있으며, 어텐션 메커니즘을 통해 중요한 입력 요소를 찾는 데 사용
• 기계 번역에서 디코더의 현재 출력 단어에 해당하는 쿼리가 사용될 수 있으며, 이 쿼리는 입력 문장의 어떤 부분에 더 집중해야 하는지를 결정

 

✅ 키 (Key)
• 키는 입력 시퀀스의 각 요소에 대한 정보를 나타냄
• 키는 쿼리와 비교되어 유사성을 측정하며, 어떤 입력 요소가 현재 쿼리와 얼마나 관련 있는지를 결정하는 데 사용.
• 키는 일반적으로 입력 시퀀스의 각 요소 (예: 단어 또는 문장)에 대한 벡터 또는 표현으로 표현됨

 

✅ 값 (Value)
• 값은 입력 시퀀스의 각 요소에 대한 정보를 담고 있다.
• 값은 어텐션 메커니즘에서 가중 평균을 계산할 때 사용되며, 쿼리와 키의 유사성에 따라 값에 가중치가 부여된다.
• 값은 주로 입력 시퀀스의 각 요소에 대한 정보를 포함하는 벡터 또는 표현으로 표현된다.

 

이러한 Q,K,V(쿼리, , 벨류)를 가지고 Attention층에서는 Attention 함수 사용되는데 이때 다양한 함수(Attention Score Function)를 이용해서 Attention Score가 만들어지고 보통 SoftMax 함수를 통해 Attention Value가 생성됨

 

 

어텐션 함수는 주어진 쿼리(Query)에 대해 모든 키(Key)와의 유사도를 구한다.

벡터간의 거리(유사도)를 구하는 방법은 내적코사인 유사도유클리디안 거리 방법 등이 있지만 내적 유사도를 보통 사용한다고 한다.

 

유사도 개념 중요 ★

 

여기서 Attention Score 함수 중 Dot-product Attention에 대해서 알아보자!!

아래 그림 참조

인코더의 시점(time step)을 각각 1, 2, ... N이라고 하였을 때 인코더의 은닉 상태(hidden state)를 각각 ℎ1, ℎ2, ... ℎ𝑁라고 합시다. 디코더의 현재 시점(time step) t에서의 디코더의 은닉 상태(hidden state)를 𝑠𝑡라고 해보자.

 

어텐션 메커니즘의 첫 걸음인 어텐션 스코어(Attention score)에 대해서 배우기전에, 이전 챕터 배웠던 디코더의 현재 시점 t에서 필요한 입력값을 다시 떠올려보자. 시점 t에서 출력 단어를 예측하기 위해서 디코더의 셀은 두 개의 입력값을 필요로 하는데, 바로 이전 시점인 t-1의 은닉 상태와 이전 시점 t-1에 나온 출력 단어다.

그런데 어텐션 메커니즘에서는 출력 단어 예측에 또 다른 값을 필요로 하는데 바로 어텐션 값(Attention Value)이라는 새로운 값이다. t번째 단어를 예측하기 위한 어텐션 값을 𝑎𝑡이라고 해보자.

 

어텐션 스코어란 현재 디코더의 시점 t에서 단어를 예측하기 위해, 인코더의 모든 은닉 상태 각각이 디코더의 현 시점의 은닉 상태 𝑠𝑡와 얼마나 유사한지를 판단하는 스코어값이다.

닷-프로덕트 어텐션에서는 이 스코어 값을 구하기 위해 𝑠𝑡를 전치(transpose)하고 각 은닉 상태와 내적(dot product)을 수행합니다. 즉, 모든 어텐션 스코어 값은 스칼라입니다. 예를 들어 𝑠𝑡과 인코더의 i번째 은닉 상태의 어텐션 스코어의 계산 방법은 아래와 같습니다.



-----------------------------------------------------------------------------------------------------------------------------------------------------------------

유튜브(https://www.youtube.com/watch?v=8E6-emm_QVg&t=80s)를 통해서 복습.

 

결국 어텐션이란 -> decoder의 각각의 상태에서, 시점마다 다른 context vector를 쓴다!!!! 

-> 4번째 시점에서 예측할 때는, 4번째에서 context vector를 구해야겠지?

Context Vector 4 = C4라고 하고, dot product를 써보면,  C4 = <S4,h1>h1 + <s4,h2>h2 + <s4,h2> + <s4,h3>h3 -> weighted sum이라고 할 수 있음.

 

weighted sum -> 취사 선택!! 즉, h1,h2,h3 중 어느것을 더 많이 쓸까? (어떤 단어를 더 볼까??~~)

-> 유사도 기준으로 쓰는게 논리적이겠지?? (내적 유사도를 구해보자!!)

 

-> 유사도가 더 높다 -> 더 닮았다!!! -> 너에게 더 Attention 해주겠다 -> 더 높은 가중치를 부여!

 

"선형 변환"

Loss를 가장 줄일 수 있는 벡터는 h1,h2,h3중 무엇일까~~요?

S4랑 어떤 단어를 더 가깝게 위치시킬지를 학습시킬까!,

l4 (loss)를 가장 잘 줄이기 위해서, S4랑 어떤 단어를 더 가깝게 놓도록 선형변환해야 좋을까??? 이게 핵심

-> h1이겠지!!!!

그럼 h1에 더 높은 가중치를 주게 되는 것이다!

h1가 가장 높은 가중치를 준 후, c4를 구해 -> s4랑 지지고 볶아서 y hat을 구해. -> 소프트맥스 통과 -> 디코더의 결과

 

또한, Attention과 Transformer를 통해서, Parallelization이 가능해졌다고 한다!

기존의 RNN연산은 구조적으로 Sequential연산 때문에, 병렬처리가 어려워 CPU로만 했어야 했지만, 

Transformer의 등장으로 GPU연산이 가능해졌다고 한다람쥐

 

 

참고1: (혁펜하임) https://www.youtube.com/watch?v=8E6-emm_QVg&t=80s

참고2: https://wikidocs.net/22893

 

15-01 어텐션 메커니즘 (Attention Mechanism)

앞서 배운 seq2seq 모델은 **인코더**에서 입력 시퀀스를 컨텍스트 벡터라는 하나의 고정된 크기의 벡터 표현으로 압축하고, **디코더**는 이 컨텍스트 벡터를 통해서 출력 …

wikidocs.net

참고3:https://velog.io/@sjinu/%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC-Attention-Mechanism

 

[개념정리] Attention Mechanism

Transformer의 기반이 되는 Attention 기법에 대해 정리한 글입니다.

velog.io

 

이번에 살펴본 RNN 구조는 두 개로 나누어, 하나는 인코더, 하나는 디코더로 명명한 후, 두 개의 RNN을 연결해서 사용하는 인코더-디코더 구조이다.

 

해당 인코더-디코더 구조는 "입력 문장"과 "출력 문장"의 길이가 다를 경우에 주로 사용한다.

대표적인 예시로 번역기/텍스트 요약이 있다.

 

(영어 -> 한국어로 번역 시 문장의 길이가 달라질 수 있으므로!

(원본 텍스트 -> 요약 -> 문장 수 감소 {문장 길이 변화})

 

1. 시퀀스-투-시퀀스 (Sequence-to-Sequence, seq2seq)

 

시퀀스-투-시퀀스는 입력된 시퀀스로부터 다른 도메인의 시퀀스를 출력하는 다양한 분야에서 사용된다고 한다. (챗봇, 기계 번역등)

입력 시퀀스와 출력 시퀀스를 각각 질문&대답으로 구성하면 챗봇을 만들 수 있고, 각각 입력 문장&번역 문장으로 만들면

번역기로 만들 수 있는 것이다. 그 외에도 텍스트 요약이니ㅏ STT(speech to text)에서도 쓰일 수 있다고 함.

seq2seq는 번역기에서 대표적으로 사용되는 모델로, 딥 러닝의 '블랙 박스'에서 확대해가는 방식으로 설명한다.

이제 위 그림에서 i am a student에서 프랑스어로 변화하는 내부 과정을 살펴보자.

인코더와 디코더를 통해 변환되는데, 여기서 중요한 포인트가 있다.

인코더는 입력 문장의 모든 단어들을 순차적으로 입력받은 뒤에 마지막에 모든 단어 정보를 압축해서 하나의 벡터로 만드는데, 이를 컨텍스트 벡터라고 한다.

(입력 문장의 정보가 하나의 context vector로 모두 압축 -> 인코더는 context vector를 디코더로 전송! -> 디코더는 입력받은 context vector를 하나씩 순차적으로 출력하는 과정)

 

실제로 사용되는 seq2seq 모델에서는 context vector가 수백개의 차원을 갖고 있다고 한다. (그림에서는 4차원)

또한, 성능 이슈로 인해 실제로는 바닐라 RNN이 아닌, LSTM/GRU 셀로 구성한다고 함!

 

주황색 인코더를 자세히 보면, 입력 문장은 단어 토큰화를 통해서 단어 단위로 쪼개어지고, 단어 토큰 각각은 RNN 셀의 각 시점에서 입력이 된다. 인코더 LSTM 셀은 모든 단어를 입력받은 뒤 인코더 LSTM 셀의 마지막 시점의 은닉 상태를 디코더 RNN 셀로 넘겨주는데, 이게 contexet vector인 것이다! 따라서 context vector는 디코더 RNN 셀의 첫 번쨰 은닉 상태겠지?

 

이제 그림의 디코더의 LSTM 셀을 보면, <sos>라는 심볼을 볼 수 있다.

sos는 초기 입력으로 문장의 시작을 의미하는 심볼이라고 하고, 이게 입력되면 다음에 등장할 확률이 높은 단어를 예측함

여기서는 je라고 예측했다고 볼 수 있다. 그리고 이 je가 다음 셀의 입력으로 들어가서 또 예측을 진행, suis를 결과! (반복)

참고로 이것은 테스트 과정 동안의 프로세스를 나타낸다. 

 

seq2seq는 훈련 과정과 테스트 과정의 작동 방식에 차이가 있다.

 

훈련 과정: context vector와 실제 정답을 동시에 가지므로, 지도 학습 방식을 통해 훈련함! = teacher forcing(교사 학습)

테스트 과정: 훈련 과정과 달리 오직 context vector와 sos 심볼만 입력받은뒤 예측 -> 결과 -> 예측 -> 결과 반복!!

 

알다 시피 기계는 텍스트보다 숫자 연산에 특화되어 있다. NLP는 기본적으로 tetx -> 벡터로 바꾸는 워드 임베딩을 주로 사용하고 있다 즉, seq2seq에서 사용되는 단어들은 모두 임베딩 벡터로 변환 후 입력으로 사용됨. 아래 그림은 임베딩 층임

                                                                   (I, am, a student의 embedding layer)

 

현재 시점을 t라고 할 때, RNN셀은 t-1에서의 은닉 상태와 t에서의 입력 벡터를 입력으로 받고, t에서의 은닉 상태를 만든다.

이때 t에서의 은닉 상태는 바로 위에 또 다른 은닉층이나 출력층이 존재할 경우 위 층으로 보내거나, 필요없다면 무시 할 수있다. 그리고 RNN 셀은 다음 시점에 해당하는 t+1의 셀의 입력으로 현재 t에서의 은닉 상태를 입력으로 보낸다.

 

(현 시점 t의 은닉 상태는 과거 심저의 동일한 RNN 셀에서의 모든 은닉 값들에 영향을 누적해 받아온 값임)

 

2. seq2seq 코드 실습

seq2seq2 모델을 설계하고, teacher forcing을 사용하여 훈련시켜보자.


참고로, vocab size 변수에 대한 정보는 아래 그림과 같다.

 

인코더 코드를 보자.

lstm의 은닉 상태 크기는 256

return_state = True -> 인코더의 내부 상태를 디코더로 넘겨주어야 하기 때문

 

LSTM에서 state_h, state_c를 리턴받는데, 이는 은닉 상태와 셀 상태에 해당한다.

이 두 가지 상태를 encoder_states에 저장한다.

그리고 encoder_states를 디코더에 전달함으로, 두 가지 상태 모두를 디코더로 전달하게 된다,! (이게 context vector)

 

디코더 코드)

디코더는 인코더의 마지막 은닉 상태를 초기 은닉 상태로 사용한다.

위에서 initial_state의 인자값으로 encoder_states를 주는 코드가 이에 해당한다고 볼 수 있다.

또한 동일하게 디코더의 은닉 상태 크기도 256으로 설정

 

 

테스트(activate) 동작 설계

 

디코더를 설계해보자. 

단어로부터 인덱스를 얻는 것이 아니라 인덱스로부터 단어를 얻을 수 있는 index_to_src와 index_to_tar로 만들기

 

sdsd

 

출처: 만들면서 배우는 생성 AI, 데이비드 포스터

 

확산 모델은 GAN과 함께 최근 AI 기술 중 많은 관심을 받은 개념이라고 한다.

확산 모델은 여러 벤치마크에서 GAN 보다 우수한 성능을 보이며, CV쪽에서 활발히 사용된다고 한다.

 

5.1 아이디어

Diffusion model의 기본 원리를 TV 매장으로 비유한 소개글이지만, 정말 설명을 못하는 것 같다.

어쨌든 이러한 아이디어가 확산 모델의 기본 개념을 나타낸다. 여러 노이즈에 노출된 후, 학습이 진행됨에 따라 노이즈를 제거하여 최종적으로는 진짜 같은 영상(이미지)를 생성하는 것 같다.

 

5.2 잡음 제거 확산 모델

잡음 제거 확산 모델의 기본 개념은 위 TV의 아이디어와 유사하다.

연속해서 이미지 속에서 노이즈를 없애는 것이다.(없애도록 훈련 시키는 것)

확산 모델에서는 정방향 (잡음 추가)과 역방향 (잡음 제거)가 존재한다고 함!

 

5.3 정방향 확산 과정

 

위 그림을 통해서 정방향 확산 과정 (노이즈 추가)을 알아보자.

x0을 계속해서 손상시켜 Xt로, 즉 랜덤한 가우스잡음과 동일하게 만든다고 가정해보자.

이렇게 하려면 어떻게 해야할까?

 

위 그림 Xt-1 이미지에 분산 Bt를 갖는 약간의 가우스 잡음을 추가하여 이미지 Xt를 생성하는 함수 q를 정의할 수 있다.

 

이 함수를 계속 적용하면 계속해서 노이즈가 커지는 이미지 시퀀스를 만들어낼 수 있는 것이다.

 

업데이트 과정을 수식으로 표현하면 다음과 같다.

 

결론: 정방향 확산 과정은 input된 이미지를 완전한 노이즈로 바꾸기 위해 계속해서 일정한 분산을 갖는 노이즈를 추가시킴.

 

5.3.1 재매개변수화 트릭

위에서는 그럼 계산을 T번 해야하는 건가? T번 계산하지 않고 input이미지에서 바로 최종 이미지(잡음 낀 이미지)로 건너뛸 수는 없을까? 

 

이를 위해 재매개변수화 트릭이라는 개념이 등장한다.

수식의 두 번째 줄 (xt = √at * xt-1 ~ ) 이 줄은 두 개의 가우스 분포를 더하여 새로운 가우스 분포 하나를 얻을 수 있다는 사실을 이용한다. 따라서 원본 이미지에서, 최종 뿐 아니라 어떠한 단계로든 이동할 수 있다!

 

또한, 원래 Bt대신 표본at를 사용하여 확산 스케쥴을 정의할 수 있다.

표본 at는 신호(원본 이미지)로 인한 분산이고, 1-표본at는 잡음으로 인한 분산이다.

따라서 정방향 확산 과정 q는 다음과 같이 쓸 수 있다.

 

5.4 확산 스케쥴

또한 각 타임 스텝마다 다른 Bt를 자유롭게 선택할 수 있다. 즉, 모두 동일할 필요가 없다는 것이다! 

이처럼 Bt값이 t에 따라 변하는 방식을 확산 스케쥴이라고 한다.

 

(원래 논문에서 저자들은 Bt에 대해서 선형 확산 스케쥴이라고 했다고 한다.)

{Bt가 B1=0.0001에서 Bt=0.02까지 선형적으로 증가되기 때문}

이렇게 하면 잡음 추가하는 과정에서 초기 단계에서 나중 단계보다 노이즈가 적게 추가된다.

(나중 단계는 거의 노이즈 상태이기 때문!)

 

 

확산 스케쥴은 선형, 코사인, 오프셋 코사인 대표적으로 이 세가지로 나뉘고, 위 그림을 통해 각각의 특징을 보자.

 

코사인 확산 스케쥴 (초록) 에서 잡음이 더 느리게 상승하는 것을 볼 수 있다. 

 

 

 

5.5 U-Net 잡음 제거 모델

이제 본격적으로 확산 모델을 사용해보자.

출력과 입력의 크기가 같아야할 때는 U-Net이 유용하므로, U-net을 이용하여 구조를 만들어보자.

noisy_images = layers.Input(shape=(64,64,3)) # 잡음 제거하려는 이미지
x = layers.Conv2D(32, kernerl_size=1)(noisy_images) # Conv2D 통과하면서 채널 수 증가

noise_variances = layers.input(shape=(1,1,1))  # 두 번째 입력은 잡음의 분산(스칼라)
noise_embedding = layers.Lambda(sinusoidal_embedding)(noise_variances) # 사인파 임베딩을 통해서 인코딩 됨
noise_embedding = layers.UpSampling2D(size=64, interpolation = 'nearest')(noise_embedding)

x = layers.Concatenate()([x, noise_embedding])

skips = []

x = DownBlock(32, block_depth = 2)([x, skips])
x = DownBlock(64, block_depth = 2)([x, skips])
x = DownBlock(96, block_depth = 2)([x, skips])

x = ResidualBlock(128)(x)
x = ResidualBlock(128)(x)

x = UpBlock(96, block_depth = 2)([x, skips])
x = UpBlock(64, block_depth = 2)([x, skips])
x = UpBlock(32, block_depth = 2)([x, skips])

x = layers.Conv2D(32, kernerl_size=1, kernel_initalizer='zeros')(x)

unet = layers.Conv2D(3, kernel_size = 1, kernel_initializer='zeros')(x)

unet = models.Model([noisy_images, noise_variances], x, name='unet')

코드 네 번째 줄의 사인파 임베딩이 뭘까??

 

 

'딥 러닝 > 생성형 AI' 카테고리의 다른 글

04. 적대적 생성 신경망(GAN)  (0) 2024.04.06
03. 변이형 오토인코더  (2) 2024.03.22
02. 딥러닝  (1) 2024.03.17
01. 생성 모델  (1) 2024.03.11

기울기 소실(Vanishing Gradient)이란?

기울기 소실은 오차 역전파과정에서, 출력층에서 멀어질 수록 Gradient 값이 매우 작아지는 현상을 말한다.

 

기울기 소실의 원인?

-> 기울기 소실은 활성화 함수의 기울기와 관련지어 설명할 수 있다.

아래 Sigmoid 함수를 예시로, 아래 그림을 보면서 이해해보자.

 

Sigmoid

왼쪽은 시그모이드, 오른쪽은 도함수이다.

오른쪽 그림을 보면, Sigmoid 함수의 미분 값은 입력값이 0일때 가장 크지만, 0.25에 불과하고, x값이 크거나 작아짐에 따라 기울기는 거의 0에 수렴한다.

따라서, 역전파 과정에서 Sigmoid 함수의 미분값 (1보다 작겠지?)가 곱해지면 곱해질 수록 Gradient값이 매우 작아질 수 밖에 없다. (더불어 e(자연상수) 또한 근사값으로 계산해야하기 때문에 오차까지 쌓이게 된다.)

tanh 함수

ranh의 경우, 0을 기준으로 출력값이 -1~1 (시그모이드는 0~1)로 2배 늘어났다. 하지만 여전히 시그모이드와 같은 이유로 인해 기울기 소실이 발생한다.

 

ReLU 함수

ReLU함수의 경우 입력값이 양수일 경우, 그 값에 상관없이 항상 그 값과 동일한 미분 결과값을 뱉게된다.(1)

-> 역전파 과정에서 기울기 소실이 되지 X + 연산속도가 빠르다(sigmoid는 자연상수 존재 ..!)

한계점 -> 음수의 경우 항상 미분값이 0이기 때문에 입력값이 음수일 경우 그 부분에 대해서 다시 회생할 수 없음

-> 이를 죽어간느 RELU (Dying ReLU라고 한다고 함.)

 

Leaky ReLU

ReLU와 차이점 -> 음수일 경우 0이 아닌, 매우 작은 값을 출력하도록 해줆!

 

 

'부록' 카테고리의 다른 글

오차 역전파 & chain rule  (0) 2024.04.23
Resnet 논문 리뷰  (0) 2024.04.22
Style GAN & Style GAN2  (1) 2024.04.07
LSTM  (0) 2023.08.02
[Modeling] XGB Classifier + 그리드서치 / 베이지안 옵티마이저  (0) 2023.03.18

신경망 모델은 기본적으로 손실 함수의 값을 최소화 하는 가중치를 찾는 방향으로 학습해 나간다. (전역 최소값)

 

대표적으로 경사하강법(Gradient Descent)의 경우, 기울기를 통해 가중치를 갱신하는데, 그 이유는 기울기가 경사 하강법에서 손실 함수 값을 줄일 수 있는 방향을 제시해주는 지표이기 때문,

'부록' 카테고리의 다른 글

기울기 소실  (0) 2024.04.23
Resnet 논문 리뷰  (0) 2024.04.22
Style GAN & Style GAN2  (1) 2024.04.07
LSTM  (0) 2023.08.02
[Modeling] XGB Classifier + 그리드서치 / 베이지안 옵티마이저  (0) 2023.03.18

Deep Residual Learning for Image Recognition, 2015

본 글은 2015년 MS에서 개발/발표한 알고리즘 논문을 초특급으로 간단하게 리뷰할 예정!

 

ILSVRC(ImageNet Large Scale Visual Recognition Challenge)에서 우승을 차지한 뛰어난 성능을 자랑했던 모델이고,

현재에도 다양한 논문에서 많이 참조되고 있다.(고 한다.)

 

Background

앞서 말했듯이, Resnet은 바로 직전 2014년 GoogleNet이 22개 층으로 구성되어 있던 것에 비해, 152층을 갖는다.

그럼 네트워크가 깊어질 수록, 성능이 올라가는 거구나! 라고 생각할 수 있다.

하지만 Resnet저자들은 이를 20층, 56층 네트워크의 성능을 비교/테스트 해보았따.

그림을 보면 알 수 있듯이, 56층 네트워크가 더 나쁜 성능을 갖는 것을 확인할 수 있다.

(층의 깊이가 능사가 아니라는 점)

그럼 152층의 네트워크를 가진 Resnet은 어떻게 지금까지 활용되고, 좋은 성능을 낸 것 일까? 핵심은 아래에 후술하겠다.

 

Residual Block

Resnet논문의 핵심은 Residual Blcok개념이다. 아래 그림을 보고 이해해보자.

Residual Block = "기존 CNN에서 conv층 네트워크에서, input인 x를 더해주는 지름길 (short cut)만 더해주는 개념이다."

따라서, 동일한 연산을 하고 나서 input x를 더하는 것 & 더하지 않는 것이 유일한 차이다.

이 단순한 개념이 얼마나 대단한 것인지 잘 생각해보자.

<기존 Network>

레이어의 output인 Feature Map(vector)을 y라 하면, y = f(x)일 것이다. 

아웃풋인 y는 x를 통해 새롭게 학습하는 정보일 것이다. (기존에 학습한 정보를 보존X, 새롭게 생성해야함.)

 

CNN이 고차원 Feature vector로 매핑해야한다는 점을 생각하면, 층이 깊어질 수록 한번에 학습해야 할 Mapping이 너무 많아져 학습이 어려워질 것이다. 여기서 Gradient Vanishing(기울기 소실)이 발생한다고 함

기울기 소실 자세히 -> https://heytech.tistory.com/388

 

[딥러닝] 기울기 소실(Vanishing Gradient)의 의미와 해결방법

📚 목차 1. 기울기 소실의 의미 2. 기울기 소실의 원인 3. 기울기 소실의 해결방법 1. 기울기 소실의 의미 딥러닝 분야에서 Layer를 많이 쌓을수록 데이터 표현력이 증가하기 때문에 학습이 잘 될

heytech.tistory.com

 

<Residual Network> 

기존 network와 달리, y = f(x) + x 라고 설명할 수 있다.

여기서는 x가 input 그대로 보존되고, f(x)에 대해서만 학습을 진행하면 된다.

이는 곧 output에서 이전 레이어에서 학습한 정보를 연결함으로써 현재 층에서는 추가적으로 학습해야 할 정보만을 Mapping(학습)하면 된다는 것을 의미한다.

 

그리고 학습이 계속 진행되면서, 층의 깊이가 깊어질수록 (학습이 많이 될 수록) x는 출력값 y에 근접하게 되어 f(x)는 최종적으로 0에 수렴하게 될 것이다.

수식을 보면서 이해하자면, y = f(x) + x 에서 추가 학습량에 해당하는 F(x) = H(x) - x가 최소값(0)이 되도록 학습이 진행된다.

 

Architecture

 Renset은 기본적으로 VCG-19의 구조를 뼈대로 하고 있다고 한다.

VCG-19층에 ConV층들을 추가해서 깊게 만든 이후에, shortcut(Residual Block)을 추가하는 것이 전부라고 한다.

 

아래 그림은 34층의 ResNet과 거기에서 shortcut들을 제외한 버전인 plain 네트워크의 구조이다.

그림 -> 34층의 Resnet은 처음을 제외하고 균일하게 3x3 사이즈의 ConV 필터를 사용함을 알 수 있다.

그리고 특성맵의 사이즈가 반으로 줄어들 때, 특성맵의 Depth를 2배로 높였다.

 

아래 그림은 18층&34층의 기존 network와 Resnet을 비교한 것이다.

y축(오차)를 동일하게 보았을 때, Resnet의 오차율이 더 적은것을 볼 수 있다.

 

왼쪽 그래프를 보면 plain 네트워크는 망이 깊어지면서 오히려 에러가 커졌음을 알 수 있다. 34층의 plain 네트워크가 18층의 plain 네트워크보다 성능이 나쁘다. 반면, 오른쪽 그래프의 ResNet은 망이 깊어지면서 에러도 역시 작아졌다! shortcut을 연결해서 잔차(residual)를 최소가 되게 학습한 효과가 있다는 것이다.
아래 표는 18층, 34층, 50층, 101층, 152층의 ResNet이 어떻게 구성되어 있는가를 잘 나타내준다.

18-Layer의 경우는 conv2_x에서 2X2, conv3_x에서 2X2, conv4_x에서 2X2, conv5_x에서 2X2, 입력1, 출력1해서 이 된다.

다음 표는 ResNet에서 Layer가 깊을 수록 더 좋은 성능을 보여준다는 것을 나타낸다.

CIFAR-10, CIFAR-100은 머신러닝 용 이미지 분류 데이터셋을 말하며 CIFAR-10 dataset이 10개의 클래스로 분류가 되고 CIFAR-100 dataset이 100개의 클래스로 분류가 된다.
위의 표를 보면 CIFAR-10, CIFAR-100둘다 ResNet의 layer가 깊을 수록 error율(%)이 더 작은 것을 볼 수 있다. 

 

심화

Resnet은 2개 이상의 Conv Layer와 skip-connection을 활용해서 Residual Block을 만들어서 네트워크를 구성한다.

 

앞서 말했듯, Neural Network 층을 깊게 쌓으면 기울기 소실이 발생하기 때문에 마냥 좋은 것이 아니다.

그렇다면 Residual Block이 기울기 소실을 어떻게 피할까? 

 

먼저 용어부터 정리하고 가자.

 : 현재 layer의 index
 : 전체 layer의 갯수
 : 가중치 행렬
 : Residual Function
 : Activation Function(ReLU)
 : Identity Mapping을 위한 Dimension 세팅용 함수

활성함수 을 identity mapping이라고 가정하면,


(참고로 identify mapping은 입력으로 들어간 가 어떠한 함수를 통과해도 다시 가 나오는 것으로 항등함수 가 대표적인 identity mapping에 해당한다.)
(도 identity mapping으로 가정했으므로 가 그대로 사용된다.)
이 식으로부터 일반화식을 표현하면 다음과 같이 나타낼 수 있다.

Loss function의 gradient의 계산식은 backward propagation chain rule로 부터 아래 식으로 나타낼 수 있다.

오차 역전파 & chain rule : https://amber-chaeeunk.tistory.com/18

 

딥러닝) 오차 역전파 backpropagation , 연쇄법칙 chain rule , 기울기 효율적으로 구하기

신경망 모델을 최적화 하기 위해서는 손실 함수의 값을 최소화하는 가중치 매개변수를 찾아야 한다. 복잡한 손실 함수에서 더 좋은 가중치를 찾기 위해 경사하강법(Gradient Descent)을 이용하여 가

amber-chaeeunk.tistory.com

 

위 식에서 우리는 가 두 개 값의 합으로 분해할 수 있다는것을 알 수 있다.


먼저,(1) 앞 부분의 은 weight layer와 무관하게 다이렉트로 전파되는 정보이다. 따라서 정보는 어떤 layer든 같은 정보가 전파된다.
(2) 뒷 부분의  은 weight layer를 거쳐 전파되는 정보이다.
backward propagation을 할 때  이 0이 되기 위해서는 weight layer를 거쳐 역전파되는 값이 -1이 되어야 한다.
실제 학습을 할 때 전체 데이터를 한번에 학습하는것이 아닌 데이터의 일부분씩 학습하는 mini-batch방식이 사용되는데, 모든 mini-batch에서 역전파값이 -1이 되는것은 불가능에 가깝다. 때문에  은 항상 0이 아닌 어떠한 값을 갖게 되고, 역전파된 값이 0에 가깝게 되는 vanishing gradient가 발생하지 않게 된다.

 

Resnet논문에 BottleNeck / 배치 정규화 적용 여부에 따른 성능 비교 부분은 패스~~

'부록' 카테고리의 다른 글

기울기 소실  (0) 2024.04.23
오차 역전파 & chain rule  (0) 2024.04.23
Style GAN & Style GAN2  (1) 2024.04.07
LSTM  (0) 2023.08.02
[Modeling] XGB Classifier + 그리드서치 / 베이지안 옵티마이저  (0) 2023.03.18

https://prowiseman.tistory.com/entry/StyleGAN-StyleGAN2

 

StyleGAN / StyleGAN2

들어가며 StyleGAN과 StyleGAN2의 논문을 살짝 읽어보긴 했는데, 수식이 너무 어려워서 곤란해하던 중 From GAN basic to StyleGAN2 이란 포스트에 잘 정리돼 있어 위 포스트를 보고 공부하였다. 그래서 아래

prowiseman.tistory.com

본 포스트는 위 글을 100% 참조하여 쓴 글이다.

바로 본론으로 들어가보자.

 

GAN의 평가 지표

GAN은 비지도학습이기 때문에 Accuracy 나 Confusion Matrix 등의 개념을 사용할 수 가 없다.

여기 Style GAN은 FID / PPL 라는 방법을 사용하여 성능을 평가한다고 한다.

 

FID (Frechat Inception Distance)

Frechat Inception Distance(FID)는 생성된 이미지의 분포가 원본 이미지의 분포에 얼마나 가까운지 측정한다.

그러나 이미지는 고차원 공간에 매장되어 있기(embedded) 때문에 분포의 거리를 쉽게 측정할 수 없다. 

따라서 FID는 저차원 공간에 이미지를 매장(embedded)하고 그 공간에서 분포의 거리를 측정하는 것이다. (매니폴드의 개념과 유사)

 

FID 공식은 아래와 같다.

FID 공식

m과 c는 임베디드 공간의 평균 벡터(mean vectors)와 공변량 행렬(covariance matrices)이다.

아래 첨자로 w가 있는 기호는 생성된 이미지이고, 아래 첨자가 없는 것은 실제 이미지이다.

이것이 분포의 거리를 보여주기 때문에 값이 작을수록 가짜 이미지가 진짜 이미지처럼 보인다.

이것은 생성자가 더 나은 성능을 보여준다는 것을 가리킨다.

 

(GPT에게 FID 수식을 자세히 설명해달라고 했다.) 

 

복잡하게 생각할 필요없이,

m과 c만 보면, 실제와 유사한 이미지를 만들었다고 하면 좌측 |m-m|은 0에 수렴, 우측 또한 0에 수렴할 것이다.

Perceptual Path Length (PPL)

Perceptual Path Length, PPL은 이미지가 지각적으로 부드럽게 바뀌었는지에 대한 지표이다.

우리가 하얀 개를 생산하는 잠재 변수인 z1과 검정 개를 생산하는 잠재 변수 z2가 있다고 생각해 보자.

색깔 이외의 다른 요소는 바뀌지 않았으므로 중간의 데이터의 잠재 변수는 흰색과 검은색 사이의 경로에 따라 바뀌는 게 이상적이다.

 

즉 회색 개가 나오는 게 목표라고 할 수 있다. 다시 말해 색만 바뀌는 파란색 경로는 "지각적으로(perceptually)" 가장 짧은 거리이다.

 

반대로 객체의 모양을 바꾸고 침대와 같은 이미지를 통과하는 초록색 경로는 "지각적으로(perceptually)" 거리가 멀다.

 

이는 PPL로 정량화됐고 공식의 정의는 다음과 같다. 이것은 두 잠재 변수 z_1과 z_2를 비 t로 혼합해서(mixed) 얻어진 잠재 변수와 이 둘을 t + ε의 비율로 혼합해서(mixed) 얻은 잠재 변수에 의해 생성된 이미지 사이 거리의 기댓값이다.

FID와 마찬가지로 PPL값이 작을 수록 실제 이미지와 만들어진 이미지가 유사(부드럽게)한 것을 나타낸다.

 

 

Style GAN

이제 StyleGAN에서 주로 쓰이는 평가 지표인 FID와 PPL을 토대로, 본격적으로 Style GAN에 대해서 알아보자.

우선 Style GAN은 두 가지 특징이 있다고 한다.

 

1. 고 해상도의 이미지를 Progressive Growing을 통해 생성한다. (PG GAN의 느낌(?))

2. AdaIN을 통해 각 레이어에 이미지와 스타일을 결합한다.

 

첫 번째로 이 두 가지 특징과 StyleGAN의 세부적 구조에 대해서 들어가보자.

 

Progressive Growing

Progressive Growing은 Progressive-Growing(PG-GAN)에서 제안된 고해상도 이미지를 생성하는 방법이다. 대략 말하면 이는 저해상도의 이미지부터 시작해 점진적으로 고해상도 생성자(Generators)와 판별자(Discriminators)를 추가하여 고해상도 이미지를 만드는 방법이다. (계층적 구조를 가짐)

 

AdaIN

AdaIN은 2017년 Xun Huang 외에 의해 제안된 style transfer의 정규화(normalization) 방법이다. 수학식은 아래와 같다.

 

x: content input

y: style input

->평균과 분산으로 정규화한다.

 

AdaIN은 다른 정규화(normalization) 방법과는 달리 오직 스타일과 콘텐츠 이미지의 통계로만 수행된다.

그리고 학습되는 파라미터는 쓰이지 않는다.

이는 학습 데이터에서 한 번도 본 적 없는 스타일로 변환할 수 있도록 한다.

 

Network architecture of StyleGAN

StyleGAN의 키포인트는 다음과 같다.

  • 점진적으로 해상도를 올리기 위해서 Progressive Growing을 사용한다.
  • 일반적인 GANs에서처럼 확률적(stochastically)으로 생성된 잠재 변수를 통해 이미지를 생성하는 것이 아닌 고정된 값의 텐서(fixed value tensor)를 통해 이미지를 생성한다.
  • 확률적(stochastically)으로 생성된 잠재 변수는 8-layer의 비선형 변환 신경망을 통과한 후 각 해상도에 AdaIN을 통해 스타일 벡터로 사용한다.

 

 

위 그림의 (a)는 PG-GAN이고 (b)는 StyleGAN이다. 둘 다 점진적으로 해상도를 올리는 progressive growing을 사용한다.

 

그러나 PG-GAN은 확률적 잠재 변수 z로부터 이미지를 생성하는 반면, StyleGAN은 고정된 4x4x512 텐서로부터 이미지를 생성한다.

게다가 확률적 잠재 변수는 그대로 쓰이지 않고 스타일로서 쓰이기 전, Mapping Network라 불리는 fully connected

network로 비선형 변환을 해 준다.

 

Mixing Regularization

StyleGAN은 Mixing Regularization이라 불리는 정규화(regularization) 방법을 사용하는 데, 이는 스타일에 사용된 두 잠재 변수를 학습하는 동안 혼합(mixes)하는 것이다. 예를 들어 스타일 벡터인 w_1과 w_2가 잠재 변수인 z_1과 z_2에서부터 맵핑(mapped)되었다고 할 , w_1은 4x4의 이미지를 생성할 때 사용되고 w_2는 8x8의 이미지를 생성할 때 사용된다.

 이를 함으로써 아래 보이는 것과 같이 두 이미지의 스타일을 섞을 수 있다.

 

'부록' 카테고리의 다른 글

오차 역전파 & chain rule  (0) 2024.04.23
Resnet 논문 리뷰  (0) 2024.04.22
LSTM  (0) 2023.08.02
[Modeling] XGB Classifier + 그리드서치 / 베이지안 옵티마이저  (0) 2023.03.18
[딥러닝] 옵티마이저 [퍼온 글]  (0) 2023.03.06

적대적 생성 신경망 (Generative adversarial networks)

먼저 오토인코더에서와 마찬가지로, 간단한 예시로 GAN의 등장배경을 알아보자.

위 이야기의 정품 벽돌과 위조 벽돌의 발전 과정은 GAN(Generative Adversial Networks)의 훈련 과정과 똑같다.

GAN은 생성자와 판별자라는 두 적대자간의 싸움이다.

그림을 통해 이해하면,

생성자(정품or위조)는 랜덤한 잡음원래 데이터셋에서 샘플링한 것처럼 보이는 샘플로 변환한다.

판별자는 그 샘플이 원래 데이터셋에서 나왔는지, 아니면 위조품인지를 예측한다.

 

그렇다면 정보가 없는 맨 처음은? -> 생성자: 잡음 이미지를 그대로 출력 / 판별자: 랜덤으로 판별 -> 다음부터는 위와 같음.

 

4.1 심층 합성곱 GAN (DC GAN)

심층 합성곱을 이용하면 사실적인 이미지를 만들어 내고, 이미지 품질을 향상시킬 수 있다.!

 

예제를 통해 DC GAN을 구현해보자.

데이터 : 캐글의 레고 데이터셋

 

원본 데이터는 0~255로 이루어져 있는데, GAN을 훈련할 때는 [-1 ~ 1]로 스케일을 재조정한다.

(생성자의 출력층에서 하이퍼볼릭 탄젠트 함수를 사용하기 위해서!)

 

tf.cast => 텐서의 데이터타입을 변경 (np.astype과 비슷)

 

4.2 판별자

판별자는 생성자가 

코드는 아래와 같다.

유의: 3번=마지막 합성곱 출력을 펼친다. 이 지점에서 텐서 크기는 1x1x1이다. 따라서 마지막 Dense층이 필요하지 않음.

판별자의 모델 Summary()는 다음과 같다.

4.3 생성자

이제 생성자를 만들어보자.

생성자에서 Input은 다변량 표준 정규 분포에서 뽑은 벡터라고 한다.

      ''           output은 원본 훈련 데이터에 있는 이미지와 동일한 크기의 이미지다.

 

다변량 표준 정규 분포라는 키워드를 보면 변이형 오토인코더가 떠오를텐데, 실제로 GAN의 생성자는 VAE(변이 오토인코더)의 디코더와 정확히 같은 목적을 수행한다고 한다.

생성자의 INPUT & VAE의 디코더  = 잠재 공간의 벡터를 이미지로 변환

 

생성형 모델에서는 잠재 공간에서 원래 도메인으로 다시 매핑하는 개념은 아주 많이 쓰이는데, 이는 잠재공간에서 벡터를 조정하는 것으로 이미지의 고차원적인 특성을 바꿀 수 있기 때문이다.

 

코드와 모델 summary를 알아보자.

 

검정색 동그라미를 보자.

1 = 생성자의 Input 층 -> 길이가 100인 벡터로 정의

2 = Reshape층을 통해 1x1x100 크기의 텐서로 변환 -> 전치 합성곱층 사용할 수 있게

3 = 4개의 Transpose CNN층에 통과, 그 사이에 배치정규화 및 리키렐루 층을 놓음.

4 = 마지막 전치 합성곱 층은 하이퍼볼릭 탄젠트 함수를 활성화 함수로 두고 출력을 원본 이미지와 같은 [-1,1] 범위로!

5 = 생성자 모델을 정의 -> 길이가 100인 벡터를 받고 [64,64,1] 크기의 텐서를 출력

 

 

출력층을 제외하고 4개의 전치합성곱층에서 첫 번째 층을 제외한 나머지 3개 층은 strides가 2로 되어있다.

-> 텐서가 네트워크를 통과하면서 방향의 크기가 증가함. (채널 수는 줄어든다-> 마지막에는 1로.!  <-? )

위 사진은 스트라이드2 + 전치합성곱층과 업샘플링+스트라이드1인 일반 합성곱층을 비교하는 글이다.

 

Upsample층은 픽셀 사이 공간을 0으로 채우지 않고 기존 픽셀 값을 사용해 업샘플링 한다고 한다.

 

전치합성곱층은 일반적으로 출력 이미지 경계에 계단/체크무늬 패턴을 만들어서 출력 품질을 떨어뜨린다고 하는데, 뛰어난 GAN 논문에서 여전히 많이 사용한다고 한다. 따라서 Upsampling층이나 Conv2DTranspose 잘 비교해보고 사용해보자.

 

4.3 DC GAN (Deep Convolutional Generative Adversial Network) 훈련

위의 코드와 설명이 바로 DC GAN이다. (Conv2DTranspose층 사용) -> 심층 합성곱을 사용해 고품질 이미지 생성에 기여할 수 있다. 이제 이 DC GAN 모델의 훈련을 알아보도록 하자.

GAN을 진짜 이해하려면 훈련 과정을 이해해야 한다고 한다. (책에서..)

 

먼저 훈련 세트에서 진짜 샘플과 생성자의 출력을 합쳐서 훈련 세트를 만든다. (이를 지도 학습 문제로 다루자!)

정답 이미지 (진짜) = 1, 가짜 이미지 = 0, 손실 함수 = 이진 크로스 엔트로피

 

생성자는 어떻게 훈련시켜야 할까?

생성된 이미지에 점수를 부여하고 높은 점수를 낸 이미지로 최적화하는 방법을 찾아야 한다. (판별자가 이 역할을 수행)

 

배치 이미지를 생성하고 이를 판별자에 통과시켜 각 이미지에 대한 점수를 얻을 수 있다고 한다.

(판별자가 진짜라고 생각하는 이미지를 생성하도록 생성자를 훈련하고 싶기 때문)

 

그리고 한 번에 한 네트워크의 가중치만 업데이트 될 수 있도록 두 네트워크를 번갈아가면서 훈련하는 것이 중요하다.

생성자를 훈련할 때 판별자의 가중치가 변경되도록 허용하면 생성된 이미지를 진짜라고 여기도록 조정되기 때문.

 

-> 판별자가 약해서가 아니라 생성자가 강하기 때문에 생성된 이미지가 1에 가까운 값으로 예측되어야 한다!

 

아래 그림은 판별자와 생성자의 훈련 과정을 보여준다.

DC GAN compile code

 

코드의 검정 동그라미를 보자.

 

 

4.4 GAN 훈련의 트릭과 팁

GAN은 생성형 AI 분야에서 큰 혁신이지만 훈련이 어렵기로도 유명하다고 한다.

 

이 절에서는 무엇이 어려운지, 어떻게 해결할 수 있을지 알려준다고 하니 집중력을 잃지 말자!

 

Case #1 판별자 > 생성자

판별자가 더 뛰어나다면 손실 함수의 신호가 약해져 생성자의 성장(좋은 이미지를 만들어낼 수 있는 능력)이 저해된다.

최악의 상황 -> 판별자가 신같은 존재 -> 학습이 이루어지지 않아버렷!

 

해결방안

 - 판별자의 dropout층의 rate 매개변수값을 증가시켜 네트워크를 통해 흐르는 정보 양 감소시키기

 - 판별자의 학습률 감소시키기

 - 판별자의 합성곱 필터 수 감소시키기

 - 판별자 훈련 시 레이블에 잡음 증가시키기

 - 판별자 훈련 시 일부 레이블 이미지 무작위로 뒤집기

 

Case #1 판별자 < 생성자

고급스러운 말로 모드 붕괴(mode collapse)라고 한다고 한다.

생성자를 이기적인(현명한?) 사람이라고 생각해보자. 어떻게 판별자를 속일 수 있을까? (훈련 방향이 어떨까?)

만약 판별자의 가중치를 업데이트하지 않는다고 해보자. 그렇다면 당연히 생성자는 여러개가 아닌, 판별자를 속일 수 있는 '단 하나'의 샘플만을 찾으려고 할 것이다. 그 샘플만 찾아낸다면 영원히 판별자를 속일 수 있기 떄문이다!

 

유용하지 않은 손실

딥러닝 모델은 손실 함수의 값이 작아지는 방향으로 학습하기 때문에 손실이 작을수록 이미지 품질이 좋아진다고 착각하기 쉽다. 하지만 생성자는 현재의 판별자에 의해서만 평가되고, 판별자는 계속해서 업데이트 되기 때문에 훈련 과정의 다른 지점에서 평가된 손실을 비교할 수 없다.

 -> 생성자의 손실과 이미지 품질 사이의 연관성 부족때문에은 GAN의 중간과정 모니터링이 어렵다.

 

하이퍼 파라미터

위의 코드를 보았듯이, GAN에서는 튜닝해야 할 하이퍼 파라미터의 개수가 상당히 많을것을 볼 수 있다.

-> 배치 정규화 / 드롭 아웃 / 학습률 / 활성화 층 / 합성곱 필터 / 커널 크기 / 스트라이드 / 배치 크기 / 잠재 공간 크기 등

 

GAN의 도전과제 해결

위의 여러가지 문제점들은 최근 몇 년간 똑똑이들에 의해서 많이 개선되었다고 하는데, 어떻게 되었는지 더 자세히 알아보자!

 

4.5 와서 스테인 GAN- 그레디언트 패널티 (WGAN-GP)

아르좁스키라는 스키 2017년 "와서스테인 GAN"이라는 논문을 통해 GAN의 모델 안정성 구축에 크게 기여했다.

핵심은 두 가지다.

1: 생성자가 수렴하는 것과 샘플의 품질을 연관 짓는 의미 있는 손실 측정 방법

2: 최적화 과정의 안정성 향상

 

참고)와서스테인은 손실 함수이다!

'딥 러닝 > 생성형 AI' 카테고리의 다른 글

05. 확산 모델 (Diffusion model)  (0) 2024.05.31
03. 변이형 오토인코더  (2) 2024.03.22
02. 딥러닝  (1) 2024.03.17
01. 생성 모델  (1) 2024.03.11

목표

  • 오토인코더의 구조를 배우고 생성형 AI기술과 적합성 검증
  • 오토인코더 직접 실습해 만들어보기
  • 오토인코더의 한계점을 확인, 변이형 오토인코더 학습
  • 변이형 오토인코더 직접 실습해 만들어보기

2013년 변이형 오토인코더라는신경망에 관한 논문이 게재되었다.

변이형 오토인코더는 생성형 AI에서 가장 기본적이고 널리 알려진 딥러닝이며, 생성형 AI의 시작점이라고 해도 무방하다.

그 전에 먼저 표준 오토인코더에 대해서 알아보자.

 

먼저 오토인코더가 해결하려는 문제부터 알아보자.

자취방에 옷 무덤을 떠올려보자. 니트,티셔츠,바지,속옷 등 갖가지 옷들이 생매장되어있다. 

따라서 이를 해결하기위해 무한한 높이의 옷장을 만들었다고 가정해보자. 자비스라는 AI에게 옷장의 특정 위치를 알려주기만 하면 그 위치에 해당하는 의류를 새로 만들어 줄 수 있을것이다. -> 비슷한 옷은 서로 가까이 배치해야하겠지?

 

이것이 오토인코더의 개념과 밀접하다는데 더 자세히 알아보자.

 

3.1 오토인코더

여기서 우리는 "인코더(Encoder)"의 역할을 수행해야 한다.

즉, 의류를 특정 위치로 이동시켜야 한다. 이 과정을 인코딩이라고 하며, 자비스는 "디코더(Decoder)" 역할을 맡아

옷장의 위치를 넘겨 받으면 그 위치에 해당하는 의류를 생성하려고 할 것이다. 이를 디코딩이라고 한다.

옷장의 각 위치는 두 개의 숫자값 (벡터)으로 표현된다.

인코더는 디코더가 정확하게 숫자값으로 이동할 수 있게 도와줘야 한다. 이 벡터 값 (디코더를 위한 정보)을 임베딩(Embedding)이라고도 한다.

 

결정적으로 좌표평면 (2D) 공간에 있는 모든 포인트를 디코딩하여 새로운 옷을 만들 수 있으므로 생성모델로 사용할 수 있는 것이다.

 

3.1.1 실습

fashion_mnist를 불러오고,

기존 이미지 값 -> (0~255) -> 255로 나누어서 0~1로 바꾸기

 

numpy메소드의 pad 함수 np.pad 의미

제로패딩 두 개의 픽셀로 채워넣었다는 의미이다. 

 

3.1.1 오토인코더의 구조

오토인코더는 두 부분으로 구성된 신경망이다.

  • 인코더: 네트워크는 이미지같은 고차원 입력 데이터를 저차원 임베딩 벡터로 압축
  • 디코더: 네트워크는 임베딩 벡터를 원본 도메인으로 압축 해제 (ex 이미지로 되돌립니다.

오토인코더는 인코더로 들어가서 디코더로 나오면서 이미지를 재구성하도록 훈련한다.

아니 그럼 왜 원본이미지를 냅두고 굳이 이 지롤을 하는것일까?

 

이 이유는 앞서 설명했듯이 임베딩 공간(잠재공간)과 관려되어 있다고 볼 수 있다. 이 공간에서 샘플링하여 새로운 이미지를 생성할 수 있기 때문이라고 한다.

임베딩(z) = 원본 이미지를 저차원 잠재 공간으로 압축하는 것

잠재 공간에서 임의의 포인트를 선택해 디코더에 통과시키면 새로운 이미지를 생성할 수 있다. 디코더는 잠재 공간의 포인트를 유효한 이미지로 변환하는 방법을 학습했기 때문!

 

3.1.2 인코더

오토인코더에서 인코더의 역할은 입력을 이미지로 받아 잠재 공간 안의 임베딩 벡터에 매핑하는 것.

직접 실습해보자.

3.1.3 디코더

디코더는 인코더와 반대이다. (미분이 뭐야? 적분의 반대. 적분이 뭐야? 미분의 반대.)

 

합성곱 오토인코더 = 인코딩 -> 합성곱 사용 / 디코딩 -> 전치 합성곱 사용

참고

https://m.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS4816849548&cate_cd=001

 

말하는 대로 그려 주는 기술의 비밀: 합성곱 오토인코더, 생성적 적대 신경망

이미지 생성 모델은 최근 몇 년 동안 발전하여, 사람들이 생각하는 것보다 더욱 세밀하고 현실적인 이미지를 생성할 수 있게 되었습니다. 혁신적인 알고리즘을 구축하고, 대규모 데이터로 학습

m.hanbit.co.kr

디코더에서는 전치 합성곱 층을 사용

 

디코더는 합성곱 층 대신 전치 합성곱이라는 층을 사용한다.

전치 합성곱(Transposed convolution) 연산과 deconvolutionl 연산은 다르다. deconvolutionl은 convolution 역 연산이므로 input 데이터를 다시 출력한다. Transposed convolution은 input을 원래대로 되돌리는 역할을 하고, output의 차원의 크기도 동일하다는 점에서 deconvolution과 유사하지만 연산 수행 방식이 다르다.

참고

https://yeong-jin-data-blog.tistory.com/entry/Autoencoder

 

오토인코더(Autoencoder), 합성곱 오토인코더(Convolutional Autoencoder)

📚 오토인코더 (Autoencoder) 오토인코더는 비지도학습 모델로, 입력 데이터의 패턴을 학습해서 최대한 유사한 데이터를 새롭게 생성한다. 데이터가 입력되면 encoder를 통해서 저차원의 벡터로 변

yeong-jin-data-blog.tistory.com

 

전치 합성곱층을 사용한 디코딩을 실습해보자.

3.1.4 인코딩 <-> 디코딩 연결하기

인코더와 디코더를 연결시키려면 이미지가 인코더를 통과해 디코더로 나오는 모델을 정의해야한다.

다행히도, 케라스의 Model 클래스를 이용해서 쉽게 연결시킬 수 있다.

 

이제 모델 정의가 끝났으므로, 손실함수&옵티마이저를 정하여 모델 컴파일을 진행해보자.(RMSE/이진 크로스엔트로피)

 

손실함수 관련 참고

 

언제 MSE, MAE, RMSE를 사용하는가?

제목에 열거한 RMSE, MSE, MAE는 딥러닝 모델을 최적화 하는 데 가장 인기있게 사용되는 오차 함수들이다. 이번 포스팅에서는 (1) 이들의 특징을 알아보고, (2) 이 3 가지 손실 함수를 비교 분석해본다

jysden.medium.com

MSE/RMSE의 가장 큰 차이점은 "이상치에 민감하냐"의 여부이다.

MSE의 경우 루트가 안쓰이기 때문에 이상치에 더 민감하다고 볼 수 있다. (학습과정이 불안정할 수 있음.)

RMSE의 경우, "큰 오류값 차이에 대해서 크게 패널티를 주는 이점"이 있다고 볼 수 있다.

 

오토인코더 훈련

이미지 재구성하기

위 그림을 보다시피, 디코딩된 이미지는 원본 이미지와 똑같지 않다!

이는 인코딩 할 때, 원본 이미지를 두 개의 숫자값으로 축소 시켜놨기 때문에 정보가 소실되기 때문이다.

이제 인코더가 잠재공간에서 어떻게 이미지를 표현하는지 알아보자.

잠재 공간 시각화

 테스트 세트를 인코더에 통과시켜 만들어진 임베딩을 시각화

그림 & 좌표 숫자를 잘 보고 분석해보자.

데이터 포인터들이 서로 구분지어 멀리 떨어져 있지 않고, 뒤섞여서 붙어 있다!

위와 같은 부분들 때문에 실제로 잠재 공간에서의 샘플링 작업은 힘들 수 있다.

문제 = 일반 오토인코더는 잠재 공간이 연속적으로 할 것인지에 대해 강제하지 않기 때문임

 -> 변이형 오토인코더로 해결할 수 있다!

 

3.2 변이형 오토인코더

 처음 설명 했던 무한한 높이의 옷장을 다시 떠올려보자.

처음 (일반 오토인코더)의 경우 옷을 정확한 위치에 할당한다고 했다면, 지금 (변이형 오토인코더)은 가능성이 높은 지역을 할당한다고 해보자.(범위) -> 불연속성 문제를 해결할 수 있지 않을까?

+규칙을 새로 만들자! 데이터의 중앙 -> 좌표 중앙에 배치한 후, 편차 또한 일정 범위로 제한!!

 

3.2.1 인코더

오토인코더와 변이형 오토인코더의 차이

2차원 한 점에 할당  vs  잠재 공간의 다변량 정규 분포에 할당

 

다변량 정규 분포란?

표준 정규 분포 = 평균0, 분산이 1인 정규 분포

 

다변량 정규 분포란

평균이 뮤, 분산이 시그마인 정규 분포에서 샘플링하여 구하는 것

이게 뭔 개소리노

 

변이형 오토인코더는 데이터를 평균&분산 벡터에 각각 매핑하기만 하면 되고, 차원간 공분산을 신경 쓸 필요가없다고 한다. (잠재공간에서는 차원간에 상관관계가 없다고 가정)

+분산값은 항상 양수여야 하므로 분산의 로그에 매핑 (로그 함수를 생각)

 

요약하면 인코더는 원본 이미지 -> 잠재 공간의 다변량 정규분포를 구성하는 분포의 평균, 분산의 로그 값 두 개의 벡터로 인코딩 한다.

위 방법을 통해서 z 샘플링 -> 디코딩하는 과정

 

'딥 러닝 > 생성형 AI' 카테고리의 다른 글

05. 확산 모델 (Diffusion model)  (0) 2024.05.31
04. 적대적 생성 신경망(GAN)  (0) 2024.04.06
02. 딥러닝  (1) 2024.03.17
01. 생성 모델  (1) 2024.03.11

+ Recent posts