Commit 298009a8 authored by Geazy Menezes's avatar Geazy Menezes

grafical confusion matrix(cnn support) and fix feature extraction selectors

parent 072d35cb
......@@ -26,6 +26,9 @@ from keras.models import Model, load_model
from keras.layers import Dropout, Flatten, Dense
from keras.callbacks import ModelCheckpoint, TensorBoard
from keras import backend as K
from numpy import resize, expand_dims
from keras.preprocessing.image import load_img, img_to_array
from interface.interface import InterfaceException as IException
from classification.classifier import Classifier
......@@ -35,7 +38,7 @@ from collections import OrderedDict
from util.config import Config
from util.file_utils import File
from util.utils import TimeUtils
logger = logging.getLogger('PIL')
logger.setLevel(logging.WARNING)
......@@ -49,6 +52,13 @@ START_TIME = time.time()
IMG_WIDTH, IMG_HEIGHT = 256, 256
weight_path = None
dict_preprocessing = {}
dict_preprocessing[0] = applications.xception.preprocess_input, applications.xception.decode_predictions
dict_preprocessing[1] = applications.vgg16.preprocess_input, applications.vgg16.decode_predictions
dict_preprocessing[2] = applications.vgg19.preprocess_input, applications.vgg19.decode_predictions
dict_preprocessing[3] = applications.resnet50.preprocess_input, applications.resnet50.decode_predictions
dict_preprocessing[4] = applications.inception_v3.preprocess_input, applications.inception_v3.decode_predictions
dict_preprocessing[5] = applications.mobilenet.preprocess_input, applications.mobilenet.decode_predictions
class CNNKeras(Classifier):
""" Class for CNN classifiers based on Keras applications """
......@@ -201,6 +211,7 @@ class CNNKeras(Classifier):
except Exception, e:
print e
else:
print File.make_path(predict_directory, file)
os.symlink(File.make_path(predict_directory, file),
File.make_path(predict_directory, 'png', file))
......@@ -208,7 +219,7 @@ class CNNKeras(Classifier):
classify_generator = classify_datagen.flow_from_directory(
File.make_path(predict_directory, 'png'),
target_size=(IMG_HEIGHT, IMG_WIDTH),
taet_size=(IMG_HEIGHT, IMG_WIDTH),
batch_size=1,
shuffle=False,
class_mode=None)
......@@ -333,21 +344,27 @@ class CNNKeras(Classifier):
def select_model_params(self, num_classes):
if self.fine_tuning_rate.value != -1:
if self.architecture.value == "Xception":
self.app = 0
model = applications.Xception(
weights="imagenet", include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "VGG16":
self.app = 1
model = applications.VGG16(
weights="imagenet", include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "VGG19":
self.app = 2
model = applications.VGG19(
weights="imagenet", include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "ResNet50":
self.app = 3
model = applications.ResNet50(
weights="imagenet", include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "InceptionV3":
self.app = 4
model = applications.InceptionV3(
weights="imagenet", include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "MobileNet":
self.app = 5
model = applications.MobileNet(
weights="imagenet", include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
......@@ -356,21 +373,27 @@ class CNNKeras(Classifier):
else: # without transfer learning
if self.architecture.value == "Xception":
self.app = 0
model = applications.Xception(
weights=None, include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "VGG16":
self.app = 1
model = applications.VGG16(
weights=None, include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "VGG19":
self.app = 2
model = applications.VGG19(
weights=None, include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "ResNet50":
self.app = 3
model = applications.ResNet50(
weights=None, include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "InceptionV3":
self.app = 4
model = applications.InceptionV3(
weights=None, include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
elif self.architecture.value == "MobileNet":
self.app = 5
model = applications.MobileNet(
weights=None, include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
for layer in model.layers:
......@@ -456,6 +479,9 @@ class CNNKeras(Classifier):
img.save(File.make_path(dir_class_train,
new_file), "PNG", quality=100)
else:
print 100*'-'
print File.make_path(root, file)
print 100*'-'
os.symlink(File.make_path(root, file),
File.make_path(dir_class_train, file))
......@@ -524,7 +550,12 @@ class CNNKeras(Classifier):
return train_generator, validation_generator, test_generator
def single_classify(self, image_path, directory, extractors, dict_classes):
from matplotlib.pylab import imread
image = imread(image_path)
predict = self.model.predict([image])[0]
return dict_classes[predict]
\ No newline at end of file
preprocess_input, decode_predictions = dict_preprocessing[self.app]
pil_image = load_img(image_path)
np_image = img_to_array(pil_image)
res_image = resize(np_image, (IMG_HEIGHT, IMG_WIDTH, 3))
tensor = expand_dims(res_image, axis=0)
tensor = preprocess_input(tensor)
predict = self.model.predict(tensor)
predict = np.argmax(predict, axis=1)
return dict_classes[predict[0]]
......@@ -13,7 +13,7 @@ __all__ = ["extractor",
"hog",
"image_moments",
"lbp",
"gabor"]
"gabor"]
from collections import OrderedDict
......@@ -24,11 +24,10 @@ _extractor_list = OrderedDict( [
["color_summarizer", Config("Color Statistics", True, bool, meta=ColorStats)],
["glcm", Config("Gray-Level Co-Occurrence Matrix", True, bool, meta=GLCM)],
["hog", Config("Histogram of Oriented Gradients", True, bool, meta=HOG)],
["hu_moments", Config("Hu Image Moments", False, bool, meta=HuMoments)],
["rc_moments", Config("Image Moments (Raw/Central)", False, bool, meta=RawCentralMoments)],
["hu_moments", Config("Hu Image Moments", True, bool, meta=HuMoments)],
["rc_moments", Config("Image Moments (Raw/Central)", True, bool, meta=RawCentralMoments)],
["lbp", Config("Local Binary Patterns", True, bool, meta=LBP)],
["gabor", Config("Gabor Filter Bank", True, bool, meta=GABOR)]
] )
def get_extractor_config():
......
......@@ -416,10 +416,10 @@ class Act(object):
self.extractors = [new_config[extractor].meta for extractor in new_config
if new_config[extractor].value == True ]
if len(self.extractors) == 0:
raise IException("Please select at least one extractor")
self.tk.append_log("\nConfig updated:\n%s",
'\n'.join(["%s: %s" % (new_config[extractor].label, "on" if new_config[extractor].value==True else "off")
for extractor in new_config]))
......@@ -945,44 +945,52 @@ class Act(object):
def run_grafic_confusion_matrix(self):
'''
Generate a a graphical confusion matrix where images are classified and according to classification go to the wrong or right folder.
Just Available to WekaClassifier and CNNKeras.
'''
from classification import WekaClassifiers
if not isinstance(self.classifier, WekaClassifiers):
message='Only available to Weka Classifiers.'
IException(message)
from classification import WekaClassifiers, CNNKeras
is_weka = isinstance(self.classifier, WekaClassifiers)
is_keras = isinstance(self.classifier, CNNKeras)
if not (is_weka or is_keras):
message='Only available to Weka and CNN Keras classifiers.'
raise IException(message)
if not self.has_trained:
message='Dataset Must Be Trained.'
IException(message)
raise IException(message)
from os.path import abspath
from os.path import abspath, isdir
directory = self.tk.utils.ask_directory()
if not directory:
message = 'No directory selected.'
IException(message)
folder = self.tk.utils.ask_directory()
if not folder:
message = 'No selected directory.'
raise IException(message)
return
directory = abspath(directory)
folder = abspath(folder)
dataset = abspath(self.dataset)
if directory == self.dataset:
if folder == self.dataset:
title = 'Same Dataset'
message = 'The dataset selected is the same of the trained. Are you sure that is right?'
option=self.tk.ask_ok_cancel(title, message)
if not option:
return
from os import listdir, mkdir
listdirs=listdir(folder)
size_dirs = reduce(lambda a,b: a+b, [0]+[len(listdir(folder+'/'+d)) for d in listdirs if isdir(folder+'/'+d)])
if not size_dirs:
message = 'Dataset has no content or the subfolder has no content.'
raise IException(message)
from shutil import rmtree
from os import mkdir, listdir
from os.path import isdir
from os import symlink
def create_folder_struct(matrix_path, class_names, human, computer):
try:
rmtree(matrix_path)
except Exception as e:
print str(e)
pass
mkdir(matrix_path, 0777)
for class_ in class_names:
......@@ -991,13 +999,15 @@ class Act(object):
for _class in class_names:
mkdir(real+computer+_class, 0777)
index=directory[-2::-1].index('/')
matrix_path=directory[:-(index+1)]+'folder_confusion_matrix'
class_names, classes=listdir(directory), {}
header_output = 'Starting Graphical Confusion Matrix\n\n'
index=folder[-2::-1].index('/')
matrix_path=folder[:-(index+1)]+'folder_confusion_matrix'
class_names, classes=listdir(folder), {}
for i in range(len(class_names)-1,-1,-1):
if isdir(dataset+'/'+class_names[i]):
if class_names[i][0] is not '.':
if class_names[i][0] != '.':
continue
del class_names[i]
for i, name in enumerate(class_names):
......@@ -1005,21 +1015,27 @@ class Act(object):
images=[]
for classe in class_names:
image_names=listdir(directory+'/'+classe)
image_names=listdir(folder+'/'+classe)
for i in range(len(image_names)):
image_names[i]=directory+'/',classe ,'/'+image_names[i]
image_names[i]=folder+'/',classe ,'/'+image_names[i]
images.extend(image_names)
human, computer = '/human_', '/computer_'
create_folder_struct(matrix_path, class_names, human, computer)
for image_path in images:
original=reduce(lambda a,b:a+b, image_path)
header_output_middle = header_output + 'Dataset selected: ' + folder + '\n\n'
self.tk.write_log(header_output_middle + 'Initializing...')
total = str(len(images))
for i, image_path in enumerate(images):
original_name=reduce(lambda a,b:a+b, image_path)
real_class_path=matrix_path+human+image_path[1]
predicted=self.classifier.single_classify(original, directory, self.extractors, classes)
predicted=self.classifier.single_classify(original_name, folder, self.extractors, classes)
message = header_output_middle + str(i + 1) + ' of ' + total + ' images classifield.'
self.tk.write_log(message)
predicted_class_path = real_class_path+computer+predicted
name_predicted=predicted_class_path+image_path[2]
symlink(original, name_predicted)
predicted_name=predicted_class_path+image_path[2]
symlink(original_name, predicted_name)
message = 'Graphical Confusion Matrix saved in '+matrix_path
self.tk.append_log(message)
message = header_output + 'Saved in ' + matrix_path
self.tk.write_log(message)
......@@ -374,9 +374,9 @@ class BooleanUtils(object):
@staticmethod
def str_to_bool(s):
if s == 'True':
if s == 'True' or s == 1:
return True
elif s == 'False':
elif s == 'False' or s == 0:
return False
else:
raise ValueError
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment