Skip to content

Commit

Permalink
add ability to use different number of classes for training and valid…
Browse files Browse the repository at this point in the history
…ation data and more config files
  • Loading branch information
RocketFlash committed Sep 3, 2019
1 parent 5c448ac commit 01a9b12
Show file tree
Hide file tree
Showing 15 changed files with 2,422 additions and 2,308 deletions.
2 changes: 1 addition & 1 deletion configs/road_signs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model.h5'
model_save_name : 'best_model_simple2.h5'
18 changes: 18 additions & 0 deletions configs/road_signs_mobilenetv2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
input_shape : [96, 96, 3]
encodings_len: 1024
mode : 'triplet'
distance_type : 'l1'
backbone : 'mobilenetv2'
backbone_weights : 'imagenet'
optimizer : 'radam'
learning_rate : 0.0001
project_name : 'road_signs/'
freeze_backbone : True

#paths
dataset_path : '/home/rauf/datasets/road_signs/road_signs_separated/'
tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model_mobilenetv2.h5'
18 changes: 18 additions & 0 deletions configs/road_signs_resnet18.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
input_shape : [48, 48, 3]
encodings_len: 1024
mode : 'triplet'
distance_type : 'l1'
backbone : 'resnet18'
backbone_weights : 'imagenet'
optimizer : 'radam'
learning_rate : 0.0001
project_name : 'road_signs/'
freeze_backbone : True

#paths
dataset_path : '/home/rauf/datasets/road_signs/road_signs_separated/'
tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model.h5'
18 changes: 18 additions & 0 deletions configs/road_signs_resnet50v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
input_shape : [48, 48, 3]
encodings_len: 1024
mode : 'triplet'
distance_type : 'l1'
backbone : 'resnet50v2'
backbone_weights : 'imagenet'
optimizer : 'radam'
learning_rate : 0.0001
project_name : 'road_signs/'
freeze_backbone : True

#paths
dataset_path : '/home/rauf/datasets/road_signs/road_signs_separated/'
tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model_resnet50v2.h5'
18 changes: 18 additions & 0 deletions configs/road_signs_resnet50v2_merged_dataset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
input_shape : [48, 48, 3]
encodings_len: 1024
mode : 'triplet'
distance_type : 'l1'
backbone : 'resnet50v2'
backbone_weights : 'imagenet'
optimizer : 'radam'
learning_rate : 0.0001
project_name : 'road_signs/'
freeze_backbone : True

#paths
dataset_path : '/home/rauf/datasets/road_signs_merged/'
tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model_resnet50v2_merged.h5'
18 changes: 18 additions & 0 deletions configs/road_signs_resnext50.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
input_shape : [48, 48, 3]
encodings_len: 1024
mode : 'triplet'
distance_type : 'l1'
backbone : 'resnext50'
backbone_weights : 'imagenet'
optimizer : 'radam'
learning_rate : 0.0001
project_name : 'road_signs/'
freeze_backbone : True

#paths
dataset_path : '/home/rauf/datasets/road_signs/road_signs_separated/'
tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model.h5'
18 changes: 18 additions & 0 deletions configs/road_signs_resnext50_merged_dataset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
input_shape : [48, 48, 3]
encodings_len: 256
mode : 'triplet'
distance_type : 'l1'
backbone : 'resnext50'
backbone_weights : 'imagenet'
optimizer : 'radam'
learning_rate : 0.0001
project_name : 'road_signs/'
freeze_backbone : False

#paths
dataset_path : '/home/rauf/datasets/road_signs_merged/'
tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model_resnext50_merged.h5'
18 changes: 18 additions & 0 deletions configs/road_signs_simple2_merged_dataset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
input_shape : [48, 48, 3]
encodings_len: 1024
mode : 'triplet'
distance_type : 'l1'
backbone : 'simple2'
backbone_weights : 'imagenet'
optimizer : 'radam'
learning_rate : 0.0001
project_name : 'road_signs/'
freeze_backbone : True

#paths
dataset_path : '/home/rauf/datasets/road_signs_merged/'
tensorboard_log_path : 'tf_log/'
weights_save_path : 'weights/'
plots_path : 'plots/'
encodings_path : 'encodings/'
model_save_name : 'best_model_simple2_merged.h5'
2 changes: 1 addition & 1 deletion siamese_net/backbones.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def get_backbone(input_shape,encodings_len=4096,backbone_type='simple',backbone_
include_top=False)

if freeze_backbone:
for layer in backbone_model.layers:
for layer in backbone_model.layers[:-2]:
layer.trainable = False

