Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
inovisao
pynovisao
Commits
3c86801e
Commit
3c86801e
authored
Jan 16, 2017
by
Alessandro dos Santos Ferreira
Browse files
Pynovisao - Documentando classifiers
parent
d4b928d1
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
220 additions
and
5 deletions
+220
-5
src/classification/classifier.py
src/classification/classifier.py
+42
-0
src/classification/cnn_caffe.py
src/classification/cnn_caffe.py
+65
-3
src/classification/weka_alias.py
src/classification/weka_alias.py
+25
-0
src/classification/weka_classifiers.py
src/classification/weka_classifiers.py
+86
-0
src/pynovisao.py
src/pynovisao.py
+2
-2
No files found.
src/classification/classifier.py
View file @
3c86801e
...
...
@@ -13,14 +13,33 @@ from interface.interface import InterfaceException as IException
from
abc
import
ABCMeta
,
abstractmethod
class
Classifier
(
object
):
"""Abstract class for classifiers algorithms."""
__metaclass__
=
ABCMeta
def
get_name
(
self
):
"""Return the name of class.
Returns
-------
name : string
Returns the name of instantiated class.
"""
return
self
.
__class__
.
__name__
@
staticmethod
def
confusion_matrix
(
labels
,
matrix
,
title
=
None
):
"""Return a formatted confusion matrix.
Returns
-------
labels : list of string
List of name of classes of confusion matrix.
matrix : list of list of int
Matrix of confusion.
title : string, optional, default = None
Title of confusion matrix.
"""
title
=
"Confusion Matrix"
if
title
is
None
else
"Confusion Matrix "
+
title
info
=
"=== "
+
title
+
" ===
\n
"
...
...
@@ -36,31 +55,54 @@ class Classifier(object):
@
abstractmethod
def
get_config
(
self
):
"""Return configuration of classifier.
Implement this method to extend this class with a new classifier algorithm.
"""
pass
@
abstractmethod
def
set_config
(
self
,
configs
):
"""Update configuration of classifier.
Implement this method to extend this class with a new classifier algorithm.
"""
pass
@
abstractmethod
def
get_summary_config
(
self
):
"""Return fomatted summary of configuration.
Implement this method to extend this class with a new classifier algorithm.
"""
pass
def
must_train
(
self
):
"""Return if classifier must be trained.
"""
return
False
def
train
(
self
,
dataset
,
training_data
,
force
=
False
):
"""Perform the training of classifier.
"""
pass
@
abstractmethod
def
classify
(
self
,
dataset
,
test_dir
=
None
,
test_data
=
None
):
"""Perform the classification.
Implement this method to extend this class with a new classifier algorithm.
"""
pass
def
cross_validate
(
self
,
detail
=
True
):
"""Perform cross validation using trained data.
"""
raise
IException
(
"Method not available for this classifier"
)
def
experimenter
(
self
):
"""Perform a test using all classifiers available.
"""
raise
IException
(
"Method not available for this classifier"
)
def
reset
(
self
):
"""Clean all data of classification.
Implement this method to extend this class with a new classifier algorithm.
"""
pass
src/classification/cnn_caffe.py
View file @
3c86801e
...
...
@@ -32,11 +32,18 @@ from classifier import Classifier
class
CNNCaffe
(
Classifier
):
CREATE_LMDB
=
False
# I tried to use the default python interface to perform the classification as explained at here:
# http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb
# But for some unknown reason it didn't work as expected, it generated poor results.
# I kept the implementation anyway, to use must be set CREATE_LMDB = False.
# Otherwise it will used another approach that generates optimal results.
CREATE_LMDB
=
True
def
__init__
(
self
):
"""Constructor.
"""
self
.
model_def
=
Config
(
"ModelDef"
,
'../examples/deploy.prototxt'
,
str
)
self
.
model_weights
=
Config
(
"ModelWeights"
,
'../examples/caffenet_train_iter_
75
00.caffemodel'
,
str
)
self
.
model_weights
=
Config
(
"ModelWeights"
,
'../examples/caffenet_train_iter_
150
00.caffemodel'
,
str
)
self
.
mean_image
=
Config
(
"MeanImage"
,
'../examples/imagenet_mean.binaryproto'
,
str
)
self
.
labels_file
=
Config
(
"LabelsFile"
,
'../examples/labels.txt'
,
str
)
...
...
@@ -56,6 +63,13 @@ class CNNCaffe(Classifier):
def
get_config
(
self
):
"""Return configuration of classifier.
Returns
-------
config : OrderedDict
Current configs of classifier.
"""
caffe_config
=
OrderedDict
()
caffe_config
[
"model_def"
]
=
self
.
model_def
...
...
@@ -66,6 +80,13 @@ class CNNCaffe(Classifier):
return
caffe_config
def
set_config
(
self
,
configs
):
"""Update configuration of classifier.
Parameters
----------
configs : OrderedDict
New configs of classifier.
"""
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
)
...
...
@@ -74,6 +95,13 @@ class CNNCaffe(Classifier):
self
.
_create_net
()
def
get_summary_config
(
self
):
"""Return fomatted summary of configuration.
Returns
-------
summary : string
Formatted string with summary of configuration.
"""
caffe_config
=
OrderedDict
()
caffe_config
[
self
.
model_def
.
label
]
=
self
.
model_def
.
value
...
...
@@ -89,6 +117,23 @@ class CNNCaffe(Classifier):
def
classify
(
self
,
dataset
,
test_dir
,
test_data
):
"""Perform the classification.
Parameters
----------
dataset : string
Path to image dataset.
test_dir : string
Name of test data directory.
test_data : string
Not used.
Returns
-------
summary : list of string
List of predicted classes for each instance in test data in ordered way.
"""
# if CNNCaffe.CREATE_LMDB = True use the alternative approach.
if
CNNCaffe
.
CREATE_LMDB
:
return
self
.
_classify_lmdb
(
dataset
,
test_dir
,
test_data
)
...
...
@@ -135,16 +180,33 @@ class CNNCaffe(Classifier):
# perform classification
output
=
self
.
net
.
forward
()
# the output probability vector for the
first
image in the batch
# the output probability vector for the
each
image in the batch
prediction
=
output
[
'prob'
][
0
]
print
([
"%0.4f"
%
pr
for
pr
in
prediction
])
# append the class with max probability.
classes
.
append
(
labels
[
prediction
.
argmax
()])
return
classes
def
_classify_lmdb
(
self
,
dataset
,
test_dir
,
test_data
):
"""Perform the alternative classification creating LMDB backend.
Parameters
----------
dataset : string
Path to image dataset.
test_dir : string
Name of test data directory.
test_data : string
Not used.
Returns
-------
summary : list of string
List of predicted classes for each instance in test data in ordered way.
"""
test_dir
=
File
.
make_path
(
dataset
,
test_dir
)
classes
=
[]
...
...
src/classification/weka_alias.py
View file @
3c86801e
...
...
@@ -165,9 +165,27 @@ _weka_alias = {
}
class
WekaAlias
(
object
):
"""Class of alias for classifiers available on python-weka-wrapper."""
@
staticmethod
def
get_classifier
(
name
):
"""Return full name of classifier.
Parameters
----------
name : string
Alias of classifier, not case sensitive.
Returns
-------
classifier : string
Full name of classifier.
Raises
------
IException 'Invalid classifier'
The user must install the required dependencies to classifiers.
"""
classifiers
=
[
_weka_alias
[
alias
]
for
alias
in
_weka_alias
]
if
name
in
classifiers
:
...
...
@@ -184,4 +202,11 @@ class WekaAlias(object):
@
staticmethod
def
get_aliases
():
"""Return all aliases.
Returns
-------
classifier : Dictionary
Dictionary with all aliases.
"""
return
_weka_alias
src/classification/weka_classifiers.py
View file @
3c86801e
...
...
@@ -27,8 +27,18 @@ from weka_alias import WekaAlias
from
classifier
import
Classifier
class
WekaClassifiers
(
Classifier
):
"""Class for all classifiers available in python-weka-wrapper"""
def
__init__
(
self
,
classname
=
"weka.classifiers.functions.SMO"
,
options
=
'default'
):
"""Constructor.
Parameters
----------
classname : string, optional, default = 'weka.classifiers.functions.SMO'
Classifier initialized as default.
options : string, optional, default = 'default'
Classifier options initialized as default. Use the string 'default' to default options.
"""
if
not
jvm
.
started
:
jvm
.
start
()
...
...
@@ -39,6 +49,13 @@ class WekaClassifiers(Classifier):
def
get_config
(
self
):
"""Return configuration of classifier.
Returns
-------
config : OrderedDict
Current configs of classifier.
"""
weka_config
=
OrderedDict
()
weka_config
[
"classname"
]
=
self
.
classname
...
...
@@ -49,12 +66,26 @@ class WekaClassifiers(Classifier):
return
weka_config
def
set_config
(
self
,
configs
):
"""Update configuration of classifier.
Parameters
----------
configs : OrderedDict
New configs of classifier.
"""
configs
[
"classname"
].
value
=
WekaAlias
.
get_classifier
(
configs
[
"classname"
].
value
)
self
.
classname
=
Config
.
nvl_config
(
configs
[
"classname"
],
self
.
classname
)
self
.
options
=
Config
.
nvl_config
(
configs
[
"options"
],
self
.
options
)
def
get_summary_config
(
self
):
"""Return fomatted summary of configuration.
Returns
-------
summary : string
Formatted string with summary of configuration.
"""
weka_config
=
OrderedDict
()
weka_config
[
self
.
classname
.
label
]
=
self
.
classname
.
value
...
...
@@ -68,9 +99,26 @@ class WekaClassifiers(Classifier):
def
must_train
(
self
):
"""Return if classifier must be trained.
Returns
-------
True
"""
return
True
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.
"""
if
self
.
data
is
not
None
and
not
force
:
return
...
...
@@ -89,6 +137,22 @@ class WekaClassifiers(Classifier):
def
classify
(
self
,
dataset
,
test_dir
,
test_data
):
"""Perform the classification.
Parameters
----------
dataset : string
Path to image dataset.
test_dir : string
Not used.
test_data : string
Name of test data file.
Returns
-------
summary : list of string
List of predicted classes for each instance in test data in ordered way.
"""
loader
=
WLoader
(
classname
=
"weka.core.converters.ArffLoader"
)
test_file
=
File
.
make_path
(
dataset
,
test_data
)
...
...
@@ -113,6 +177,18 @@ class WekaClassifiers(Classifier):
def
cross_validate
(
self
,
detail
=
True
):
"""Perform cross validation using trained data.
Parameters
----------
detail : boolean, optional, default = True
If true return a detailed information of cross validation.
Returns
-------
info : string
Info with results of cross validation.
"""
start_time
=
TimeUtils
.
get_time
()
info
=
"Scheme:
\t
%s %s
\n
"
%
(
str
(
self
.
classifier
.
classname
)
,
" "
.
join
([
str
(
option
)
for
option
in
self
.
classifier
.
options
]))
...
...
@@ -145,11 +221,19 @@ class WekaClassifiers(Classifier):
def
experimenter
(
self
):
"""Perform a test using all classifiers available.
Returns
-------
info : string
Info with results of experimenter.
"""
info
=
""
aliases
=
sorted
(
WekaAlias
.
get_aliases
())
for
alias
in
aliases
:
try
:
# Ignore very slow classifiers.
if
alias
==
'KStar'
or
alias
==
'LWL'
or
alias
==
'MultilayerPerceptron'
:
continue
...
...
@@ -173,5 +257,7 @@ class WekaClassifiers(Classifier):
def
reset
(
self
):
"""Clean all data of classification.
"""
self
.
data
=
None
self
.
classifier
=
None
src/pynovisao.py
View file @
3c86801e
...
...
@@ -259,12 +259,12 @@ class Act(object):
Parameters
----------
name : string
.
name : string
Name of class.
Returns
-------
index : integer
.
index : integer
Index of class in list self.classes.
Raises
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment