이항 분류 :: 컴퓨터 비전 - mindscale
Skip to content

이항 분류

텐서플로 설치

텐서플로 홈페이지 참고 https://www.tensorflow.org/install

pip install tensorflow

GPU 지원을 위해서는 별도로 CUDA 및 CuDNN 설치 필요

텐서플로 임포트

import tensorflow as tf

손글씨 데이터 이항 분류

데이터 받기

(x_train, y_train), (x_test, y_test) = \
    tf.keras.datasets.mnist.load_data()

이미지 보기

from PIL import Image
Image.fromarray(x_train[0])

0과 1만 추리기

두 개의 클래스만 추출해주는 함수

import numpy as np
def filter_dataset(x, y, neg_cls, pos_cls):
    m = (y == pos_cls) | (y == neg_cls)
    x = x[m]
    y = y[m]
    y = np.where(y == neg_cls, 0, 1)
    return x, y

0과 1만 추출

x_train2, y_train2 = filter_dataset(x_train, y_train, 0, 1)

모형 정의

from tensorflow.keras.layers import *
model = tf.keras.Sequential([
    Flatten(),
    Dense(1, activation='sigmoid'),
])

설정

model.compile(loss='binary_crossentropy', 
              metrics=['accuracy'])

훈련

데이터에 적합(fit)한 파라미터를 추정(parameter estimation)하여 모델을 훈련(train)

result = model.fit(x_train2, y_train2, validation_split=0.1, epochs=10)

validation_split=0.1: 10%의 데이터를 검증에 사용(훈련에는 제외)

에포크에 따른 정확도 추이

import matplotlib.pyplot as plt
plt.plot(result.history['accuracy'], 'b-', label='accuracy')
plt.plot(result.history['val_accuracy'], 'r--', label='val_accuracy')
plt.legend()
<matplotlib.legend.Legend at 0x194abddbcd0>
plt.plot(result.history['loss'], 'b-', label='loss')
plt.plot(result.history['val_loss'], 'r--', label='val_loss')
plt.legend()
<matplotlib.legend.Legend at 0x194b3e1fca0>

평가

테스트 데이터에서 0과 1만 추리기

x_test2, y_test2 = filter_dataset(x_test, y_test, 0, 1)

테스트 데이터로 평가

model.evaluate(x_test2, y_test2)
62/62 [==============================] - 0s 1ms/step - loss: 17.1769 - accuracy: 0.8106
[17.17691993713379, 0.810644805431366]

파라미터

모형의 파라미터는 각 단어에 대한 가중치 weight와 y 절편 bias

weight, bias = model.trainable_weights

예측

확률 예측

prob = model.predict(x_test2)
62/62 [==============================] - 0s 557us/step

문턱값을 지정

threshold = 0.5

문턱값보다 크면 1, 아니면 0으로 예측

import numpy as np
y_pred = np.where(prob > threshold, 1, 0)

직접 손글씨 입력해보기

이미지 불러와서 흑백으로 변환

img = Image.open('hand.png').convert('L')
img

넘파이 배열로 변환

x = np.array(img)

훈련 데이터는 (N, 28, 28) 형태(N은 데이터 개수) x는 (28, 28) 형태이므로 0번 차원을 추가, (1, 28, 28) 형태로 맞춰준다

x = np.expand_dims(x, 0)

예측

model.predict(x)
1/1 [==============================] - 0s 13ms/step
array([[1.]], dtype=float32)

얼리스톱핑을 이용한 훈련

model = tf.keras.Sequential([
    Flatten(),
    Dense(1, activation='sigmoid'),
])

model.compile(loss='binary_crossentropy', 
              metrics=['accuracy'])

model.fit(
    x_train2, y_train2, epochs=100,
    validation_split=0.1,
    callbacks=[
        tf.keras.callbacks.EarlyStopping(patience=2)
    ])

자동 저장

검증 정확도가 가장 좋은 모델의 파라미터를 자동 저장

model = tf.keras.Sequential([
    Flatten(),
    Dense(1, activation='sigmoid'),
])

model.compile(loss='binary_crossentropy', 
              metrics=['accuracy'])

model.fit(x_train2, y_train2, epochs=10, validation_split=0.1,
    callbacks=[tf.keras.callbacks.ModelCheckpoint(
        'checkpoints',           # checkpoint 폴더에
        monitor="val_accuracy",  # 정확도 기준
        save_best_only=True,     # 이전보다 좋은 결과만 저장
        save_weights_only=True,  # 파라미터만 저장
)])

저장된 파라미터 불러오기

model.load_weights('checkpoints')
<tensorflow.python.checkpoint.checkpoint.CheckpointLoadStatus at 0x194b74ad4b0>