'Deep Learning > Pytorch' 카테고리의 다른 글

20_Pytorch_ResNet  (0) 2021.10.06
19_Pytorch_VGG16  (0) 2021.10.05
17_Pytorch_CNN (Convolutional_Neural_Network)  (0) 2021.09.30
16_Pytorch_Batch_Normalization  (0) 2021.09.29
15_Pytorch_Overfitting_Dropout  (0) 2021.09.14

Convolution

고양이가 어떠한 이미지를 바라볼때 모든 뉴런들이 동작하는 것이 아니라 이지미의 특정부분에 대해서 일부분의 뉴런만 동작하는 것에서 착안하여 나온것이 Convolution입니다.

 

 


 

32 * 32 * 3 사이즈의 이미지가 있다고 가정을 해보겠습니다.

※ 여기서 3이라는 숫자는 이미지가 흑백인지 컬러인지를 나타내주는 값입니다. R, G, B 각각 하나씩이라고 보면 될것같습니다.

 

위에서 언급했던 이미지의 일부분의 특징값을 뽑아낼 수 있는 neuron의 역할을 할 수 있는

filter를 이용하여 특징값을 추출해줍니다.

 

filter를 이미지에서 이동을 시키며 하나의 값들로 추출하여 특징값을 가진 이미지를 만들어줍니다.

※ 같은 filter로 특징값을 추출해줍니다!

 


Convolution 연산

값을 추출해주는 연산입니다.

단순히 행렬 연산의 곱이 연속된 것이라고 생각하면 됩니다.

 

여기서 filter를 Wx + b에서 W값이라고 보시면 되겠습니다.

 

또한 filter를 한칸씩 이동하면서 연산을 하게 되는데 이때 stride=1 이라고 합니다.

 

즉, 5 * 5 이미지에 3 * 3 filter를 적용하게 되면 3 * 3의 특징값들이 나오게 됩니다.

 

 

 

 

 

여러 채널을 가진 Input Data에서의 Convolution 연산

 

 

Convolution은 Filter (Kernel) 하나당 하나의 Feature Map이 나오게 됩니다.

 

 

 

 


 

Neuron과 Convolution

 

kernel은 위에서 말했던 것처럼 Weight값입니다.

 


Padding

위의 Convolution 연산을 진행하다 보면 이미지가 계속 작아지게 됩니다.

그렇게 되면 이미지가 작아지는 만큼 이미지에 대한 정보를 잃어버리게 된다는 뜻도 됩니다.

특히, 모서리 부분의 정보를 잃어버리게 되는데 이를 위해 Padding이라는 것이 등장했습니다.

위의 사진과 같이 이미지를 0으로 감싸주는 것입니다.

이를 함으로써 모서리 부분의 특징값들을 살리면서 이미지가 급격하게 작아지는 것을 방지해줍니다.

 

※ Convolution의 Output 크기 계산 예시!

https://ggongsowon.tistory.com/9

 

Pytorch Conv Output_Size 계산

nn.Conv2d(3, 32, 3, padding=1) 첫번째 parameter 인 3은 input_channel_size가 되겠습니다. 여기서 input_channel_size는 Input Image의 RGB depth 인 3이 되겠습니다. (즉, 32*32 Image 3장이 들어간다고 보면..

ggongsowon.tistory.com


Pooling Layer (sampling)

Conv Layer에서 한 Layer씩 뽑아 sampling을 해줍니다.

ex) channel이 3이면 3장중 한장씩 뽑아서 sampling

Pooling에서는 Max Pooling, Avg Pooling 등이 있습니다.

여기서 Max Pooling을 살펴보겠습니다.

보시는 것과 같이 filter 내에서 가장 큰 특징값을 추출하여 새로운 이미지를 만들어 줍니다.

Avg는 말 그대로 평균값을 이용해주는 것입니다.


Code

Pytorch에서 Conv2d를 사용하기 위한 함수입니다.

  • in_channels = filter의 개수
  • out_channels = output의 개수
  • kernel_size = filter의 행렬 크기
  • stride = filter의 이동 칸수
  • padding = padding의 사이즈
  • dilation = filter 사이 간격 사이즈
  • groups = 입력 채널들을 여러 개의 그룹으로 나누어 독립적인 컨볼루션을 수행
  • bias = bias 사용 유무

 

 

 

 

 

 

출처:

