랩요정들은 인코더에서 사용한 pre-trained모델의 전체 레이어에서 앞단의 5개 레이어를 제외한 네트워크 파라미터를 업데이트 하였다.
"Fine-tuning은 모델의 전체 레이어에서 앞단의 5개의 레이어를 제외한 네트워크의 파라미터를 업데이트하여 이루어졌습니다."
Fine-tuning 이란?
- 기존에 학습되어져 있는 모델을 기반으로 아키텍쳐를 새로운 목적(나의 이미지 데이터에 맞게)변형하고 이미 학습된 모델 Weights로 부터 학습을 업데이트하는 방법을 말한다.
출처: https://eehoeskrap.tistory.com/186 [Enough is not enough]
# EFNS = [efn.EfficientNetB0, efn.EfficientNetB1, efn.EfficientNetB2, efn.EfficientNetB3,
# efn.EfficientNetB4, efn.EfficientNetB5, efn.EfficientNetB6]
class CNN_Encoder(tf.keras.Model): # tf.keras.Model을 상속받음.
# you should define your layers in __init__
def __init__(self, embedding_dim):
super(CNN_Encoder, self).__init__() # super : 자식 클래스에서 부모클래스의 내용을 사용하고 싶을 경우 사용.
# self.base = EFNS[ef](input_shape=(224,224,3),weights='imagenet',include_top=False) # --> (None,7,7,1280)
self.base = tf.keras.applications.ResNet152(include_top=False, weights='imagenet',input_shape=(224,224,3))
for i, layer in enumerate(self.base.layers):
if i<5 :
layer.trainable = False
print(i,"번째 label trainable : " ,layer.trainable)
else :
print(i,"번째 label trainable : " ,layer.trainable)
self.dropout = tf.keras.layers.Dropout(0.5)
self.fc = tf.keras.layers.Dense(embedding_dim, dtype='float32')
#you should implement the model's forward pass in call.
def call(self, x):
x = self.base(x)
x = self.dropout(x)
x = tf.reshape(x, [tf.shape(x)[0],tf.shape(x)[1]*tf.shape(x)[2],feature_shape]) # (BATCH_SIZE, 49,1280)
x = self.fc(x)
x = tf.nn.relu(x)
return x
0~4번째layer는 trainable을 False로 두었다
5~514번째 layer는 True로 두었다.
batchsize를 24로 줄이고 (*8)로 하니 메모리 문제는 해결이 되었는데
듀토리얼.-->
다음과 같이 loss가 nan이 나왔다 왜 그런것일까?
이유가 뭘까?
원인파악
1. 일단. 랩요정들 코드에서정의한 fine_tune함수를 분석해보자.
def fine_tune(self, fine_tune=True):
for p in self.resnet.parameters():
p.requires_grad = False
# If fine-tuning, only fine-tune convolutional blocks 2 through 4
for c in list(self.resnet.children())[5:]: #5층 이후부터 학습이 가능하게 했다.
for p in c.parameters():
p.requires_grad = fine_tune # 자동 미분을 가능하게 한다. 이게 무슨 말이지?
5충부터 부터 자동 미분을 가능하게 했는데 실제로도 5~514번째 layer를 학습가능하게 한 것인지 확인 해 볼 필요가 있다.
pytorch에서는Resnet.parameters의 개수가464까지밖에 안나온다.
뭐가 다른 것인가.
label trainable
미세조정(fine_tuning)이란?
모델을 재사용하는 데 널리 사용되는 하나의 기법은 특성 추출을 보완하는 미세 조정(fine-tuning) 입니다. 미세 조정은 특성 추출에 사용했던 동결 모델의 상위 층 몇 개를 동결에서 해제하고 모델에 새로 추가한 층(여기서는 완전 연결 분류기)과 함께 훈련하는 것입니다. 재사용 모델의 표현을 일부 조정하기에 미세 조정이라고 부릅니다. 네트워크를 미세 조정하는 단계는 다음과 같습니다.
- 사전에 훈련된 기반 네트워크 위에 새로운 네트워크를 추가
- 기반 네트워크 동결
- 새로 추가한 네트워크 훈련
- 기반 네트워크에서 일부 층 동결 해제
- 동결 해제 층과 새로 추가한 층을 함께 훈련
완전 연결 분류기의 값이 지나치게 조정하는 것을 방지하기 위해 새로 추가한 네트워크를 먼저 훈련합니다. 즉 위에서 이미 3단계까지는 한 것입니다. 여기서는 구조가 너무 길어 생략하지만 본 사전 훈련된 네트워크의 구조는 5 블록으로 이루어져있고, 각 단계는 합성곱 층 3개와 풀링 층 1개로 이루어져있습니다. 미세 조정은 block_5에서만 진행합니다. 더 많은 층을 미세 조정하지 않는 이유는 다음과 같습니다.
- 합성곱 기반 층에 있는 하위 층들은 좀 더 일반적이고 재사용 가능한 특성들을 인코딩
- 반면 상위 층은 좀 더 특화된 특성을 인코딩 -> 새로운 문제에는 구체적 특성이 필요 -> 상위층만
- 훈련해야 할 파라미터가 많으면 과대적합의 위험이 커짐. 작은 데이터 셋에 1500만개의 파라미터는 위험.
이제 미세조정은 다음과 같이 하드코딩합니다.
https://subinium.github.io/Keras-5-2/
블로그의 예제에서는 vgg16을 썼는데
Resnet152의 경우는 어떻게 바뀌는지 확인해보자.
resnet152는 몇개의 블록으로 이루어져 있는가? : 5개의 블록으로 이루어져 있다.
각 단계는 합성곱층 몇개와 풀링층 몇개로 이루어져 있는가? : 아래 표와 같다.
block5에서만 미세조정을 진행한다!
랩요정들은 어떻게 미세조정을 진행했는가?
block 3,4,5 전부 미세조정을 진행한것 같다.
only fine-tune convolutional blocks 2 through 4 ??
"Fine-tuning은 모델의 전체 레이어에서 앞단의 5개의 레이어를 제외한 네트워크의 파라미터를 업데이트하여 이루어졌습니다." 라고 했다.