Created
October 11, 2019 22:52
-
-
Save rabiulcste/ccca2a730a7dd34808300d9f9f8a9365 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: utf-8 | |
# In[1]: | |
# Importing necessary libraries | |
import numpy as np | |
import pandas as pd | |
import os | |
import glob | |
import cv2 | |
import matplotlib.pyplot as plt | |
import pickle | |
import keras | |
from keras.utils import to_categorical | |
from keras.layers import Dense, Activation, BatchNormalization, Input, Conv2D, Convolution2D, Flatten, Dropout | |
from keras.layers import ZeroPadding2D, MaxPooling2D, MaxPool2D, GlobalAveragePooling2D, AveragePooling2D | |
from keras.optimizers import RMSprop, Adam, Adadelta, SGD | |
from keras.models import Model | |
from keras.models import Sequential | |
from keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau | |
from keras import initializers, regularizers, constraints, optimizers, layers, callbacks | |
from keras import backend as K | |
from __future__ import print_function | |
get_ipython().run_line_magic('matplotlib', 'inline') | |
from sklearn.model_selection import train_test_split | |
from sklearn.metrics import confusion_matrix | |
# In[2]: | |
from keras.preprocessing.image import ImageDataGenerator | |
from keras.callbacks import LearningRateScheduler | |
# In[3]: | |
FS_AXIS_LABEL=14 | |
FS_TITLE=17 | |
FS_TICKS=12 | |
FIG_WIDTH=20 | |
ROW_HEIGHT=2 | |
RESIZE_DIM=160 # The images will be resized to 28x28 pixels | |
# In[4]: | |
data_dir=os.path.join('..','D:\BanglaLekha\BanglaLekha-Isolated\Images') | |
arr_train = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20'] | |
iterator_train = len(arr_train) | |
paths_train_all=[] | |
for i in range(iterator_train): | |
#print (arr_train[i]) | |
dirx= arr_train[i] | |
paths_train_x=glob.glob(os.path.join(data_dir,dirx,'*.png')) | |
paths_train_all=paths_train_all+paths_train_x | |
# In[5]: | |
len(paths_train_all) | |
# In[6]: | |
def get_img(path,mode=cv2.IMREAD_GRAYSCALE): | |
# get image data | |
img=cv2.imread(path) | |
# opencv stores color images in BGR format by default, so transforming to RGB colorspace | |
if len(img.shape)>2: | |
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) | |
if img is not None: | |
return img | |
else: | |
raise FileNotFoundError('Image does not exist at {}'.format(path)) | |
def imshow_group(paths,n_per_row=10): | |
# plot multiple digits in one figure, by default 10 images are plotted per row | |
n_sample=len(paths) | |
j=np.ceil(n_sample/n_per_row) | |
fig=plt.figure(figsize=(FIG_WIDTH,ROW_HEIGHT*j)) | |
for i, path in enumerate(paths): | |
img=get_img(path) | |
plt.subplot(j,n_per_row,i+1) | |
if len(img.shape)<3: # if grayscale | |
plt.imshow(img,cmap='gray') | |
else: | |
plt.imshow(img) | |
plt.axis('off') | |
return fig | |
# In[7]: | |
#We are going to randomly choose a few image filepaths from training set aand plot them. | |
paths=np.random.choice(paths_train_all,size=50) | |
fig=imshow_group(paths) | |
fig.suptitle('Samples from {} training images in dataset all'.format(len(paths_train_all)), fontsize=16) | |
plt.show() | |
# In[8]: | |
def get_key(path): | |
# seperates the key of an image from the filepath | |
key=path.split(sep=os.sep)[-1] | |
return key | |
def get_data(paths_img,path_label=None,resize_dim=None): | |
'''reads images from the filepaths, resizes them (if given), and returns them in a numpy array | |
Args: | |
paths_img: image filepaths | |
path_label: pass image label filepaths while processing training data, defaults to None while processing testing data | |
resize_dim: if given, the image is resized to resize_dim x resize_dim (optional) | |
Returns: | |
X: group of images | |
y: categorical true labels | |
''' | |
X=[] # initialize empty list for resized images | |
for i,path in enumerate(paths_img): | |
img=cv2.imread(path,cv2.IMREAD_GRAYSCALE) # images loaded in color (BGR) | |
#img = cv2.bilateralFilter(img,9,75,75) | |
#img = cv2.medianBlur(img,5) | |
#img = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21) | |
#img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # cnahging colorspace to GRAY | |
if resize_dim is not None: | |
img=cv2.resize(img,(resize_dim,resize_dim),interpolation=cv2.INTER_AREA) # resize image to 28x28 | |
#X.append(np.expand_dims(img,axis=2)) # expand image to 28x28x1 and append to the list. | |
gaussian_3 = cv2.GaussianBlur(img, (9,9), 10.0) #unblur | |
img = cv2.addWeighted(img, 1.5, gaussian_3, -0.5, 0, img) | |
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]]) #filter | |
img = cv2.filter2D(img, -1, kernel) | |
#thresh = 200 | |
#maxValue = 255 | |
#th, img = cv2.threshold(img, thresh, maxValue, cv2.THRESH_BINARY); | |
ret,img = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) | |
X.append(img) # expand image to 28x28x1 and append to the list | |
# display progress | |
if i==len(paths_img)-1: | |
end='\n' | |
else: end='\r' | |
print('processed {}/{}'.format(i+1,len(paths_img)),end=end) | |
X=np.array(X) # tranform list to numpy array | |
if path_label is None: | |
return X | |
else: | |
y_label=[int(get_key(path).split('_')[-1][:-4])-1 for path in paths_img] # get the labels corresponding to the images | |
y=to_categorical(y_label,20) # transfrom integer value to categorical variable | |
return X, y | |
# In[9]: | |
X_train_all,y_train_all=get_data(paths_train_all,True,resize_dim=RESIZE_DIM) | |
# In[10]: | |
X_train_all.shape | |
# In[11]: | |
paths=np.random.choice(len(X_train_all),size=30) | |
fig=plt.figure(figsize=(FIG_WIDTH,ROW_HEIGHT*3)) | |
for i in range(len(paths)): | |
n_sample=len(paths) | |
n_per_row=10 | |
j=np.ceil(n_sample/n_per_row) | |
plt.subplot(j,n_per_row,i+1) | |
plt.imshow(X_train_all[paths[i]], cmap=plt.get_cmap('gray')) | |
#plt.axis('off') | |
# In[12]: | |
X_train_all = X_train_all.reshape(X_train_all.shape[0],160,160,1).astype('float32') | |
# In[13]: | |
X_train_all.shape | |
# In[14]: | |
X_train_all = X_train_all/255 | |
# In[15]: | |
indices=list(range(len(X_train_all))) | |
np.random.seed(42) | |
np.random.shuffle(indices) | |
ind=int(len(indices)*0.90) | |
# train data | |
X_train=X_train_all[indices[:ind]] | |
y_train=y_train_all[indices[:ind]] | |
# test data | |
X_test=X_train_all[indices[-(len(indices)-ind):]] | |
y_test=y_train_all[indices[-(len(indices)-ind):]] | |
# In[16]: | |
#plot some images and labels | |
plt.figure(figsize=(15,9)) | |
label = np.argmax(y_train[:50], axis=1) | |
for i in range(50): | |
plt.subplot(5,10,1+i) | |
plt.title(label[i]) | |
plt.imshow(X_train[i].reshape(160,160), cmap='gray') | |
# In[17]: | |
# Split the train and the validation set for the fitting | |
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size = 0.05, random_state=42) | |
# In[18]: | |
model= Sequential() | |
model.add(ZeroPadding2D((3, 3), input_shape = (160,160,1))) | |
model.add(Conv2D(filters = 32, kernel_size = (5,5), strides=(2,2), | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
model.add(MaxPool2D(pool_size=(3,3), strides=(2,2))) | |
#model.add(Dropout(0.2)) | |
model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2))) | |
#model.add(Dropout(0.2)) | |
model.add(Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same', | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
model.add(Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same', | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2))) | |
model.add(Conv2D(filters = 256, kernel_size = (3,3),padding = 'Same', | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
model.add(Conv2D(filters = 256, kernel_size = (3,3),padding = 'Same', | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
#model.add(Dropout(0.2)) | |
model.add(Conv2D(filters = 256, kernel_size = (1,1), | |
activation ='relu')) | |
model.add(BatchNormalization()) | |
model.add(AveragePooling2D(pool_size=(5,5))) | |
model.add(Flatten()) | |
model.add(Dense(20, activation = "softmax")) | |
# In[19]: | |
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True) | |
model.compile( | |
optimizer=sgd, | |
loss='categorical_crossentropy', | |
metrics=['accuracy']) | |
# In[20]: | |
model.summary() | |
# In[21]: | |
# With data augmentation to prevent overfitting (accuracy 0.99286) | |
datagen = ImageDataGenerator( | |
featurewise_center=False, # set input mean to 0 over the dataset | |
samplewise_center=False, # set each sample mean to 0 | |
featurewise_std_normalization=False, # divide inputs by std of the dataset | |
samplewise_std_normalization=False, # divide each input by its std | |
zca_whitening=False, # apply ZCA whitening | |
rotation_range=10, # randomly rotate images in the range (degrees, 0 to 180) | |
zoom_range = 0.1, # Randomly zoom image | |
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width) | |
height_shift_range=0.1, # randomly shift images vertically (fraction of total height) | |
shear_range=0.1, | |
horizontal_flip=False, # randomly flip images | |
vertical_flip=False, | |
fill_mode='nearest') # randomly flip images | |
datagen.fit(X_train) | |
# In[22]: | |
from keras.callbacks import ReduceLROnPlateau | |
lr_tuner = ReduceLROnPlateau(monitor='val_acc', | |
patience=3, | |
verbose=1, | |
factor=0.1, | |
min_lr=0.0001) | |
# In[23]: | |
batch_size = 128 | |
epochs = 15 | |
# In[24]: | |
#path_model='model_filter.h5' # save model at this location after each epoch | |
#K.tensorflow_backend.clear_session() # destroys the current graph and builds a new one | |
#model=get_model() # create the model | |
#K.set_value(model.optimizer.lr,1e-3) # set the learning rate | |
# fit the model | |
h=model.fit_generator(datagen.flow(X_train,y_train, batch_size=batch_size),epochs=epochs, | |
verbose=1,validation_data=(X_val,y_val),steps_per_epoch=X_train.shape[0] // batch_size, | |
shuffle=True, callbacks=[lr_tuner,]) | |
# In[25]: | |
print(h.history.keys()) | |
accuracy = h.history['acc'] | |
val_accuracy = h.history['val_acc'] | |
loss = h.history['loss'] | |
val_loss = h.history['val_loss'] | |
epochs = range(len(accuracy)) | |
plt.plot(epochs, accuracy, color='r', label='Training accuracy') | |
plt.plot(epochs, val_accuracy, color='b', label='Validation accuracy') | |
plt.title('Training and validation accuracy') | |
plt.legend() | |
plt.show() | |
plt.figure() | |
plt.plot(epochs, loss, color='r', label='Training loss') | |
plt.plot(epochs, val_loss, color='b', label='Validation loss') | |
plt.title('Training and validation loss') | |
plt.legend() | |
plt.show() | |
# In[26]: | |
score, acc = model.evaluate(X_test, y_test, batch_size=64) | |
print('Test score:', score) | |
print('Test accuracy:', acc) | |
# In[ ]: | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment