Skip to content

Commit

Permalink
Merge pull request #99 from Paeti/Adjustments_Code
Browse files Browse the repository at this point in the history
Adjustments code(model, trainer, test), Docs written
  • Loading branch information
Paeti authored Feb 7, 2019
2 parents 2628d16 + 57e72b8 commit 9c6d8af
Show file tree
Hide file tree
Showing 14 changed files with 390 additions and 419 deletions.
34 changes: 34 additions & 0 deletions docs/OurModel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
The OurModel class builds and compiles the convolutional networks for gender or age estimation.
Depending on the identifier in the construcor either a gender or a age estimation network will be build.

The model from the OurModel class consists of a vgg16 base model with the pre-trained weights from 'imagenet' and 5 additional layers.

So the structure is as follows:

16 Layer from the vgg16 base model
1 GlobalAveragePooling2D layer
2 Dense layer

1 Dense layer with sigmoid for age estimation
or
1 Dense layer with softmax for gender estimation

The structure of this model is inspired by the following paper.
https://www.vision.ee.ethz.ch/en/publications/papers/proceedings/eth_biwi_01229.pdf

As optimizer the GradientDescentOptimizer from tf.train is use.
This optimizer makes it possible to load and save the trained model as saved_model file effortlessly.
https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer


The load_model method offers the possibility to load a saved_model file and compile it allready.
So after the model is loaded with this method, it's ready for training.









12 changes: 12 additions & 0 deletions docs/Train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
This is the main method of the training. Here the training will be started, models can be loaded and/or evaluated.

Requirement for training:
Make sure to have the dataset be available in subfolders sorted by their use. So the structure is as follows:
../dataset/Train
../dataset/Valid
../dataset/Test

https://medium.com/@vijayabhaskar96/tutorial-image-classification-with-keras-flow-from-directory-and-generators-95f75ebe5720



27 changes: 27 additions & 0 deletions docs/Trainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
The Trainer class does the training for gender or age estimation depending on the identifier given in the constructor of this class.

Loading and preprocessing of the dataset will be done by the ImageDataGenerator from keras.
All the preprocessing parameters are adjusted by the preprocess_input from keras. These are the parameters which were used for the imagent weights.

The Trainer class takes use of the Cback class, which consits of the callbacks for the training.
These callbacks are in use:
EarlyStopping
batch_print_callback
json_logging_callback
cleanup_callback

For further reading:
https://keras.io/callbacks/

The train method returns the trained model and saves the model in the Trainer instance.
The trained model will be saved per default. This will be default directory for the saved model:

/IPNeuronaleNetze/models/GenderWeights for gender
or
/IPNeuronaleNetze/models/AgeWeights" for age

A .csv file will be created by the evaluate method. Use this .csv file in combination with the parser scripts to interpret the results of the training.




11 changes: 11 additions & 0 deletions docs/parsers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
The files parse_age.py and parse_gender.py are for evualtion of the .csv file created in training.
parse_age: returns the average difference in years from test dataset
parse_gender: returns the correct predictions in percent from test dataset

Requirement:
python 3

How to:
python3 parse_age csv.file_name
python3 parse_gender csv.file_name

37 changes: 37 additions & 0 deletions docs/tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
The modelTest class offers a few methods to confirm the proper functionality of the convolutional network you want to train.
It is advisable to take a small dataset with just a couple of hundreds of pictures. Due to the test environment each single step
of training will take more ressources of your computer as well as time than it would normally do.

This testclass tests the correct structure of the OurModel class, which will be used for training.
Also it tests the training itself, to confirm the right functionality within the training.

Test cases:
1. Test whether saved model file will be created after training
test_model_get_saved

2. Test whether model will be saved and loaded properly
test_model_get_saved_and_loaded_correctly

3. Test whether the weigts are changed after one step of training
test_one_training_step

4. Test whether all of the layers of a model are trainable, except the input layers
test_model_layers_allTrainable

5. Test whether Gendermodel is in expected shape
test_Gendermodel_layerLength

6. Test whether Agemodel is in expected shape
test_Agemodel_layerLength

Recommendation:
Use the test.py before the actual training.

Note:
Test case 1 and 2 will create a folder with a saved_model file.
You might want to delete these folders before the actual training.