https://www.youtube.com/watch?v=Em63mknbtWo&list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&index=35 

https://www.youtube.com/watch?v=rySyghVxo6U&list=PLQ28Nx3M4JrhkqBVIXg-i5_CVVoS1UzAv&index=19 

 

'Deep Learning > Pytorch' 카테고리의 다른 글

19_Pytorch_VGG16  (0) 2021.10.05
18_Pytorch_CNN_MNIST  (0) 2021.09.30
16_Pytorch_Batch_Normalization  (0) 2021.09.29
15_Pytorch_Overfitting_Dropout  (0) 2021.09.14
14_Pytorch_Weight Initialization  (0) 2021.09.09

Internal Covariate Shift

  • Train Data와 Test Data의 분포의 차이

또한 Train시 한 레이어마다 입력과 출력이 있습니다.

그런데 여기서 한 레이어마다 Internal Covariate Shift가 발생하고 레이어가 많을수록 더욱 심해집니다.

 

 


BatchNormalization

Internal Covariate Shift를 해결해주기 위해 BatchNormalization을 사용합니다.

 

BatchNormalization

여기서, 주목할 것은 Training 파라미터가 추가가 된다는 것입니다.

※ Bias는 Beta로 대체됩니다!

 

 

 


Code

 

 

 

 

 

 

 

 

출처:

https://www.youtube.com/watch?v=m61OSJfxL0U&t=100s 

https://www.youtube.com/watch?v=HCEr5f-LfVE&list=PLQ28Nx3M4JrhkqBVIXg-i5_CVVoS1UzAv&index=17 

 

 

'Deep Learning > Pytorch' 카테고리의 다른 글

18_Pytorch_CNN_MNIST  (0) 2021.09.30
17_Pytorch_CNN (Convolutional_Neural_Network)  (0) 2021.09.30
15_Pytorch_Overfitting_Dropout  (0) 2021.09.14
14_Pytorch_Weight Initialization  (0) 2021.09.09
13_Pytorch_Activation_Gradient Vanishing  (0) 2021.09.08

Overfitting

Overfitting

Training Dataset에 너무 최적화되어 Test Dataset에서 낮은 정확도를 얻는 현상

  • 너무 Deep한 Layer일때 Overfitting 발생
  • 위 사진의 빨간 선부터 Overfitting 발생

 

 


Solution for Overfitting

  1. 더 많은 Training Dataset
  2. Regularization (정규화)
  3. Dropout

 


Dropout

 

  • Train시 neuron들을 랜덤하게 사용하지 않음

 

※ Dropout 사용시 주의할점!

model.train()과 model.eval() 에 대해 알아야 합니다.

model.eval()은 eval mode에서 사용할 것이라고 모든 레이어에 선언하는 것이며,

BatchNomalization과 Dropout들은 train mode 대신에 eval model로 작동합니다.

또한 eval 에서 torch.no_grad()는 Backpropagation에 사용하는 계산량을 줄여서 처리 속도를 높입니다.

(eval mode에서는 dropout은 비활성화, BatchNomalization은 학습에서 저장된 파라미터를 사용)

 


Code

 

 

 

 

 

 

출처:

https://www.youtube.com/watch?v=wTxMsp22llc&list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&index=32&t=2s 

 

Weight Initialization

이전 글에서 Gradient Vanishing을 해결하기 위해서 Activation Function을 ReLU로 바꿨습니다.

그리고 여기 Gradient Vanishing을 해결하기 위한 방법이 또 한가지 있습니다.

 

ReLU를 똑같이 사용했는데도 학습과정에서 속도가 차이가 나는것을 알 수 있습니다.

이것은 Weight 값을 입력할때 보통 랜덤값을 넣고 실행하기 때문입니다.

 

여기서, Weight값을 0으로 초기값으로 진행을 한다면

Backpropagation을 진행할때 기울기가 0이 되므로 Gradient Vanishing 현상이 일어납니다.

 

그래서 우리가 초기값을 0을 사용하면 안되고 (학습이 진행이 안됨) Weight의 초기값을 정해주기 위해

RBM(Restricted Boatman Machine)이라는 방법이 나옵니다. (현재는 많이 사용하지 않음)

 

 

 

RBM

학습을 수행하는데 있어 Forward와 Backward를 진행하게 됩니다.

endcoder, decoder라고도 부를 수 있습니다.

 

