![](output/images/real_world/1.png) | ![](output/images/real_world/19.png) | ![](output/images/real_world/62.png) | ![](output/images/real_world/40.png) | ![](output/images/real_world/15.png) | ![](output/images/real_world/5.png) |
![](output/images/real_world/3.png) | ![](output/images/real_world/33.png) | ![](output/images/real_world/60.png) | ![](output/images/real_world/11.png) | ![](output/images/real_world/55.png) | ![](output/images/real_world/51.png) |
|--- output
|--- core
| |--- __init__.py
| |--- lenet.py
|--- train_aps.py
|--- aug_train_aps.py
|--- test_lenet.py
the __init__.py file only import the LeNet class:
# import the necessary packages from lenet import LeNet, load_images, deshear, normalize_image
|--- images
| |--- train
| |--- test
| |--- real_world
lenet.py :
In [1]:
# import the necessary packages
from keras.models import Sequential
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Activation, Flatten, Dense
import os
import numpy as np
from skimage import io
class LeNet:
def __init__(self, input_shape, conv_1, pool_1, conv_2, pool_2, hidden,
classes):
self.model = Sequential()
# first set of CONV => RELU => POOL
self.model.add(Conv2D(*conv_1, padding='same', activation='relu',
data_format='channels_last',
input_shape=input_shape))
self.model.add(MaxPooling2D(pool_1[0], pool_1[1]))
# second set of CONV => RELU => POOL
self.model.add(Conv2D(*conv_2, padding='same', activation='relu',
data_format='channels_last'))
self.model.add(MaxPooling2D(pool_2[0], pool_2[1]))
# set of FC => RELU layers
self.model.add(Flatten())
self.model.add(Dense(hidden, activation='relu'))
# softmax classifier
self.model.add(Dense(classes, activation='softmax'))
def load_images(folder):
images = []
labels = []
for file in os.listdir(folder):
if file.endswith(".png"):
images.append(io.imread(folder + file, as_grey=True))
if file.find("einstein") > -1:
labels.append(1)
elif file.find("curie") > -1:
labels.append(2)
elif os.path.splitext(file)[0].isdigit():
labels.append(int(os.path.splitext(file)[0]))
else:
labels.append(0)
return images, labels
def deshear(filename):
image = io.imread(filename)
distortion = image.shape[1] - image.shape[0]
shear = tf.AffineTransform(shear=math.atan(distortion/image.shape[0]))
return tf.warp(image, shear)[:, distortion:]
def normalize_images(images):
for i in range(len(images)):
images[i] = images[i][0:100, 0:100]
images[i] = images[i]/np.amax(images[i])
return np.array(images)
In [1]:
# append the package folder to sys.path
import sys
sys.path.append("core")
# import the necessary packages
from core import LeNet, load_images, deshear, normalize_images
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
from keras.utils import np_utils
import numpy as np
# Loading image data sets and normalizing color scale
training_set, training_labels = load_images("output/images/train/")
test_set, test_labels = load_images("output/images/test/")
rw_set, rw_file_labels = load_images("output/images/real_world/")
training_set = normalize_images(training_set)
training_set = training_set[..., np.newaxis]
test_set = normalize_images(test_set)
test_set = test_set[..., np.newaxis]
rw_set = normalize_images(rw_set)
rw_set = rw_set[..., np.newaxis]
rw_set = np.array([x for (y, x) in sorted(zip(rw_file_labels, rw_set))])
# Getting labels for real world set from file
f = open('output/images/real_world/labels.txt', "r")
lines = f.readlines()
rw_labels = []
for x in lines:
rw_labels.append(int((x.split(' ')[1]).replace('\n', '')))
f.close()
# Augmenting basic data set to improve performance in real world set
datagen = ImageDataGenerator(rotation_range=10, shear_range=0.3,
zoom_range=0.2, width_shift_range=0.15,
height_shift_range=0.15, fill_mode='constant',
cval=1)
# Parameters for LeNet convolutional network
classes = 3 # number of classes to identify
hidden = 500 # number of nuerons in hidden layer
conv_1 = (20, (15, 15)) # (num of filters in first layer, filter size)
conv_2 = (50, (15, 15)) # (num of filters in second layer, filter size)
pool_1 = ((6, 6), (6, 6)) # (size of pool matrix, stride)
pool_2 = ((6, 6), (6, 6)) # (size of pool matrix, stride)
# Converting integer labels to categorical labels
training_labels = np_utils.to_categorical(training_labels, classes)
test_labels = np_utils.to_categorical(test_labels, classes)
rw_labels = np_utils.to_categorical(rw_labels, classes)
# Initialize the optimizer and model for training
print("[INFO] compiling model...")
aps = LeNet(training_set[1].shape, conv_1, pool_1, conv_2, pool_2, hidden,
classes)
aps.model.compile(loss='categorical_crossentropy', optimizer='adam',
metrics=["accuracy"])
# Training the CNN
print("[INFO] training...")
aps.model.fit_generator(datagen.flow(training_set, training_labels, batch_size=10),
steps_per_epoch=len(training_set), epochs=50, verbose=1)
# Testing aps model of both sets
print("[INFO] Test model in both sets...")
test_probs = aps.model.predict(test_set)
test_prediction = test_probs.argmax(axis=1)
rw_probs = aps.model.predict(rw_set)
rw_prediction = rw_probs.argmax(axis=1)
# show the accuracy on the testing set
print("[INFO] evaluating test set...")
(loss, accuracy) = aps.model.evaluate(test_set, test_labels, verbose=0)
print("[INFO] accuracy: {:.2f}%".format(accuracy * 100) +
" - loss: {:.2f}".format(loss))
# show the accuracy on the real world
print("[INFO] evaluating real world set...")
(loss, accuracy) = aps.model.evaluate(rw_set, rw_labels, verbose=0)
print("[INFO] accuracy: {:.2f}%".format(accuracy * 100) +
" - loss: {:.2f}".format(loss))
# Save weights trained
print("[INFO] dumping weights to file...")
aps.model.save_weights('output/aug_lenet_weights.hdf5', overwrite=True)
print("[INFO] Done!")
In [1]:
# append the package folder to sys.path
import sys
sys.path.append("core")
# import the necessary packages
from core import LeNet, load_images, deshear, normalize_images
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
from keras.utils import np_utils
import numpy as np
import cv2
# Loading image data sets and normalizing color scale
rw_set, rw_file_labels = load_images("output/images/real_world/")
rw_set = normalize_images(rw_set)
rw_set = rw_set[..., np.newaxis]
rw_set = np.array([x for (y, x) in sorted(zip(rw_file_labels, rw_set))])
# Getting labels for real world set from file
f = open('output/images/real_world/labels.txt', "r")
lines = f.readlines()
rw_labels = []
for x in lines:
rw_labels.append(int((x.split(' ')[1]).replace('\n', '')))
f.close()
# Parameters for LeNet convolutional network
classes = 3 # number of classes to identify
hidden = 500 # number of nuerons in hidden layer
conv_1 = (20, (15, 15)) # (num of filters in first layer, filter size)
conv_2 = (50, (15, 15)) # (num of filters in second layer, filter size)
pool_1 = ((6, 6), (6, 6)) # (size of pool matrix, stride)
pool_2 = ((6, 6), (6, 6)) # (size of pool matrix, stride)
# Converting integer labels to categorical labels
rw_labels = np_utils.to_categorical(rw_labels, classes)
# Initialize the optimizer and model for training
print("[INFO] compiling model...")
aps = LeNet(rw_set[1].shape, conv_1, pool_1, conv_2, pool_2, hidden,
classes)
aps.model.compile(loss='categorical_crossentropy', optimizer='adam',
metrics=["accuracy"])
aps.model.load_weights('output/aug_lenet_weights.hdf5')
# Testing aps model of both sets
print("[INFO] Test model in real world set...")
rw_probs = aps.model.predict(rw_set)
rw_prediction = rw_probs.argmax(axis=1)
# show the accuracy on the real world
print("[INFO] evaluating real world set...")
(loss, accuracy) = aps.model.evaluate(rw_set, rw_labels, verbose=0)
print("[INFO] accuracy: {:.2f}%".format(accuracy * 100) +
" - loss: {:.2f}".format(loss))
imlabel = ['any', 'einstein', 'curie']
for i in np.random.choice(np.arange(0, len(rw_labels)), size=(10,)):
print("[INFO] Predicted: {}, Actual: {}".format(rw_prediction[i],
np.argmax(rw_labels[i])))
image = (rw_set[i] * 255).astype("uint8")
image = cv2.merge([image] * 3)
cv2.putText(image, str(imlabel[rw_prediction[i]]), (5, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 255, 0), 2)
cv2.imshow("Digit", image)
cv2.waitKey(0)
In [ ]: