[KR_OCR] Training(하이퍼파라미터튜닝)_v1
데이터 셋과 모델, 그외 유틸등이 준비가 되면 학습을 시작
기본파라미터부터 시작해서 다양한 방법으로 학습시켜 loss를 최소로 줄인다
1. Training_CRNN_1
## 딕셔너리(라벨)에 한글데이터셋만 존재
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.01, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : CTC loss
- 200 Epoch
< Training Process_1 >
< Training Graph >
30 Epoch
200 Epoch
- 대략 30 epoch이 지나면 바로 오버피팅이 발생한다.
- 최소 val_loss 값 : 13점대
2. Training_CRNN_2
## 딕셔너리(라벨)에 영어와 숫자 라벨 추가
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : CTC loss
- 200 Epoch
< Training Process_2 >
200 Epoch
- 대략 70 epoch이 지나면 바로 오버피팅이 발생한다.
- 영어 레이블이 추가되면서 전체적인 loss값이 높아졌다. 학습이 더디게 진행된다.
- 최소 val_loss 값 : 17점대
3. Training_CRNN_3( Pretrained Weight )
## pretrained weight 사용
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : CTC loss
- 200 Epoch
< 코드 : pretrained weight >
model, model_pred = CRNN(input_shape, len(cracker_dict), gru=False)
model_trained,_ = CRNN(input_shape, len(alphabet87), gru=False)
model_trained.load_weights('./checkpoints/201904090148_crnn_lstm_cocotext_pretrained_v13/weights.006000.h5')
for idx in range(16):
extracted_weights = model_trained.layers[idx].get_weights()
model.layers[idx].set_weights(extracted_weights)
- CRNN 기본모델을 사용할 모델과, 가중치를 불러올 모델 이렇게 2개를 생성한다.
- model_trained에 load_weights으로 미리 학습된 가중치를 불러온다.
- 모델에서 원하는 레이어만큼 get_weights을 통해 가져오고, 해당 레이어에 가중치를 set_weights을 해준다
< 코드 : Transfer Learning >
freeze = ['conv1_1',
'conv2_1',
'conv3_1', 'conv3_2',
'conv4_1',
'conv5_1',
#'conv6_1',
#'lstm1',
#'lstm2'
]
for layer in model.layers:
layer.trainable = not layer.name in freeze
- Training Learning의 fine-tuning을 하기위해서 동결할 레이어를 설정해준다.
- freeze에 없는 레이터는 layer.trainable을 설정해주면서 동결을 해제해준다 : 학습가능
< Training Process_3 >
200 Epoch
< Training Graph >
200 Epoch
- 대략 70 epoch이 지나면 바로 오버피팅이 발생한다.
- 원래 학습 된 가중치를 사용했는데도 큰 성능차이가 보이지 않는다
- 최소 val_loss 값 : 17점대
4. Training_CRNN_4( Focal CTC Loss )
## 손실값 계산을 원래 CTC Loss 에서 Focal CTC Loss로 변경
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : Focal CTC loss ( a : 0.75, r : 0.5 )
- activation func : Relu
- freeze = ['conv1_1', 'conv2_1', 'conv3_1', 'conv3_2', 'conv4_1', 'conv5_1',]
- 200 Epoch
## Focal CTC Loss : https://www.hindawi.com/journals/complexity/2019/9345861/
- 위의 논문을 참고해서 CTC loss를 계산법을 Focal CTC Loss로 변경
- 요약 : 영어와 달리 중국어와 한국어의 경우는 라벨값 자체가 많기 때문에 라벨마다의 데이터의 비중이 다르다
: 자주 나오는 라벨에 대해서는 오버피팅되고, 잘 안나오는 라벨은 언더피팅이 된다
: 따라서 easy sample과 hard sample로 나누어서 가중치를 다르게 준다
: 균등하지 않은 데이터셋을 가지고 있는 경우에 사용하면 좋다
- 현재 가지고 있는 데이터 라벨의 비중의 분포를 그래프로 확인
- 논문에서 소개 된 ALGORITHM
- 추가된 CODE : ctc loss값에 음의 자연로그를 취한 뒤, focal loss 공식에 대입해준다.
def focal_ctc_lambda_func(args):
labels, y_pred, input_length, label_length = args
ctc_loss = K.ctc_batch_cost(labels, y_pred, input_length, label_length)
p = tf.exp(-ctc_loss)
focal_ctc_loss = alpha*tf.pow((1-p),gamma)*ctc_loss
return focal_ctc_loss
< Training Process_4 >
200 Epoch
< Training Graph >
200 Epoch
- 대략 100 epoch이 지나면 바로 오버피팅이 발생한다.
- loss 계산을 Focal CTC Loss로 변경한 뒤 확실하게 성능이 향상되었다.
- 최소 val_loss 값 : 13점대 (에폭 200기준)
5. Training_CRNN_5( Focal CTC Loss + DropOut(0.1))
"현재 가장 성능이 좋다"
## 오버피팅 방지를 위해 DropOut적용(LSTM)
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : Focal CTC loss ( a : 0.75, r : 0.5 )
- activation func : Relu
- Dropout : LSTM
- 200 Epoch
< CODE : LSTM dropout >
x = Bidirectional(LSTM(256, return_sequences=True,dropout=0.1,recurrent_dropout=0.1, name='lstm1'))(x)
x = Bidirectional(LSTM(256, return_sequences=True,dropout=0.1,recurrent_dropout=0.1, name='lstm2'))(x)
- CNN 레이어를 다 쌓은 이후에 붙이는 LSTM에 Dropout을 추가해준다.
< Training Process_5 >
200 Epoch
< Training Graph >
Epoch100 - 200
- 대략 180 Epoch 부터는 val_loss가 어느정도 유지되는 것을 확인 할 수 있다
- LSTM에 Dropout을 추가하고 확실하게 성능이 향샹된 것을 확인 할 수 있다.
- 최소 val_loss 값 : 8점대 (에폭 200기준)
6. Training_CRNN_6( Focal CTC Loss + DropOut(0.2) + LeakyRelu(0.1)
## 오버피팅 방지를 위해 DropOut적용(LSTM, 0.2) + Activation Function(LeakyRelu, 0.1)변경
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : Focal CTC loss ( a : 0.75, r : 0.5 )
- activation func : LeakyRelu
- Dropout : LSTM
- freeze = ['conv1_1', 'conv2_1', 'conv3_1', 'conv3_2', 'conv4_1', 'conv5_1',]
- 300 Epoch
< Training Process_6 >
300 Epoch
< Training Graph >
- Train5 와 비교해서 계속 학습이 되고는 있지만 학습속도가 매우 느리다.
- 300 epoch을 돌았는데 Train5가 200 Epoch보다 val_loss값이 크다
- LeakyRuLU의 값을 조정할 필요가 있다 (현재는 0.1)
- 최소 val_loss 값 : 9점대 (에폭 300기준)
7. Training_CRNN_7( Focal CTC Loss(a:0.99, r:1) + DropOut(0.1) + Relu)
## Focal_CTC_Loss의 알파(0.99)와 감마(1) 값 수정
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : Focal CTC loss ( a : 0.99, r : 1 )
- activation func : relu
- Dropout : LSTM
- freeze = ['conv1_1', 'conv2_1', 'conv3_1', 'conv3_2', 'conv4_1', 'conv5_1',]
- 200 Epoch
< Training Process_7 >
200 Epoch
- 다시 처음 Focal CTC Loss를 사용했을 때로 돌아가서, 최대한 낮은 loss에서 시작하기 위해 알파와 감마를 수정하는 테스트를 해본 결과 그전의 파라미터 값이 성능이 더 좋다.
- 훈련 데이터 셋에 오버피팅이 되어있다.
- Focal CTC Loss 의 파라미터 값은 그전으로 고정
- 계속 val_loss가 낮아지기는 하나 속도가 너무 느리다.
- 최소 val_loss 값 : 11점대 (에폭200기준)
8. Training_CRNN_8( Focal CTC Loss + DropOut(0.1) + Relu + Dense Dropout(0.1))
## Dense층에 Dropout 추가
- 총 1084개의 데이터 ( Train : 867개, Validation : 217개)
- optimizer : SGD( lr = 0.001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5 )
- 손실 값 : Focal CTC loss ( a : 0.75, r : 0.5 )
- activation func : relu
- Dropout : LSTM, Dense
- freeze = ['conv1_1', 'conv2_1', 'conv3_1', 'conv3_2', 'conv4_1', 'conv5_1',]
- 200 Epoch
< CODE : Dense Dropout >
x = Dense(num_classes, name='dense1')(x)
x = Dropout(0.1)(x)
< Training Process_3 >
200 Epoch
< Training Graph >
- Dense Layer에 dropout을 추가했을 경우는 그래프가 일단 부드럽지 않다.
- Dense Layer에 dropout이 없는 모델과 비교했을 때 성능이 더 좋지 않다.
- 오버피팅이 되지는 않았으나 학습 속도가 느리다.
- 최소 val_loss 값 : 16점대 (에폭200기준)