Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
Marius Laska
boxPrediction
Commits
046521e8
Commit
046521e8
authored
Nov 30, 2020
by
Marius Laska
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cross entropy loss for grid cell classification + scalable dnn reference model of paper
parent
65154d88
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
246 additions
and
11 deletions
+246
-11
base/BboxModel.py
base/BboxModel.py
+16
-6
base/bbox_model_definition.py
base/bbox_model_definition.py
+68
-0
base/custom_loss.py
base/custom_loss.py
+5
-2
base/ujiindoorloc_fullgrid_provider.py
base/ujiindoorloc_fullgrid_provider.py
+2
-2
config/gpu_uji_full_grid_hyper_cross.yml
config/gpu_uji_full_grid_hyper_cross.yml
+81
-0
main.py
main.py
+74
-1
No files found.
base/BboxModel.py
View file @
046521e8
...
...
@@ -13,7 +13,7 @@ from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from
tensorflow.keras.optimizers
import
Adam
,
Adamax
from
base.bbox_model_definition
import
bbox_model_for_generator
,
\
cnn_deep_loc_box
,
ae_model
,
cnn_bbox_model_for_generator
cnn_deep_loc_box
,
ae_model
,
cnn_bbox_model_for_generator
,
scalabel_bbox_model
,
scalable_ae_model
from
base.hier_model_definition
import
hier_model_for_generator
from
base.custom_loss
import
bbox_loss
,
define_bbox_loss
,
define_circle_loss
,
\
define_quantile_loss
,
\
...
...
@@ -72,9 +72,8 @@ class BboxModel(DnnModel):
params
.
update
({
'last_activation'
:
sigmoid
,
'losses'
:
loss_func
})
elif
self
.
type
==
"GRID_OVERLAP-BBOX"
:
elif
self
.
type
==
"GRID_OVERLAP-BBOX"
or
self
.
type
==
"GRID_OVERLAP-BBOX_SCALABLE-DNN"
:
if
'loss'
in
params
:
#loss_func = define_yolo_loss_tanh(params['loss'])
loss_func
=
define_yolo_loss_tanh_no_size
(
params
[
'loss'
])
params
.
update
({
'last_activation'
:
tanh
,
...
...
@@ -154,7 +153,10 @@ class BboxModel(DnnModel):
def
train_autoencoder
(
self
):
x_cols
,
_
=
self
.
data_provider
.
get_data_dims
(
"regression"
)
self
.
classifier
,
bottleneck_model
=
ae_model
(
x_cols
,
self
.
params
)
if
self
.
type
==
"GRID_OVERLAP-BBOX_SCALABLE-DNN"
:
self
.
classifier
,
bottleneck_model
=
scalable_ae_model
(
x_cols
,
self
.
params
)
else
:
self
.
classifier
,
bottleneck_model
=
ae_model
(
x_cols
,
self
.
params
)
self
.
_train_model
(
save_weights_only
=
False
,
evaluate
=
False
,
autoencoder
=
True
)
bottleneck_model
.
save
(
self
.
output_dir
+
"AE_bottleneck_{}_f{}.hdf5"
.
format
(
self
.
filename
,
self
.
data_provider
.
current_split_idx
),
include_optimizer
=
False
)
...
...
@@ -209,7 +211,10 @@ class BboxModel(DnnModel):
dp
.
floorplan_height
/
dp
.
grid_size
)
*
math
.
ceil
(
dp
.
floorplan_width
/
dp
.
grid_size
)
if
self
.
type
==
"GRID_OVERLAP-BBOX"
or
self
.
type
==
"GRID_OVERLAP-BBOX_CNN"
or
self
.
type
==
"GRID_OVERLAP-BBOX_2D-CNN"
:
if
self
.
type
==
"GRID_OVERLAP-BBOX"
\
or
self
.
type
==
"GRID_OVERLAP-BBOX_CNN"
\
or
self
.
type
==
"GRID_OVERLAP-BBOX_2D-CNN"
\
or
self
.
type
==
"GRID_OVERLAP-BBOX_SCALABLE-DNN"
:
num_gs
=
dp
.
get_num_grid_cells
()
if
num_gs
is
None
:
y_cols
=
5
*
(
math
.
ceil
(
...
...
@@ -243,6 +248,11 @@ class BboxModel(DnnModel):
self
.
filename
,
self
.
data_provider
.
current_split_idx
)
self
.
classifier
=
cnn_deep_loc_box
(
ae_file
,
y_cols
,
params
)
elif
self
.
type
==
"GRID_OVERLAP-BBOX_SCALABLE-DNN"
:
ae_file
=
self
.
output_dir
+
"AE_bottleneck_{}_f{}.hdf5"
.
format
(
self
.
filename
,
self
.
data_provider
.
current_split_idx
)
self
.
classifier
=
scalabel_bbox_model
(
x_cols
,
y_cols
,
ae_file
,
params
)
elif
self
.
type
==
"GRID_OVERLAP-BBOX_2D-CNN"
:
x_cols
,
_
=
dp
.
get_data_dims
(
"CNN"
)
classifier_template
=
cnn_bbox_model_for_generator
()
...
...
@@ -341,7 +351,7 @@ class BboxModel(DnnModel):
steps_per_epoch
=
train_steps_per_epoch
,
epochs
=
params
[
'epochs'
],
callbacks
=
[
earlyStopping
,
checkpoint
],
verbose
=
0
)
verbose
=
2
)
# evaluate model and store results in summary file
if
evaluate
:
...
...
base/bbox_model_definition.py
View file @
046521e8
...
...
@@ -118,6 +118,74 @@ def bbox_model_for_generator(metrics):
return
define_classification_model_for_generator
def
scalabel_bbox_model
(
X_cols
,
Y_cols
,
ae_base_model_file
,
params
):
ae_model
=
load_model
(
ae_base_model_file
)
#, compile=False)
for
layer
in
ae_model
.
layers
:
layer
.
trainable
=
True
model
=
Sequential
()
model
.
add
(
ae_model
)
model
.
add
(
Dense
(
64
,
input_dim
=
X_cols
,
activation
=
"relu"
,
kernel_regularizer
=
regularizers
.
l2
(
params
[
'regularization_penalty'
])
))
seed_val
=
None
if
'seed'
in
params
:
seed_val
=
params
[
'seed'
]
model
.
add
(
Dropout
(
params
[
'dropout'
],
training
=
None
,
seed
=
seed_val
))
model
.
add
(
Dense
(
128
,
activation
=
"relu"
,
kernel_regularizer
=
regularizers
.
l2
(
params
[
'regularization_penalty'
])
))
#
model
.
add
(
Dense
(
Y_cols
,
activation
=
params
[
'last_activation'
],
# kernel_initializer=params['kernel_initializer'],
kernel_regularizer
=
regularizers
.
l2
(
params
[
'regularization_penalty'
])))
# ,
# compile the model
model
.
compile
(
loss
=
params
[
'losses'
],
optimizer
=
params
[
'optimizer'
](
lr
=
lr_normalizer
(
params
[
'lr'
],
params
[
'optimizer'
])))
return
model
def
scalable_ae_model
(
X_cols
,
params
):
input
=
Input
((
X_cols
,))
encode_layer
=
Dense
(
256
,
activation
=
params
[
'activation'
],
name
=
'en1'
)(
input
)
encode_layer
=
Dense
(
128
,
activation
=
params
[
'activation'
],
name
=
'en2'
)(
encode_layer
)
decode_layer
=
Dense
(
256
,
activation
=
params
[
'activation'
],
name
=
'de2'
)(
encode_layer
)
decode_layer
=
Dense
(
X_cols
,
activation
=
params
[
'activation'
],
name
=
'de-1'
)(
decode_layer
)
encoder_model_256_128
=
Model
(
inputs
=
input
,
outputs
=
decode_layer
)
bottleneck_model_256_128
=
Model
(
inputs
=
input
,
outputs
=
encode_layer
)
encoder_model
=
encoder_model_256_128
bottleneck_model
=
bottleneck_model_256_128
encoder_model
.
compile
(
loss
=
MSE
,
optimizer
=
params
[
'optimizer'
](
lr
=
lr_normalizer
(
params
[
'lr'
],
params
[
'optimizer'
]))
# lr=0.005)
)
return
encoder_model
,
bottleneck_model
def
ae_model
(
X_cols
,
params
):
input
=
Input
((
X_cols
,))
encode_layer
=
Dense
(
128
,
activation
=
params
[
'activation'
],
name
=
'en1'
)(
input
)
...
...
base/custom_loss.py
View file @
046521e8
...
...
@@ -856,6 +856,7 @@ def define_yolo_loss_tanh(params):
return
yolo_loss
def
define_yolo_loss_tanh_no_size
(
params
):
def
yolo_loss
(
y_true
,
y_pred
):
...
...
@@ -870,7 +871,9 @@ def define_yolo_loss_tanh_no_size(params):
# grid cell true
grid_cell_true
=
tf
.
one_hot
(
tf
.
cast
(
y_true
[:,
2
],
dtype
=
tf
.
int32
),
depth
=
tf
.
shape
(
grid_cell_pred
)[
1
])
class_loss
=
tf
.
reduce_sum
(
tf
.
squared_difference
(
grid_cell_pred
,
grid_cell_true
),
axis
=
1
)
# class_loss = tf.reduce_sum(tf.squared_difference(grid_cell_pred, grid_cell_true), axis=1)
class_loss
=
tf
.
losses
.
softmax_cross_entropy
(
grid_cell_true
,
logits
=
grid_cell_pred
)
if
"scale"
in
params
[
"grid"
]:
factor
=
params
[
"grid"
][
"scale"
]
...
...
@@ -965,7 +968,7 @@ def define_yolo_loss_tanh_no_size(params):
box_loss
+=
outside_loss
loss
+=
box_loss
*
box_loss_scale
loss
+=
box_loss
#
* box_loss_scale
return
loss
...
...
base/ujiindoorloc_fullgrid_provider.py
View file @
046521e8
...
...
@@ -135,8 +135,8 @@ class UJIndoorLocProviderFullGrid(UJIndoorLocProviderGrid):
decoded_preds
[
dp_idx
,
4
:]
=
np
.
array
(
key
)
decoded_true
[
dp_idx
,
:
2
]
=
y_true_labels
[
dp_idx
,
:
2
]
print
(
"Enc->DEC: {}"
.
format
(
np
.
array_equal
(
y_true_labels
[
dp_idx
,
:],
decoded_labels
[:,
:
2
])))
#
print("Enc->DEC: {}".format(
#
np.array_equal(y_true_labels[dp_idx, :], decoded_labels[:, :2])))
return
decoded_preds
,
decoded_true
...
...
config/gpu_uji_full_grid_hyper_cross.yml
0 → 100644
View file @
046521e8
data
:
# The data provider which should be used
provider
:
UJIndoorLocFullProvider
# File name of floor plan img
floor_plan_img
:
<test>.jpg
# (train, val, test) test=0.2 => 5 fold # The number of temporal epochs into which the dataset is split
split_ratio
:
[
0.7
,
0.1
,
0.2
]
#
# are used when not locally set for pipeline
#
global_params
:
# number of experiment repetitions
repetitions
:
10
preprocessing
:
# Whether to standardize the RSS values
standardize
:
True
# Whether to assign labels with no matching area to closet area
assign_closest
:
False
# The floor number of the Lohan dataset, which should be used
#floor: 0
# The epoch number of the split dataset
#num_epochs: 10
#epoch: 5
# How to check for area matches of labels (to label positions with matching areas)
area_assignment
:
convex_hull
grid_size
:
40
floor_plan
:
# 'segmentation' => computes floor plan segmentation,
# 'regression' => uses DBSCAN to partitions labels into train, test split
type
:
floor_classification
model_params
:
type
:
GRID_OVERLAP-BBOX_CNN
# (DNN, CNN, kNN, SVM) supported (require different parameters)
lr
:
0.7
batch_size
:
32
epochs
:
200
dropout
:
0.5
regularization_penalty
:
0.0
pipelines
:
-
name
:
DNN-DLB
model_params
:
type
:
GRID_OVERLAP-BBOX
# (DNN, CNN, kNN, SVM) supported (require different parameters)
first_neuron
:
512
hidden_layers
:
1
augmentation
:
0
#autoencoder: load
dropout
:
0.5
loss
:
grid
:
scale
:
20.0
outside
:
scale
:
1.0
delta
:
7.5
-
name
:
SCALABLE-DNN-DLB
model_params
:
type
:
GRID_OVERLAP-BBOX_SCALABLE-DNN
# (DNN, CNN, kNN, SVM) supported (require different parameters)
augmentation
:
0
autoencoder
:
train
dropout
:
0.2
loss
:
grid
:
scale
:
20.0
outside
:
scale
:
1.0
delta
:
7.5
# base directories for file storage
output
:
model_dir
:
evaluation/uji/gpu/full_grid/scalable_dnn/output/
summary_dir
:
evaluation/uji/gpu/full_grid/scalable_dnn/summary/
img_folder
:
evaluation/uji/
# folder where floorplan images is located (if not present, will be downloaded)
main.py
View file @
046521e8
...
...
@@ -12,6 +12,7 @@ from base.ujiindoorloc_fullgrid_provider import test_encoding_decoding
log
=
getLogger
(
level
=
logging
.
INFO
)
from
base.bbox_pipeline
import
BboxPipeline
import
numpy
as
np
import
pandas
as
pd
from
numpy.random
import
seed
from
tensorflow
import
set_random_seed
...
...
@@ -258,5 +259,77 @@ def calc_acc(y_true, y_pred):
print
(
"ACC: {}"
.
format
(
num_correct
/
len
(
y_true
)))
def
calc_vals
(
file
,
num_rep
=
1
):
bld_acc_sum
=
0
floor_acc_sum
=
0
pos_error_sum
=
0
for
idx
in
range
(
num_rep
):
p
:
BboxPipeline
=
Storable
.
load
(
file
.
format
(
idx
+
1
))
p
.
data_provider
.
decode_pipe_grid_labels
(
p
)
y_pred
=
np
.
concatenate
(
p
.
summary
.
y_pred
,
axis
=
0
)
y_true
=
np
.
concatenate
(
p
.
summary
.
y_true
,
axis
=
0
)
# avg size
size
=
np
.
mean
(
np
.
prod
(
y_pred
[:,
2
:],
axis
=
1
))
acc_box
,
wrong_mask
,
correct_mask
=
calc_acc_c
(
y_true
,
y_pred
)
bld_pred
=
y_pred
[:,
4
]
bld_true
=
y_true
[:,
2
]
bld_acc
=
np
.
where
(
bld_pred
==
bld_true
)[
0
]
floor_pred
=
y_pred
[:,
5
]
floor_true
=
y_true
[:,
3
]
floor_acc
=
np
.
where
(
floor_pred
==
floor_true
)[
0
]
pos_error
=
np
.
mean
(
np
.
linalg
.
norm
(
y_pred
[:,
:
2
]
-
y_true
[:,
:
2
],
axis
=
1
))
# pos error correct
mask
=
np
.
where
(
np
.
logical_and
(
bld_pred
==
bld_true
,
floor_pred
==
floor_true
))[
0
]
pos_error_correct
=
np
.
mean
(
np
.
linalg
.
norm
(
y_pred
[
mask
,
:
2
]
-
y_true
[
mask
,
:
2
],
axis
=
1
))
bld_acc_sum
+=
len
(
bld_acc
)
/
len
(
bld_true
)
floor_acc_sum
+=
len
(
floor_acc
)
/
len
(
floor_true
)
pos_error_sum
+=
pos_error
# print("bld_acc: {}".format(len(bld_acc)/len(bld_true)))
# print("floor_acc: {}".format(len(floor_acc) / len(floor_true)))
#
# print("MSE: {}".format(pos_error))
# print("MSE (only correct): {}".format(pos_error_correct))
# print("--------------")
return
bld_acc_sum
/
num_rep
,
floor_acc_sum
/
num_rep
,
pos_error_sum
/
num_rep
def
main_uji
():
pd_dict
=
{
"HL"
:
[],
"HU"
:
[],
"Dropout"
:
[],
"bld"
:
[],
"floor"
:
[],
"mse"
:
[]}
folder
=
"evaluation/uji/gpu/full_grid/hyper/output/"
file_name
=
"DNN-DLB_first_neuron_{}_hidden_layers_{}_dropout_{}"
for
hl
in
[
1
,
2
,
3
]:
for
hu
in
[
128
]:
for
dropout
in
[
0.0
,
0.1
,
0.2
,
0.3
,
0.4
,
0.5
,
0.6
,
0.7
]:
bld_acc
,
fl_acc
,
mse
=
calc_vals
(
folder
+
file_name
.
format
(
hl
,
hu
,
dropout
)
+
"_{}"
,
num_rep
=
5
)
pd_dict
[
"HL"
].
append
(
hl
)
pd_dict
[
"HU"
].
append
(
hu
)
pd_dict
[
"Dropout"
].
append
(
dropout
)
pd_dict
[
"bld"
].
append
(
bld_acc
)
pd_dict
[
"floor"
].
append
(
fl_acc
)
pd_dict
[
"mse"
].
append
(
mse
)
df
=
pd
.
DataFrame
(
pd_dict
)
print
(
df
)
if
__name__
==
"__main__"
:
main
()
\ No newline at end of file
#main_uji()
main
()
#file_name = "/home/laskama/PycharmProjects/bboxPrediction/evaluation/uji/gpu/full_grid/scalable_dnn/output/BASE-DNN-DLB"
#bld_acc, fl_acc, mse = calc_vals(file_name + "_{}", num_rep=1)
# print([bld_acc, fl_acc, mse])
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