โ ๋ฐ์ดํฐ ์ฆ๊ฐ๊ธฐ๋ฒ์ด๋ ?
๊ฐ๊ณ ์๋ ๋ฐ์ดํฐ์
์ ์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก augmentํ์ฌ ์ค์ง์ ์ธ ํ์ต ๋ฐ์ดํฐ์
์ ๊ท๋ชจ๋ฅผ ํค์ธ ์ ์๋ ๋ฐฉ๋ฒ
๐งฉ ์ ์ฉ ์์
train_datagen = ImageDataGenerator(
rescale=1./255, # ์ผ๋ฐํ
rotation_range=10, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ํ์ (๋จ์: ๋, 0-180)
zoom_range=0.1, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง ํ๋ (%)
width_shift_range=0.1, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ์ํ์ผ๋ก ์ด๋ (%)
height_shift_range=0.1, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ์์ง์ผ๋ก ์ด๋ (%)
horizontal_flip=True # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ์ํ์ผ๋ก ๋ค์ง๊ธฐ
)
์ด๋ฒ ํ ํ๋ก์ ํธ๋ ๊ฐ์์ง์ ์ข ์ ๊ตฌ๋ถํ๋ ๋ฐ์ดํฐ์ ์ ํ์ต์์ผฐ๋๋ฐ, ์ด๋ฒ์๋ ๊ณ ์์ด์ ๊ฐ์์ง๋ฅผ ๋ถ๋ฅํ๋ ๋ฐ์ดํฐ์ ์ ํ์ต์์ผฐ๋ค.
๐งฉ ์ ์ฉ ์์
์ผ๋จ ์๋์ ํ์ผ์ kaggle์์ ๋ค์ด๋ฐ์๊ณ , ํ์์ ์ผ๋ก ๋ค์ด๋ฐ์์ผ ํ ๋ชจ๋์ ์ํฌํธํ๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ต๋ฐ์ดํฐ์๊ฒฝ์ฐ ๋ฐ์ดํฐ์ฆ๊ฐ๊ธฐ๋ฒ์ ํ์ฉํด ์ ํ๋๋ฅผ ๋์ด๊ณ , ํ ์คํธ๋ฐ์ดํฐ๋ ์ผ๋ฐํ์์ผฐ๋ค.
train_datagen = ImageDataGenerator(
rescale=1./255, # ์ผ๋ฐํ
rotation_range=10, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ํ์ (๋จ์: ๋, 0-180)
zoom_range=0.1, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง ํ๋ (%)
width_shift_range=0.1, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ์ํ์ผ๋ก ์ด๋ (%)
height_shift_range=0.1, # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ์์ง์ผ๋ก ์ด๋ (%)
horizontal_flip=True # ๋๋คํ๊ฒ ์ด๋ฏธ์ง๋ฅผ ์ํ์ผ๋ก ๋ค์ง๊ธฐ
)
test_datagen = ImageDataGenerator(
rescale=1./255 # ์ผ๋ฐํ
)
train_gen = train_datagen.flow_from_directory(
'test_set/test_set',
target_size=(256, 256), # (height, width)
batch_size=32,
seed=2021,
class_mode='binary',
shuffle=True
)
test_gen = test_datagen.flow_from_directory(
'training_set/training_set',
target_size=(256, 256), # (height, width)
batch_size=32,
seed=2021,
class_mode='binary',
shuffle=False
)
๊ณ ์์ด๋ '0'์ผ๋ก , ๊ฐ์์ง๋ '1'
from pprint import pprint
pprint(train_gen.class_indices)
๊ฐ์๋ชจ๋ธ
model = Sequential([
Conv2D(filters=32, kernel_size=3, padding='same', activation="relu", input_shape=(256, 256, 3)),
MaxPooling2D(pool_size=(2, 2), strides=2),
Conv2D(filters=64, kernel_size=3, padding='same', activation="relu"),
MaxPooling2D(pool_size=(2, 2), strides=2),
Conv2D(filters=128, kernel_size=3, padding='same', activation="relu"),
MaxPooling2D(pool_size=(2, 2), strides=2),
Flatten(),
Dense(128, activation='relu'),
Dense(1, activation="sigmoid")
])
model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.001), metrics=['acc'])
ํ์ต์ํค๊ธฐ
from tensorflow.keras.callbacks import ModelCheckpoint
history = model.fit(
train_gen,
validation_data=test_gen, # ๊ฒ์ฆ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ํ epoch์ด ๋๋ ๋๋ง๋ค ์๋์ผ๋ก ๊ฒ์ฆ
epochs=20, # epochs ๋ณต์ํ์ผ๋ก ์ฐ๊ธฐ!
callbacks=[
ModelCheckpoint('model.h5', monitor='val_acc', verbose=1, save_best_only=True)
]
)
์ค๋์ ๋กค์ฑํผ์ธ์ ๊ตฌ๋ถํด์ฃผ๋ ๊ธฐ๋ฅ์ ํ์ต์์ผ ๋ง๋ค๊ธฐ ์ํด ํ๋ก ํธ์๋๋ฅผ ์์ฑํ๊ณ , ๋๋ ๋กค๊ฒ์์ ํ์ง์์๊ธฐ ๋๋ฌธ์ ํ์์์ด ๊ฐ ๊ฒ์ ์บ๋ฆญํฐ์ ์ด๋ฏธ์ง๋ฅผ ์ง์ ์ฌ์ง์ ์ฐ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ชจ์ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ต์์ผฐ๋ค. ํ ํ๋ก์ ํธ ๊ธฐ๊ฐ๋์ ๋ ๊ฐ์ ํ๋ก์ ํธ๋ฅผ ์งํํ ์ผ์ด ์ฒ์์ด๋ผ์ ๋๋ผ์ ๋ค.. ์๋๋ ์ ํด์ง ํ๋ก์ ํธ๊ธฐ๊ฐ์ด ์งง๊ฒ๋๊ปด์ง์ ๋์ฌ์ ํ๋ก์ ํธ๋ฅผ ์์ฑํ๋๋ฐ์ ๋ฒ๊ฑฐ์ ์๋๋ฐ! ์ด๋ฒ ํ๋ก์ ํธ ๊ธฐ๊ฐ๋์ ํ๋ฃจ์ ์ ํด๋์๋ ๊ณํ๋ณด๋ค ๋ ์ผ์ฐ ๋๋ผ ์ ์์ด์ ์๋นํ ์ฌ์ ๋ก์ ๋ค. ๋ค์ ํ๋ก์ ํธ๋ '๋ทํ๋ฆญ์ค'๋ฅผ ๊ตฌํํ๋ ํ๋ก์ ํธ๋ก ์๊ณ ์๋๋ฐ, ๋๋ฌด ๊ธฐ๋๊ฐ ๋๋ค.
๐ ์์ธํ ์ฝ๋๋ colab ์ ๊ฒ์ํ์ต๋๋ค