본문 바로가기

Hello MLop/DL

MLop_DL_ResNet 실습

20221121

34일차

 


오늘 해볼 실습은 ResNet(CNN) 신경망 이다.

중간에 프로젝트가 있어 조금 밀렸지만

다시 열심히 해보겠다.


ResNet(Residual neural network)?

사전적 의미는 잔차 신경망이다. # Residual : 어떤 과정이 끝나고 난 뒤에 남은, 잔여[잔류]의

 

왜 생겨났을까?

 

딥러닝에서 사용하는 여러 신경망중   

 

미지 처리를 할때는 CNN(Convolutional Neural network)이 주로 사용되고

자연어 처리를 할때는 RNN(Recurrent Neural network)가 주로 사용된다.

 

이 두 신경망은 훌륭한 학습 결과를 자랑하지만

아쉬운점은 신경망의 레이어가 깊어지면 vanishing gradient problem 때문에 error가 증가한다는 단점이 있다.


💡 vanishing gradient problem? 기울기 소멸 문제

레이어가 깊어지면 오차역전파등의 경우 가중치가 점점 사라져  제대로된 판단을  못하는 모델이 됨.

 

💡 Degradation Problem?

정확도가 어느 순간부터 정체되고 레이어가 더 깊어질수록 성능이 더 나빠지는 현상


이를 방지하기 위해 태어난것이 ResNet 신경망이다.

 

그럼 ResNet 신경망은 어떻게 기울기 소멸 문제를 해결했을까?

 

스킵 연결(skip connection)을 통해 잔차를 학습했다. # x_ = x

스키 연결을 하는 이유를 쉽게 설명하면 가중치를 최적화 할때를 대비해

가중치가 마르지 않게 계속 원래 값을 보충해줬다.

 


 

💡 스킵 연결 #aka. skip connection = identity mapping =  identity shortcut connection

 

입력값출력값이 같은 매핑을 의미

 


출처: wikidocs

위의 그래프는 실제 연구한 그래프인데,

Plain neural network와 비교했을 때 Layer를 상당히 깊게 쌓았음에도

적게 쌓았을 때보다 에러가 낮으며

degradation problem이 발생하지 않은 것을 알 수 있다.

 

🔥 정리

 

일반적으로 다층 신경망의 결과를 도출 후 가중치 학습을 할 때

 

층(layer)이 많아 질수록 가중치 학습시

학습할 가중치가 점점 크기가 작아진다. 

 

그래서 가중치가 마르지 않도록 스킵 연결을 해주는 신경망이

ResNet이다.

 

 


이제 실습 코드를 보자.

 

 

위의 코드를 이번엔 그려보았다.

Basic Block의 구조이다.

 

💡  각 용어 주석

Kernel = k

Pedding = p

Conv2d = C2

BatchNorm2d = BN2

 

로 표시하였다.

 

Basic Block 은 총 4개의 작은 층으로 정의되었다.

 

c1

데이터를 입력받고

p=1로 만들어주고 k로

Conv2d 합성곱 연산 # 2차원 데이터 을 거쳐

출력 해준다.

 

c2

out,out 구조인데

출력된 데이터를 

p=1로 만들어주고 k로

Conv2d 합성곱 연산 # 2차원 데이터 을 거쳐

출력 해준다.

 

downsample

데이터를 입력받고

p없이 k(1 * 1)로

Conv2d 합성곱 연산 # 2차원 데이터 을 거쳐

출력 해준다.

 

마지막으로bn1,2

num_features가 들어와서

BN2를 거쳐

out_channels로 나온다.


💡torch.nn.Conv2d 

 

 

이미지를 R,G,B를 기준으로 나눠

3채널로 시작해  Convolutin 연산이 진행되는 과정이다.

 


💡 BatchNorm2d ⭐⭐⭐⭐⭐

배치 정규화는 튀는 분포가 나오지 않도록 조절하게 하는 역할

 

정규화는 왜 할까? 아래의 그래프를 보자.

출처 : https://eehoeskrap.tistory.com/

