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
40c0028c
Commit
40c0028c
authored
Feb 22, 2018
by
Diogo Nunes Gonçalves
Browse files
Funcao cnn_keras e segnet_keras adicionadas
parent
1896c8e3
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1508 additions
and
178 deletions
+1508
-178
INSTALL.sh
INSTALL.sh
+0
-0
requeriments.txt
requeriments.txt
+1
-0
src/classification/__init__.py
src/classification/__init__.py
+13
-1
src/classification/classifier.py
src/classification/classifier.py
+1
-1
src/classification/cnn_caffe.py
src/classification/cnn_caffe.py
+1
-1
src/classification/cnn_keras.py
src/classification/cnn_keras.py
+184
-136
src/classification/segnet_keras.py
src/classification/segnet_keras.py
+817
-0
src/classification/weka_classifiers.py
src/classification/weka_classifiers.py
+1
-1
src/main.py
src/main.py
+4
-0
src/pynovisao.py
src/pynovisao.py
+278
-38
src/segmentation/segmenter.py
src/segmentation/segmenter.py
+1
-0
src/util/file_utils.py
src/util/file_utils.py
+29
-0
src/util/utils.py
src/util/utils.py
+177
-0
src/util/x11_colors.py
src/util/x11_colors.py
+1
-0
No files found.
INSTALL.sh
100644 → 100755
View file @
40c0028c
File mode changed from 100644 to 100755
requeriments.txt
View file @
40c0028c
...
...
@@ -10,3 +10,4 @@ javabridge
python-weka-wrapper
cycler
cython
h5py
src/classification/__init__.py
View file @
40c0028c
...
...
@@ -18,9 +18,18 @@ except Exception as e:
CNNKeras
=
None
print
e
.
message
try
:
from
.segnet_keras
import
SEGNETKeras
except
Exception
as
e
:
SEGNETKeras
=
None
print
e
.
message
__all__
=
[
"classifier"
,
"cnn_caffe"
,
"cnn_keras"
,
"segnet_keras"
,
"weka_classifiers"
]
...
...
@@ -33,7 +42,9 @@ _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
)],
[
"cnn_keras"
,
Config
(
"Invalid"
if
CNNKeras
is
None
else
CNNKeras
.
__name__
,
CNNKeras
is
not
None
,
bool
,
meta
=
CNNKeras
,
hidden
=
CNNKeras
is
None
)],
CNNKeras
is
not
None
,
bool
,
meta
=
CNNKeras
,
hidden
=
CNNKeras
is
None
)],
[
"segnet_keras"
,
Config
(
"Invalid"
if
SEGNETKeras
is
None
else
SEGNETKeras
.
__name__
,
SEGNETKeras
is
not
None
,
bool
,
meta
=
SEGNETKeras
,
hidden
=
SEGNETKeras
is
None
)],
[
"weka_classifiers"
,
Config
(
"Invalid"
if
WekaClassifiers
is
None
else
WekaClassifiers
.
__name__
,
WekaClassifiers
is
not
None
,
bool
,
meta
=
WekaClassifiers
,
hidden
=
WekaClassifiers
is
None
)]
]
)
...
...
@@ -44,4 +55,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
[
"cnn_keras"
]
=
Config
.
nvl_config
(
configs
[
"cnn_keras"
],
_classifier_list
[
"cnn_keras"
])
_classifier_list
[
"segnet_keras"
]
=
Config
.
nvl_config
(
configs
[
"segnet_keras"
],
_classifier_list
[
"segnet_keras"
])
_classifier_list
[
"weka_classifiers"
]
=
Config
.
nvl_config
(
configs
[
"weka_classifiers"
],
_classifier_list
[
"weka_classifiers"
])
\ No newline at end of file
src/classification/classifier.py
View file @
40c0028c
...
...
@@ -90,7 +90,7 @@ class Classifier(object):
pass
@
abstractmethod
def
classify
(
self
,
dataset
,
test_dir
=
None
,
test_data
=
None
):
def
classify
(
self
,
dataset
,
test_dir
=
None
,
test_data
=
None
,
image
=
None
):
"""Perform the classification.
Implement this method to extend this class with a new classifier algorithm.
"""
...
...
src/classification/cnn_caffe.py
View file @
40c0028c
...
...
@@ -116,7 +116,7 @@ class CNNCaffe(Classifier):
return
summary
def
classify
(
self
,
dataset
,
test_dir
,
test_data
):
def
classify
(
self
,
dataset
,
test_dir
,
test_data
,
image
):
"""Perform the classification.
Parameters
...
...
src/classification/cnn_keras.py
View file @
40c0028c
...
...
@@ -14,14 +14,15 @@ import os
import
shutil
import
random
import
numpy
as
np
import
json
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.models
import
Model
,
load_model
from
keras.layers
import
Dropout
,
Flatten
,
Dense
from
keras.callbacks
import
ModelCheckpoint
from
sklearn.cross_validation
import
train_test_split
from
keras.callbacks
import
ModelCheckpoint
,
TensorBoard
from
keras
import
backend
as
K
from
interface.interface
import
InterfaceException
as
IException
from
classification.classifier
import
Classifier
...
...
@@ -42,12 +43,12 @@ START_TIME = time.time()
IMG_WIDTH
,
IMG_HEIGHT
=
256
,
256
CLASS_NAMES
=
[
'FolhasLargas'
,
'Gramineas'
,
'Soja'
,
'Solo'
]
weight_path
=
None
class
CNNKeras
(
Classifier
):
""" Class for CNN classifiers based on Keras applications """
def
__init__
(
self
,
architecture
=
"
VGG16
"
,
learning_rate
=
0.
0
001
,
momentum
=
0.9
,
batch_size
=
16
,
epochs
=
1
,
fine_tuning_rate
=
100
,
transfer_learning
=
False
,
save_weights
=
True
):
def
__init__
(
self
,
architecture
=
"
ResNet50
"
,
learning_rate
=
0.001
,
momentum
=
0.9
,
batch_size
=
32
,
epochs
=
50
,
fine_tuning_rate
=
100
,
transfer_learning
=
False
,
save_weights
=
True
,
perc_train
=
80
,
perc_validation
=
20
,
recreate_dataset
=
False
):
"""
Constructor of CNNKeras
"""
...
...
@@ -68,7 +69,12 @@ class CNNKeras(Classifier):
"Transfer Learning"
,
transfer_learning
,
bool
)
self
.
save_weights
=
Config
(
"Save weights"
,
save_weights
,
bool
)
self
.
perc_train
=
Config
(
"Perc Train"
,
perc_train
,
float
)
self
.
perc_validation
=
Config
(
"Perc Validation"
,
perc_validation
,
float
)
self
.
recreate_dataset
=
Config
(
"Recreate Dataset"
,
recreate_dataset
,
bool
)
self
.
file_name
=
"kerasCNN"
self
.
model
=
None
...
...
@@ -93,7 +99,9 @@ class CNNKeras(Classifier):
keras_config
[
"Fine Tuning rate"
]
=
self
.
fine_tuning_rate
keras_config
[
"Transfer Learning"
]
=
self
.
transfer_learning
keras_config
[
"Save weights"
]
=
self
.
save_weights
keras_config
[
"Perc Train"
]
=
self
.
perc_train
keras_config
[
"Perc Validation"
]
=
self
.
perc_validation
keras_config
[
"Recreate Dataset"
]
=
self
.
recreate_dataset
return
keras_config
def
set_config
(
self
,
configs
):
...
...
@@ -104,31 +112,17 @@ class CNNKeras(Classifier):
configs : OrderedDict
New configs of classifier.
"""
keras_config
=
OrderedDict
()
keras_config
[
"Architecture"
]
=
Config
.
nvl_config
(
configs
[
"Architecture"
],
self
.
architecture
)
keras_config
[
"Learning rate"
]
=
Config
.
nvl_config
(
configs
[
"Learning rate"
],
self
.
learning_rate
)
keras_config
[
"Momentum"
]
=
Config
.
nvl_config
(
configs
[
"Momentum"
],
self
.
momentum
)
keras_config
[
"Batch size"
]
=
Config
.
nvl_config
(
configs
[
"Batch size"
],
self
.
batch_size
)
keras_config
[
"Epochs"
]
=
Config
.
nvl_config
(
configs
[
"Epochs"
],
self
.
epochs
)
keras_config
[
"Fine Tuning rate"
]
=
Config
.
nvl_config
(
configs
[
"Fine Tuning rate"
],
self
.
fine_tuning_rate
)
keras_config
[
"Transfer Learning"
]
=
Config
.
nvl_config
(
configs
[
"Transfer Learning"
],
self
.
transfer_learning
)
keras_config
[
"Save weights"
]
=
Config
.
nvl_config
(
configs
[
"Save weights"
],
self
.
save_weights
)
self
.
architecture
=
Config
.
nvl_config
(
configs
[
"Architecture"
],
self
.
architecture
)
self
.
learning_rate
=
Config
.
nvl_config
(
configs
[
"Learning rate"
],
self
.
learning_rate
)
self
.
momentum
=
Config
.
nvl_config
(
configs
[
"Momentum"
],
self
.
momentum
)
self
.
batch_size
=
Config
.
nvl_config
(
configs
[
"Batch size"
],
self
.
batch_size
)
self
.
epochs
=
Config
.
nvl_config
(
configs
[
"Epochs"
],
self
.
epochs
)
self
.
fine_tuning_rate
=
Config
.
nvl_config
(
configs
[
"Fine Tuning rate"
],
self
.
fine_tuning_rate
)
self
.
transfer_learning
=
Config
.
nvl_config
(
configs
[
"Transfer Learning"
],
self
.
transfer_learning
)
self
.
save_weights
=
Config
.
nvl_config
(
configs
[
"Save weights"
],
self
.
save_weights
)
self
.
perc_train
=
Config
.
nvl_config
(
configs
[
"Perc Train"
],
self
.
perc_train
)
self
.
perc_validation
=
Config
.
nvl_config
(
configs
[
"Perc Validation"
],
self
.
perc_validation
)
self
.
recreate_dataset
=
Config
.
nvl_config
(
configs
[
"Recreate Dataset"
],
self
.
recreate_dataset
)
def
get_summary_config
(
self
):
"""Return fomatted summary of configuration.
...
...
@@ -148,14 +142,16 @@ class CNNKeras(Classifier):
keras_config
[
self
.
fine_tuning_rate
.
label
]
=
self
.
fine_tuning_rate
.
value
keras_config
[
self
.
transfer_learning
.
label
]
=
self
.
transfer_learning
.
value
keras_config
[
self
.
save_weights
.
label
]
=
self
.
save_weights
.
value
keras_config
[
self
.
perc_train
.
label
]
=
self
.
perc_train
.
value
keras_config
[
self
.
perc_validation
.
label
]
=
self
.
perc_validation
.
value
keras_config
[
self
.
recreate_dataset
.
label
]
=
self
.
recreate_dataset
.
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
):
def
classify
(
self
,
dataset
,
test_dir
,
test_data
,
image
):
""""Perform the classification.
Parameters
...
...
@@ -175,63 +171,43 @@ class CNNKeras(Classifier):
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
# Create a Keras class
if
not
os
.
path
.
exists
(
predict_directory
+
"/png"
):
os
.
makedirs
(
predict_directory
+
"/png"
)
# move the .png images to inside the class
for
_
,
_
,
files
in
os
.
walk
(
predict_directory
,
topdown
=
False
):
for
name
in
files
:
if
name
.
endswith
(
'.png'
):
shutil
.
move
(
os
.
path
.
join
(
predict_directory
,
name
),
os
.
path
.
join
(
predict_directory
,
"png"
,
name
))
if
not
os
.
path
.
exists
(
File
.
make_path
(
predict_directory
,
"png"
)):
os
.
makedirs
(
File
.
make_path
(
predict_directory
,
"png"
))
for
file
in
os
.
listdir
(
predict_directory
):
print
(
File
.
make_path
(
predict_directory
,
file
))
if
os
.
path
.
splitext
(
file
)[
-
1
]
==
".tif"
:
try
:
img
=
Image
.
open
(
File
.
make_path
(
predict_directory
,
file
))
#img.thumbnail(img.size)
new_file
=
os
.
path
.
splitext
(
file
)[
0
]
+
".png"
img
.
save
(
File
.
make_path
(
predict_directory
,
'png'
,
new_file
),
"PNG"
,
quality
=
100
)
except
Exception
,
e
:
print
e
else
:
os
.
symlink
(
File
.
make_path
(
predict_directory
,
file
),
File
.
make_path
(
predict_directory
,
'png'
,
file
))
classify_datagen
=
ImageDataGenerator
()
classify_generator
=
classify_datagen
.
flow_from_directory
(
predict_directory
,
File
.
make_path
(
predict_directory
,
'png'
),
target_size
=
(
IMG_HEIGHT
,
IMG_WIDTH
),
batch_size
=
1
,
shuffle
=
False
,
class_mode
=
None
)
validation_datagen
=
ImageDataGenerator
()
validation_generator
=
validation_datagen
.
flow_from_directory
(
dataset
,
target_size
=
(
IMG_HEIGHT
,
IMG_WIDTH
),
batch_size
=
self
.
batch_size
.
value
,
shuffle
=
False
,
class_mode
=
None
)
# TODO - A better solution to num_classes - 1
self
.
model
=
self
.
select_model_params
(
validation_generator
.
num_classes
-
1
)
try
:
self
.
model
.
load_weights
(
"../models_checkpoints/"
+
self
.
file_name
+
".h5"
)
#self.model.load_weights(
#"../models_checkpoints/" + self.file_name + ".h5")
K
.
clear_session
()
if
self
.
weight_path
is
not
None
:
self
.
model
=
load_model
(
self
.
weight_path
)
path_classes
=
self
.
weight_path
.
replace
(
"_model.h5"
,
"_classes.npy"
)
CLASS_NAMES
=
np
.
load
(
path_classes
).
item
().
keys
()
except
Exception
,
e
:
raise
IException
(
"Can't load the model in "
+
"../models_checkpoints/"
+
self
.
file_name
+
".h5"
+
str
(
e
))
self
.
weight_path
+
str
(
e
))
output_classification
=
self
.
model
.
predict_generator
(
classify_generator
,
classify_generator
.
samples
,
verbose
=
2
)
...
...
@@ -259,51 +235,64 @@ class CNNKeras(Classifier):
"""
# select .h5 filename
if
self
.
transfer_learning
.
value
==
100
:
file_name
=
str
(
self
.
architecture
.
value
)
+
\
if
self
.
fine_tuning_rate
.
value
==
100
:
self
.
file_name
=
str
(
self
.
architecture
.
value
)
+
\
'_learning_rate'
+
str
(
self
.
learning_rate
.
value
)
+
\
'_transfer_learning'
elif
self
.
transfer_learning
.
value
==
-
1
:
file_name
=
str
(
self
.
architecture
.
value
)
+
\
elif
self
.
fine_tuning_rate
.
value
==
-
1
:
self
.
file_name
=
str
(
self
.
architecture
.
value
)
+
\
'_learning_rate'
+
str
(
self
.
learning_rate
.
value
)
+
\
'_without_transfer_learning'
else
:
file_name
=
str
(
self
.
architecture
.
value
)
+
\
self
.
file_name
=
str
(
self
.
architecture
.
value
)
+
\
'_learning_rate'
+
str
(
self
.
learning_rate
.
value
)
+
\
'_fine_tunning_'
+
str
(
self
.
fine_tuning_rate
.
value
)
File
.
remove_dir
(
File
.
make_path
(
dataset
,
".tmp"
))
train_generator
,
validation_generator
=
self
.
make_dataset
(
dataset
)
train_generator
,
validation_generator
,
test_generator
=
self
.
make_dataset
(
dataset
)
# Save the model according to the conditions
if
self
.
save_weights
:
if
not
os
.
path
.
exists
(
"../models_checkpoints/"
):
os
.
makedirs
(
"../models_checkpoints/"
)
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
)
else
:
checkpoint
=
None
self
.
model
=
self
.
select_model_params
(
train_generator
.
num_classes
)
tensorboard
=
TensorBoard
(
log_dir
=
"../models_checkpoints/logs_"
+
self
.
file_name
,
write_images
=
False
)
#tensorboard.set_model(self.model)
# compile the model
self
.
model
.
compile
(
loss
=
"categorical_crossentropy"
,
optimizer
=
optimizers
.
SGD
(
lr
=
self
.
learning_rate
.
value
,
momentum
=
self
.
momentum
.
value
),
metrics
=
[
"accuracy"
])
# Save the model according to the conditions
if
self
.
save_weights
:
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
)
else
:
checkpoint
=
None
train_images
,
validation_images
=
train_test_split
(
train_generator
,
test_size
=
0.4
)
# Train the model
self
.
model
.
fit_generator
(
train_generator
,
steps_per_epoch
=
train_generator
.
samples
//
self
.
batch_size
.
value
,
epochs
=
self
.
epochs
.
value
,
callbacks
=
[
checkpoint
],
validation_data
=
trai
n_generator
,
validation_steps
=
trai
n_generator
.
samples
//
self
.
batch_size
.
value
)
callbacks
=
[
checkpoint
,
tensorboard
],
validation_data
=
validatio
n_generator
,
validation_steps
=
validatio
n_generator
.
samples
//
self
.
batch_size
.
value
)
if
self
.
save_weights
:
self
.
model
.
save_weights
(
"../models_checkpoints/"
+
self
.
file_name
+
".h5"
)
#self.model.save_weights(
# "../models_checkpoints/" + self.file_name + ".h5")
self
.
model
.
save
(
"../models_checkpoints/"
+
self
.
file_name
+
"_model.h5"
)
self
.
weight_path
=
"../models_checkpoints/"
+
self
.
file_name
+
"_model.h5"
dict_classes
=
validation_generator
.
class_indices
np
.
save
(
"../models_checkpoints/"
+
self
.
file_name
+
"_classes.npy"
,
dict_classes
)
def
must_train
(
self
):
"""Return if classifier must be trained.
...
...
@@ -344,7 +333,7 @@ class CNNKeras(Classifier):
model
=
applications
.
MobileNet
(
weights
=
"imagenet"
,
include_top
=
False
,
input_shape
=
(
IMG_WIDTH
,
IMG_HEIGHT
,
3
))
for
layer
in
model
.
layers
[:
int
(
len
(
model
.
layers
)
*
(
self
.
fine_tuning_rate
.
value
/
100
))]:
for
layer
in
model
.
layers
[:
int
(
len
(
model
.
layers
)
*
(
self
.
fine_tuning_rate
.
value
/
100
.0
))]:
layer
.
trainable
=
False
else
:
# without transfer learning
...
...
@@ -386,48 +375,95 @@ class CNNKeras(Classifier):
def
make_dataset
(
self
,
dataset
):
# create symbolic links to the dataset
KERAS_DATASET_DIR_NAME
=
"keras_dataset"
KERAS_DATASET_DIR_NAME
=
".keras_dataset"
#KERAS_DATASET_DIR_NAME = File.make_path("..", os.path.split(dataset)[-1] + "_keras_dataset")
KERAS_DIR_TRAIN_NAME
=
"train"
KERAS_DIR_VALIDATION_NAME
=
"validation"
PERC_TRAIN
=
60
KERAS_DIR_TEST_NAME
=
"test"
PERC_TRAIN
=
self
.
perc_train
.
value
PERC_VALIDATION
=
self
.
perc_validation
.
value
# create keras dir dataset
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
)):
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
))
or
self
.
recreate_dataset
.
value
:
if
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
)):
shutil
.
rmtree
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
))
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
))
# create keras dir train
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
)):
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
))
# create keras dir validation
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
)):
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
))
for
root
,
dirs
,
files
in
os
.
walk
(
dataset
,
topdown
=
False
):
# shuffle array
random
.
shuffle
(
files
)
quant_files
=
len
(
files
)
file_index
=
0
if
not
KERAS_DATASET_DIR_NAME
in
root
.
split
(
"/"
)
and
root
.
split
(
"/"
)[
-
1
]
!=
dataset
.
split
(
"/"
)[
-
1
]:
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
,
root
.
split
(
"/"
)[
-
1
])):
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
,
root
.
split
(
"/"
)[
-
1
]))
# create keras dir train
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
)):
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
))
# create keras dir validation
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
)):
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
))
# create keras dir test
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TEST_NAME
)):
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TEST_NAME
))
dir_classes
=
sorted
(
File
.
list_dirs
(
dataset
))
if
KERAS_DATASET_DIR_NAME
in
dir_classes
:
dir_classes
.
remove
(
KERAS_DATASET_DIR_NAME
)
for
dir_class
in
dir_classes
:
root
=
File
.
make_path
(
dataset
,
dir_class
)
files
=
os
.
listdir
(
root
)
random
.
shuffle
(
files
)
quant_files
=
len
(
files
)
quant_train
=
int
((
quant_files
/
100.0
)
*
PERC_TRAIN
)
quant_validation
=
int
((
quant_files
/
100.0
)
*
PERC_VALIDATION
)
files_train
=
files
[
0
:
quant_train
]
files_validation
=
files
[
quant_train
:
quant_train
+
quant_validation
]
files_test
=
files
[
quant_train
+
quant_validation
:
quant_files
]
print
(
"Processing class %s - %d itens - %d train items - %d validation items"
%
(
dir_class
,
quant_files
,
quant_train
,
quant_validation
))
for
file
in
files_train
:
dir_class_train
=
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
,
dir_class
)
if
not
os
.
path
.
exists
(
dir_class_train
):
os
.
makedirs
(
dir_class_train
)
if
os
.
path
.
splitext
(
file
)[
-
1
]
==
".tif"
:
img
=
Image
.
open
(
File
.
make_path
(
root
,
file
))
#img.thumbnail(img.size)
new_file
=
os
.
path
.
splitext
(
file
)[
0
]
+
".png"
img
.
save
(
File
.
make_path
(
dir_class_train
,
new_file
),
"PNG"
,
quality
=
100
)
else
:
os
.
symlink
(
File
.
make_path
(
root
,
file
),
File
.
make_path
(
dir_class_train
,
file
))
for
file
in
files_validation
:
dir_class_validation
=
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
,
dir_class
)
if
not
os
.
path
.
exists
(
dir_class_validation
):
os
.
makedirs
(
dir_class_validation
)
if
not
os
.
path
.
exists
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
,
root
.
split
(
"/"
)[
-
1
])):
os
.
makedirs
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
,
root
.
split
(
"/"
)[
-
1
]))
if
os
.
path
.
splitext
(
file
)[
-
1
]
==
".tif"
:
img
=
Image
.
open
(
File
.
make_path
(
root
,
file
))
#img.thumbnail(img.size)
new_file
=
os
.
path
.
splitext
(
file
)[
0
]
+
".png"
img
.
save
(
File
.
make_path
(
dir_class_validation
,
new_file
),
"PNG"
,
quality
=
100
)
else
:
os
.
symlink
(
File
.
make_path
(
root
,
file
),
File
.
make_path
(
dir_class_validation
,
file
))
for
file
in
files_test
:
dir_class_test
=
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TEST_NAME
,
dir_class
)
if
not
os
.
path
.
exists
(
dir_class_test
):
os
.
makedirs
(
dir_class_test
)
if
os
.
path
.
splitext
(
file
)[
-
1
]
==
".tif"
:
img
=
Image
.
open
(
File
.
make_path
(
root
,
file
))
#img.thumbnail(img.size)
new_file
=
os
.
path
.
splitext
(
file
)[
0
]
+
".png"
img
.
save
(
File
.
make_path
(
dir_class_test
,
new_file
),
"PNG"
,
quality
=
100
)
else
:
os
.
symlink
(
File
.
make_path
(
root
,
file
),
File
.
make_path
(
dir_class_test
,
file
))
for
file
in
files
:
if
file_index
<=
((
quant_files
/
100
)
*
PERC_TRAIN
):
if
not
os
.
path
.
islink
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
,
root
.
split
(
"/"
)[
-
1
],
file
)):
os
.
symlink
(
File
.
make_path
(
root
,
file
),
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TRAIN_NAME
,
root
.
split
(
"/"
)[
-
1
],
file
))
file_index
+=
1
else
:
if
not
os
.
path
.
islink
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
,
root
.
split
(
"/"
)[
-
1
],
file
)):
os
.
symlink
(
File
.
make_path
(
root
,
file
),
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_VALIDATION_NAME
,
root
.
split
(
"/"
)[
-
1
],
file
))
train_datagen
=
ImageDataGenerator
()
...
...
@@ -449,4 +485,16 @@ class CNNKeras(Classifier):
shuffle
=
True
,
class_mode
=
"categorical"
)
return
train_generator
,
validation_generator
test_datagen
=
ImageDataGenerator
()
test_generator
=
test_datagen
.
flow_from_directory
(
File
.
make_path
(
dataset
,
KERAS_DATASET_DIR_NAME
,
KERAS_DIR_TEST_NAME
),
target_size
=
(
IMG_HEIGHT
,
IMG_WIDTH
),
batch_size
=
self
.
batch_size
.
value
,
shuffle
=
True
,
class_mode
=
"categorical"
)
return
train_generator
,
validation_generator
,
test_generator
\ No newline at end of file
src/classification/segnet_keras.py
0 → 100644
View file @
40c0028c
import
time
import
os
import
shutil
import
random
import
numpy
as
np
import
json
import
itertools
from
PIL
import
Image
from
matplotlib
import
pyplot
as
plt
import
keras
from
keras
import
applications
,
models
,
optimizers
from
keras
import
backend
as
K
from
keras.preprocessing.image
import
ImageDataGenerator
from
keras.models
import
Model
,
load_model
from
keras.layers
import
Dropout
,
Flatten
,
Dense
,
Input
from
keras.layers.convolutional
import
Conv2D
,
MaxPooling2D
,
UpSampling2D
from
keras.layers.normalization
import
BatchNormalization
from
keras.layers.core
import
Activation
,
Reshape
,
Permute
from
keras.callbacks
import
ModelCheckpoint
,
TensorBoard
from
interface.interface
import
InterfaceException
as
IException
from
classification.classifier
import
Classifier
from
collections
import
OrderedDict
from
util.config
import
Config
from
util.file_utils
import
File
from
util.utils
import
TimeUtils
os
.
environ
[
'TF_CPP_MIN_LOG_LEVEL'
]
=
'2'
# Suppress warnings
START_TIME
=
time
.
time
()
IMG_WIDTH
,
IMG_HEIGHT
=
256
,
256
class
SEGNETKeras
(
Classifier
):
def
__init__
(
self
,
architecture
=
"ResNet50"
,
learning_rate
=
0.01
,
momentum
=
0.9
,
batch_size
=
16
,
epochs
=
150
,
fine_tuning_rate
=
0
,
transfer_learning
=
False
,
save_weights
=
True
,
perc_train
=
80
,
perc_validation
=
20
,
recreate_dataset
=
False
,
num_classes
=
2
):
self
.
architecture
=
Config
(
"Architecture"
,
architecture
,
str
)
self
.
learning_rate
=
Config
(
"Learning rate"
,
learning_rate
,
float
)
self
.
momentum
=
Config
(
"Momentum"
,
momentum
,
float
)
self
.
batch_size
=
Config
(
"Batch size"
,
batch_size
,
int
)
self
.
epochs
=
Config
(
"Epochs"
,
epochs
,
int
)
self
.
fine_tuning_rate
=
Config
(
"Fine Tuning Rate"
,
fine_tuning_rate
,
int
)
self
.
transfer_learning
=
Config
(
"Transfer Learning"
,
transfer_learning
,
bool
)
self
.
save_weights
=
Config
(
"Save weights"
,
save_weights
,
bool
)
self
.
perc_train
=
Config
(
"Perc Train"
,
perc_train
,
float
)
self
.
perc_validation
=
Config
(
"Perc Validation"
,
perc_validation
,
float
)
self
.
recreate_dataset
=
Config
(
"Recreate Dataset"
,
recreate_dataset
,
bool
)
self
.
num_classes
=
Config
(
"Num Classes"
,
num_classes
,
int
)
self
.
file_name
=
"segnet_keras"
self
.
model
=
None
self
.
trained
=
False
def
get_config
(
self
):
"""Return configuration of classifier.
Returns
-------
config : OrderedDict
Current configs of classifier.