after_backbone = backbone_model.output
Expand Down
25 changes: 12 additions & 13 deletions siamese_net/data_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,20 @@ class SiameseImageLoader:
Image loader for Siamese network
"""

def __init__(self, dataset_path, number_of_classes=2, input_shape=None, augmentations=None, data_subsets=['train', 'val']):
def __init__(self, dataset_path, input_shape=None, augmentations=None, data_subsets=['train', 'val']):
self.dataset_path = dataset_path
self.data_subsets = data_subsets
self.images_paths = {}
self.images_labels = {}
self.input_shape = input_shape
self.number_of_classes = number_of_classes
self.augmentations = augmentations
self.current_idx = {d: 0 for d in data_subsets}
self._load_images_paths()
self.classes = list(set(self.images_labels['train']))
self.n_classes = len(self.classes)
self.classes = {s: list(set(self.images_labels[s])) for s in data_subsets}
self.n_classes = {s:len(self.classes[s]) for s in data_subsets}
self.n_samples = {d: len(self.images_paths[d]) for d in data_subsets}
self.indexes = {d: {cl: np.where(np.array(self.images_labels[d]) == cl)[
0] for cl in self.classes} for d in data_subsets}
0] for cl in self.classes[d]} for d in data_subsets}

def _load_images_paths(self):
for d in self.data_subsets:
Expand Down Expand Up @@ -57,8 +56,8 @@ def get_batch_pairs(self, batch_size, s='train'):

n_same_class = batch_size // 2

selected_class_idx = random.randrange(0, self.n_classes)
selected_class = self.classes[selected_class_idx]
selected_class_idx = random.randrange(0, self.n_classes[s])
selected_class = self.classes[s][selected_class_idx]
selected_class_n_elements = len(self.indexes[s][selected_class])

indxs = np.random.randint(
Expand All @@ -79,8 +78,8 @@ def get_batch_pairs(self, batch_size, s='train'):

for i in range(n_same_class, batch_size):
another_class_idx = (
selected_class_idx + random.randrange(1, self.n_classes)) % self.n_classes
another_class = self.classes[another_class_idx]
selected_class_idx + random.randrange(1, self.n_classes[s])) % self.n_classes[s]
another_class = self.classes[s][another_class_idx]
another_class_n_elements = len(self.indexes[s][another_class])
idx1 = indxs[i]
idx2 = random.randrange(0, another_class_n_elements)
Expand All @@ -103,12 +102,12 @@ def get_batch_triplets(self, batch_size, s='train'):
count = 0

for i in range(batch_size):
selected_class_idx = random.randrange(0, self.n_classes)
selected_class = self.classes[selected_class_idx]
selected_class_idx = random.randrange(0, self.n_classes[s])
selected_class = self.classes[s][selected_class_idx]
selected_class_n_elements = len(self.indexes[s][selected_class])
another_class_idx = (
selected_class_idx + random.randrange(1, self.n_classes)) % self.n_classes
another_class = self.classes[another_class_idx]
selected_class_idx + random.randrange(1, self.n_classes[s])) % self.n_classes[s]
another_class = self.classes[s][another_class_idx]
another_class_n_elements = len(self.indexes[s][another_class])

indxs = np.random.randint(
Expand Down
2 changes: 1 addition & 1 deletion siamese_net/losses_and_accuracies.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def contrastive_loss(y_true, y_pred):
margin_square = K.square(K.maximum(margin - y_pred, 0))
return K.mean(y_true * sqaure_pred + (1 - y_true) * margin_square)

def triplet_loss(y_true, y_pred, alpha = 0.4):
def triplet_loss(y_true, y_pred, alpha = 0.5):
"""
Implementation of the triplet loss function
Arguments:
Expand Down
4 changes: 3 additions & 1 deletion siamese_net/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,12 @@ def load_encodings(self, path_to_encodings):
self.encoded_training_data = load_encodings(path_to_encodings)

def load_model(self,file_path):
from keras_radam import RAdam
self.model = load_model(file_path,
custom_objects={'contrastive_loss': lac.contrastive_loss,
'accuracy': lac.accuracy,
'triplet_loss': lac.triplet_loss})
'triplet_loss': lac.triplet_loss,
'RAdam': RAdam})
self.input_shape = list(self.model.inputs[0].shape[1:])
self.base_model = Model(inputs=[self.model.layers[3].get_input_at(0)],
outputs=[self.model.layers[3].layers[-1].output])
Expand Down
2 changes: 1 addition & 1 deletion siamese_net/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def parse_net_params(filename='configs/road_signs.yml'):
optimizer = optimizers.RMSprop(lr=learning_rate)
elif cfg['optimizer'] == 'radam':
from keras_radam import RAdam
optimizer = RAdam()
optimizer = RAdam(learning_rate)
else:
optimizer = optimizers.SGD(lr=learning_rate)

Expand Down
4,560 changes: 2,273 additions & 2,287 deletions test_network.ipynb

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions train.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
batch_size = 8
val_steps = 100

model = SiameseNet('configs/road_signs.yml')
model = SiameseNet('configs/road_signs_simple2_merged_dataset.yml')

initial_lr = 1e-4
decay_factor = 0.99
decay_factor = 0.95
step_size = 1

callbacks = [
LearningRateScheduler(lambda x: initial_lr *
decay_factor ** np.floor(x/step_size)),
ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=4, verbose=1),
EarlyStopping(patience=50, verbose=1),
TensorBoard(log_dir=model.tensorboard_log_path),
ModelCheckpoint(filepath=os.path.join(model.weights_save_path, model.model_save_name),
Expand All @@ -29,7 +30,7 @@
val_steps=val_steps, epochs=n_epochs)


model.generate_encodings()
model.generate_encodings(save_file_name='encodings_simple2_merged.pkl', max_num_samples_of_each_classes=30, shuffle = True)

model_accuracy = model.calculate_prediction_accuracy()
print('Model accuracy on validation set: {}'.format(model_accuracy))

0 comments on commit 01a9b12

Please sign in to comment.