Path: blob/master/site/ko/guide/keras/transfer_learning.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
전이 학습 및 미세 조정
설정
시작하기
전이 학습은 한 가지 문제에 대해 학습한 기능을 가져와서 비슷한 새로운 문제에 활용하는 것으로 구성됩니다. 예를 들어, 너구리를 식별하는 방법을 배운 모델의 기능은 너구리를 식별하는 모델을 시작하는 데 유용할 수 있습니다.
전이 학습은 일반적으로 전체 모델을 처음부터 훈련하기에는 데이터세트에 데이터가 너무 적은 작업에 대해 수행됩니다.
딥 러닝의 맥락에서 전이 학습의 가장 일반적인 구현은 다음 워크플로와 같습니다.
이전에 훈련된 모델에서 레이어를 가져옵니다.
추후 훈련 라운드 중에 포함된 정보가 손상되지 않도록 동결합니다.
고정된 레이어 위에 훈련할 수 있는 새 레이어를 추가합니다. 해당 레이어는 기존 기능을 새로운 데이터세트에 대한 예측으로 전환하는 방법을 배웁니다.
데이터세트에서 새로운 레이어를 훈련합니다.
마지막으로 선택적인 단계는 미세 조정입니다. 이 단계는 위에서 얻은 전체 모델(또는 모델의 일부)을 동결 해제하고 학습률이 매우 낮은 새로운 데이터에 대해 재훈련하는 과정으로 구성됩니다. 이는 사전 훈련된 특성을 새로운 데이터에 점진적으로 적용함으로써 의미 있는 개선을 달성할 수 있습니다.
먼저, Keras의 trainable
API에 대해 자세히 살펴보겠습니다. 이 API는 대부분의 전이 학습 및 미세 조정 워크플로의 기초가 됩니다.
그런 다음 ImageNet 데이터세트에서 사전 훈련된 모델을 사용하여 Kaggle "cats vs dogs" 분류 데이터세트에서 재훈련함으로써 일반적인 워크플로를 시연합니다.
이것은 Deep Learning with Python과 2016 블로그 게시물 "building powerful image classification models using very little data"로부터 조정되었습니다.
레이어 동결: trainable
속성의 이해
레이어 및 모델에는 세 가지 가중치 속성이 있습니다.
weights
는 레이어의 모든 가중치 변수 목록입니다.trainable_weights
는 훈련 중 손실을 최소화하기 위해 업데이트(그래디언트 디센트를 통해)되어야 하는 목록입니다.non_trainable_weights
는 훈련되지 않은 가중치 변수의 목록입니다. 일반적으로 순방향 전달 중에 모델에 의해 업데이트됩니다.
예제: Dense
레이어에는 2개의 훈련 가능한 가중치가 있습니다(커널 및 바이어스)
일반적으로 모든 가중치는 훈련이 가능합니다. 훈련할 수 없는 가중치가 있는 유일한 내장 레이어는 BatchNormalization
레이어입니다. 훈련할 수 없는 가중치를 사용하여 훈련 중 입력의 평균 및 분산을 추적합니다. 훈련할 수 없는 가중치를 사용자 정의 레이어에서 사용하는 방법을 배우려면 새 레이어를 처음부터 작성하는 방법을 참조하세요.
예제: BatchNormalization
레이어에는 2개의 훈련 가능한 가중치와 2개의 훈련할 수 없는 가중치가 있습니다
레이어 및 모델에는 boolean 속성 trainable
도 있습니다. 값은 변경될 수 있습니다. layer.trainable
을 False
로 설정하면 모든 레이어의 가중치가 훈련 가능에서 훈련 불가능으로 이동합니다. 이를 레이어 "동결"이라고 합니다. 동결 레이어의 상태는 fit()
을 사용하거나 trainable_weights
에 의존하는 사용자 정의 루프를 사용해 훈련하여 그래디언트 업데이트를 적용할 때도 훈련하는 동안 업데이트되지 않습니다.
예제: trainable
을 False
로 설정
훈련 가능한 가중치가 훈련할 수 없게 되면 훈련 중에 그 값이 더는 업데이트되지 않습니다.
layer.trainable
속성을 레이어가 추론 모드 또는 훈련 모드에서 순방향 전달을 실행해야 하는지를 제어하는 layer.__call__()
의 인수 training
과 혼동하지 마세요. 자세한 내용은 Keras FAQ를 참조하세요.
trainable
속성의 재귀 설정
모델 또는 하위 레이어가 있는 레이어에서 trainable = False
를 설정하면 모든 하위 레이어도 훈련할 수 없게 됩니다.
예제:
일반적인 전이 학습 워크플로
이를 통해 Keras에서 일반적인 전이 학습 워크플로를 구현할 수 있습니다.
기본 모델을 인스턴스화하고 사전 훈련된 가중치를 여기에 로드합니다.
trainable = False
를 설정하여 기본 모델의 모든 레이어를 동결합니다.기본 모델에서 하나 이상의 레이어 출력 위에 새 모델을 만듭니다.
새 데이터세트에서 새 모델을 훈련합니다.
보다 가벼운 대안 워크플로는 다음과 같습니다.
기본 모델을 인스턴스화하고 사전 훈련된 가중치를 여기에 로드합니다.
이를 통해 새로운 데이터세트를 실행하고 기본 모델의 하나의(또는 여러) 레이어의 출력을 기록합니다. 이를 특성 추출이라 합니다.
이 출력을 더 작은 새 모델의 입력 데이터로 사용합니다.
이 두 번째 워크플로의 주요 장점은 훈련 epoch마다 한 번이 아니라 한 번의 데이터로 기본 모델을 실행한다는 것입니다. 따라서 훨씬 빠르고 저렴합니다.
그러나 두 번째 워크플로의 문제점은 훈련 중에 새 모델의 입력 데이터를 동적으로 수정할 수 없다는 것입니다. 예를 들어 데이터 증강을 수행할 때 필요합니다. 전이 학습은 일반적으로 새 데이터세트에 데이터가 너무 작아서 전체 규모의 모델을 처음부터 훈련할 수 없는 작업에 사용되며, 이러한 시나리오에서는 데이터 증강이 매우 중요합니다. 따라서 다음 내용에서는 첫 번째 워크플로에 중점을 둘 것입니다.
Keras의 첫 번째 워크플로는 다음과 같습니다.
먼저, 사전 훈련된 가중치를 사용하여 기본 모델을 인스턴스화합니다.
그런 다음 기본 모델을 동결합니다.
맨 위에 새 모델을 만듭니다.
새 데이터로 모델을 훈련합니다.
미세 조정
모델이 새로운 데이터에 수렴하면 기본 모델의 일부 또는 전부를 동결 해제하고 학습률이 매우 낮은 전체 모델을 전체적으로 재훈련할 수 있습니다.
이 단계는 선택적으로 마지막 단계이며 점진적으로 개선할 수 있습니다. 또한 잠재적으로 빠른 과대적합을 초래할 수 있습니다. 명심하세요.
동결된 레이어가 있는 모델이 수렴하도록 훈련된 후에만 이 단계를 수행하는 것이 중요합니다. 무작위로 초기화된 훈련 가능한 레이어를 사전 훈련된 특성을 보유하는 훈련 가능한 레이어와 혼합하는 경우, 무작위로 초기화된 레이어는 훈련 중에 매우 큰 그래디언트 업데이트를 유발하여 사전 훈련된 특성을 파괴합니다.
또한 이 단계에서는 일반적으로 매우 작은 데이터 집합에서 첫 번째 훈련보다 훨씬 더 큰 모델을 훈련하기 때문에, 매우 낮은 학습률을 사용하는 것이 중요합니다. 결과적으로 큰 가중치 업데이트를 적용하면 과도하게 빠른 과대적합의 위험이 있습니다. 여기에서는 사전 훈련된 가중치만 점진적인 방식으로 다시 적용하려고 합니다.
다음은 전체 기본 모델의 미세 조정을 구현하는 방법입니다.
compile()
및 trainable
에 대한 중요 사항
모델에서 compile()
을 호출하는 것은 해당 모델의 동작을 "동결"하기 위한 것입니다. 이는 compile
이 다시 호출될 때까지 모델이 컴파일될 때 trainable
속성값이 해당 모델의 수명 동안 유지되어야 함을 의미합니다. 따라서 trainable
값을 변경하면 모델에서 compile()
을 다시 호출하여 변경 사항을 적용합니다.
BatchNormalization
레이어에 대한 중요 사항
많은 이미지 모델에는 BatchNormalization
레이어가 포함되어 있습니다. 그 레이어는 상상할 수 있는 모든 수에서 특별한 경우입니다. 다음은 명심해야 할 몇 가지 사항입니다.
BatchNormalization
에는 훈련 중에 업데이트되는 훈련 불가능한 2개의 가중치가 포함되어 있습니다. 입력의 평균과 분산을 추적하는 변수입니다.bn_layer.trainable = False
를 설정하면BatchNormalization
레이어가 추론 모드에서 실행되며 평균 및 분산 통계가 업데이트되지 않습니다. 가중치 훈련 및 추론/훈련 모드가 직교 개념이므로 일반적으로 다른 레이어의 경우에는 해당하지 않습니다. 그러나BatchNormalization
레이어의 경우 두 가지가 묶여 있습니다.미세 조정을 위해
BatchNormalization
레이어를 포함하는 모델을 동결 해제하면 기본 모델을 호출할 때training=False
를 전달하여BatchNormalization
레이어를 추론 모드로 유지해야 합니다. 그렇지 않으면 훈련 불가능한 가중치에 적용된 업데이트로 인해 모델이 학습한 내용이 갑작스럽게 파괴됩니다.
이 가이드 끝의 엔드 투 엔드 예제에서 이 패턴이 적용되는 것을 볼 수 있습니다.
사용자 정의 훈련 루프를 사용한 전이 학습 및 미세 조정
fit()
대신 자체 저수준 훈련 루프를 사용하는 경우 워크플로는 본질적으로 동일하게 유지됩니다. 그래디언트 업데이트를 적용할 때 목록 model.trainable_weights
만 고려해야 합니다.
미세 조정의 경우도 마찬가지입니다.
엔드 투 엔드 예제: 고양이 vs 개 데이터세트에서 이미지 분류 모델 미세 조정
이러한 개념을 강화하기 위해 구체적인 엔드 투 엔드 전이 학습 및 미세 조정 예제를 안내합니다. ImageNet에서 사전 훈련된 Xception 모델을 로드하고 Kaggle "cats vs. dogs" 분류 데이터세트에서 사용합니다.
데이터 얻기
먼저 TFDS를 사용해 고양이 vs 개 데이터세트를 가져옵니다. 자체 데이터세트가 있다면 유틸리티 tf.keras.preprocessing.image_dataset_from_directory
를 사용하여 클래스별 폴더에 보관된 디스크의 이미지 세트에서 유사한 레이블이 지정된 데이터세트 객체를 생성할 수 있습니다.
전이 학습은 매우 작은 데이터로 작업할 때 가장 유용합니다. 데이터세트를 작게 유지하기 위해 원래 훈련 데이터(25,000개 이미지)의 40%를 훈련에, 10%를 유효성 검사에, 10%를 테스트에 사용합니다.
이것은 훈련 데이터세트에서 처음 9개의 이미지입니다. 보시다시피 이미지는 모두 크기가 다릅니다.
레이블 1이 "개"이고 레이블 0이 "고양이"임을 알 수 있습니다.
데이터 표준화하기
원시 이미지는 다양한 크기를 가지고 있습니다. 또한 각 픽셀은 0에서 255 사이의 3개의 정숫값(RGB 레벨값)으로 구성됩니다. 이는 신경망에 공급하기 적합하지 않습니다. 2가지를 수행해야 합니다.
고정된 이미지 크기로 표준화합니다. 150x150을 선택합니다.
정상 픽셀 값은 -1 과 1 사이입니다. 모델 자체의 일부로
Normalization
레이어를 사용합니다.
일반적으로 이미 사전 처리된 데이터를 사용하는 모델과 달리 원시 데이터를 입력으로 사용하는 모델을 개발하는 것이 좋습니다. 모델에 사전 처리 된 데이터가 필요한 경우 모델을 내보내 다른 위치(웹 브라우저, 모바일 앱)에서 사용할 때마다 동일한 사전 처리 파이프 라인을 다시 구현해야하기 때문입니다. 이것은 매우 까다로워집니다. 따라서 모델에 도달하기 전에 가능한 최소한의 전처리를 수행해야합니다.
여기에서는 데이터 파이프라인에서 이미지 크기 조정을 수행하고(심층 신경망은 인접한 데이터 배치만 처리할 수 있기 때문에) 입력값 스케일링을 모델의 일부로 생성합니다.
이미지 크기를 150x150으로 조정해 보겠습니다.
또한 데이터를 일괄 처리하고 캐싱 및 프리페치를 사용하여 로딩 속도를 최적화합니다.
무작위 데이터 증강 사용하기
큰 이미지 데이터세트가 없는 경우 임의의 수평 뒤집기 또는 작은 임의의 회전과 같이 훈련 이미지에 무작위이지만 사실적인 변형을 적용하여 샘플 다양성을 인위적으로 도입하는 것이 좋습니다. 이것은 과대적합을 늦추면서 모델을 훈련 데이터의 다른 측면에 노출하는 데 도움이 됩니다.
다양한 무작위 변형 후 첫 번째 배치의 첫 번째 이미지가 어떻게 보이는지 시각화해 보겠습니다.
모델 빌드하기
이제 앞에서 설명한 청사진을 따르는 모델을 만들어 보겠습니다.
참고 사항:
입력 값(처음에는
[0, 255]
범위)을[-1, 1]
범위로 조정하기 위해Rescaling
레이어를 추가합니다.정규화를 위해 분류 레이어 앞에
Dropout
레이어를 추가합니다.기본 모델을 호출할 때
training=False
를 전달하여 추론 모드에서 실행되므로 미세 조정을 위해 기본 모델을 동결 해제한 후에도 batchnorm 통계가 업데이트되지 않습니다.
최상위 레이어 훈련하기
전체 모델의 미세 조정 수행하기
마지막으로 기본 모델을 동결 해제하고 낮은 학습률로 전체 모델을 전체적으로 훈련합니다.
중요한 것은 기본 모델이 훈련 가능하지만 모델 빌드를 호출할 때 training=False
를 전달했으므로 여전히 추론 모드로 실행되고 있다는 것입니다. 이는 내부의 배치 정규화 레이어가 배치 통계를 업데이트하지 않음을 의미합니다. 만약 레이어가 배치 통계를 업데이트한다면 지금까지 모델이 학습한 표현에 혼란을 줄 수 있습니다.
10 epoch 후에, 미세 조정이 크게 개선됩니다.