요즘 딥러닝 분야에서 학계를 넘어 사회적으로 가장 널리 회자되는 모델이 GPT-3가 아닌가 싶다.

나는 NLP 분야와는 거리가 멀지만, 최신 번역 모델의 기초가 되는 transformer가 무엇인지 간단하게 알아보기로 한다

시계열 분석에 대한 아이디어를 잘캐치하면 내 분야에도 적용할 기회가 있지않을까!

 

학습자료로는 서울대 윤성로 교수님의 강의영상을 활용했다

코시국 동안에 촬영하신 강의를 유투브로 배포하시는 교수님들이 많이 계시는데,

대학교나 딥러닝 회사 커뮤니티에 속하지 않은 나는 매우 감사할 따름이다.

 

 

1. Attention = learned allignment (between source and target)

번역 태스크에서 단어의 배열과 어순의 변경 등을 결정하기 위해서는 배열(allignment)정보를 가지는 벡터가 필요한데, 이것이 attention의 주요 역할이다.

source: Olah & Carter, 2016. https://distill.pub/2016/augmented-rnns/

이전의 seq2seq 모델에서는 배열정보를 가지기 위해 encoder에서 context vector를 계산했는데, encoder가 정보를 충분히 처리할 수 없는 (overloaded 되는) 문제가 발생한다. attention 을 도입함으로써 context vector computing 을 강화해서 더 좋은 성능을 가지게 되었다.

A traditional sequence-to-sequence model has to boil the entire input down into a single vector and then expands it back out. Attention avoids this by allowing the RNN processing the input to pass along information about each word it sees, and then for the RNN generating the output to focus on words as they become relevant.
Olah & Carter, 2016

이미지캡션 분야에서도 image-to-text 를 위해 집중해야할 이미지 영역을 강조하기 위해 이용된다

 

 

2. Attenetion 의 분류

Cross attention : 입력과 출력 시퀀스 사이에 어텐션을 생성한다. (works on different sequences)

Self attention : 시퀀스 내부에서 어텐션을 생성한다 (relates different positions of a single sequence to compute its representation)

 

Soft attention : 모든 인풋 데이터 패치에 대해 weight를 부여하고 전체의 average를 context vector로 가진다. 모델이 smooth and differntiable 하지만 연산량이 큰 단점이 있다

Hard attenetion : 선택된 일부 데이터 패치에 대해서만 weight를 부여한다. 연산량이 적고 속도가 빠르지만 selection 은 미분불가능한 stochastic한 방법이다.

 

Global attention : soft attention 의 개념과 유사함. 타겟을 생성하기 위해 모든 인풋을 살펴본다

Local attention : soft 와 hard attention 이 결합된 형태. 타겟 생성에 필요한 source 위치를 예측하고 그 주변에 window를 씌워서 타겟을 생성함.

 

 

3. Transformer 모델의 기본 연산과정 ("Attention Is All You Need" 논문의 모델)

기본적으로 인코더와 디코더 레이어를 쌓아서 many-to-many 맵핑을 수행하는 seq2seq 모델의 일종이다.

 

Encoder: 구조적으로 동일하고 가중치를 공유하지않는 6개의 레이어로 구성된다. 각각 2개의 sub-layer로 구성되어있는데 첫번째는 self-attention , 두번째는 feed-forward-net 이다. 

Decoder: 3개의 sub-layer로 구성되어있다. 첫번째는 self-attetion, 두번째는 encoder-decoder attention, 세번째는 feed-forward-net

 

트랜스포머 논문에서는 key와 value의 개념을 이용해서 다음과 같이 정의된 표현을 사용한다

Query: (projected) decoder hidden state

Key: (projected) encoder hidden state for attention weight computation

Value: (projected) encoder hidden state for context vector build

Context Vector = weighted sum of values

(위치의 weight 또는 score 값은 query 와 key를 내적해서 생성됨)

 

모델의 연산 과정

