Compare commits

..
Author SHA1 Message Date
Jake Miller dc8a7b0302 Display help by default and add verbose opt
Unfortunately, this will only somewhat quiet down tensorflow, but it helps
2019-05-17 15:49:23 -04:00
6 changed files with 23 additions and 63 deletions

No files matched your search

+1 -5
View File
@@ -32,11 +32,7 @@ endif
$(PIP) install --upgrade -r $(REQUIREMENTS)
@echo -e $(TAG)Installing Eyeballer$(END)
ifeq ($(shell lspci | grep NVIDIA),NVIDIA))
$(PIP) install --upgrade --editable .[tf_gpu]
else
$(PIP) install --upgrade --editable .[tf]
endif
$(PIP) install --upgrade --editable .
ifeq ($(strip $(MAKECMDGOALS)),conda)
@echo -e $(TAG)Activate virtualenv to run eyeballer: $(END)
-1
View File
@@ -1 +0,0 @@
from eyeballer.model import EyeballModel # noqa: F401
+10 -4
View File
@@ -2,6 +2,7 @@
import click
import csv
import os
from eyeballer.model import EyeballModel, DATA_LABELS
from eyeballer.visualization import HeatMap
@@ -9,10 +10,17 @@ from eyeballer.visualization import HeatMap
@click.group(invoke_without_command=True)
@click.option('--weights', default=None, type=click.Path(), help="Weights file for input/output")
@click.option('-v', '--verbose', default=False, help="Verbose TensorFlow Output")
@click.option('--summary/--no-summary', default=False, help="Print model summary at start")
@click.option('--seed', default=None, type=int, help="RNG seed for data shuffling and transformations, defaults to random value")
@click.pass_context
def cli(ctx, weights, summary, seed):
def cli(ctx, weights, verbose, summary, seed):
if ctx.invoked_subcommand is None:
print(ctx.get_help())
if not verbose:
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
model_kwargs = {"weights_file": weights,
"print_summary": summary,
"seed": seed}
@@ -65,10 +73,8 @@ def pretty_print_evaluation(results):
for label in DATA_LABELS:
print(f"{label} Precision Score: {results[label]['precision']:4.2%}")
print(f"{label} Recall Score: {results[label]['recall']:4.2%}")
print(f"'None of the above' Precision: {results['none_of_the_above_precision']:4.2%}")
print(f"'None of the above' Recall: {results['none_of_the_above_recall']:4.2%}")
print(f"All or nothing Accuracy: {results['all_or_nothing_accuracy']:4.2%}")
print(f"Overall Binary Accuracy: {results['total_binary_accuracy']:4.2%}")
print(f"All or nothing accuracy: {results['all_or_nothing_accuracy']:4.2%}")
print(f"Top 10 worst predictions: {results['top_10_worst'][1]}")
+3 -40
View File
@@ -1,6 +1,5 @@
import os
import random
import sys
# Prevent Tkinter Dependency
import matplotlib
@@ -51,7 +50,7 @@ class EyeballModel:
image_width, image_height = 224, 224
input_shape = (image_width, image_height, 3)
def __init__(self, weights_file, print_summary=False, seed=None):
def __init__(self, print_summary=False, weights_file="weights.h5", seed=None):
"""Constructor for model class.
Keyword arguments:
@@ -96,16 +95,10 @@ class EyeballModel:
self.training_labels = self.training_labels.sample(frac=1)
if weights_file is not None and os.path.isfile(weights_file):
try:
self.model.load_weights(weights_file)
except OSError:
print(f"ERROR: Unable to open weights file '{weights_file}'")
sys.exit(-1)
self.model.load_weights(weights_file)
print("Loaded model from file.")
else:
if weights_file is not None:
raise FileNotFoundError
print("WARN: No model loaded from file. Generating random model")
print("No model loaded from file")
# Data augmentation
augmentor = Augmentor.Pipeline()
@@ -313,38 +306,8 @@ class EyeballModel:
stats["all_or_nothing_accuracy"] = accuracy_score(ground_truth, predictions)
stats["top_10_best"] = self._top_images(evaluation_generator, predictions, best=True)
stats["top_10_worst"] = self._top_images(evaluation_generator, predictions, best=False)
stats["none_of_the_above_recall"] = self._none_of_the_above_recall(ground_truth, predictions)
stats["none_of_the_above_precision"] = self._none_of_the_above_precision(ground_truth, predictions)
return stats
def _none_of_the_above_recall(self, labels, predictions):
"""Returns the recall score for the 'none of the above' images.
That means, all the images that don't have a category.
"""
total_count = 0
correct_count = 0
for item in zip(labels.astype(int), predictions.astype(int)):
# Is this a none of the above?
if not item[0].any():
total_count += 1
if not item[1].any():
correct_count += 1
return correct_count / total_count
def _none_of_the_above_precision(self, labels, predictions):
"""Returns the precision score for the 'none of the above' images.
That means, all the images that don't have a category.
"""
total_count = 0
correct_count = 0
for item in zip(labels.astype(int), predictions.astype(int)):
# Is this a none of the above prediction?
if not item[1].any():
total_count += 1
if not item[0].any():
correct_count += 1
return correct_count / total_count
def _top_images(self, labels, predictions, top_k=10, best=False):
"""Collect top-k best or top-k worst predicted images
+2 -5
View File
@@ -6,7 +6,7 @@ setup(
packages=find_packages(exclude=["tests"]),
url='https://github.com/BishopFox/eyeballer',
license='GNU General Public License v3.0',
author='Bishop Fox',
author='Daniel Petro',
author_email='',
description='',
entry_points={
@@ -22,12 +22,9 @@ setup(
'pandas',
'pillow',
'sklearn',
'tensorflow',
'keras @ git+https://github.com/keras-team/keras',
],
extras_require={
'tf': ['tensorflow'],
'tf_gpu': ['tensorflow-gpu'],
},
dependency_links=[
],
)
+7 -8
View File
@@ -2,8 +2,7 @@ import errno
import os
import unittest
from eyeballer.model import EyeballModel
from eyeballer.model import EyeballModel, DATA_LABELS
class PredictTest(unittest.TestCase):
def setUp(self):
@@ -11,9 +10,9 @@ class PredictTest(unittest.TestCase):
if not os.path.isfile(weights_file):
print("Error: Symlink the latest weights file to 'latest_weights.h5'")
raise FileNotFoundError(
errno.ENOENT,
os.strerror(errno.ENOENT),
weights_file)
errno.ENOENT,
os.strerror(errno.ENOENT),
weights_file)
model_kwargs = {
"weights_file": weights_file,
@@ -52,15 +51,15 @@ class PredictTest(unittest.TestCase):
self.assertEquals(results_one, results_two)
def get_prediction_by_name(self, results):
def get_prediction_by_name(self,results):
prediction = None
max_val = 0.0
print(results)
for k, v in results[0].items():
if not isinstance(v, str) and v > max_val:
prediction = k
max_val = v
prediction = k
max_val = v
return prediction
def test_predict_custom404(self):