Forward와 Backward 진행 후 input 값을 서로 비교하여 일치하게 만들어주는 Weight값들을 찾아주는 겁니다.

여러 Layer가 있다면 두개의 Layer씩 비교를 하며 마지막 Layer까지 진행을 해줍니다.

※ RBM 적용 후 학습을 시킬때

   이를 학습이라고 하지 않고 Fine Tuning이라고 합니다.

   그 이유는 Weight들을 값만 바꿔주는 Tuning만 해주면 되기 때문입니다.

 

RBM을 사용하기에는 너무 복잡하기 때문에 Xavier Initialization이라는 방법이 나오게 됩니다.

 

 


Xavier Initialization

Xavier Initialization은 input(fan_in)과 output(fan_out)의 개수에 따라

2010년에는 위의 수식대로 Weights값을 주어지면 되는 것입니다.

2015년에는 위의 수식대로 Weights값을 주어지면 되는 것입니다.

 

이제 코드로 직접 사용해보겠습니다.

 

 


이전글의 Model 선언부 입니다.

여기에서 달라진건 __init__ 함수 부분의 마지막인

torch.nn.init.xavier_uniform_(self.linear4.weight) 입니다.

위와 같이 적용해주면 됩니다.

'Deep Learning > Pytorch' 카테고리의 다른 글

16_Pytorch_Batch_Normalization  (0) 2021.09.29
15_Pytorch_Overfitting_Dropout  (0) 2021.09.14
13_Pytorch_Activation_Gradient Vanishing  (0) 2021.09.08
12_Pytorch_Multi_Layer_Perceptron_XOR  (0) 2021.08.25
11_Pytorch_Backpropagation  (0) 2021.08.25

저희가 저번시간에는 XOR 문제를 해결해 보았습니다.

XOR를 사용하기 위해서 Perceptron 사이사이 Sigmoid를 사용해 주었습니다.

이런 함수들을 Activation Function이라고 부릅니다.

다음 Layer로 값이 넘어갈때 임의의값을 기준으로 활성화를 시킬지 말지의

기능을 하기 때문에 Activation Function이라고 불립니다.

 

Activation Function을 Sigmoid로 적용한 후 Backpropagation을 실행하면

엄청난 문제가 발생합니다.

깊지 않은 Layer을 쌓았을때는 그렇게 크게 문제가 되지는 않지만

깊은 Layer를 쌓았을때는 기울기 소실문제(Gradient Vanishing)가 발생하게 됩니다.

 

 

Backpropagation을 진행을 하면서 Chain Rule을 통해 많은 미분을 하게 됩니다.

즉, Sigmoid를 미분하게 됩니다.

그런데 여기서 Sigmoid를 미분하게 되면 0~1 사이의 값을 가지게 됩니다.

Sigmoid

그런데 여기서 Sigmoid의 미분값이 0.00000001 일수도 있고

0.001이 연속적으로 이어질 수 있습니다.

결국 이러한 값들이 계속 곱해지게 되면 기울기가 0에 가까운 값에 수렴되면서

기울기 소실문제가 발생하게 됩니다.

 

이러한 문제를 해결하기 위해 여러가지 Activation들이 나오게 됩니다.

그렇게 ReLU라는 Activation Function이 나오게 됩니다.

ReLU

ReLU는 기울기가 0 or 1이기 때문에 Sigmoid의 기울기 소실문제를

어느정도 해결할 수 있게 되었습니다.

ReLU 말고도 다른 Activation Function들도 많이 개발되었습니다.

ex) tanh, ELU, swish, Leaky ReLU 등등...

 

하지만 성능적인 측면에서 어마어마한 효과가 있는것이 아니기 때문에

실무에서는 ReLU를 주로 사용하고 있습니다. (제 기준)

 


CODE

 

 

 

출처:

https://www.youtube.com/watch?v=cKtg_fpw88c&list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&index=30 

https://www.youtube.com/watch?v=86vpXy1TA5s&list=PLQ28Nx3M4JrhkqBVIXg-i5_CVVoS1UzAv&index=14 

'Deep Learning > Pytorch' 카테고리의 다른 글

15_Pytorch_Overfitting_Dropout  (0) 2021.09.14
14_Pytorch_Weight Initialization  (0) 2021.09.09
12_Pytorch_Multi_Layer_Perceptron_XOR  (0) 2021.08.25
11_Pytorch_Backpropagation  (0) 2021.08.25
10_Pytorch_Perceptron_XOR  (0) 2021.08.25

