train_datagen = ImageDataGenerator(
rescale=1./255, # 이미지 픽셀값 0~255를 0~1로 정규화
rotation_range=10, # 이미지 회전 각도 범위
zoom_range=0.3, # 이미지 확대/축소 범위
brightness_range=[0.5, 1.5], # 이미지 명도 범위
channel_shift_range=50, # 이미지 채도 범위
horizontal_flip=True, # 수평 방향으로 이미지 뒤집기
vertical_flip=True, # 수직 방향으로 이미지 뒤집기
fill_mode='nearest' # 이미지 변환 후 빈 영역을 채우는 방법
)
valid_datagen = ImageDataGenerator(
rescale=1./255,
)
test_datagen = ImageDataGenerator(
rescale=1./255,
)
train_generator = train_datagen.flow_from_directory(
train_path,
target_size=(img_size, img_size),
class_mode='binary',
shuffle = True,
)
valid_generator = train_datagen.flow_from_directory(
valid_path,
target_size=(img_size, img_size),
class_mode='binary',
shuffle = True,
)
test_generator = test_datagen.flow_from_directory(
test_path,
target_size=(img_size, img_size),
class_mode='binary',
shuffle = False,
)
train_generator = datagen.flow(
x_train, y_train, # 입력 데이터 및 레이블
batch_size=32 # 배치 크기
)
팀원과 실험한 결과, 파라미터를 많이 주고 변형을 많이 했을 때보다 변형이 적었을 때 성능이 더 좋았음
| 증강 없음 | 적은 변형 | 극단 변형 | 명도, 채도 변형 | |
|---|---|---|---|---|
| 성능(Accurarcy) | 0.85 | 0.89 | 0.84 | 0.79 |
이유
lr = ReduceLROnPlateau(monitor = 'val_accuracy',
factor = 0.1,
patience = 3,
verbose = 1,
mode = 'auto',
min_delta = 0.01,
min_lr = 0)
es = EarlyStopping(monitor = 'val_loss',
min_delta = 0.001,
patience = 7,
restore_best_weights = True,
verbose = 1)
Transfer Learning에서는 'include_top = False'로 설정하면 마지막 fully connected layer가 제거되고, 분류 레이어를 사용자가 직접 만들어 사용 가능(base_model의 layer를 Freeze한다고 표현)
base_model.trainable=False를 통해 pre-trained weights를 고정
| 설정 | include_top | .trainable |
|---|---|---|
| True | 분류 레이어를 포함 | Fine-Tuning에 대해 업데이트 O |
| False | 분류 레이어를 제외 | Fine-Tuning에 대해 업데이트 X |
base_model = ResNet50V2(weights='imagenet', include_top=False, input_shape=(img_size, img_size,3))
base_model.trainable = False
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(128, activation='relu')(x)
x = Dropout(0.2)(x)
predictions = Dense(1, activation='sigmoid')(x)
resnet50 = Model(inputs=base_model.input , outputs=predictions)
resnet50.compile(loss=keras.losses.binary_crossentropy,
metrics=['accuracy'],
optimizer= keras.optimizers.Adam(learning_rate = 0.0001))


keras.backend.clear_session()
base_model = EfficientNetV2B0(weights='imagenet', include_top=False, input_shape=(img_size, img_size,3))
base_model.trainable = True/False
Fine Tuning은 적용/미적용 비교
| Trainable | Trainable Params | Non-Trainable Params | Total |
|---|---|---|---|
| True | 5.8M | 0.06M | 5.9M |
| False | 1281 | 5.9M | 5.9M |
- val_accuracy가 0.5로 고정되는 문제 발생


base_model = VGG16(weights='imagenet', include_top=False, input_shape=(img_size, img_size,3))
base_model.trainable = False
x = base_model.output
x = Flatten()(x)
x = Dense(1024, activation = 'relu')(x)
x = Dropout(0.25)(x)
predictions = Dense(1 , activation='sigmoid')(x)

