728x90

detach()와 clone()은 기존 Tensor를 복사하는 방법 중 하나이다.

tensor.clone()은 기존 텐서의 내용을 복사한 텐서를 생성하겠다는 의미이며, detach()는 기존 텐서에서 기울기가 전파되지 않는 텐서이다.

즉, tensor.clone().detach()는 기존 텐서를 복사한 새로운 텐서를 생성하지만 기울기에 영향을 주지는 않겠다는 의미이다.

구분 메모리 계산 그래프 상주 유무
tensor.clone() 새롭게 할당 계산 그래프에 계속 상주
tensor.detach() 공유해서 사용 계산 그래프에 상주하지 않음
tensor.clone().detach() 새롭게 할당 계산 그래프에 상주하지 않음

 

728x90

'딥러닝 > Pytorch' 카테고리의 다른 글

Pytorch 기본 예제  (0) 2022.12.24
[Pytorch] register_buffer  (0) 2022.08.01
pytorch - nn.function과 nn의 차이점  (0) 2022.06.19
torch - GPU 사용하기  (0) 2022.06.13
Pytorch nn.ModuleList  (0) 2022.05.30
728x90

transformer를 공부하던 중 positional encoding부분에서 register_buffer라는 부분이 생소하여 포스팅으로 기록한다.

torch.nn.Module.register_buffer는 매개 변수로 간주되지 않는 버퍼를 등록하는 데 사용된다. register_buffer는 다음과 같은 특징이 있다.

  1. optimizer가 update하지 않는다.
  2. state_dict에는 저장된다.
  3. GPU에서 작동한다.

즉, 네트워크를 구성하는데 있어 중간에 업데이트를 하지 않는 일반 layer를 넣고 싶을 때 사용한다.

728x90

'딥러닝 > Pytorch' 카테고리의 다른 글

Pytorch 기본 예제  (0) 2022.12.24
tensor의 복사방법  (0) 2022.08.06
pytorch - nn.function과 nn의 차이점  (0) 2022.06.19
torch - GPU 사용하기  (0) 2022.06.13
Pytorch nn.ModuleList  (0) 2022.05.30
728x90

1. Transformer (Vaswani et al., 2017)

1.1 개요

Transformer는 Attention mechanism의 장점을 극대화한 모델이다. RNN처럼 순차적으로 데이터를 처리하는 것이 아니라 한꺼번에 시퀀스를 처리하는 것이 가장 큰 특징이다.

Transformer 구조

Transformer는 Encoding component와 Decoding component의 연결로 구성되어 있다.

여기서 encoding component와 decoding component는 encoder와 decoder의 stack들이다.

여기서 encoder는 구조가 모두 동일하지만 가중치를 공유하지는 않는다. 또한 각각의 encoder는 self-attention과 feed forward nn 두 개의 하위 계층으로 나뉜다. 반면, decoder는 encoder-decoder attention 계층 하나가 더 추가되어 있는 구조이다.

 

이제 자세히 transformer 구조를 알아보자.

1.2 Input Embeddings

먼저 Input Embeddings 과정이다.

input이 들어오게 되면 먼저 embedding algorithm을 이용해 각각의 단어들을 벡터화시킨다. 맨 처음 encoder만 embedding vector를 받고 그 다음 encoder부터는 바로 아래의 encoder의 ouput을 받게 된다.

Input Enbedding

1.3 Positional Encoding

두번째로 Positional Encoding 과정이다.

Transformer는 단어들이 한꺼번에 input으로 들어가기 때문에 어떤 단어가 몇번째로 들어갔는지에 대한 정보의 손실이 존재한다. 이러한 손실을 막기 위해 만들어진 것이 positional encoding 과정이다. 이번 포스팅에서는 간단하게만 다루고 추후에 독립적인 포스팅을 할 기회가 있을 것 같다.

positional encoding은 두 벡터의 거리가 멀수록 값이 커저야 한다는 개념이다. 

positional encoding 시각화

