Classifying mnist by using Tensorflow's eager execution.
This guide uses these high-level TensorFlow concepts:
Enable an eager execution development environment,
Import data with the Datasets API
Build model class by inheriting tf.keras.Model
with TensorFlow's Keras API
Reference
from __future__ import absolute_import, division, print_function
import numpy as np
import tensorflow as tf
from tensorflow import keras
tf.enable_eager_execution()
print(tf.__version__)
1.12.0
SoftmaxClassifier
class and loss_fn
function¶class SoftmaxClassifier(keras.Model):
def __init__(self, num_classes):
super(SoftmaxClassifier, self).__init__()
self.__dense = tf.keras.layers.Dense(units = num_classes)
def call(self, inputs):
score = self.__dense(inputs)
return score
def loss_fn(model, x, y):
ce_loss = tf.losses.sparse_softmax_cross_entropy(labels = y, logits = model(x))
return ce_loss
model
instance¶model = SoftmaxClassifier(num_classes = 10)
(x_train, y_train), (x_tst, y_tst) = tf.keras.datasets.mnist.load_data()
x_train = (x_train / 255).astype(np.float32).reshape(-1, 784)
x_tst = (x_tst / 255).astype(np.float32).reshape(-1, 784)
tr_indices = np.random.choice(range(x_train.shape[0]), size = 55000, replace = False)
x_tr = x_train[tr_indices]
y_tr = y_train[tr_indices].astype(np.int32)
x_val = np.delete(arr = x_train, obj = tr_indices, axis = 0)
y_val = np.delete(arr = y_train, obj = tr_indices, axis = 0).astype(np.int32)
print(x_tr.shape, y_tr.shape)
print(x_val.shape, y_val.shape)
(55000, 784) (55000,) (5000, 784) (5000,)
epochs = 30
batch_size = 32
learning_rate = .01
tr_dataset = tf.data.Dataset.from_tensor_slices((x_tr, y_tr))
tr_dataset = tr_dataset.shuffle(buffer_size = 10000)
tr_dataset = tr_dataset.batch(batch_size = batch_size)
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(batch_size = batch_size)
opt = tf.train.AdamOptimizer(learning_rate = learning_rate)
for epoch in range(epochs):
avg_tr_loss = 0
avg_val_loss = 0
tr_step = 0
val_step = 0
# train
for x_mb, y_mb in tr_dataset:
with tf.GradientTape() as tape:
tr_loss = loss_fn(model = model, x = x_mb, y = y_mb)
grads = tape.gradient(target = tr_loss, sources = model.variables)
opt.apply_gradients(zip(grads, model.variables))
avg_tr_loss += tr_loss
tr_step += 1
else:
avg_tr_loss /= tr_step
# validation
for x_mb, y_mb in val_dataset:
val_loss = loss_fn(model = model, x = x_mb, y = y_mb)
avg_val_loss += val_loss
val_step += 1
else:
avg_val_loss /= val_step
if (epoch + 1) % 5 == 0:
print('epochs : {:2}, tr_loss : {:.3f}, val_loss : {:.3f}'.format(epoch + 1, avg_tr_loss, avg_val_loss))
epochs : 5, tr_loss : 0.321, val_loss : 0.372 epochs : 10, tr_loss : 0.316, val_loss : 0.390 epochs : 15, tr_loss : 0.309, val_loss : 0.430 epochs : 20, tr_loss : 0.307, val_loss : 0.445 epochs : 25, tr_loss : 0.302, val_loss : 0.433 epochs : 30, tr_loss : 0.303, val_loss : 0.453