(그림은 https://jalammar.github.io/illustrated-transformer/ 에서 가져옴) 

 

(1) Query, Key, Value 를 생성

encoder에서 단어를 벡터로 word-embedding (1X512 벡터) 하고,

행렬 W_q, W_k, W_v 를 곱해서 

(2) 각 단어의 self-attention socre를 생성한다

위에서 정의한대로 score = query 와 key 를 내적한 값이다.

그 결과, 입력 시퀀스의 여러 단어(=key)에 대한 attention score 값이 생성된다

(3) attention score 를 normalize 한다

key 벡터의 길이가 64이므로, 제곱근인 8로 나누어주는 scaled-dot-product 를 적용한다. 정규화 를 통해 more stable gradient 를 얻는 장점이 있다

그리고 softmax를 적용해서 score를 probability 값으로 변환해준다

 

 

(4) self-attention layer의 output 를 계산한다

여기서 attention layer의 output (=context vector) 는 weighted sum of value vectors 이다.

즉 앞서 구한 softmax 값을 이용해서 z1 = v1*0.88 + v2*0.12 으로 계산된다

 

위의 과정을 행렬로 나타내면 다음과 같이 간단하게 표현할 수 있다

 

 

(5) multi-head attention

트랜스포머 모델은 각각 다른 방식으로 attention을 계산하기 위해서 8개의 attention head를 가진다.

그리고 multi-heads (z0, z1, ,,, z7) 를 하나로 concat한다.

 

(6) Positonal-Encoding 

각 단어가 문장에서 어디에 위치하는지 정보를 표현하는 벡터이다. 단어의 문장 내 위치와 다른 단어들과의 거리를 나타낼 수 있다. 본 논문에서는 20개 position에 대해 sin 함수를 이용해서 -1과 1사이의 값을 더한다 (물론 word-embedding 되었으므로 각 위치는 512개 차원의 값을 가진다)

(7) Add and Norm 서브레이어

Encoder에는 레이어를 스킵하는 residual connection 를 추가한다. 그림에서는 즉 x를 z에 더해주는 skip connection 이다. 그리고 그 결과를 layer normalization 를 수행한다.

즉 모든 Encoder 에서 Add and Norm 이라는 sub-layer 계산이 2번씩 추가되는 것으로 볼 수 있다.

 

(8) Decoder 레이어의 특징

인코더와 달리 encoder-decoder attention (=cross attention) 레이어를 가진다. 이 attention은 디코더가 인풋 시퀀스의 각 부분에 가중치를 가질 수 있도록 한다.

self-attention 계산과정에서 아직 생성되지않은 뒷 부분에 대한 attention을 가지지 않도록 수정된 구조(masked self-attention)를 가진다.

 

 

(9) 최종 결과물 생성하는 Logits and Softmax Layer

디코더의 최종 값은 float vector 꼴로 생성된다. 이를 단어로 변환하기 위해서 vocab size 수준의 매우 큰 Logits 로 바꿔야한다. 그리고 Logit vector 를 softmax 확률로 계산해서 가장 적합한 단어를 판정한다.

 

결과를 생성하는 방법으로는

① greedy decoding : softmax 확률이 가장 높은 단어를 추출한다

② beam search : beam size (=k) 개의 단어 후보를 동시에 고려하되, top beams(=t) 만큼의 결과만 저장해서 greedy 하게 진행한다. 

 

 

 

 

자 이제 "Attention Is All You Need"  논문에 나온 아래 트랜스포머 모델의 모든 요소를 다 이해했다!

교수님 감사합니다 !!

 

이후 강의에서 BERT와 GPT 모델에 대해서 설명해주시는데

번역 모델들에 대해 너무 자세히 알아볼 필요는 없으므로 트랜스포머 정리는 여기까지 !

 

 

### 추가로 참고하면 좋은 자료

ICML2019 tutorial : Attention in Deep Learning 

 

남세동 대표님의 면접질문리스트 시리즈 3번째 softmax 이다

이번엔 비교적 간단한 질문들이라 짧게 정리할 수 있겠다

 

3. softmax의 수식이 어떻게 되나요?

소프트맥스 뿐만 아니라 딥러닝에서 사용되는 여러 활성함수와 함께 비교해보자

source: https://towardsdatascience.com/deep-learning-with-tensorflow-5d3a7a8c55cd

 

다시말해 softmax(a) 는 x=a 일 확률의 표현방법이기 때문에 SUM(softmax(X))=1 이 된다

 

 

3-a. e^x를 미분하면 어떻게 되나요?

간단하다. d/dx (e^x) = e^x 

 

3-b. softmax를 사용하는 이유가 뭘까요?
이게 젤 중요한 질문이다. Bishop 책을 인용하자면

The term softmax is used because this activation function represents a smooth version of the winner-takes-all activation model in which the unit with the largest input has output +1 while all other units have output 0.
— Page 238, Neural Networks for Pattern Recognition, 1995.

즉, argmax가 가장 확률이 높은 한가지 정답만을 보여준다면 softmax 는 전체 선택지 중 정답이 될 수 있는 확률을 상대적으로 비교하기 위해 이용된다

물론 이는 최종적으로 학습과정에서 true value 와의 오차를 계산하고 뉴럴넷을 학습시키기 위해 이용된다.

전체 과정을 잘 표현한 그림이 있길래 인용하면서 마무리한다

 

source: https://wikidocs.net/35476

 

 

남세동 대표님의 면접질문리스트 시리즈를 이어간다

 

2. 이미지를 처리할 때 CNN이 좋은 이유가 뭔가요?

CNN이 이미지 뿐만 아니라 여러 딥러닝 문제 해결에 기존의 MLP모델보다 효과가 좋다는 것은 이미 경험적으로 잘 알려져있지만, 어떠한 이유로 성능이 좋아지는지 여러가지 이유를 정리해보자.

(은근히 답하기 어려운 질문이라고 생각한다. 딥러닝 세계에서 좋다라는 의미를 정확히 말하면 지금까지 좋았다- 는 것이기도 하니까)

 

먼저 CNN이 어떻게 작동하는지 간단하게 정리해보자.

convolution은 CNN(딥러닝 모델) 이전에도 이미지나 신호 처리에서 많이 이용되었던 방법 중 하나이다. 컨볼루션 필터를 이미지에 적용한다는 것은 쉽게 말해 행렬을 내적해준다는 뜻이고, 그 결과 특정한 성격의 신호를 강조하거나 삭제할 수 있다.

 

컨볼루션에서는 그 행렬을 convolution kernel 또는 filter 라고 부른다.

예를들어 아래와 같은 커널을 이미지데이터에 적용하면 윤곽선만 하얗게 남긴 결과물을 보여준다.

source: https://developer.nvidia.com/discover/convolution

 

행렬이라..어렴풋이 기억난다...

 

그리고 CNN에서는 convolution kernel을 뉴럴넷의 레이어로 정의해서 아래와 같이 연산을 해준다

source: CS231n 강의노트 (https://cs231n.github.io/convolutional-networks/)

 

그리고 이런 레이어를 잘쌓고 잘만들었더니... 5개의 Convolution Layer를 적용해서

2012년에 AlexNet이 탄생하고, CNN 천하가 열리게 된 것이다.

AlexNet의 구조 (https://learnopencv.com/understanding-alexnet/)

 

자 그럼 다시 본론으로 돌아가서,

왜 CNN이 이미지 처리에 유리한가?

달리 말하면 fully-connected layer 가 이미지 처리에 효과적이지 않은 이유는 무엇인가?

 

Lecun & Bengio (1995) 에서 

(1) 파라미터의 갯수를 줄임으로써 학습이 잘 이루어진다

FC 레이어는 기본적으로 파라미터의 숫자가 많아서 오버피팅의 위험이 있고 학습과정에서 컴퓨팅 파워를 많이 소모한다. 특히 이미지나 음성과 같은 데이터를 다룰 때는 size-normalized 와 centered 되지않은 인풋데이터의 로컬 변수를 모두 학습하기 위해서 FC레이어의 사이즈가 굉장히 커야하는 문제가 있다.

"they have no built-in invariance with respect to translations, or local distortions of the inputs. (...) Learning these weight configurations requires a very large number of training instances to cover the space of possible variation"

반면, CNN은 weight 를 공유하면서 자동으로 위치에 대한 불변량(invariance)을 가질 수 있으므로 이러한 단점을 극복할 수 있다.

 

특히 이 장점은 뉴럴넷의 구조가 깊어지고 많은 데이터를 학습해야하는 딥러닝에서는 그 효과가 더욱 돋보인다.

참고로, Convolution Layer의 파라미터 수는 

N of parameters = (kernel size * number of channel * number of kernel) + (number of kernel) 

 

(2) 데이터의 위치(위상) 정보를 학습할 수 있다.

이미지를 예를들면 2D상에서 가까이 있는 픽셀의 값들이 local feature 을 이루는 중요한 단서가 되므로, 각 픽셀의 위치 관계를 매우 중요하게 다루어야한다. 그러나 FC레이어는 픽셀을 한줄로 쭉 늘어뜨린 형태로 학습하므로 2D의 위치 정보가 모두 사라지게된다. ("a deficiency of fully-connected architectures is that the topology of the input is entirely ignore"). 반면 convolution kernel을 이용하는 CNN은 2D상에서 인접한 데이터들을 kernel 에 입력하므로 픽셀의 위치정보를 학습할 수 있다.

 

 

Andre Ng 의 coursera 강의노트에서는 다음과 같이 조금 다르게 표현하지만 거의 같은 의미로 이해할 수 있다.

WHY CONVOLUTIONS?
"Parameter Sharing : A feature detector (such as a vertical edge detector) that’s useful in one part of the image is probably useful in another part of the image.
Sparsity of Connectivity : In each layer, each output value depends only on a small number of inputs. "

 

 

2-a. CNN에서 MaxPool의 역할이 무엇인가요?

MaxPooling 은 pooling filter의 영역내에서 가장 큰 값만을 남기는 과정이다.

너무 간단한 내용이니까 자세한 설명은 생략하고,,

MaxPooling Layer (https://cs231n.github.io/convolutional-networks/)

 

max pooling의 주요 역할은

(1) 이미지의 크기를 줄임으로써(downsampling), 학습 파라미터의 갯수를 줄이고 오버피팅을 방지한다

(2) invariance to local translation을 통해 특정 영역 내에서 가지는 특징을 더 강조할 수 있다.

 

여기서 (2)번이 약간 어렵게 느껴지는데...

Goodfellow의 책에서

"pooling helps to make the representation become approximately invariant to small translations of the input. (...) Invariance to local translation can be a useful property if we care more about whether some feature is present than exactly where it is." 

이라고 설명되어있다.

 

그리고 카카오브레인 블로그를 읽어보니 좀더 쉽게 이해할 수 있다.

"CNN은 피카소의 작품 속(기형적인) 대상(object)을 사람으로 인식한다. 맥스 풀링을 통해 눈, 코, 입, 귀의 상대적인 위치, 방향과 상관없이 특징을 추출하기 때문이다. CNN은 풀링을 통해 위치(translation)와 관계없이 객체를 동일하게 인식하지만, 방향(orientation)이나 비율(proportion)이 달라지면 서로 다른 객체로 인식한다."

 

 

2-b. MaxPool에서 BackPropagation이 어떻게 될까요?

또 BP 관련 질문이다.

사실 BP 계산은 코딩예제로 배우다보면 신경쓰지않고 넘어가기 쉬운데 간단히 정리할 수 있어서 좋다.

 

CS231n 강의자료 에서는

Backpropagation Recall from the backpropagation chapter that the backward pass for a max(x, y) operation has a simple interpretation as only routing the gradient to the input that had the highest value in the forward pass. Hence, during the forward pass of a pooling layer it is common to keep track of the index of the max activation (sometimes also called the switches) so that gradient routing is efficient during backpropagation."

backpropagation chapter 에서 배웠다는 내용을 찾아보자.

f(x,y)=max(x,y) 일 때, 

x>=y 이면, f/x=1

y>=x 이면, f/y=1

따라서 (sub)gradient 는 최대 입력변수에 대해서 1, 그리고 그외 입력변수에 대해서는 0 이다.

 

 

이번 질문들도 CNN의 기초개념이라 이미 익숙한 내용이지만

신뢰할 만한 자료들과 논문을 찾아보면서 정확하게 이해한다는 점에서 의미가 있다.

 

'데이터 사이언스 or 엔지니어링 > 머신러닝' 카테고리의 다른 글

모델의 Loss Surface  (0) 2022.02.23
mini-batch 를 사용하는 이유  (0) 2022.02.22
Transformer 의 기초 이해하기  (0) 2022.02.21
Softmax 알아보기  (0) 2022.02.20
ReLU를 사용하는 이유  (0) 2022.02.03

머신러닝 기초공부를 정리를 어떻게 할까 생각하고있었는데,

마침 보이저엑스 남세동대표님이 딥러닝개발자에게 묻는 면접질문을 페북에 포스팅해주셨다.

 

딥러닝을 업무에 이용하고는 있었지만 이론적으로 깊이있게 다루지않다보니

기초적인 질문에 대해 자신있게 답변하기는 어렵더라...

기초적인 내용인 만큼 정리하면서 다시 공부해보자

 

 

1. sigmoid 대신 ReLU를 사용하는 이유가 뭔가요? 

 

가장 먼저 sigmoid, tanh, ReLU, Leaky ReLU 등의 정의와 그래프부터 파악하자

출처: https://medium.com/dataseries/basic-overview-of-convolutional-neural-network-cnn-4fcc7dbb4f17

 

뉴럴넷에서는 입력된 값을 weight 와 bias로 연산하고, 연산결과를 활성함수(activation function) 으로 처리한다.

sigmoid function 은 모든 실수를 0과 1사이의 값으로 변환하는 활성함수이다. 따라서, 각 노드의 결과값은 y=sigmoid(Wx+b) 로 나타난다.

 

뉴럴넷은 학습과정에서 backpropagation 이라는 방법을 이용해서 결과값의 오차를 역전파해서 노드의 가중치 w를 수정한다. 이 때 chain rule에 의한 미분식은 다음과 같이 전개된다

(출처: https://ayearofai.com/rohan-4-the-vanishing-gradient-problem-ec68f76ffb9b)

 

여기서 "output"은 2번째 히든레이어의 결과에 활성함수를 적용한 결과, 즉 sigmoid(z1) 이다.

2번째 히든레이어의 입력값인 "hidden2"은 1번째 히든레이어의 결과에 활성함수를 적용한 결과, 즉 sigmoid(z2) 이다.

 

이처럼 sigmoid를 활성함수로 사용하는 뉴럴넷은 Backpropagation 학습 시, sigmoid 미분값이 chain rule 에 의해 곱해진다.

여기서 sigmoid function 의 미분값은 (0, 0.25) 범위에 존재한다. sigmoid functioin 의 그래프를 보기만 해도 미분값이 굉장히 작다는 것을 쉽게 알 수 있다. 따라서 레이어의 층수가 깊어질수록 레이어의 미분값인 d(error)/d(w1)는 매우 작아진다. 즉, 최종 값의 오차가 앞에있는 레이어까지 전달되지 않아서 뉴럴넷의 학습이 저하되는 vanishing gradient 문제가 발생한다.

 

(간혹 sigmoid의 출력값인 (0,1) 사이 값이 곱해지므로 gradient가 작아진다고 설명하는 자료를 볼 수 있는데,

sigmoid 함수의 미분값인 (0, 0.25) 값이 곱해지는 것이 좀더 정확한 설명인 듯하다....)

 

반면, ReLU는 max(0,x)로 음수는 모두 0으로 반환하고 양수는 값을 그대로 반환하는 활성함수이다.

그래서 ReLU 함수의 미분은 다음과 같다

따라서 sigmoid 대신 ReLU를 사용하면, 위와 똑같이 chain rule 이 적용될 때 레이어의 갯수가 늘어나더라도 최종결과의 오차를 레이어에 그대로 전달할 수 있다.

 

 

1-a. ReLU는 미분 불가능한데 BP가 어떻게 가능한가요? 

ReLU가 미분 불가능한 지점은 x=0일 때뿐인데, 실제 연산에서 x=0이 되는 경우는 극히 드물기때문에 이를 무시하고 사용할 수 있다는 것이 일반적인 견해이다.

 

★심화★ ReLU의 미분불가능한 영역(x=0)이 backpropagation 연산에 미치는 영향에 대한 최신의 연구결과도 있다.

(Bertoin et al., 2021. Numerical influence of ReLU’(0) on backpropagation @ NeurIPS 2021)

TensorFlow와 PyTorch 와 같은 상용라이브러리에서는 ReLU'(0) = 0 으로 두고 전체 학습에 영향이 없을 것으로 가정한다.

하지만 저자인 Bertoin의 실험결과에 따르면 TF와 Torch의 기본셋팅인 32비트 연산에서는 x=0이 되는 지점(bifurcation zone)이 실제로 발생할 수 있고, 이 때 ReLU'(0)=0 또는 ReLU'(0)=1 으로 할 떄 학습결과에서 유의미한 차이가 발생할 수 있다고 주장한다. 동일한 학습을 16비트에서 할때는 결과가 더 안좋아지고, 64비트에서는 문제가 없어진다.

결론적으로, x=0인 minima가 거의 발생하지 않으므로 BP 자체는 문제가 없다고 가정할 수 있다. 그러나 이론적인 생각과 달리 컴퓨팅 과정에서 x=0 이 문제를 야기할 수도 있다.

 

 

1-b. Leaky-ReLU는 무엇인가요?

ReLU에서는 0보다 작은 입력값의 반환값과 미분값이 모두 0으로 반환되기 때문에 많은 많은 뉴런들이 0으로 비활성화 된다는 단점이 있다 (dying ReLU 문제). 이를 보완하기 위해서 Leaky-ReLU(x) = max(0.01x,x) 와 같이 ReLU 의 음수구간에서 x보다 작은 값을 취할 수 있도록 정의한 함수이다. 이 외에도 ELU, PReLU 등 ReLU의 음수구간을 보완하기 위한 방안들이 존재한다.

 

그러나 ReLU를 통해서 뉴런이 0으로 변하는 것은 네트워크의 Sparsity 를 높이는 장점으로 보기도 한다. 벤지오랩에서 Rectifier 에 대해 제안한 2009년 논문 (Glorot et al., 2009. Deep Sparse Rectifier Neural Networks) 에서 일찍이 논한 것 처럼 이미 Sparsity의 장점은 잘 알려져 있다.

그러므로 어떤게 더 좋냐는 질문보다는 해결해야할 문제, 뉴럴넷의 구조, 그 외 학습환경 등을 종합적으로 고려해서 가장 적합한 활성함수를 찾는게 베스트라는... 딥러닝연구스러운 결론에 도달할 수 있다 ㅎㅎ;; 

 

텐서플로우 튜토리얼을 통해 파이썬-텐서플로우 기초 문법을 뽀개보자

심전도데이터에서 이상치를 감지하는 ECG50000 분석용 오토인코더 모델 만들기 를 첫번째 주제로 정했다.

 

1. 클래스 생성과 클래스 상속

class AnomalyDetector(Model):

AnomalyDetector 라는 클래스를 생성한다.

이때 class 자식클래스(부모클래스) 문법을 사용하면 괄호안에 있는 클래스의 속성과 메서드를 상속받는다.

튜토리얼상에는 import 구문이 가장 위에 있어서 잠깐 헤멜 수 있는데, tensorflow.keras.models 에서 Model 을 import 한 것을 찾을 수 있다.

즉, AnomalyDetector라는 클래스는 tensorflow.keras 모듈의 기본 모델 클래스의 기능을 그대로 물려받는다는 뜻!

 

 

2. __init__ 메서드로 초기화 하기 

  def __init__(self):
    super(AnomalyDetector, self).__init__()
    self.encoder = tf.keras.Sequential([
      layers.Dense(32, activation="relu"),
      layers.Dense(16, activation="relu"),
      layers.Dense(8, activation="relu")])
    self.decoder = tf.keras.Sequential([
      layers.Dense(16, activation="relu"),
      layers.Dense(32, activation="relu"),
      layers.Dense(140, activation="sigmoid")])

이제 클래스를 생성했으니 필요한 메서드를 생성해야한다. 가장 먼저 __init__ 메서드를 만들자.

__init__ 메소드는 파이썬의 특수 메서드로 클래스가 생성될 때 자동으로 호출되는 메서드이다.

따라서 딥러닝 모델 클래스를 만들 때는 __init__ 으로 모델의 구조를 정의하는 것이 일반적이다.

 

super()는 자식 클래스에서 부모 클래스의 메서드를 이용하기 위해 사용한다.

부모클래스인 Model에 뭐가있는지는 잘 몰라도 어쨋든 케라스 모듈을 다 가져오기 위해서 필요한 부분이다.

 

super를 사용하지 않은 경우에는 자식클래스에서 선언된 __init__ 이 부모클래스의 __init__ 을 오버라이딩한다.

다음과 같이 예시를 들면 이해가 쉽다

class father():
    def __init__(self):
        print("나는 아빠다")

class bro(father):
    def __init__(self):
        print("나는 아들이다")

class sis(father):
    def __init__(self):
        super(sis, self).__init__()
        print("나는 딸이다")

man = father()
boy = bro()
girl = sis()

### 출력값

# 나는 아빠다

# 나는 아들이다

# 나는 아빠다
# 나는 딸이다

 

3. call 으로 순방향 연산 정의

  def call(self, x):
    encoded = self.encoder(x)
    decoded = self.decoder(encoded)
    return decoded

keras 에서 모델 클래스의 call은 순방향 연산을 정의하는 내용으로 작성한다. 

파이썬 매직메서드인 __call__ 과 다르다는 것에 유의하자. (call 에 대한 자세한 내용은 다음기회에...)

 

현재 모델은 __init__에서 레이어를 정의하면서 연산방법, 즉 activation function을 이미 정해줬으므로

call 에서는 간단하게 self.encoder 와 self.decoder 를 연달아 연산해주기만하면

각 레이어별 연산을 완료할 수 있다.

 

 

4. 모델 컴파일 및 학습

autoencoder = AnomalyDetector()
autoencoder.compile(optimizer='adam', loss='mae')

history = autoencoder.fit(normal_train_data, normal_train_data, 
          epochs=20, 
          batch_size=512,
          validation_data=(test_data, test_data),
          shuffle=True)

이제 클래스 정의가 끝났으므로 오토인코더 모델을 실행시켜보자.

 

새로 정의한 클래스는 tensorflow.keras.models 클래스를 상속받았으므로,

.compile 과 .fit 라는 인스턴스 메서드를 그대로 이용할 수 있다. 

 

optimizer와 loss function 을 정의해서 모델 컴파일 하고

모델 학습에 필요한 하이퍼 파라미터를 정의해주고 실행하면 끝!

 

<튜토리얼 링크>

<참고자료>

[1] "왕초보를 위한 Python: 쉽게 풀어 쓴 기초 문법과 실습" https://wikidocs.net/book/2

[2] https://velog.io/@gwkoo/클래스-상속-및-super-함수의-역할

 

+ Recent posts