Inspiration for the test cases:
https://medium.com/@keeper6928/how-to-unit-test-machine-learning-code-57cf6fd81765


82 changes: 36 additions & 46 deletions models/OurModel.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,57 @@
import sys, os
parent_dir = os.getcwd()
sys.path.append("/home/ip/IPNeuronaleNetze")
sys.path.append("/home/ip/IPNeuronaleNetze/trainers")
import sys
sys.path.append("/IPNeuronaleNetze")
sys.path.append("/IPNeuronaleNetze/trainers")
import tensorflow as tf

from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.applications.vgg16 import VGG16
from tensorflow.python.keras.models import Model
from tensorflow.python.keras import models
from tensorflow.python.keras.layers import Flatten, Dense, Dropout, GlobalAveragePooling2D, Input
from tensorflow.python.keras.layers import Flatten, Dense, GlobalAveragePooling2D, Input
from tensorflow.python.keras.optimizers import SGD
import numpy as np
from models.optimizer.LR_SGD import LR_SGD

from keras.utils import plot_model


class OurModel:
def __init__(self, identifier):
self.model = self.buildModel(identifier)

self.model = self.build_model(identifier)

def build_model(self, identifier):
# Load VGG16
base_model = VGG16(weights='imagenet', include_top=False)
fyipg = base_model.output

def buildModel(self, identifier):
# LOAD VGG16
base_model = VGG16(weights='imagenet', include_top=False)
fyipg = base_model.output

# add a global spatial average pooling layer
fyipg = GlobalAveragePooling2D()(fyipg)
# let's add a fully-connected layer
fyipg = Flatten(name ='Flatten1')(fyipg)
# Add a global spatial average pooling layer
fyipg = GlobalAveragePooling2D()(fyipg)
# Let's add a fully-connected layer
fyipg = Flatten(name ='Flatten1')(fyipg)
fyipg = Dense(4096, activation='relu', name='AdditianlLayer1')(fyipg)
fyipg = Dense(4096, activation='relu', name='AdditianlLayer2')(fyipg)
if identifier == 1:
fyipg = Dense(1, activation='sigmoid', name='Predictions')(fyipg)
else:
fyipg = Dense(101, activation='softmax', name='Predictions')(fyipg)

# this is the model we will train
model = Model(inputs = base_model.input , outputs = fyipg)

# Setting the Learning rate multipliers
LR_mult_dict = {}
LR_mult_dict['Flatten1'] = 100
LR_mult_dict['AdditianLayer1'] = 100
LR_mult_dict['AdditianLayer2'] = 100
LR_mult_dict['Predictions'] = 100

# Setting optimizer for model
optimizer = LR_SGD(lr=0.0001, momentum=0.9, decay=0.0005, nesterov=True, multipliers = LR_mult_dict)

# This is the model we will train
model = Model(inputs = base_model.input , outputs = fyipg)
# Setting optimizer for model
optimizer =tf.train.GradientDescentOptimizer(learning_rate = 0.0001)
# Optimize model for gender- and agemodel
if identifier == 1:
model.compile(optimizer=optimizer,
loss='binary_crossentropy', metrics=['mae'])
loss='binary_crossentropy', metrics=['mae','acc'])
else:
model.compile(optimizer= optimizer,
loss='categorical_crossentropy', metrics=['mae'])

return model


def loadModel(self, filepath):
self.model = tf.contrib.saved_model.load_keras_model(filepath)
return self.model


loss='categorical_crossentropy', metrics=['mae', 'acc'])
return model

def load_model(self, filepath, identifier):
# Load the save_model file
self.model = tf.contrib.saved_model.load_keras_model(filepath)
# Setting optimizer for model
optimizer =tf.train.GradientDescentOptimizer(learning_rate = 0.0001)
# Optimize model for gender- and agemodel
if identifier == 1:
self.model.compile(optimizer=optimizer,
loss='binary_crossentropy', metrics=['mae','acc'])
else:
self.model.compile(optimizer= optimizer,
loss='categorical_crossentropy', metrics=['mae', 'acc'])
return self.model
49 changes: 0 additions & 49 deletions models/dataloaders/image.py

This file was deleted.

72 changes: 0 additions & 72 deletions models/optimizer/LR_SGD.py

This file was deleted.

Loading

0 comments on commit 9c6d8af

Please sign in to comment.