!pip install comet-ml
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import logging
import absl.logging
logging.root.removeHandler(absl.logging._absl_handler)
absl.logging._warn_preinit_stderr = False
import tensorflow as tf
if tf.test.gpu_device_name():
print('Default GPU Device: {}'.format(tf.test.gpu_device_name()))
import sys
sys.path.append('..')
from caracteres.src.data.emnist_dataset import EMNIST
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from tqdm import tqdm
from collections import defaultdict
dataset = EMNIST()
(x_train, y_train), (x_test, y_test) = dataset.load_data()
print(dataset)
print('Training shape:', x_train.shape, y_train.shape)
print('Test shape:', x_test.shape, y_test.shape)
classes = dataset.mapping
# plot the images in the batch, along with the corresponding labels
fig = plt.figure(figsize=(25, 4))
rnd_ind = np.random.randint(low=0, high=len(x_train), size=20)
for idx, i in enumerate(rnd_ind):
ax = fig.add_subplot(2, int(20/2), idx+1, xticks=[], yticks=[])
ax.imshow(x_train[i], cmap='gray')
# print out the correct label for each image
ax.set_title(str(classes[np.where(y_train[i]==1)[0][0]]))
img = x_train[1]
fig = plt.figure(figsize = (12,12))
ax = fig.add_subplot(111)
ax.imshow(img, cmap='gray')
width, height = img.shape
thresh = img.max()/2.5
for x in range(width):
for y in range(height):
val = round(img[x][y],2) if img[x][y] !=0 else 0
ax.annotate(str(val), xy=(y,x),
horizontalalignment='center',
verticalalignment='center',
color='white' if img[x][y]<thresh else 'black')
def distribution(labels, classes):
lbl_dist = dict.fromkeys(value for key,value in classes.items())
lbl_dist = defaultdict(lambda:1)
for idx in tqdm(range(len(labels))):
lbl_dist[classes[np.where(labels[idx]==1)[0][0]]] += 1
return lbl_dist
distribution(y_train, classes)
distribution(y_test, classes)
from numpy.random import seed
seed(42)
tf.random.set_seed(42)
! python caracteres/src/training/train_model.py -b 2048 -n lenet -find_lr True
#without using cylic lr
! python caracteres/src/training/train_model.py -b 2048 -e 50 -n lenet
#1e-4 1e-3 with cyclic lr
! python caracteres/src/training/train_model.py -b 2048 -e 50 -n lenet
from keras.models import load_model
from src.networks.lenet import lenet
from src.networks.resnet import resnet
from src.networks.custom import customCNN
from sklearn.metrics import classification_report
classes = [value for value in dataset.mapping.values()]
batch_size = 2048
def test_generator(batch_size):
num_iters = int(np.ceil(x_test.shape[0] / batch_size))
while 1:
for i in range(num_iters):
tmp = x_test[i*batch_size:(i+1)*batch_size].astype('float32')
tmp /= 255.0
yield tmp, y_test[i*batch_size:(i+1)*batch_size]
def evaluate_model(weights_dir, network):
model = network(dataset.input_shape, dataset.output_shape)
model.load_weights(weights_dir)
num_iters = int(np.ceil(x_test.shape[0] / batch_size))
t_generator = test_generator(batch_size=batch_size)
# evaluate the network and show a classification report
print("[INFO] evaluating network...")
predictions = model.predict_generator(t_generator, steps=num_iters)
print(classification_report(y_test.argmax(axis=1),
predictions.argmax(axis=1),
target_names=classes))
return model
weights_lenet_dir = 'caracteres/models/Character_Model_EMNIST_lenet_weights.h5'
weights_resnet_dir = 'caracteres/models/Character_Model_EMNIST_resnet_weights.h5'
weights_custom_dir = 'caracteres/models/Character_Model_EMNIST_customCNN_weights.h5'
model_lenet = evaluate_model(weights_lenet_dir, lenet)
model_resnet = evaluate_model(weights_resnet_dir, resnet)
model_custom = evaluate_model(weights_custom_dir, customCNN)
# obtain one batch of test images
rnd_index = np.random.randint(low=0, high=len(x_test), size=32)
images, labels = x_test[rnd_index], y_test[rnd_index]
# get sample outputs
predict = model_lenet.predict_on_batch(images)
# convert output probabilities to predicted class
preds = np.argmax(predict, axis=1)
labels = np.argmax(labels, axis=1)
# plot the images in the batch, along with predicted and true labels
fig = plt.figure(figsize=(25, 4))
for idx in np.arange(32):
ax = fig.add_subplot(2, int(32/2), idx+1, xticks=[], yticks=[])
ax.imshow(images[idx].reshape((28, 28)), cmap='gray')
ax.set_title("{} ({})".format(str(classes[preds[idx]]), str(classes[labels[idx]])),
color=("green" if preds[idx]==labels[idx] else "red"))
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Input
from tensorflow.keras.models import Model, load_model
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
batch_size = 300
epochs = 4
es = EarlyStopping(monitor='val_loss', patience=3, verbose=1)
callbacks = [es]
num_classes = 62
input_shape = (28, 28, 3)
x_train = np.stack([x_train] * 3, axis=-1)
x_test = np.stack([x_test] * 3, axis=-1)
# split train dataset into train 98% and valid 2%
(x_train, x_valid, y_train, y_valid) = train_test_split(x_train, y_train, test_size=50,
random_state=42)
print ('[INFO] Training shape: ', x_train.shape, y_train.shape)
print ('[INFO] Validation shape: ', x_valid.shape, y_valid.shape)
print ('[INFO] Test shape: ', x_test.shape, y_test.shape)
dataset = dict({
'x_train' : x_train,
'y_train' : y_train,
'x_valid' : x_valid,
'y_valid' : y_valid,
'x_test' : x_test,
'y_test' : y_test
})
def train_generator(dataset, shuff_index, batch_size):
num_iters = int(np.ceil(dataset['x_train'].shape[0] / batch_size))
while 1:
for i in range(num_iters):
idx = shuff_index[i*batch_size:(i+1)*batch_size]
tmp = dataset['x_train'][idx].astype('float32')
tmp -= np.mean(dataset['x_train'], axis=0, keepdims=True)
tmp /= 255.0
yield tmp, dataset['y_train'][idx]
def valid_generator(dataset, batch_size):
num_iters = int(np.ceil(dataset['x_valid'].shape[0] / batch_size))
while 1:
for i in range(num_iters):
tmp = dataset['x_valid'][i*batch_size:(i+1)*batch_size].astype('float32')
tmp -= np.mean(dataset['x_train'], axis=0, keepdims=True)
tmp /= 255.0
yield tmp, dataset['y_valid'][i*batch_size:(i+1)*batch_size]
#get the batches from generator
shuff_index = np.random.permutation(dataset['x_train'].shape[0])
trn_generator = train_generator(dataset, shuff_index, batch_size=batch_size)
val_generator = valid_generator(dataset, batch_size=batch_size)
iters_train = int(np.ceil(dataset['x_train'].shape[0] / float(batch_size)))
iters_test = int(np.ceil(dataset['x_valid'].shape[0] / float(batch_size)))
print ('Number:', iters_train, iters_test)
input_tensor = Input(shape=input_shape)
base_model = ResNet50(weights='imagenet', include_top=False,
input_tensor=input_tensor)
#base_model = ResNet50V2(weights='imagenet', include_top=False)
#base_model = ResNeXt50(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D()(x)
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
# and a logistic layer with 62 classes
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)
model.summary()
# freeze all convolutional resnet layers
for layer in base_model.layers:
layer.trainable = False
model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['acc'])
#train the model using fit_generator
history = model.fit_generator(
generator=trn_generator,
steps_per_epoch=iters_train,
epochs=3,
callbacks=callbacks,
validation_data=val_generator,
validation_steps=iters_test,
use_multiprocessing=True,
shuffle=True
)
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()