Skip to content

Commit

Permalink
Merge pull request #12 from alessiosavi/v0.3.0
Browse files Browse the repository at this point in the history
V0.3.0
  • Loading branch information
alessiosavi committed Dec 3, 2019
2 parents 9622114 + eb6e953 commit a371c06
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 20 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,8 @@ The tool is powered with `Flask_MonitoringDashboard` that expose some useful uti
- [Pillow](https://github.com/python-pillow/Pillow) The friendly PIL fork (Python Imaging Library)
- [scikit-learn](https://github.com/scikit-learn/scikit-learn) Machine learning in Python

***NOTE***: If you encounter an error during `pip install -r requirements.txt`, it's possible that you have not installed `cmake`. `dlib` need `cmake`, and you can install using `apt install cmake -y` (debian/ubuntu) or `yum install cmake -y` (CentOS/Fedora/RedHat).

## Table Of Contents

- [PyRecognizer](#pyrecognizer)
Expand Down
7 changes: 5 additions & 2 deletions api/Api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@



def predict_image(img_path, clf, PREDICTION_PATH):
def predict_image(img_path, clf, PREDICTION_PATH,treshold=45):
"""
:param PREDICTION_PATH: global variable where image recognized are saved
Expand All @@ -30,7 +30,7 @@ def predict_image(img_path, clf, PREDICTION_PATH):
prediction = None
else:
log.debug("predict_image | Predicting {}".format(img_path))
prediction = clf.predict(img_path)
prediction = clf.predict(img_path,treshold)
log.debug("predict_image | Result: {}".format(prediction))

# Manage error
Expand Down Expand Up @@ -132,3 +132,6 @@ def tune_network(folder_uncompress, zip_file, clf):
response.description))

return response.__dict__



3 changes: 3 additions & 0 deletions api/templates/upload.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ <h1>Face recognition tool</h1>
<form enctype=multipart/form-data method=post>
<input name=file type=file>
<input type=submit value=Upload>
<br><br>
<label for="treshold">Treshold</label>
<input type="text" name="treshold" value="45">
<input name=_csrf_token type=hidden value="{{ csrf_token() }}">
</form>
{% with messages = get_flashed_messages() %}
Expand Down
2 changes: 1 addition & 1 deletion conf/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"classifier": {
"trainin_dir": "dataset/images/",
"model_path": "dataset/model/",
"timestamp": "20191125_004201"
"timestamp": "20191202_153034"
},
"data": {
"test_data": "/tmp/test_data/"
Expand Down
Binary file added dataset/face_training_dataset.zip
Binary file not shown.
Binary file removed dataset/model/20191125_004201/model.clf
Binary file not shown.
1 change: 0 additions & 1 deletion dataset/model/20191125_004201/model.json

This file was deleted.

Binary file added dataset/model/20191202_153034/model.clf
Binary file not shown.
File renamed without changes.
1 change: 1 addition & 0 deletions dataset/model/20191202_153034/model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"classifier_file": "20191202_153034/model.clf", "params": {"activation": "identity", "hidden_layer_sizes": [128], "learning_rate": "constant", "solver": "adam"}}
4 changes: 2 additions & 2 deletions datastructure/Administrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def add_user(self) -> bool:
return False

log.warning("Encrypting password -> {}".format(self.password))
self.password = self.encrypt_password(self.password)
self.password = self.encrypt_password(str(self.password))
log.warning("Passwrod encrypted {}".format(self.password))
self.redis_client.set(self.get_name(), self.password)
log.warning("User {} registered!".format(self.get_name()))
Expand All @@ -99,7 +99,7 @@ def get_name(self) -> str:
def encrypt_password(self, plain_text_password: str) -> str:
# Hash a password for the first time
# (Using bcrypt, the salt is saved into the hash itself)
return bcrypt.hashpw(plain_text_password.encode('utf-8'), bcrypt.gensalt())
return bcrypt.hashpw(plain_text_password, bcrypt.gensalt())

def check_password(self, plain_text_password: str, hashed_password: str) -> bool:
# Check hashed password. Using bcrypt, the salt is saved into the hash itself
Expand Down
13 changes: 7 additions & 6 deletions datastructure/Classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def train(self, X, Y, timestamp):

X_train, x_test, Y_train, y_test = train_test_split(
X, Y, test_size=0.25)

log.debug("train | Training ...")
self.classifier.fit(X_train, Y_train)
log.debug("train | Model Trained!")
Expand All @@ -144,18 +145,18 @@ def tuning(self, X, Y, timestamp):

X_train, x_test, Y_train, y_test = train_test_split(
X, Y, test_size=0.25)
self.classifier = MLPClassifier(max_iter=200)
self.classifier = MLPClassifier(max_iter=250)
# Hyperparameter of the neural network (MLP) to tune
# Faces are encoded using 128 points
parameter_space = {
'hidden_layer_sizes': [(200,), (100, 200, 100), (100,), ],
# 'activation': ['identity', 'tanh', 'relu'],
'activation': ['identity'],
'hidden_layer_sizes': [(128,), (200,), (200, 128,), ],
'activation': ['identity', 'tanh', 'relu'],
'solver': ['adam'],
'learning_rate': ['constant'],
'learning_rate': ['constant', 'adaptive'],
}
log.debug("tuning | Parameter -> {}".format(pformat(parameter_space)))
grid = GridSearchCV(self.classifier, parameter_space,
cv=2, scoring='accuracy', verbose=20, n_jobs=None, pre_dispatch=1)
cv=2, scoring='accuracy', verbose=20, n_jobs=8)
grid.fit(X_train, Y_train)
log.info("TUNING COMPLETE | DUMPING DATA!")
# log.info("tuning | Grid Scores: {}".format(pformat(grid.grid_scores_)))
Expand Down
26 changes: 25 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from api.Api import predict_image, train_network, tune_network
from datastructure.Classifier import Classifier
from datastructure.Administrator import Administrator
from datastructure.Response import Response
from utils.util import init_main_data, random_string, secure_request

# ===== LOAD CONFIGURATION FILE =====
Expand Down Expand Up @@ -74,10 +75,33 @@ def predict():
log.warning("predict_api | No file choosed!")
return redirect(request.url) # Return to HTML page [GET]
file = request.files['file']
treshold = request.form.get('treshold')
log.debug("Recived file [{}] and treshold [{}]".format(file,treshold))
try:
treshold = int(treshold)
except ValueError:
log.error("Unable to convert treshold")
response = Response()
response.error = "UNABLE_CAST_INT"
response.description = "Treshold is not an integer!"
response.status = "KO"
return jsonify(response=response.__dict__)
if not 0 <= treshold <= 100:
log.error("Treshold wrong value")
response = Response()
response.error = "TRESHOLD_ERROR_VALUE"
response.description = "Treshold have to be greater than 0 and lesser than 100!"
response.status = "KO"
return jsonify(response=response.__dict__)

treshold /= 100


log.debug("Recived file {} and treshold {}".format(file,treshold))
filename = secure_filename(file.filename)
img_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(img_path)
return jsonify(response=predict_image(img_path, clf, TMP_UPLOAD_PREDICTION))
return jsonify(response=predict_image(img_path, clf, TMP_UPLOAD_PREDICTION,treshold))


@app.route('/train', methods=['GET'])
Expand Down
15 changes: 8 additions & 7 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
Flask==1.1.1
Flask_Login==0.2.9
face_recognition==1.2.3
scikit-learn==0.21.3
tqdm==4.39.0
redis==3.3.11
Flask_MonitoringDashboard==3.0.5
werkzeug==0.16.0
Flask==1.1.1
numpy==1.17.4
tqdm==4.39.0
Werkzeug==0.16.0
Pillow==6.2.1
numpy
redis

py-bcrypt
scikit_learn==0.21.3

0 comments on commit a371c06

Please sign in to comment.