Keras는 기본적으로 high level API 입니다. 아래 링크에서 언급하고 있듯이 딥러닝의 아주 기본적인 연산들(ex: tensor들의 연산 or 미분)이나 CPU, GPU, TPU 같은 hardware를 동작시키는 같은 작업(ex: CUDA)들은 Keras에서 구현하지 않습니다.
하지만, Keras가 딥러닝 학습을 하려면 앞서 언급한 딥러닝의 기본적인 연산을 해야하는데, 이를 어떻게 사용할 수 있을까요?
Keras는 backend engine에서 제공하는 특화된 tensor library를 사용함으로써 딥러닝의 기본적인 연산을 수행합니다. 예를 들어, tensorflow, theano, CNTK 라는 딥러닝 프레임워크를 backend로 사용합니다. 다양한 backend (tensorflow, theano, CNTK) 를 사용한다고 하여 아래와 같이 표현하기도 합니다.
"Kerass는 multi-backend(멀티 백엔드)를 지원합니다"
Theano: developed by LISA Lab at Université de Montréal → http://deeplearning.net/software/theano
Tensorflow: developed by Google→ https://www.tensorflow.org
CNTKL: developed by Microsoft→ http://github.com/Microsoft/CNTK
2. Tensorflow와 Keras의 관계 (Tensorflow 2.5 & Keras 2.4)
예전에는 기존 케라스 사용자들이 Keras API를 사용하면서 backend로 종종 tensorflow를 사용했습니다.
하지만, 2020.06.18에 케라스가 2.4 버전을 release 하면서 아래와 같은 말을 했습니다. (현재(2021.06.30)까지도 keras 최신 버전은 2.4입니다)
"We have discontinued multi-backend Keras to refocus exclusively on the TensorFlow implementation of Keras."
"In the future, we will develop the TensorFlow implementation of Keras in the present repo, atkeras-team/keras. For the time being, it is being developed intensorflow/tensorflowand distributed astensorflow.keras. In this future, thekeraspackage on PyPI will be the same astf.keras."
결국 multi-backend를 더 이상 지원하지 않고 오로지 tensorflow backend만을 지원할 것이라고 선언했습니다. 기존에는 Keras-team/keras라는 repo에서 다양한 backend를 지원하는 keras API를 업데이트하고 있었는데, 이제는 tf.keras에서 keras 관련 기능들을 업데이트 할거라고 명시했습니다.
다시 말해,keras-team/keras 저장소는 오로지 tensorflow만을 위한 tensorflow 백엔드 전용 Keras 되고 tf.keras가 keras-team/keras를 사용할 것으로 예상되었습니다.
3. Keras separate from Tensorflow 2.6 (2021.06.30)
아래 박혜선님의 글을 인용하면 올해(2021) 초부터 keras-team/keras 저장소의 코드가 다시 채워지고 있었다고 합니다. 당시에는 tf.keras 코드를 기반으로 keras-team/keras에 코드를 그대로 복사 붙여넣기 하여 싱크를 맞추는 작업(복붙)이 대부분이였다고 하네요. 그래서 tensorflow 2.5를 설치하면 keras-nightly 패키지(←복사붙여넣기된 keras-team/keras)도 같이 설치가되어 별도의 패키지로써 제공했다고 합니다.
그리고, 2021.06.30일에 Tensorflow 2.6 버전이 release 되면서, tensorflow 진영에서 아래와 같은 선언을 하게 됩니다.
Keras has been split into a separate PIP package (keras), and its code has been moved to the GitHub repository keras-team/keras. → Tensorflow 2.6 버전부터 keras는 tensorflow 패키지에서 분리가 됩니다. 앞으로 tensorflow 2.6 이후 부터 업데이트되는 Keras 관련 코드들은 다시 keras-team/keras로 옮겨진다고 하니 앞으로 "import keras"를 다시 사용해야 할 것 같습니다.
The API endpoints fortf.kerasstay unchanged, but are now backed by thekerasPIP package. All Keras-related PRs and issues should now be directed to the GitHub repository keras-team/keras.
첫 번째에는 아예 새로운 CNN 모델을 구축(by Functional API)하여 학습시키는 방식을 구현하고, 두 번째에는 pre-trained model을 다운받아 transfer learning과 fine-tuning을 적용시킨 방식을 구현해보도록 하겠습니다.
1. New model 구축 버전
import os
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers
from tensorflow import keras
import matplotlib.pyplot as plt
import math
base_dir = './datasets/COVID_19/'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
train_datagen = ImageDataGenerator(
featurewise_center=True,
featurewise_std_normalization=True,
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
validation_split=0.2)
validation_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
# 타깃 디렉터리
train_dir,
# 모든 이미지를 150 × 150 크기로 바꿉니다
target_size=(150, 150),
batch_size=32,
# categorical_crossentropy 손실을 사용
class_mode='categorical') #COVID_19는 3개의 클래스로 구성됨
validation_generator = validation_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=32,
class_mode='categorical')
2. Pre-trained model with transfer learning an fine tuning 구축 버전
import os
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers
from tensorflow import keras
from tensorflow.keras.applications import VGG16
import matplotlib.pyplot as plt
import math
base_dir = './datasets/COVID_19/'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
train_datagen = ImageDataGenerator(
featurewise_center=True,
featurewise_std_normalization=True,
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
validation_split=0.2)
validation_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
# 타깃 디렉터리
train_dir,
# 모든 이미지를 150 × 150 크기로 바꿉니다
target_size=(150, 150),
batch_size=32,
# categorical_crossentropy 손실을 사용
class_mode='categorical') #COVID_19는 3개의 클래스로 구성됨
validation_generator = validation_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=32,
class_mode='categorical')
위와 같이 transfer learning을 적용시킨 후 특정 layer들만 학습시키려면 우선 아래와 같이 Convolution base 부분을 아래 코드와 같이 freezing 시킵니다.
for layer in vgg_base.layers:
layer.trainable = False
보통 fine tuning을 할 때, 끝단에 위치한 bottom conv layer (=deeper layer) 부분만 미세하게 학습시켜주는 것이 일반적입니다. 왜냐하면, 어떠한 이미지분류 문제이든 해당 객체의 edge(←top layer의 conv filter가 뽑는 feature)는 거의 비슷할 테니까요. 중간 layer에 있는 conv filter가 보통 texture feature를 뽑아내는데, 만약 ImageNet에서 학습한 이미지의 texture와 내가 분류하려는 새로운 이미지들의 texture가 많이 다르다는 판단을 하게 된다면 이 부분도 미세하게 학습시켜주어야 합니다. 이러한 방법은 아래와 같은 코드로 진행이 됩니다.
for layer in vgg_base.layers[15:]:
layer.trainable = True
[정리]
지금까지 배운 pre-trained model을 다운받아 transfer learning 및 fine-tuning을 적용시키는 코드를 작성해보도록 하겠습니다.
from tensorflow.keras import models
from tensorflow.keras import layers
from tensorflow.keras.applications import VGG16
앞선 작업을 통해 학습시킨 CNN 모델을 따로 저장할 수 도 있고, 나중에 데이터셋이 더 마련되면 해당 CNN 모델을 불러와 다시 re-training 시킬 수 있습니다.
tensorflow에서 CNN 모델을 저장시키거나 불러올 때 사용되는 CNN 모델 파일 format은 TensorFlow SavedModel 형식 or Keras H5 형식 or checkpoint 형식으로크게 세 가지가 있습니다.
3-1. h5 파일 형태로 저장 또는 불러오기
tensorflow에서는 학습시킨 모델을 h5 형태의 파일로 저장시킬 수 있습니다. 본래 h5 형태의 파일은 keras에서 지원하던 파일형식인데 keras가 tensorflow backend를 사용할 때 tf.keras 로 h5 형태의 파일을 저장 및 불러오는 것을 가능하게 했습니다.
# Calling `save('my_model.h5')` creates a h5 file `my_model.h5`.
model.save("my_h5_model.h5")
# It can be used to reconstruct the model identically.
reconstructed_model = keras.models.load_model("my_h5_model.h5")
H5 파일은 Hierarchical Data Format (HDF) 5의 축약표현입니다. 보통 과학 데이터의 다차원 배열이 포함되기 때문에 다양한 과학분야(ex: 물리학, 공학, 딥러닝, ... 등)에서 주로 사용되는 파일형태입니다.
3-2. SavedModel 형태로 저장 또는 불러오기
# Calling `save('my_model')` creates a SavedModel folder `my_model`.
model.save("my_model")
# It can be used to reconstruct the model identically.
reconstructed_model = keras.models.load_model("my_model")
아래링크에서 SavedModel과 h5파일을 사용할 때 어떠한 차이가 있는지 기술해놓았으니 참고하시면 좋을 것 같습니다.
기존 tensorflow에서는 모델을 저장시키거나 불러올 때, SavedModel 방식 또는 Checkpoint 방식을 사용했습니다. Checkpoint에 대한 설명은 추후에 더 자세히 다루도록 하겠습니다. 아래링크에서 checkpoint에 관한 내용을 다루고 있으니 참고하시면 좋을 것 같습니다.
import os
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers
from tensorflow import keras
##Data Load Code##
base_dir = './datasets/cats_and_dogs/'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
train_datagen = ImageDataGenerator(
featurewise_center=True,
featurewise_std_normalization=True,
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
validation_split=0.2)
validation_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
# 타깃 디렉터리
train_dir,
# 모든 이미지를 150 × 150 크기로 바꿉니다
target_size=(150, 150),
batch_size=32,
# binary_crossentropy 손실을 사용하기 때문에 이진 레이블이 필요합니다
class_mode='binary') #cats_and_dogs는 2개의 클래스만 있음
validation_generator = validation_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=32,
class_mode='binary')
step_per_epoch: 한 epoch에 사용한 스텝 수를 지정합니다. 총 20000개의 training sample이 있고 batch size가 32이므로, 20000를 32로 나눈 몫(=20000/32=625)이 됩니다. (만약, 20001개의 training sample이 있다면 step_per_epoch은 "(20001//32)+1"이 되어야 합니다) 이러한 이유로 위의 train_step, valid_step을 아래와 같이 변경시켜주는 것이 좋습니다.
ex)총 45개의 훈련 샘플이 있고 배치사이즈가 3이라면 15 스텝(=step_per_epoch)으로 지정합니다.
validation_step: 한 epoch 종료 시 마다 검증할 때 사용되는 검증 스텝 수를 지정합니다.
ex) 총 15개의 validation 샘플이 있고 배치사이즈가 3이라면, validation_step을 5 스텝으로 지정합니다.
검은색: training sample/ 빨간색: validation sample
1. Metrics
딥러닝의 성능을 평가하기 위해 여러 성과지표(metrics)가 사용됩니다.
위에서 설명한 metrics은 accurcy로써 가장 대표적인 성과지표라 할 수 있습니다.
accuracy를 이용해 성과지표를 visualization하면 아래와 같이 표현할 수 있습니다.
※loss function에 따라 metrics도 바뀔 수 있는 듯 합니다. (예전에 사용할 때 loss function을 categorical_crossentropy를 사용했을 때, 그냥 metrics를 accuracy로 해도 문제가 없었던것 같은데 나중에 바꿔서 써봐야겠네요)
두 번째 방식. loss instance 생성 후, compile 함수에 있는 loss 속성에 앞서 생성한 loss instance를 기재
loss = CategoricalCrossentropy()
model.compile(loss=loss, optimizer='adam', metrics=["accuracy"])
Q. tf.keras.losses 부분 보면 bianry_crossentropy는 function이고, BinaryCrossentropy는 class로 되어 있는데, 이 두 가지가 어떤 차이가 있는지 모르겠네요. 어느 사이트 보면 function으로 선언한 경우 accuracy가 더 떨어져서 나온다는 말도 있는데, 정확히 어떤 차이가 있는건지...
1-2. 세 가지 기본 Loss function 소개
앞서 tensorflow에서 제공한 기본 loss 함수 중에, 딥러닝 분류 목적으로 사용하는 대표적인 loss function은 3가지 입니다.
1) Binary Crossentropy
Tensorflow에서 제공하는 BinaryCrossentropy는 2가지의 클래스를 구분하는 task에 적용할 수 있는 함수입니다.
2) Categorical Crossentropy
3개 이상의 클래스를 classification 할 경우 우리는 이를 multiclassification이라고 합니다.
이 경우에는 tensorflow에서 제공하는 CategoricalCrossentropy를 적용해주어야 합니다.
3) SparseCategorical Crossentropy
10개의 클래스를 분류한다고 한다는 가정하에 아래 그림에 있는 기호를 간단히 표현하면 다음과 같습니다.
t → label=answer → [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
y → probability = predict → [0.1, 0.05, 0.05, 0.1, 0.1, 0.3, 0.1, 0.05, 0.05, 0.1]
아래의 CategoricalCrossentropy 수식을 보면 사실 6번째 해당하는 class를 제외하면 모든 t는 0이기 때문에 loss function에 아무런 영향도 미치지 않습니다. 사실상 6번째에 해당하는 t, y 값만 고려해주고 나머지는 무시해줘도 되는 것이죠.
예를 들어, if 문을 이용하여 정답에 해당하는 label에 대해서만 "loss=-t×log(y)" 를 적용해주면 속도도 더 빨라지게 되는데, 이러한 방식의 loss function을 SparseCategoricalCrossentropy 라고 합니다. (실제로 DNN을 hardcoding 했을 때, CategoricalCrossentropy와 SparseCategoricalCrossentropy 학습 결과에는 변함이 없었습니다. 또한, 실제로 돌려보면 SparseCategoricalCrossentropy 방식으로 hardcoding 했을 때 좀 더 학습 속도가 빨랐습니다)
1-3. Label smoothing
Tensorflow 기본 loss API에서는 label smoothing을 쉽게 적용할 있게 구현해 놨습니다.
loss = CategoricalCrossentropy(label_smoothing=0.1)
model.compile(loss=loss, optimizer='adam', metrics=["accuracy"])
For example, if 0.1, use (0.1 / num_classes) for non-target labels and (0.9 + (0.1 / num_classes)) for target labels. (참고로 non-target labels의 확률값은 uniform distribution을 따릅니다)
참고로 앞서 설명한 SparseCategoricalCrossentropy의 기본전제는 hard label이기 때문에, label smoothing 속성이 왜 없는지 쉽게 파악할 수 있습니다.
hard label: 실제 정답외에 모든 label 값은 0으로 설정하는 방식
1-4. Extra loss functions by Tensorflow addons
Tensorflow 기본 loss API외에 SIG라는 곳에서 추가적인 loss function 들을 구현해 tensorflow에 contribution하고 있습니다. 예를 들어, 최근에 contrastive loss 도 주목을 받고 있는데, 이러한 loss를 Tensorflow Addons (by SIG) 에서 제공하는 API를 이용해 사용할 수 있습니다.
우리가 사용할 loss function이 앞서 소개된 기본 loss function에 없다면 우리가 스스로 만들어야 합니다.
대부분 정해진 task에 의해 기본적인 loss function을 쓰는 것이 보편적이지만, 종종 자신만의 loss function을 만들어 사용하는 경우도 있습니다. 예를 들어, Semi-supervised loss function, focal loss function과 같은 경우는 tensorflow에서 기본적으로 제공되는 loss function이 아니기 때문에 사용자가 직접 함수를 만들어 사용해야 합니다.
예를 들어, hubber loss라는 것을 만들어 사용하려면 아래와 같이 작성해주면 됩니다.
※Learning rate warm-up도 굉장히 자주쓰이는 트릭인데, tensorflow에서 기본적으로 제공해주는 방식은 없는 듯합니다. Github에서 다운받거나 아래 사이트를 참고하여 직접구현해주면서 사용해야 할 듯 합니다 (Pytorch는 굉장히 쉽게 사용할 수 있게 되어 있는데, tensorflow로 쓰려니 참...)
(↓↓↓아래 사이트에서 learning rate warm up 코드 부분을 참고해주세요!↓↓↓)
input = X
#첫 번째 conv layer에 있는 residual block
block_1_output1 = layers.Conv2D(kernel_size=(3,3), filters=channel_num, padding='same', name=name + '0_conv')(input)
block_1_output2 = BatchNormalization(name=name + '0_bn')(block_1_output1)
block_1_output3 = Activation('relu', name=name + '0_relu')(block_1_output2)
block_1_output4 = Conv2D(kernel_size=(3, ), filters=channel_num, padding='same', name=name + '1_conv')(block_1_output3)
# Zero gamma - Last BN for each ResNet block, easier to train at the initial stage.
#block_1_output4 = F(X)
block_1_output4 = BatchNormalization(gamma_initializer='zeros', name=name + '1_bn')(block_1_output4)
#merge_data = X+F(X)
merge_data = add([block_1_output4, input], name=name + '1_add')
out = Activation('relu', name=name + '2_conv')(merge_data)
위의 코드는 아래 이미지의 original 버전이라고 생각하시면 됩니다. 위의 코드를 기반으로 나머지 구조들((b), (c), (d), (e))도 구현하실 수 있겠죠?
3. Model summary
앞서 CNN 모델을 작성했다면, 해당 모델에 대한 간단한 구조를 summary 함수를 통해 알아볼 수 있습니다.
model.summary()
위의 출력결과에서는 "Non-trainable params:0"으로 표현되어 있는데, 나중에 transfer learning or fine-tuning을 적용시킬 때는 특정 layer까지 freezing 시키는 경우도 빈번하므로 Non-trainable params가 0이 아닐 때도 생깁니다. 이 부분은 trasnfer learning을 다룰 때 설명하도록 하겠습니다.
CNN모델을 학습시킬 때, 가장먼저 해야할 것은 train, validation, test dataset을 load하는 것입니다.
이번 장에서는 내가 구축한 (custom) dataset을 load하는 방식에 대해서 알아보도록 하겠습니다.
1. Custom dataset directory 설정
1) 학습데이터는 이미지 파일이므로 파일데이터와 관련된 module를 import합니다.
OS 모듈은 환경 변수나 디렉터리, 파일 등의 OS 자원을 제어할 수 있게 해주는 모듈
import os
2)학습할 데이터셋을 세팅합니다.
우선 학습할 데이터를 다운받고 아래와 같이 세팅이 되어 있는지 확인해 줍니다.
기본적으로 학습을 위한 데이터(cat_and_dogs)는 아래와 같이 train, validation, test 데이터 셋으로 구성이 되어있습니다.
train, validation, test 데이터셋(폴더)에는 각각 클래스와 관련된 폴더가 있고, 해당 폴더에 실제 이미지 데이터가 위치합니다. cats_and_dogs 분류문제는 개와 고양이 두 클래스를 구분하는 binary classification 문제이므로, 각 폴더에 2개의 클래스(개, 고양이)가 포함되어 있습니다.
!! 주석부분에 폴더 정보들을 기록해놨으니 꼭 확인해 주세요 !!
#base_dir → 다운받은 원본 데이터셋 경로 = 모든 training, validation, test 데이터셋이 포함되어 있음
#cats_and_dogs에 있는 총 이미지 데이터 개수 = 25,000 ← training:20,000 + validation:4,000 + test:500
base_dir = './datasets/cats_and_dogs/'
#train_dir → 원본 데이터셋의 학습 데이터 경로 = 모든 class(개, 고양이)들의 이미지들이 포함되어 있음
#train_dir에 있는 총 이미지 데이터 개수 = 20,000 ← 강아지=10,000 + 고양이=10,000
train_dir = os.path.join(base_dir, 'train') #train_dir = './datasets/cats_and_dogs/train'
#validation_dir → 원본 데이터셋의 학습 데이터 경로 = 모든 class(개, 고양이)들의 이미지들이 포함되어 있음
#validation_dir에 있는 총 이미지 데이터 개수 = 4,000 ← 강아지=2,000 + 고양이=2,000
validation_dir = os.path.join(base_dir, 'validation') #validation_dir = './datasets/cats_and_dogs/validation'
#test_dir → 원본 데이터셋의 학습 데이터 경로 = 모든 class(개, 고양이)들의 이미지들이 포함되어 있음
#test_dir에 있는 총 이미지 데이터 개수 = 1,000 ← 강아지=500 + 고양이=500
test_dir = os.path.join(base_dir, 'test') #test_dir = './datasets/cats_and_dogs/test'
2. Preprocessing (Normalization)
아래 링크에 걸어둔 글에서 볼 수 있듯이, 보통 효율적인 학습을 위해 딥러닝의 학습데이터들은 전처리의 일환으로 normalization이 적용됩니다
간단하게 말하자면, normalization이 적용된 학습데이터의 problem space가 더 안정적으로 형성될 수 있으므르로 학습이 더 수월하게 된다는 이점이 있습니다.
위와 같은 normalization을 적용해주기 위해서는 아래와 같이 zero center를 맞춰준후, data를 normalization 해주어야 합니다.
위와 같이 "zero-center→normalization"을 적용시켜주려면 아래와 같은 순서를 따르면 됩니다.
Zero center: 모든 데이터들의 평균을 구한다 → 모든 데이터들 각각에 해당 평균 값을 빼준다.
Normalization: 모들 데이터들의 표준편차를 구한다 → 모든 데이터들 각각에 해당 표준편차 값을 나눠준다.
위와 같은 데이터 전처리를 이미지에 적용할 때, 가능한 2가지 경우의 수가 있습니다.
2-1) 하나의 이미지 데이터를 기반으로 normalization 적용하기
예를 들어, 224×224×3 이미지가 있다고 가정해보겠습니다. 하나의 pixel에는 0~255값들이 들어 있는데, 앞에서 언급한 이미지 크기를 기준으로 한다면 150528(=224×224×3) pixel들이 존재하게 됩니다.
즉, 하나의 이미지에 해당하는 고유의 평균 및 표준편차 값을 구할 수 있기 때문에, 하나의 데이터에만 normalization을 적용할 수 있게 됩니다. 예를 들어, 150528(=224×224×3) 개의 pixel값들을 기반으로 평균 및 표준편차 값을 구하고, 모든 pixel에 평균값을 빼준후 표준편차값을 나눠주게 됩니다.
Keras API에서 의 설명을 보면 알 수 있듯이, 하나의 이미지당 normalization을 적용시키려면 samplewise 속성을 이용하면 됩니다.
samplewise_center: Boolean. Set each sample mean to 0.
samplewise_std_normalization: Boolean. Divide each input by its std.
이번에는 하나의 이미지가 아닌 batch 단위로 묶인 이미지들을 기반으로 하여 해당 평균 및 표준편차 값을 구한 뒤, normalization을 적용 시키는 방식입니다. (사실, 전체 학습 이미지에 대한 평균 및 표준편차 값을 구하는건지 아닌지 모르겠으나 해당 API에서 "The data will be looped over (in batches)."라고 기술된 부분을 보고 'batch 단위로 평균 및 표준편차 값이 구해지겠구나'라고 추정했습니다. 혹시 아니면 알려주시면 감사하겠습니다)
예를 들어 batch가 4라고 하면, 224×224×3×4 개의 pixel값들을 기반으로 평균 및 표준편차 값을 구하고, 모든 pixel에 평균값을 빼준후 표준편차값을 나눠주게 됩니다.
Keras API에서 의 설명을 보면 알 수 있듯이, batch 이미지당 normalization을 적용시키려면 featurewise 속성을 이용하면 됩니다.
Q. DNN에서 봤을 때는 이러한 것이 많은 도움이 되는걸 이론적으로 확인할 수 있습니다. 그런데, 개인적으로 pytorch 기반으로 작성하여 CNN에 적용시켰을 때는 적용을 하나 안하나 큰 차이가 없었던 것 같습니다. 다른 분야에서는 어떻게 적용하고 있는지 궁금하네요.
3. Data augmentation
CNN은 굉장히 다양한 data augmentation 기법을 지원합니다.
따라서 분류하려는 대상에 따라 적절한 data augmentation 기법을 적용시키면 됩니다.
예를 들어, Chest X-ray 같은 경우는 90도 rotation 해서 evaluation 하는 경우는 없으니, 90도 rotation은 적용시키지 않아도 되겠죠?
아래 코드에서 rescale은 overfitting을 방지하고자 모든 pixel 값들을 0~1 범위로 normalization 해주는 것인데, 앞서 "2. Preprocessing (Normalization)"에서 언급한 것과 같은 목적으로 적용된 것이라 생각하시면 될 것 같습니다.
※보통 cifar10, mnist, fashion mnist와 같은 적은 양의 데이터셋은 아래 링크에 기재된 tensorflow.keras.datasets 에서 제공을 해줍니다. 하지만, ImageNet 같은 경우는 데이터양이 워낙 방대하여 직접다운로드 받고 학습을 위한 구조를 세팅해주고 학습시켜야 한다는점 알아두시면 좋을것 같습니다!