Commit 50d4bafd authored by Alessandro dos Santos Ferreira's avatar Alessandro dos Santos Ferreira
Browse files

Pynovisao - Adicionando CNN Caffe

parent 45b3da7a
......@@ -5,7 +5,13 @@ try:
except:
WekaClassifiers = None
__all__ = ["classifier",
try:
from .cnn_caffe import CNNCaffe
except:
CNNCaffe = None
__all__ = ["cnn_caffe",
"classifier",
"weka_classifiers"]
......@@ -14,6 +20,8 @@ from util.config import Config
_classifier_list = OrderedDict( [
["cnn_caffe", Config("Invalid" if CNNCaffe is None else CNNCaffe.__name__,
WekaClassifiers is None and CNNCaffe is not None, bool, meta=CNNCaffe, hidden=CNNCaffe is None)],
["weka_classifiers", Config("Invalid" if WekaClassifiers is None else WekaClassifiers.__name__,
WekaClassifiers is not None, bool, meta=WekaClassifiers, hidden=WekaClassifiers is None)]
] )
......@@ -22,4 +30,5 @@ def get_classifier_config():
return _classifier_list
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"])
......@@ -8,6 +8,8 @@
Author: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com )
"""
from interface.interface import InterfaceException as IException
from abc import ABCMeta, abstractmethod
class Classifier(object):
......@@ -51,15 +53,14 @@ class Classifier(object):
pass
@abstractmethod
def classify(self, dataset, test_data):
def classify(self, dataset, test_dir = None, test_data = None):
pass
def cross_validate(self, detail = True):
pass
raise IException("Method not available for this classifier")
def experimenter(self):
pass
raise IException("Method not available for this classifier")
@abstractmethod
def reset(self):
pass
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
"""
Runs ImageNet Convolutional Neural Network implemented in software Caffe.
This module only implements the classification. The network must be trained previously using caffe.
Krizhevsky, Alex, Ilya Sutskever, and Geoffrey E. Hinton, Imagenet classification with deep convolutional neural networks, Advances in neural information processing systems, 2012.
Jia, Yangqing and Shelhamer, Evan and Donahue, Jeff and Karayev, Sergey and Long, Jonathan and Girshick, Ross and Guadarrama, Sergio and Darrell, Trevor, Caffe: Convolutional Architecture for Fast Feature Embedding, arXiv preprint arXiv:1408.5093, 2014.
Name: cnn_caffe.py
Author: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com )
"""
# Make sure that caffe is on the python path:
caffe_root = '/var/tmp/caffe/'
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe
import cv2
import numpy as np
import os
from collections import OrderedDict
from util.config import Config
from util.file_utils import File
from util.utils import TimeUtils
from classifier import Classifier
class CNNCaffe(Classifier):
def __init__(self):
self._create_net()
def _create_net(self):
self.model_def = Config("ModelDef", caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt', str)
self.model_weights = Config("ModelWeights", caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel', str)
self.net = caffe.Net(self.model_def.value, # defines the structure of the model
self.model_weights.value, # contains the trained weights
caffe.TEST) # use test mode (e.g., don't perform dropout)
self.mean_image = Config("MeanImage", caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy', str)
# load the mean image for subtraction
mu = np.load(self.mean_image.value)
mu = mu.mean(1).mean(1) # average over pixels to obtain the mean (BGR) pixel values
# create transformer for the input called 'data'
self.transformer = caffe.io.Transformer({'data': self.net.blobs['data'].data.shape})
self.transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension
self.transformer.set_mean('data', mu) # subtract the dataset-mean value in each channel
self.transformer.set_raw_scale('data', 255) # rescale from [0, 1] to [0, 255]
self.transformer.set_channel_swap('data', (2,1,0)) # swap channels from RGB to BGR
self.labels_file = Config("LabelsFile", caffe_root + 'data/ilsvrc12/synset_words.txt', str)
def get_config(self):
caffe_config = OrderedDict()
caffe_config["model_def"] = self.model_def
caffe_config["model_weights"] = self.model_weights
caffe_config["mean_image"] = self.mean_image
caffe_config["labels_file"] = self.labels_file
return caffe_config
def set_config(self, configs):
self.model_def = Config.nvl_config(configs["model_def"], self.model_def)
self.model_weights = Config.nvl_config(configs["model_weights"], self.model_weights)
self.mean_image = Config.nvl_config(configs["mean_image"], self.mean_image)
self.labels_file = Config.nvl_config(configs["labels_file"], self.labels_file)
self._create_net()
def get_summary_config(self):
caffe_config = OrderedDict()
caffe_config[self.model_def.label] = self.model_def.value
caffe_config[self.model_weights.label] = self.model_weights.value
caffe_config[self.mean_image.label] = self.mean_image.value
caffe_config[self.labels_file.label] = self.labels_file.value
summary = ''
for config in caffe_config:
summary += "%s: %s\n" % (config, str(caffe_config[config]))
return summary
def classify(self, dataset, test_dir, test_data):
test_dir = File.make_path(dataset, test_dir)
classes = []
labels = np.loadtxt(self.labels_file.value, str)
images = sorted(os.listdir(File.make_path(test_dir)))
for image in images:
filepath = File.make_path(test_dir, image)
image = cv2.imread(filepath)
# resize the segment
resized_image = np.zeros((512, 512, image.shape[2]), dtype="uint8")
resized_image[0:image.shape[0], 0:image.shape[1]] = image[:,:]
resized_image = resized_image[0:256, 0:256]
cv2.imwrite(filepath.replace('.tif', '.jpeg'), resized_image)
# load the image
input_image = caffe.io.load_image(filepath)
transformed_image = self.transformer.preprocess('data', input_image)
# copy the image data into the memory allocated for the net
self.net.blobs['data'].data[...] = transformed_image
# perform classification
output = self.net.forward()
# the output probability vector for the first image in the batch
prediction = output['prob'][0]
print(["%0.4f" % pr for pr in prediction ])
classes.append(labels[prediction.argmax()])
return classes
......@@ -88,10 +88,10 @@ class WekaClassifiers(Classifier):
self.classifier.build_classifier(self.data)
def classify(self, dataset, test_data):
def classify(self, dataset, test_dir, test_data):
loader = WLoader(classname="weka.core.converters.ArffLoader")
test_file = File.make_path(dataset, test_data + ".arff")
test_file = File.make_path(dataset, test_data)
predict_data = loader.load_file(test_file)
predict_data.class_is_last()
......
......@@ -22,7 +22,7 @@ _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", True, bool, meta=HuMoments)],
["hu_moments", Config("Hu Image Moments", False, bool, meta=HuMoments)],
["rc_moments", Config("Image Moments (Raw/Central)", False, bool, meta=RawCentralMoments)],
["lbp", Config("Local Binary Patterns", True, bool, meta=LBP)]
] )
......
......@@ -385,7 +385,7 @@ class Act(object):
self.tk.append_log("Running classifier on test data... (%0.3f seconds)", (TimeUtils.get_time() - start_time))
labels = self.classifier.classify(self.dataset, "test")
labels = self.classifier.classify(self.dataset, test_dir=tmp, test_data="test.arff")
f.remove_dir(f.make_path(self.dataset, tmp))
self.tk.append_log("Painting segments... (%0.3f seconds)", (TimeUtils.get_time() - start_time))
......
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