positional encoding vector는 input embedding과 더해지며 encoder의 input으로 들어가게 된다.

1.3  Self-Attention

그 다음 과정으로 Multi-head attention & Residual connection & Normalization 과정이다. 그 전에 먼저 self-attention의 역할부터 알아보자. 

self-attention은 연관 있는 단어들을 살펴보기 위한 역할을 하고 있다. self-attention은 다음과 같은 일련의 과정을 거치게 된다.

 

1. 각각의 input vector에 대해서 세 종류의 벡터를 생성한다.

  • Query : 다른 모든 단어에 대해 점수를 매기는 데 사용되는 현재 단어의 표현.
  • Key : 정보를 제공하는 단어의 집합. 즉, 단어의 label과 같은 의미.
  • Value : Key에 대한 실제 표현.

2. Score를 계산한다. score는 해당 단어에 대해 다른 단어들을 얼마나 집중하는지를 결정한다.

  • Query vector와 각각의 key vector를 곱하여 score를 산출

3. 산출된 score를 차원의 루트로 나눠준다. 이는 기울기의 안정성에 도움이 되기 때문이라고 한다.

4. softmax 함수를 통해 확률값으로 표현한다.

5. value vector들과 softmax score를 곱해준 후 모두 합하여 최종적인 output을 도출한다.

1.4 Multi-Head Attention

multi-head attention은 주어진 단어가 다른 단어를 참고할 때 하나의 경우의 수만 참고하는 것이 아닌 여러가지의 경우의 수를 참고하겠다는 아이디어이다. 즉, attention을 head의 수 많큼 쓰겠다라는 뜻이다.

1.5 Residual

residual connection은 resnet과 마찬가지로 입력의 output에 자기자신을 더해주는 방법이다. 

$${\operatorname{d}\over\operatorname{d}\!x}\{f(x)+x\}=f^\prime(x) + 1$$

그 이유는 위 식과 같이 미분을 하게 되면 도함수가 굉장히 작더라도 기울기가 최소한 1만큼은 흘려주게 되어 학습에 상당히 유리하다. 

1.6 Masked Multi-head Attention

다음으로 decoder부분의 Masked Multi-head attention 과정이다.

decoder에서의 self attention layer는 output sequence 내에서 현재 위치의 이전 위치들에 대해서만 고려해야 한다. 이는 self-attention 계산 과정에서 softmax를 취하기 전에 현재 스텝 이후의 위치들에 대해서 masking(-inf로 치환)을 해줌으로써 가능하다.

1.7 Multi-Head attention with Encoder outputs

그 다음 과정으로 encoder의 output과 decoder사이의 attention을 하는 과정이다. 

 

1.8 Final Linear and Softmax Layer

마지막 과정이다. Linear layer와 softmax layer를 통해 최종적으로 확률값을 구하고 argmax를 통해 해당하는 단어를 return하게 된다.

출처

Vaswani, Ashish, et al. "Attention is all you need." Advances in neural information processing systems 30 (2017).
728x90

'딥러닝 > 개념 공부' 카테고리의 다른 글

Seq2Seq Model  (0) 2022.07.16
728x90

1. Sequence to Sequence model (Sutskever et al., 2014, Cho et al., 2014)

먼저, 이번 포스팅의 내용은 Jalammar의 블로그 내용과 그림을 참고하였다.

Seq2Seq model이란 일련의 항목 (단어, 문자 등)을 취하여 다른 항목의 시퀀스를 출력하는 모델을 뜻한다. 

 

1.1 핵심 아이디어

Seq2Seq는 encoderdecoder라는 두가지 구조로 구성되어 있다.

Seq2Seq encoder-decoder 구조

위 영상과 같이 입력된 각각의 item을 encoder에서 처리한 후 정보들을 컴파일하여 하나의 벡터로 처리한다. 이 벡터를 context vector라고 한다. 이후, 모든 input item을 받은 후, encodercontextdecoder로 보내게 된다. Decodercotext vector를 받아 output item들을 반환하게 된다.

 

