이번에는 Courser Deep learning 특화과정 첫번째강의 2주차 수업에서 실습했던, cat classification을 구현해보도록 하겠습니다.
바로 시작해보도록 하겠습니다.
1. 필요한 package import
import tensorflow as tf
import h5py
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
print(tf.__version__)
>> 2.1.0
2. Dataset 준비
dataset은 coursera 강의에서 사용되었던 training data와 test data를 사용합니다. (필요하시면 댓글 주세요)
dataset이 h5파일이기 때문에, h5py를 사용해서 읽어오고, numpy array로 data를 input과 output으로 나누어줍니다. 각 data의 shape를 확인하면 아래와 같습니다.
# Load dataset
train_dataset = h5py.File('dataset/train_catvnoncat.h5', 'r')
test_dataset = h5py.File('dataset/test_catvnoncat.h5', 'r')
train_x_orig = np.array(train_dataset['train_set_x'][:], np.float32)
train_y = np.array(train_dataset['train_set_y'][:], np.float32)
test_x_orig = np.array(test_dataset['test_set_x'][:], np.float32)
test_y = np.array(test_dataset['test_set_y'][:], np.float32)
classes = np.array(train_dataset['list_classes'][:])
print("train set x shape :", train_x_orig.shape)
print("train set y shape :", train_y.shape)
print("test set x shape :", test_x_orig.shape)
print("test set y shape :", test_y.shape)
# example
index = 50
plt.imshow(train_x_orig[index].astype(np.int32))
print("y =", train_y[index].astype(np.int32), ", It is a " + str(classes[train_y[index].astype(np.int32)].decode("ascii")))
입력의 경우에는 위와 같은 이미지입니다.
입력의 shape가 (64, 64, 3)의 3차원이므로, flatten 작업을 해줍니다. 그래서 우리는 feature가 총 12288개인 1차원 입력으로 변경을 해주게 됩니다.
# flatten
train_x_flatten = train_x_orig.reshape(train_x_orig.shape[0], -1)
train_y = train_y.reshape(train_y.shape[0], -1)
test_x_flatten = test_x_orig.reshape(test_x_orig.shape[0], -1)
test_y = test_y.reshape(test_y.shape[0], -1)
print ("train_x_flatten shape: " + str(train_x_flatten.shape))
print ("train_y_orig shape: " + str(train_y.shape))
print ("test_x_flatten shape: " + str(test_x_flatten.shape))
print ("test_y_orig shape: " + str(test_y.shape))
print ("sanity check after reshaping: " + str(train_x_flatten[0:5,0]))
그리고, 입력은 RGB로 0~255의 값을 가집니다. 그래서 학습속도를 높이기 위해서 255로 나누어서 normalization을 진행합니다.
# normalization
train_x = train_x_flatten / 255.
test_x = test_x_flatten / 255.
train_x
이로써 data의 전처리를 모두 진행하였습니다.
3. 학습
우선 학습에 필요한 함수들을 정의합니다.
- parameter_initialization_with_zeros(dim) : 파라미터 W, b 초기화
- forward_propagation(W, b, X) : FP를 수행해 \(\hat{y}\)를 구하는 함수
- predict(W, b, X) : 학습한 파라미터로 label을 예측하는 함수
- accuracy(Y_pred, Y) : 예측한 label과 실제 label을 비교하고 정확도를 반환하는 함수
def parameter_initialization_with_zeros(dim):
W = tf.Variable(np.zeros((dim, 1)), dtype=tf.float32)
b = tf.Variable([0.], dtype=tf.float32)
return W, b
def forward_propagation(W, b, X):
z = tf.matmul(X, W) + b
return tf.math.sigmoid(z)
def predict(W, b, X):
pred = forward_propagation(W, b, X)
pred = tf.cast(pred > 0.5, dtype=tf.float32)
return pred
def accuracy(Y_pred, Y):
acc = tf.reduce_mean(tf.cast(tf.equal(Y_pred, Y), dtype=tf.float32))
return acc
그리고, 학습을 위한 model 함수를 생성합니다. 이 함수는 매 iteration마다의 cost와 학습된 파라미터 W, b, 그리고 예측한 label(train, test)을 반환합니다.
def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.01):
W, b = parameter_initialization_with_zeros(X_train.shape[1])
costs = []
optimizer = tf.optimizers.SGD(learning_rate)
for iter in range(1, num_iterations + 1):
with tf.GradientTape() as tape:
pred = forward_propagation(W, b, X_train)
cost = tf.reduce_mean(-tf.reduce_sum(Y_train*tf.math.log(pred) + (1 - Y_train)*tf.math.log(1 - pred), 1))
# compute gradient
grad = tape.gradient(cost, [W, b])
# update gradient
optimizer.apply_gradients(zip(grad, [W, b]))
if iter % 100 == 0:
acc = accuracy(predict(W, b, X_train), Y_train)
costs.append(cost)
print(f"Cost after iteratioin {iter} : {cost} / train acc : {acc*100} %")
Y_pred_train = predict(W, b, X_train)
Y_pred_test = predict(W, b, X_test)
print(f"train accuracy : {accuracy(Y_pred_train, Y_train) * 100} %")
print(f"test accuracy : {accuracy(Y_pred_test, Y_test) * 100} %")
ret = {"costs" : costs,
"Y_pred_train" : Y_pred_train,
"Y_pred_test" : Y_pred_test,
"W" : W,
"b" : b}
return ret
그리고 학습을 진행합니다. learning rate는 0.005, iteration은 2000으로 설정해주었습니다.
result = model(train_x, train_y, test_x, test_y, 2000, 0.005)
학습결과 99%의 train accuracy와 70%의 test accuracy를 얻었습니다. train accuracy가 압도적으로 높은 것으로 보아 이 모델은 training data에 overfitting(과적합)된 것으로 추측할 수 있습니다. 추후에 이 overfitting을 해결해보도록 하겠습니다.
cost 변화의 추이를 살펴보면 다음과 같습니다.
costs = np.squeeze(result['costs'])
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per 100)')
plt.show()
'ML & DL > tensorflow' 카테고리의 다른 글
Initialization에 따른 학습 비교 (0) | 2020.11.15 |
---|---|
Cat Classification (2) : L-layers Neural Network (0) | 2020.11.15 |
tensorflow에서 random seed 설정 (1) | 2020.11.14 |
Logistic Regression with 1 hidden layer(planar data classification) (0) | 2020.11.13 |
Logistic Regression 예제(iris classification) (0) | 2020.11.13 |
댓글