사용한 버전
- tensorflow = 2.2.0
kaggle에서 개와 고양이 데이터셋을 다운로드하여 진행했습니다
해당 폴더 안에 (이름은 자유)
cat_and_dog
ㄴ training_set
ㄴ cats
ㄴ dogs
ㄴ test_set
ㄴ cats
ㄴ dogs
와 같이 구성해 놓아야 합니다
validation data 는 아래에서 따로 지정할 것입니다
import os
from tensorflow.keras.preprocessing.image import ImageDataGenerator
rootPath = './datasets/cat_and_dog'
imageGenerator = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
width_shift_range=0.1,
height_shift_range=0.1,
brightness_range=[0.2, 1.3],
horizontal_flip=True,
validation_split=.2
)
trainGen = imageGenerator.flow_from_directory(
os.path.join(rootPath, 'training_set'),
target_size=(64, 64),
subset='training'
)
validationGen = imageGenerator.flow_from_directory(
os.path.join(rootPath, 'training_set'),
target_size=(64, 64),
subset='validation'
)
Found 6404 images belonging to 2 classes.
Found 1601 images belonging to 2 classes.
ImageDataGenerator로 전처리와 이미지 증폭 설정
ImageDataGenerator에 대한 보다 자세한 설명은 아래 글 참조
https://blueberry-kyu.tistory.com/4
from tensorflow.keras.models import Sequential
from tensorflow.keras import layers
model = Sequential()
model.add(layers.InputLayer(input_shape=(64, 64, 3)))
model.add(layers.Conv2D(16, (3, 3), (1, 1), 'same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))
model.add(layers.Conv2D(32, (3, 3), (1, 1), 'same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))
model.add(layers.Conv2D(64, (3, 3), (1, 1), 'same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(2, activation='sigmoid'))
model.summary()
CNN 구성
이진 분류이므로 마지막 layer에 sigmoid를 사용하였습니다
model.compile(
optimizer='adam',
loss='binary_crossentropy',
metrics=['acc'],
)
epochs = 50
history = model.fit(
trainGen,
epochs=epochs,
validation_data=validationGen,
)
optimizer는 일반적으로 많이 사용하는 adam
loss는 이진 분류 이므로 binary_crossentropy를 사용하였습니다
metrics는 acc (정확도, accuracy로 써도 똑같음!)
이전 포스트에선 x_train(이미지), y_train(레이블) 형태로 데이터를 다뤘는데
그쪽이 편하다면
x_train=np.concatenate([trainGen.next()[0] for i in range(trainGen.__len__())])
y_train=np.concatenate([trainGen.next()[1] for i in range(trainGen.__len__())])
의 방법으로 변환하여 사용하면 됩니다.
validation data와 test data도 같은 방법을 사용
...
대충 30분 정도 걸린 듯
history.history.keys()
dict_keys(['loss', 'acc', 'val_loss', 'val_acc'])
history_dict = history.history
loss = history_dict['loss']
val_loss = history_dict['val_loss']
epochs = range(1, len(loss)+1)
fig = plt.figure(figsize=(12, 6))
ax1 = fig.add_subplot(1, 2, 1)
ax1.plot(epochs, loss, color='blue', label='train_loss')
ax1.plot(epochs, val_loss, color='red', label='val_loss')
ax1.set_title('Train ans Validation loss')
ax1.set_xlabel('Epochs')
ax1.set_ylabel('loss')
ax1.grid()
ax1.legend()
accuracy = history_dict['acc']
val_accuracy = history_dict['val_acc']
ax2 = fig.add_subplot(1, 2, 2)
ax2.plot(epochs, accuracy, color='blue', label='train_accuracy')
ax2.plot(epochs, val_accuracy, color='red', label='val_accuracy')
ax2.set_title('Train ans Validation Accuracy')
ax2.set_xlabel('Epochs')
ax2.set_ylabel('Accuracy')
ax2.grid()
ax2.legend()
plt.show()
testGenerator = ImageDataGenerator(
rescale=1./255
)
testGen = imageGenerator.flow_from_directory(
os.path.join(rootPath, 'test_set'),
target_size=(64, 64),
)
#model.evaluate_generator(testGen)
model.evaluate(testGen)
Found 2023 images belonging to 2 classes.
64/64 [==============================] - 8s 122ms/step - loss: 0.4474 - acc: 0.7958
정확도는 거의 80 퍼
나쁘지 않다
※ model.evaluate_generator를 이용하는 경우 경고가 뜰 수 있습니다
evaluate_generator을 사용하여도 결과는 나오지만 evaluate로 바꾸려는 추세인 듯..?
from tensorflow.keras.preprocessing.image import array_to_img
import numpy as np
index = ['cat', 'dog']
imgs = testGen.next()
arr = imgs[0][0]
img = array_to_img(arr).resize((128, 128))
plt.imshow(img)
result = model.predict_classes(arr.reshape(1, 64, 64, 3))
print('예측: {}'.format(index[result[0]]))
print('정답: {}'.format(index[np.argmax(imgs[1][0])]))
예측: cat
정답: cat
역시 셀을 반복 실행하면 다른 데이터를 볼 수 있습니다~
model.save('cat_dog_model.h5')
모델 저장하기
image와 label 분리
위의 방법은 ImageDataGenerator 를 이용한 데이터를 가지고 진행하였는데
image와 label을 따로 진행하는게 편하시다면
x_train=np.concatenate([trainGen.next()[0] for i in range(trainGen.__len__())])
y_train=np.concatenate([trainGen.next()[1] for i in range(trainGen.__len__())])
x_val=np.concatenate([validationGen.next()[0] for i in range(validationGen.__len__())])
y_val=np.concatenate([validationGen.next()[1] for i in range(validationGen.__len__())])
x_test=np.concatenate([testGen.next()[0] for i in range(testGen.__len__())])
y_test=np.concatenate([testGen.next()[1] for i in range(testGen.__len__())])
와 같은 방법으로 분리하여 진행할 수있습니다
'딥러닝 > tensorflow' 카테고리의 다른 글
predict? predict_classes? 단일이미지 예측 하기 (0) | 2021.08.13 |
---|---|
tensorflow 모델과 webcam을 이용한 Classification (0) | 2021.08.12 |
custom data를 이용한 transfer learning (0) | 2021.08.06 |
이미지 전처리, 증폭에 사용하는 ImageDataGenerator (0) | 2021.07.31 |
MNIST손글씨 데이터를 이용한 Classification (0) | 2021.07.30 |