import numpy as np
import matplotlib.pyplot as plt
from termcolor import colored
import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Activation, Dropout
from tensorflow.keras.losses import SparseCategoricalCrossentropy
from tensorflow.keras.optimizers import Adam, SGD
from tensorflow.keras.metrics import Mean, SparseCategoricalAccuracy
# from utils.learning_env_setting import dir_setting, get_classification_matrics, save_metics_model, continue_setting
# data pre processing
def get_mnist_dataset_and_normalize(ratio, n_batch_train, n_batch_test):
def normalization(images, labels):
images = tf.cast(images, tf.float32)/255
labels = tf.cast(labels, tf.int32)
return images, labels
(train_validation_ds, test_ds), ds_info = tfds.load(name='mnist', as_supervised = True, shuffle_files = True,
with_info = True, split = ['train', 'test'])
n_train_validation = ds_info.splits['train'].num_examples
n_train = int(ratio * n_train_validation)
n_validation = n_train_validation - n_train
train_ds = train_validation_ds.take(n_train)
validation_ds = train_validation_ds.skip(n_train)
train_ds = train_ds.map(normalization).shuffle(n_train).batch(n_batch_train)
validation_ds = validation_ds.map(normalization).batch(n_batch_train)
test_ds = test_ds.map(normalization).batch(n_batch_test)
return train_ds, validation_ds, test_ds
class CNN_Model(Model):
def __init__(self):
super(CNN_Model, self).__init__()
# feature extractor
self.conv1 = Conv2D(filters=8, kernel_size=5, padding='same', activation='relu')
self.conv1_maxpool = MaxPooling2D(pool_size=2, strides=2)
self.conv2 = Conv2D(filters=8, kernel_size=5, padding='same', activation='relu')
self.conv2_maxpool = MaxPooling2D(pool_size=2, strides=2)
# Classifier
self.flatten = Flatten()
self.dense1 = Dense(units=64, activation='relu')
self.dense1_dropout = Dropout(0.5)
self.dense2 = Dense(units=10, activation='softmax')
def call(self, x):
x = self.conv1(x)
x = self.conv1_maxpool(x)
x = self.conv2(x)
x = self.conv2_maxpool(x)
x = self.flatten(x)
x = self.dense1(x)
x = self.dense2(x)
return x
@tf.function
def trainer():
global model, loss_object, loss_train, acc_train, optimizer
for images, labels in train_ds:
with tf.GradientTape() as tape:
predictions = model(images)
loss = loss_object(labels, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
loss_train(loss)
acc_train(labels, predictions)
@tf.function
def validation():
global model, loss_object, loss_validation, acc_validation
for images, labels in validation_ds:
predictions = model(images)
loss = loss_object(labels, predictions)
loss_validation(loss)
acc_validation(labels, predictions)
@tf.function
def tester():
global model, loss_object, loss_test, acc_test
for images, labels in test_ds:
predictions = model(images)
loss = loss_object(labels, predictions)
loss_test(loss)
acc_test(labels, predictions)
EPOCHS = 10
n_batch_train = 32
n_batch_test = 128
ratio = 0.8
train_ds, validation_ds, test_ds = get_mnist_dataset_and_normalize(ratio, n_batch_train, n_batch_test)
model = CNN_Model()
model.compile(optimizer='adam',loss = 'sparse_categorical_crossentropy', metrics =['accuracy'])
history = model.fit(train_ds, validation_data=validation_ds, epochs=EPOCHS)
loss_object = SparseCategoricalCrossentropy()
loss_test = Mean()
acc_test = SparseCategoricalAccuracy()
def tester():
global model, loss_object, loss_test, acc_test
for images, labels in test_ds:
predictions = model(images)
loss = loss_object(labels, predictions)
loss_test(loss)
acc_test(labels, predictions)
tester()
print(colored('TEST','cyan','on_white'))
print("Test Loss : {:.4f} / Test Accuracy : {:.2f}".format(loss_test.result(), acc_test.result()*100))
model.save('MyModel')
model1 = tf.keras.models.load_model('MyModel')
def tester():
global model1, loss_object, loss_test, acc_test
for images, labels in test_ds:
predictions = model1(images)
loss = loss_object(labels, predictions)
loss_test(loss)
acc_test(labels, predictions)
tester()
print(colored('TEST','cyan','on_white'))
print("Test Loss : {:.4f} / Test Accuracy : {:.2f}".format(loss_test.result(), acc_test.result()*100))