Python, TensorFlow Image Classification(이미지 분류) 이미지 증강 및 예측하기 (Machine learning, Deep learning) for window
저번 시간에 포스팅했던 Python-TensorFlow Image Classification(이미지 분류) 모델 생성 방법 및 학습 확인 검증 (Machine learning, Deep learning) for window에서 해당 모델을 생성하고 검증하는 부분을 진행하였는데 이번에는 해당 테스트 이미지를 검사하여 어떤 자세일 확률이 높은지 예측하는 방법을 포스팅을 해보려 합니다.
이번에는 한복 스타일의 캐릭터를 학습할 데이터로 이용하여, 해당 이미지 증강 및 자세를 예측 해 보는 코드를 작성 해 보겠습니다.(학습 이미지의 파일 디렉토리 등 지난 포스팅을 꼭 참고 해 주세요! https://devdalbi.tistory.com/41 ) 자세는 다음
과 같습니다.
[ standing, sitting, bent_over, squatting, kneeling ]
standing: 서있는 자세
sitting: 앉은 자세
kneeling: 무릎꿇은 자세
squatting: 쭈그려 앉은 자세
bent_over: 허리를 구부린 자세
데이터 증강 처리
# 데이터 증강
data_aug = keras.Sequential(
[
layers.RandomFlip("horizontal", input_shape=(img_height, img_width, 3)),
layers.RandomRotation(0.1),
layers.RandomZoom(0.1)
]
)
과대적합은 일반적으로 훈련 예제가 적을 때 발생한다고 합니다. 데이터 증강은 증강 후 믿을 수 있는 이미지를 생성하는 임의 변환을 사용하는 방법입니다. 증강시 이미지를 돌려 보기도 하고, 뒤집기도하고, 여러 다방면으로 파악하게 됩니다. 데이터의 여러 방면을 파악하면 모델의 해당 데일반화가 더욱 쉬워진다고 합니다.
※과대적합: 모델이 학습중 학습 데이터를 과도하게 학습하는 것을 말합니다.(과적합 하면 실제 데이터에서 오차가 증가하게됨.)
layers.RandomFlip() 는 학습 중 이미지를 무작위로 뒤집는 전처리 레이어 입니다. 해당 mode 매개변수로는 "horizontal", "vertical" 등등 있습니다.
layers.RandomRotation(0.1)는 무작위 회전시키는 전처리 레이어 입니다.
layers.RandomZoom(0.1)는 무작위로 확대, 축소하는 전처리 레이어 입니다.
데이터 시각화 처리
plt.figure(figsize=(10, 10))
for images, _ in train_ds.take(1):
for i in range(9):
augmented_images = data_aug(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
해당 이미지 파일을 증강한 예시를 시각화 합니다.( plt로 확인 가능합니다. )
다음 이미지 데이터 증강 Model을 생성 합니다.
# 데이터 증강 신경망 생성
model = Sequential([
data_aug,
layers.Rescaling(1./255),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Dropout(0.2),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes, name="outputs")
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
epochs = 15
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='훈련 정확도')
plt.plot(epochs_range, val_acc, label='검증 정확도')
plt.legend(loc='lower right')
plt.title('훈련 및 검증 정확도')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='훈련 손실')
plt.plot(epochs_range, val_loss, label='검증 손실')
plt.legend(loc='upper right')
plt.title('훈련 및 검증 손실')
plt.show()
print("증강 종료")
위 코드에서 모델을 보면 layers.Dropout(0.2)가 있습니다. 드롭아웃은 과대적합을 줄이는 코드입니다. 이것은 신경망 훈련에 유용한 정규화 형태라고 합니다.드롭아웃 정규화는 단일 경사 단계에 대해 네트워크 계층에서 고정된 수의 단위를 무작위로 선택하는 것을 제거 한다고 합니다. 많은 단위가 삭제될수록 정규화는 더 강해진다고 합니다. 그리고 코드를 보시면 plt를 이용하여 해당 이미지 증강 작업에 대한 학습 결과를 시각화 하였습니다.
코드가 정상적으로 실행 된다면, 이미지 증강 중 로그를 확인 할 수 있습니다.
이미지 증강된 한복을 입은 캐릭터.png의 증강 시각화 예시는 다음과 같습니다.
모델의 학습에 대한 정확도와 손실 그리고 검증에 대한 정확도 및 손실도 점점 좋아지는 것을 확인 할 수 있습니다.
하지만 검증에 대한 그래프가 왔다 갔다 하는데 이것은 해당 특징이 부족한 모호한 이미지가 몇개 있는 것으로 추측됩니다.
이러한 모델의 학습 결과로 실제 학습 및 검증 세트에 포함하지 않는 이미지를 테스트하여 해당 자세를 예측해 보도록 하겠습니다. 코드는 다음과 같습니다.
print("\n데이터 예측을 시작합니다.")
imgList = "C:\\Users\\사용자이름\\.keras\\datasets\\validation"
imgList_dir = pathlib.Path(imgList)
testImg = list(imgList_dir.glob('*'))
print("img array : "+str(testImg))
for image in testImg:
print("\n검증할 image path: "+str(image))
img = tf.keras.utils.load_img(
image, target_size=(img_height, img_width)
)
img_array = tf.keras.utils.img_to_array(img)
img_array = tf.expand_dims(img_array, 0)
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
print(
"검사한 이미지는 {} 자세에 {:.2f} %로 속할 가능성이 높습니다."
.format(class_names[np.argmax(score)], 100 * np.max(score))
)
테스트 해볼 이미지 데이터는 다음과 같습니다. 한복을 입은 캐릭터.png 목록 입니다.
각 순서대로 무릎꿇은 자세(kneeling), 앉은 자세(sitting), 쭈그려 앉은 자세(squatting), 서있는 자세(standing), 허리를 구부린 자세(bent_over)가 있는 이미지 파일입니다. (이미지 예측 파일)
결과:
기분좋게 1번째 이미지는 100% 확률로 정답을 예측하였습니다. 2번째 이미지의 경우 자세는 맞긴 하지만 36%로 낮은 퍼센트로 확인 됩니다. 3번째 이미지도 99%으로 훌륭하게 예측하였습니다. 4번째 이미지는 정답이긴 하지만, 낮은 확률로 예측하였습니다. 마지막 5번째 이미지는 49% 예측하였지만 틀렸습니다. 정답 자세는 standing이 아닌 bent_over 입니다.
모든 이미지를 예측하지 못해 테스트 결과가 아쉽지만, 여러 특징이 확실한 이미지 파일을 대량으로 학습 한다면 좋은 결과가 있을 것 같습니다.