1.2 RNN 기반 Encoder-Decoder

encoder-decoder 구조를 표현하기 위한 가장 고전적인 방법으로 RNN이 사용되었었다. 

다음과 같이 각각의 입력이 들어올 때 마다 hidden state가 업데이트 된다. 모든 입력이 들어온 후 가장 마지막의 hidden state가 context vector가 되어 decoder로 전달되게 된다. decoder는 context vector를 이용해 output을 배출하게 된다.

 

2. Attention

Context vector는 가장 마지막 item에 영향을 많이 받기 때문에 긴 길이의 시퀀스에 대해 bottleneck이 있다. 때문에 이후 Attention 방법을 도입하여 input 시퀀스에 대해 item이 주목해야 하는 부분에 대해 조금 더 활용할 수 있다.

2.1 Classic Seq2Seq vs. Attention Model

 

위 영상과 같이 Encoder가 더이상 마지막 hidden state를 넘겨주는 것이 아니라 모든 hidden state를 decoder로 넘겨주게 된다. 그리고 hidden state들 중에 가장 영향을 주는 hidden state에 가중치를 주어 decoder의 output을 배출하게 된다.

 

2.2 Decoder

Attention decoder는 output을 배출하기 전 다음과 같은 extra step을 거친다.

  • encoder에서 배출된 hidden state를 모두 확인. (각각의 hidden state는 해당 입력 item의 정보를 가장 많이 가지고 있음)
  • 각각의 hidden state에 score를 할당.
  • softmax 시킨 score와 hidden state를 곱하여 결합.

위 step을 영상으로 보면 다음과 같다.

 

출처

https://jalammar.github.io/

 

Jay Alammar – Visualizing machine learning one concept at a time.

Visualizing machine learning one concept at a time.

jalammar.github.io

 

728x90

'딥러닝 > 개념 공부' 카테고리의 다른 글

Transformer  (0) 2022.07.16
728x90

파이토치로 모델링을 할 때 nn을 사용할 때도 있고 nn.functional을 사용할 때도 있다.

이 둘의 차이점은 무엇인지 알아보자.

 

먼저 nn을 사용하는 코드는 다음과 같다.

import torch
import torch.nn as nn

inputs = torch.randn(64, 3, 244, 244)
conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1)
outputs = conv(inputs)
layer = nn.Conv2d(1, 1, 3)

nn.functional을 사용하는 코드는 다음과 같다.

import torch.nn.functional as F

inputs = torch.randn(64, 3, 244, 244)
weight = torch.randn(64, 3, 3, 3)
bias = torch.randn(64)
outputs = F.conv2d(inputs, weight, bias, padding=1)

 

nn.Conv2d에서 input_channel과 output_channel을 사용해서 연산했다면 functional.conv2d는 입력과 가중치 자체를 직접 넣어준다. 이때 직접 넣어준다는 의미는 가중치를 전달해야 할 때마다 가중치 값을 새로 정의해야 함을 의미한다.

다음은 nn과 nn.functional을 비교한 표이다.

구분 nn nn.functional
형태 nn.Conv2d : 클래스
nn.Module 클래스를 상속받아 사용
nn.functional.conv2d : 함수
def function (input)으로 정의된 순수한 함수
호출 방법 하이퍼파라미터를 전달한 후 함수 호출을 통해 데이터 전달 함수를 호출할 때 하이퍼파라미터, 데이터 전달
위치 nn.Sequential 내에 위치 nn.Sequential에 위치할 수 없음
파라미터 파라미터를 새로 정의할 필요 없음 가중치를 수동으로 전달해야 할 때마다 자체 가중치를 정의

 

728x90

'딥러닝 > Pytorch' 카테고리의 다른 글

tensor의 복사방법  (0) 2022.08.06
[Pytorch] register_buffer  (0) 2022.08.01
torch - GPU 사용하기  (0) 2022.06.13
Pytorch nn.ModuleList  (0) 2022.05.30
Pytorch nn.Embedding()  (0) 2022.05.30

+ Recent posts