본문 바로가기

DeepLearning/OCR_

[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 >

 

Epoch1 : val_loss 25.5451

 

Epoch15 : val_loss 18.4637

 

Epoch30 : val_loss 14.1937

 

Epoch50 : val_loss 13.2285

 

< Training Graph > 

30 Epoch

RedLine : Training loss / BlueLine : Validation loss

200 Epoch

RedLine : Training loss / BlueLine : Validation loss

 

- 대략 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

Epoch1 : val_loss 31.4442
Epoch15 : 22.5403
Epoch30 : 20.4135
Epoch : 18.8464
Epoch100 : 17.6746

 

- 대략 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

Epoch1 : 31.4346
Epoch15 : 22.6212
Epoch30 : 20.4905
Epoch50 : 18.8880
Epoch100 : 17.6268

 

< 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/

 

Focal CTC Loss for Chinese Optical Character Recognition on Unbalanced Datasets

In this paper, we propose a novel deep model for unbalanced distribution Character Recognition by employing focal loss based connectionist temporal classification (CTC) function. Previous works utilize Traditional CTC to compute prediction losses. However,

www.hindawi.com

- 위의 논문을 참고해서 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

Epoch1 : 23.6647
Epoch15 : 17.1386 
Epoch30 : 15.4635
Epoch50 : 14.2214
Epoch100 : 13.1487

 

 

< 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

Epoch100 : val_loss 10.0753
Epoch115 : val_loss 9.6213
Epoch150 : val_loss 8.9985
Epoch200 : val_loss 8.6337

 

< 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

Epoch1 : val_loss 23.9659
Epoch50 : val_loss 18.8897
Epoch100 : val_loss 17.3426
Epoch150 : val_loss 15.6919

 

Epoch200 : val_loss 13.4659
Epoch250 : val_loss 10.9581
Epoch300 : val_loss 9.79.33

 

 

< 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

Epoch1 : val_loss 31.7757
Epoch50 : val_loss 17.9758
Epoch100 : val_loss 13.3274
Epoch150 : val_loss 11.9118
Epoch200 : val_loss 11.4573

 

- 다시 처음 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

Epoch1 : val_loss 25.8733
Epoch50 : val_loss 19.1900
Epoch100 : val_loss 17.9679
Epoch150 : val_loss 16.7524
Epoch200 : val_loss 16.4878

 

 

< Training Graph > 

- Dense Layer에 dropout을 추가했을 경우는 그래프가 일단 부드럽지 않다.

Dense Layer에 dropout이 없는 모델과 비교했을 때 성능이 더 좋지 않다.

- 오버피팅이 되지는 않았으나 학습 속도가 느리다.

- 최소 val_loss 값 : 16점대 (에폭200기준)

반응형