( 해당 글은 인프런 강의를 정리한 내용입니다 )
이번엔 Softmax Regression을 활용한 MNIST숫자분류기 구현을 해보겠다.
역시 간단히 정리하면서 알아보자
# -*- coding: utf-8 -*-
import tensorflow as tf
# MNIST 데이터를 다운로드 합니다.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# 이미지들을 float32 데이터 타입으로 변경합니다.
x_train, x_test = x_train.astype('float32'), x_test.astype('float32')
# 28*28 형태의 이미지를 784차원으로 flattening 합니다.
x_train, x_test = x_train.reshape([-1, 784]), x_test.reshape([-1, 784])
# [0, 255] 사이의 값을 [0, 1]사이의 값으로 Normalize합니다.
x_train, x_test = x_train / 255., x_test / 255.
# 레이블 데이터에 one-hot encoding을 적용합니다.
y_train, y_test = tf.one_hot(y_train, depth=10), tf.one_hot(y_test, depth=10)
# tf.data API를 이용해서 데이터를 섞고 batch 형태로 가져옵니다.
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_data = train_data.repeat().shuffle(60000).batch(100)
train_data_iter = iter(train_data)
먼저 tensorflow에 내장된 여러 함수를 이용하면 데이터 가공을 쉽게 처리할 수 있다.
특히 MNIST같은 경우 굉장히 많이 쓰이기 때문에 tensorflow 자체에서 손쉽게 가공할 수 있게 함수를 지정해준다.
데이터들이 처음 들어오면 int형이기 때문에 float형으로 바꿔주고, 2차원인 배열을 1차월로 one-hot 인코딩하는 과정을 거친 훼, Normalize과정을 거친다.
또 Tensorflow는 batch형태로 나누는것도 쉽게할 수 있다. tf.data.Dataset함수를 이용하고 그 밑에 batch안에 넣으면 몇개로 쪼갤건지를 선택할 수 있다!
위 코드의 경우 6만개 데이터를 100개씩 쪼갠것을 알 수 있다.
# tf.keras.Model을 이용해서 Softmax Regression 모델을 정의합니다.
class SoftmaxRegression(tf.keras.Model):
def __init__(self):
super(SoftmaxRegression, self).__init__()
self.softmax_layer = tf.keras.layers.Dense(10,
activation=None,
kernel_initializer='zeros',
bias_initializer='zeros')
def call(self, x):
logits = self.softmax_layer(x)
return tf.nn.softmax(logits)
그다음 케라스 모델을 활용해서 Softmax Regression 모델을 정의해준다.
우리는 tf.keras.Dense API를 활용한다.
https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense
역시 페이지에 설명이 잘 되어 있다
생성자에 케라스 하위 api로 모델구조관련부분을 가져오고, call부분에서 응답을 받아 나온 연산을 리턴해주는 구조가 계속 반복된다고 생각해도 괜찮을 것 같다.
# cross-entropy 손실 함수를 정의합니다.
@tf.function
def cross_entropy_loss(y_pred, y):
return tf.reduce_mean(-tf.reduce_sum(y * tf.math.log(y_pred), axis=[1]))
#return tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logtis, labels=y)) # tf.nn.softmax_cross_entropy_with_logits API를 이용한 구현
# 최적화를 위한 그라디언트 디센트 옵티마이저를 정의합니다.
optimizer = tf.optimizers.SGD(0.5)
# 최적화를 위한 function을 정의합니다.
@tf.function
def train_step(model, x, y):
with tf.GradientTape() as tape:
y_pred = model(x)
loss = cross_entropy_loss(y_pred, y)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
# 모델의 정확도를 출력하는 함수를 정의합니다.
@tf.function
def compute_accuracy(y_pred, y):
correct_prediction = tf.equal(tf.argmax(y_pred,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
return accuracy
그 이후에는 손실함수,옵티마이저, 최적화함수, 정확도를 출력하는 함수를 정의해준다.
또한 cross-entropy 손실함수같은 경우 자주쓰이기 때문에 tensorflow 자체에서 지원해주는것도 알아두면 좋을 것 같다.
저번글에서와 똑같이 train_step함수를 만들어서 최적화를 해주는것을 알 수 있다.
apply_gradients가 구현되는 시점이 실제로 gradients가 한번씩 동작하는 부분이라고 생각하는것이 좋을 것 같다.
해당 부분역시 이해가 잘 안되더라도 방식을 눈에 익어둔다면 코드를 동작하는데는 지장이 없을 것이다.
모델의 정확도를 출력하는 compute_accuracy는 예측값과 정답값을 넣어서 정확도를 출력할 수 있는 함수이다.
# SoftmaxRegression 모델을 선언합니다.
SoftmaxRegression_model = SoftmaxRegression()
# 1000번 반복을 수행하면서 최적화를 수행합니다.
for i in range(1000):
batch_xs, batch_ys = next(train_data_iter)
train_step(SoftmaxRegression_model, batch_xs, batch_ys)
# 학습이 끝나면 학습된 모델의 정확도를 출력합니다.
print("정확도(Accuracy): %f" % compute_accuracy(SoftmaxRegression_model(x_test), y_test)) # 정확도 : 약 91%
'Python > 인공지능' 카테고리의 다른 글
06_CNN ILSVRC,CNN모델들 (0) | 2022.03.18 |
---|---|
05_CNN 기초 (0) | 2022.03.18 |
04_오토인코더 (0) | 2022.03.18 |
03_다중 퍼셉트론 MLP,인공신경망 (0) | 2022.03.18 |
01_ 선형회귀 알고리즘 구현 (0) | 2022.03.13 |