Commit 1c65b326 authored by Gabriel Kirsten's avatar Gabriel Kirsten
Browse files

Commit parcial das funcionalidades de classificação com keras
parent 8bba4c04
......@@ -13,9 +13,12 @@ except:
try:
from .cnn_keras import CNNKeras
except:
except Exception as e:
CNNKeras = None
print e.message
__all__ = ["cnn_caffe",
"cnn_keras",
"classifier",
"weka_classifiers"]
......@@ -38,4 +41,5 @@ def get_classifier_config():
def set_classifier_config(configs):
_classifier_list["cnn_caffe"] = Config.nvl_config(configs["cnn_caffe"], _classifier_list["cnn_caffe"])
_classifier_list["weka_classifiers"] = Config.nvl_config(configs["weka_classifiers"], _classifier_list["weka_classifiers"])
_classifier_list["cnn_keras"] = Config.nvl_config(configs["cnn_keras"], _classifier_list["cnn_keras"])
_classifier_list["weka_classifiers"] = Config.nvl_config(configs["weka_classifiers"], _classifier_list["weka_classifiers"])
\ No newline at end of file
......@@ -78,7 +78,12 @@ class Classifier(object):
"""Return if classifier must be trained.
"""
return False
def must_extract_features(self):
"""Return if classifier must be extracted features.
"""
return True
def train(self, dataset, training_data, force = False):
"""Perform the training of classifier.
"""
......
......@@ -4,6 +4,7 @@
"""
Generic classifier with multiple models
Models -> (Xception, VGG16, VGG19, ResNet50, InceptionV3, MobileNet)
Name: cnn_keras.py
Author: Gabriel Kirsten Menezes (gabriel.kirsten@hotmail.com)
......@@ -11,13 +12,14 @@
import time
import os
import numpy as np
from PIL import Image
from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Model
from keras.layers import Dropout, Flatten, Dense
from keras.callbacks import ModelCheckpoint
from sklearn.metrics import confusion_matrix
from classifier import Classifier
......@@ -35,16 +37,25 @@ START_TIME = time.time()
# =========================================================
IMG_WIDTH, IMG_HEIGHT = 256, 256
TRAIN_DATA_DIR = "../data/train"
VALIDATION_DATA_DIR = "../data/validation"
BATCH_SIZE = 16
EPOCHS = 50
EPOCHS = 1
CLASS_NAMES = ['ferrugemAsiatica', 'folhaSaudavel',
'fundo', 'manchaAlvo', 'mildio', 'oidio']
class CNNKeras(Classifier):
""" Class for CNN classifiers based on Keras applications """
def __init__(self, architecture = "VGG16", fine_tuning_rate = 100):
"""
Constructor of CNNKeras
"""
self.architecture = Config("architecture", architecture, str)
self.fine_tuning_rate = Config("fineTuningRate", fine_tuning_rate, int)
self.file_name = "kerasCNN"
def __init__(self):
model = applications.VGG16(
weights="imagenet", include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))
......@@ -60,92 +71,184 @@ class CNNKeras(Classifier):
predictions = Dense(6, activation="softmax")(new_custom_layers)
# creating the final model
model_final = Model(inputs=model.input, outputs=predictions)
self.model = Model(inputs=model.input, outputs=predictions)
# compile the model
model_final.compile(loss="categorical_crossentropy",
optimizer=optimizers.SGD(lr=0.0001, momentum=0.9),
metrics=["accuracy"])
self.model.compile(loss="categorical_crossentropy",
optimizer=optimizers.SGD(lr=0.0001, momentum=0.9),
metrics=["accuracy"])
def get_config(self):
"""Return configuration of classifier.
Returns
-------
config : OrderedDict
Current configs of classifier.
"""
pass
keras_config = OrderedDict()
keras_config["architecture"] = self.architecture
keras_config["fine_tuning_rate"] = self.fine_tuning_rate
return keras_config
def set_config(self, configs):
"""Update configuration of classifier.
Parameters
----------
configs : OrderedDict
New configs of classifier.
"""
pass
keras_config = OrderedDict()
keras_config["architecture"] = Config.nvl_config(
configs["architecture"], self.architecture)
keras_config["fine_tuning_rate"] = Config.nvl_config(
configs["fine_tuning_rate"], self.fine_tuning_rate)
def get_summary_config(self):
"""Return fomatted summary of configuration.
Returns
-------
summary : string
Formatted string with summary of configuration.
"""
pass
keras_config = OrderedDict()
keras_config[self.architecture.label] = self.architecture.value
keras_config[self.fine_tuning_rate.label] = self.fine_tuning_rate.value
summary = ''
for config in keras_config:
summary += "%s: %s\n" % (config, str(keras_config[config]))
return summary
def classify(self, dataset, test_dir, test_data):
pass
""""Perform the classification.
def train(self, model_final):
# Initiate the train and test generators with data Augumentation
train_datagen = ImageDataGenerator(
rescale=1. / 255,
horizontal_flip=True,
fill_mode="nearest",
zoom_range=0.3,
width_shift_range=0.3,
height_shift_range=0.3,
rotation_range=30)
Parameters
----------
dataset : string
Path to image dataset.
test_dir : string
Not used.
test_data : string
Name of test data file.
train_generator = train_datagen.flow_from_directory(
TRAIN_DATA_DIR,
Returns
-------
summary : list of string
List of predicted classes for each instance in test data in ordered way.
"""
predict_directory = File.make_path(dataset, test_dir)
for root, dirs, files in os.walk(predict_directory, topdown=False):
for name in files:
print(os.path.join(root, name))
if os.path.splitext(os.path.join(root, name))[1].lower() == ".tif":
if os.path.isfile(os.path.splitext(os.path.join(root, name))[0] + ".png"):
print "A jpeg file already exists for %s" % name
# If a jpeg is *NOT* present, create one from the tiff.
else:
outfile = os.path.splitext(
os.path.join(root, name))[0] + ".png"
try:
im = Image.open(os.path.join(root, name))
print "Generating jpeg for %s" % name
im.thumbnail(im.size)
im.save(outfile, "PNG", quality=100)
except Exception, e:
print e
classify_datagen = ImageDataGenerator()
classify_generator = classify_datagen.flow_from_directory(
predict_directory,
target_size=(IMG_HEIGHT, IMG_WIDTH),
batch_size=BATCH_SIZE,
shuffle=True,
class_mode="categorical")
shuffle=False,
class_mode=None)
output_classification = self.model.predict_generator(
classify_generator, classify_generator.samples, verbose=1)
one_hot_output = np.argmax(output_classification, axis=1)
for index in range(0, len(one_hot_output)):
one_hot_output[index] = CLASS_NAMES[one_hot_output[index]]
return one_hot_output
def train(self, dataset, training_data, force=False):
"""Perform the training of classifier.
Parameters
----------
dataset : string
Path to image dataset.
training_data : string
Name of ARFF training file.
force : boolean, optional, default = False
If False don't perform new training if there is trained data.
"""
test_datagen = ImageDataGenerator(
rescale=1. / 255,
horizontal_flip=True,
fill_mode="nearest",
zoom_range=0.3,
width_shift_range=0.3,
height_shift_range=0.3,
rotation_range=30)
validation_generator = test_datagen.flow_from_directory(
VALIDATION_DATA_DIR,
train_datagen = ImageDataGenerator()
train_generator = train_datagen.flow_from_directory(
dataset,
target_size=(IMG_HEIGHT, IMG_WIDTH),
batch_size=BATCH_SIZE,
shuffle=True,
class_mode="categorical")
# test_datagen = ImageDataGenerator(
# rescale=1. / 255,
# horizontal_flip=True,
# fill_mode="nearest",
# zoom_range=0.3,
# width_shift_range=0.3,
# height_shift_range=0.3,
# rotation_range=30)
# validation_generator = test_datagen.flow_from_directory(
# VALIDATION_DATA_DIR,
# target_size=(IMG_HEIGHT, IMG_WIDTH),
# batch_size=BATCH_SIZE,
# shuffle=True,
# class_mode="categorical")
# Save the model according to the conditions
checkpoint = ModelCheckpoint("../models_checkpoints/" + file_name + ".h5", monitor='val_acc',
verbose=1, save_best_only=True, save_weights_only=False,
mode='auto', period=1)
checkpoint = ModelCheckpoint("../models_checkpoints/" + self.file_name + ".h5", monitor='val_acc',
verbose=1, save_best_only=True, save_weights_only=False,
mode='auto', period=1)
# Train the model
model_final.fit_generator(
self.model.fit_generator(
train_generator,
steps_per_epoch=train_generator.samples // BATCH_SIZE,
epochs=EPOCHS,
callbacks=[checkpoint],
validation_data=validation_generator,
validation_steps=validation_generator.samples // BATCH_SIZE)
callbacks=[checkpoint])
def must_train(self):
"""Return if classifier must be trained.
Returns
-------
True
"""
return True
def must_extract_features(self):
"""Return if classifier must be extracted features.
Returns
-------
False
"""
return False
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