정규화를 하지않은 모델과 한 모델의 모양을 보고 이해해야한다.수 많은 불규칙적인 값들에 가중치를 주면 불규칙적인 값들의 영향력이 커질것이다.

 

그렇다면 위와같이 우리는 가중치 최적화 하는 과정에서 처음 만나는 깊이가 최대 깊이인줄 알고학습을 중단하는데, 알고보니 뒤에 더 깊은 깊이가 있다면, 이는 제대로 학습을 하지 못한 과정이다.

 

그렇기에 미리 정규화 과정을 거쳐 가중치들의 값들을 조금 안정화 시켜준다면,가중치 학습시 우리가 원하는 목표인 제일 깊은곳에 다다르기 쉬울것이다.

 


자 그럼 BasicBlock의 최종 순전파를 보자.

위에서 정의한 블록들을 합쳐 순전파를 정의했다.

 

이때 downsample 블록에서 ResNet의 무기, 스킵연결이 일어난다.

 


ResNet(Module)

 

 

 

💡 ResNet Model 주석

 

num_classes = 10

Avgpool2d = 평균 풀링

Stride = s

nn.Linear = L

 


ResNet Model의 구성을 보자.

 

b1

3개의 입력층에서 64개의 출력층

=1024개

 

b2

64개의 입력층에서 128개의 출력층

=2048개

 

b3

128개의 입력층에서 256개의 출력층

=4096개

 

pool

k(2 * 2)로

s =2 씩 움직이면서

Avgpooling 해준다.

 


분류기

 

fc1

4096개  L   2048개

fc2

2048개   L    512개

fc3

512개   L    512개

 

위의 ResNet model로 뽑혀져 나온 데이터를

 

nn.Linear = L 를 사용해 분류해주는 블럭을 정의했다.

 


ResNet 순전파 

 

ResNet 모델을 함수로 선언해 순서를 설계했다.

 

위의 그림을 보면

 

베이직블록풀링층을 섞고

 

가중치 데이터들이 있는 1차원 부터 데이터

torch.flatten 을 사용해 

 

# torch.flatten parameters

 

torch.flatten을 하는 이유

 

Conv2d 예시

 

색상 값을 나타내는 R.G,BConv2d를 사용해 가중치를 학습했고

높이넓이pooling층을 이용해 학습 되어있다.

 

⭐⭐⭐

torch.flatten 이전의 데이터 shape

(색상값(R,G,B), 높이(H), 넓이)

[256 / 4 / 4] = # 4096

 

torch.flatten 이후의 데이터 shape

[4096] = # 4096

 


그럼 이렇게 1차원의 데이터를

nn.Linear가 들어있는 분류기 블럭을 거쳐

 

최종 결과물이 나온다.

 


자 그럼 모든 준비가 끝났으니 데이터를 넣고 돌려보자.

 

데이터의 오버피팅을 방지하기위해transforms 변수에 Compse를 저장해준다.

 

DataLoader를 통해

batch_size = 32로 하여

트레인셋과 테스트셋을 저장해준다.

 

모델을 정의해주면, 우리가 위에서 선언했었던

BasicBlockResNet 모델, 분류기, 풀링층, 등등이 적용되어 출력으로 보여준다.

 

가중치 학습 코드이다.

 

학습률을 뜻하는 Learning Rate lr = 1e-4

 

최적화 함수를 뜻하는 Optim

Adam

 

모델ResNet

 

오차를 뜻하는 lossCross Entropy Loss를 통해 구한다.

 


 

가중치 업데이트가 끝난 모델에빼두었던 테스트셋을 넣고트레인셋과의 차이를 비교하면?

 

Accuracy score0.8804

 

88%정확도를 결과로 보여줌과 동시에 

 

우리의 딥러닝의 과정이 끝남을 말해준다.

 

 

 

'Hello MLop > DL' 카테고리의 다른 글

MLop_DL_RNN 실습  (0) 2022.12.17
MLop_DL_U-Net 실습  (0) 2022.12.05
MLop_DL_CNN 실습  (0) 2022.11.30
MLop_DL_손글씨 판단 예측  (0) 2022.11.24
MLop_DL_보스톤 집값 예측  (0) 2022.11.23