Python/인공지능

02_ Softmax Regression을 활용한 MNIST숫자분류기 구현

728x90

( 해당 글은 인프런 강의를 정리한 내용입니다 )

 

이번엔 Softmax Regression을 활용한 MNIST숫자분류기 구현을 해보겠다.

 

https://github.com/solaris33/deep-learning-tensorflow-book-code/blob/master/Ch04-Machine_Learning_Basic/mnist_classification_using_softmax_regression_v2_keras.py

 

GitHub - solaris33/deep-learning-tensorflow-book-code: [『텐서플로로 배우는 딥러닝』, 솔라리스, 영진닷컴, 2

[『텐서플로로 배우는 딥러닝』, 솔라리스, 영진닷컴, 2018] 도서의 소스코드입니다. Contribute to solaris33/deep-learning-tensorflow-book-code development by creating an account on GitHub.

github.com

 

 

역시 간단히 정리하면서 알아보자

 

# -*- 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

 

tf.keras.layers.Dense  |  TensorFlow Core v2.8.0

Just your regular densely-connected NN layer.

www.tensorflow.org

 

역시 페이지에 설명이 잘 되어 있다

 

생성자에 케라스 하위 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%

 

728x90

'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