작성
·
741
1
선생님 안녕하세요.
Yolov3 train code를 보면,
1) Train with frozen layers first, to get a stable loss. --> epoch 0 ~ 50
2) Unfreeze and continue training, to fine-tune. --> epoch 50 ~ early stopping
이렇게 2번 학습을 이어가게 되어 있는데요, freeze 하는 이유와 장점을 잘 모르겠습니다. 강의를 여러번 돌려서 다시 봤는데 이해가 잘 안되요. 도움 부탁 드립니다.(freeze_body = 2 의 의미, 2는 무슨 숫자인지, 장점 이유 등등)
그리고 2)에서 모든 layer를 trainable로 변경하고 학습 수행이라고 나와 있는데요, 모든 layer라고 함은, 106번 layer 까지 말하는 건가요?
감사합니다.
답변 4
0
유영재님, free_body 2는 소스코드를 보셔야 합니다.
create_model() 함수의 인자로 freeze_body 1, 2가 인자로 들어옵니다.
def create_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2, ,,,,) 그리고 아래에서 freeze_body가 1이면 num은 185, 2이면 len(model_body.layers)-3 만큼이 되어서 model_body.layers[i].trainable = False를 수행합니다.
|
|||
0
아, 두 학습이 모델을 이어서 하는 것이군요. 먼저 FC 레이어부터 학습을 하고 하는 것이네요. 그런데 아직 freeze_body에서 2는 어떤 2를 말하는건지 이해가 되지 않네요
0
1. weight를 부여할 수 있는 레이어가 크게 feature extractor layer와 classification layer로 나뉘어 지는 것인가요?
2. freeze body에 대해서 내용은 어디에 표시된 것인가요? 아직 2에 대한 의미가 이해가 안되네요
0
보통은 이 feature extractor의 weight값은 최초에는 random 값으로 초기화 되어 있습니다(물론 random 이 아닌 다른 최적 초기화도 있지만). 이 경우 최적화된 weight값을 찾으려면 많은 학습 횟수가 필요할 수 있습니다. 하지만 pretrained 모델에서 초기부터 이미 최적화된 weight값을 기반해서 학습을 하면 보다 좋은 성능이 나타날 수 있습니다.
또한 pretrained 모델에서 학습되지 않은 이미지를 예측할때도 feature extractor 단은 pretrained 모델로 최적 학습화된 weight값으로 초기화 한 뒤 이를 학습합니다.
그리고 이러한 pretraiend 모델을 이용해서 다른 이미지를 학습 시킬 때 좀 더 성능을 높이는 방법이 일단 처음에는 feature extractor의 weight값을 학습하지 않고 별도의 classification layer(앞에서 말씀드린 2개의 결과 값으로 새롭게 만들어진 fully connected layer)부터 먼저 일정 수준 학습을 시킨 다음에, 다음에는 feature extractor를 포함한 전체를 학습하는 방법입니다.
이를 위해서 keras는 layer의 trainable 속성을 이용합니다. 특정 layer의 trainable 속성을 False로 설정하면 해당 layer는 학습을 수행하지 않습니다.
Keras yolo 소스코드에서는 이를 수행하는 부분이 https://github.com/qqwweee/keras-yolo3/blob/master/train.py 에서 create_model() 함수 입니다. (아래 코드는 게시판에서 indent를 지켜가며 제대로 붙여넣기가 힘들므로 train.py 소스코드를 참조해 주십시요)
def create_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2,
weights_path='model_data/yolo_weights.h5'):
'''create the training model'''
K.clear_session() # get a new session
image_input = Input(shape=(None, None, 3))
h, w = input_shape
num_anchors = len(anchors)
y_true = [Input(shape=(h//{0:32, 1:16, 2:8}[l], w//{0:32, 1:16, 2:8}[l], \
num_anchors//3, num_classes+5)) for l in range(3)]
model_body = yolo_body(image_input, num_anchors//3, num_classes)
print('Create YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))
if load_pretrained:
model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)
print('Load weights {}.'.format(weights_path))
if freeze_body in [1, 2]:
# Freeze darknet53 body or freeze all but 3 output layers.
num = (185, len(model_body.layers)-3)[freeze_body-1]
for i in range(num): model_body.layers[i].trainable = False
print('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))
model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})(
[*model_body.output, *y_true])
model = Model([model_body.input, *y_true], model_loss)
return model
아래 부분을 보시면 3개의 output layer를 제외하고 Darknet 53 모델의 feature extractor 부분에 해당하는 모든 layer들의 trainable 속성을 False로 바꾸어서 학습을 하지 않고 있습니다. 그리고 해당 부분이 바로 첫번째 학습 단계에서 수행되는 것입니다.
# Freeze darknet53 body or freeze all but 3 output layers.
num = (185, len(model_body.layers)-3)[freeze_body-1]
for i in range(num): model_body.layers[i].trainable = False
if freeze_body in [1, 2]:
두번째 학습 시킬때는 106번 layer까지 모든 layer를 학습 시킵니다.
감사합니다.