<가설 정의>
1. MNIST 데이터를 불러와 학습하기 적합한 형태로 변형
import tensorflow as tf
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
load_data() 호출 시 MNIST 데이터를 numpy (int)array 형태로 반환해줌
x_train, y_train에는 약 60000개의 트레이닝 데이터, x_test, y_test에는 약 10000개의 테스트 데이터가 있음
x_train, x_test = x_train.astype('float32'), x_test.astype('float32')
x_train, x_test = x_train.reshape([-1, 784]), x_test.reshape([-1, 784])
x_train, x_test = x_train / 255., x_test / 255.
astype : 데이터 형변환
reshape(-1,~) : 여기서 -1은 매직넘버. 앞 차원에 알아서 맞춰줌. 기본 옵션이라고 생각
flattening : 2차원 데이터를 한 픽셀씩 펼쳐서 1차원 데이터로 변경하는 것. 28*28 -> 784
MNIST 데이터는 픽셀 하나당 0-255까지의 숫자값을 가지므로 ,이를 255로 나누면 0-1 사이로 normalize 됨
y_train, y_test = tf.one_hot(y_train, depth=10), tf.one_hot(y_test, depth=10)
정답 데이터가 int 형이므로 one-hot encoding 을 적용해준다.
( 1 → 1000000000, 2 → 0100000000, 3 → 0010000000 이런 형식)
2. 전체 데이터를 원하는 mini-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)
tf.data.Dataset : api. 미니배치 단위로 묶는 과정을 손쉽게 할 수 있도록 함
iter : iterator. 100개씩의 미니배치를 순차적으로 가리키게 됨
3. 소프트맥스 회귀 모델 정의
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)
tf.keras.Model : 상속받는 클래스
tf.keras.layers.Dense : Wx+b를 추상화 해놓은 api (input을 넣었을 때 output으로 바꿔주는 중간 다리)
→ 10 = units. 출력 값의 크기, activation = 활성화 함수, kernel_initializer = 가중치(W) 초기화 함수, bias_initializer = 편향(b) 초기화 함수
call : 클래스 호출 시 동작하는 함수
logits : softmax(Wx+b)가 적용된 10 dimension의 값이 담겨있음
<손실함수 정의>
@tf.function
def cross_entropy_loss(y_pred, y):
return tf.reduce_mean(-tf.reduce_sum(y * tf.math.log(y_pred), axis=[1]))
<최적화>
optimizer = tf.optimizers.SGD(0.5)
@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))
SGD : 옵티마이저 종류 중 하나
0.5 : learning rate
@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
argmax : 최대값을 갖는 성분의 인덱스를 반환
y_pred는 softmax 함수 결과 값이 들어있다. [0.01, 0.4, 0.7, 0.04, 0.2, 0.082, 0.03, 0.002, 0.3, 0.06]
하지만 정답값 y에는 [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] 과 같은 형식으로 들어있다.
따라서 y_pred에 argmax 함수를 취하여 최대값을 갖는 성분의 인덱스를 반환하여 비교시키는 작업이 필요하다
SoftmaxRegression_model = SoftmaxRegression()
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))
batch_xs : (100, 784) MNIST 데이터
batch_ys : 100 dimension의 원-핫 인코딩된 데이터
결과