Shared Memory

 

  • Memory Bank
    • 데이터의 접근 통로
    • Shared Memory는 32개의 bank로 구성되어 있음
    • 구성단위: 4 byte or 8 byte (compute capability 3.x ~이상)
    • bank는 서로 독립적이며, 서로 다른 bank는 동시 접근 가능
  • Bank Conflict
    • 하나의 bank에 여러 thread가 접근하는 경우 하나의 thread씩 처리할 수 있다.
    • 즉, thread의 직렬화 발생! → 성능 저하

 

 


No Bank Conflict

성능 저하

CUDA를 사용할때 Bank Conflict를 조심해야 한다.

 

 

 

 


Example

Bank Conflict 발생

이전글에서

row = threadIdx.x 일 경우 Bank Conflict 발생!

이를 해결해주기 위해 Global Memory에서 Shared Memory로 옮길때

Transpose를 해주면서 넘겨주면 해결이 됩니다.

 

 

 

 

 

출처:

https://www.youtube.com/watch?v=hyCEFNbumOo&list=PLBrGAFAIyf5pp3QNigbh2hRU5EUD0crgI&index=25

'Cuda' 카테고리의 다른 글

12_Global_Memory_Maximizing_CUDA  (0) 2021.09.07
11_Using Shared Memory_Example_Quiz_2_CUDA  (0) 2021.09.02
10_Using Shared Memory_Example_Quiz_1_CUDA  (0) 2021.09.01
09_Memory_Active_Warp_CUDA  (0) 2021.09.01
08_Memory_Architecture_CUDA  (0) 2021.08.30

Memory Access Pattern

CUDA가 Memory에 접근하는 형태

  • Warp 안에 있는 32개의 Thread들이 하나의 Instruction에 의해 Access가 발생합니다.

 

Global Memory

  • Global Memory는 L2 cache를 통해서 이루어집니다.
    • 한번에 32 byte만큼 읽어옵니다.
    • L2 cache에서 L1 cahce로 이동을 할때 128 byte만큼 읽어옵니다.

 

 

  • Aligned memory access: 메모리 접근시 기준점에 맞춰서 읽기 시작하면 Aligned memory access라고 합니다.
    • L2 cache: 32bit * 2n 기준점
    • L1 cache: 128bit * 2n 기준점

 

  • Coalesced memory access
    • Warp 내 32개 thread가 연속된 메모리 공간을 접근
    • 아래의 사진과 같이 연속된 메모리에 접근하는 것입니다.

 

예시

예시 사진에서 32개의 Thread가 있고 하나의 Thread당 4 byte를 할당 받는다고 하면

하나의 Warp이 요청하는 데이터의 양이 128 byte라고 할 수 있습니다.

  • Aligned and Coalesced Access
    • L2 cache로 읽는 경우 4등분
    • L1 cache로 읽는 경우 한번에 접근 가능

 

  • Not Aligned and Coalesced Access
    • 데이터들이 연속적이지 않고 크기도 중구난방일 경우
    • 더 많은 tracsact가 필요하여 메모리에 접근하는 횟수가 늘어납니다.

 

되도록 Global Memory Access 할때는 Warp 안에 있는 thread들이 Aligned하고 Coalesced된 Memory Access 하도록 작성을 해야합니다.

 

 


Example

위의 사진에서

row = threadIdx.x

col = threadIdx.y

보다는

 

row = threadIdx.y

col = threadIdx.x

가 더욱 Coalesced하기 때문에 더욱 효율적입니다.

 

 

출처:

https://www.youtube.com/watch?v=ualcIR5pmsg&list=PLBrGAFAIyf5pp3QNigbh2hRU5EUD0crgI&index=24

'Cuda' 카테고리의 다른 글

13_Shared_Memory_Maximizing_CUDA  (0) 2021.09.07
11_Using Shared Memory_Example_Quiz_2_CUDA  (0) 2021.09.02
10_Using Shared Memory_Example_Quiz_1_CUDA  (0) 2021.09.01
09_Memory_Active_Warp_CUDA  (0) 2021.09.01
08_Memory_Architecture_CUDA  (0) 2021.08.30

+ Recent posts