diff --git a/.gitignore b/.gitignore index 9dfe74e86..6cd2bb5f5 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,4 @@ TAGS #.project .project - - -/examples/binary-segmentation/out/ -/examples/binary-segmentation/out2/ \ No newline at end of file +/.project diff --git a/.travis.yml b/.travis.yml index 841896b77..0912ddfb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. + os: linux dist: trusty sudo: required @@ -9,7 +10,6 @@ env: global: - CAFFE_ROOT=~/caffe - TORCH_ROOT=~/torch - # Fixes for Torch and OpenBLAS - OMP_NUM_THREADS=1 - OPENBLAS_MAIN_FREE=1 - secure: "WSqrE+PQm76DdoRLRGKTK6fRWfXZjIb0BWCZm3IgHgFO7OE6fcK2tBnpDNNw4XQjmo27FFWlEhxN32g18P84n5PvErHaH65IuS9Nv6FkLlPXZlVqGNxbPmEA4oTkD/6Y6kZyZWZtLh2+/1ijuzQAPnIy/4BEuL8pdO+PsoJ9hYM=" @@ -19,6 +19,7 @@ env: - DIGITS_TEST_FRAMEWORK=torch - DIGITS_TEST_FRAMEWORK=tensorflow - DIGITS_TEST_FRAMEWORK=none + - DIGITS_TEST_FRAMEWORK=none WITH_PLUGINS=false matrix: include: @@ -42,6 +43,7 @@ matrix: - dput - gnupg install: + - git fetch --unshallow - git remote add nvidia-digits-upstream https://github.com/NVIDIA/DIGITS.git # for forks - git fetch nvidia-digits-upstream --tags - pip install twine @@ -128,13 +130,12 @@ install: - mkdir -p ~/.config/matplotlib - echo "backend:agg" > ~/.config/matplotlib/matplotlibrc - ./scripts/travis/install-caffe.sh $CAFFE_ROOT - - if [ "$DIGITS_TEST_FRAMEWORK" == "torch" ]; then travis_wait ./scripts/travis/install-torch.sh $TORCH_ROOT; else unset TORCH_ROOT; fi - if [ "$DIGITS_TEST_FRAMEWORK" == "tensorflow" ]; then travis_wait ./scripts/travis/install-tensorflow.sh; fi + - if [ "$DIGITS_TEST_FRAMEWORK" == "torch" ]; then travis_wait ./scripts/travis/install-torch.sh $TORCH_ROOT; else unset TORCH_ROOT; fi - pip install -r ./requirements.txt - pip install -r ./requirements_test.txt - pip install -e . - - pip install -e ./plugins/data/imageGradients - - pip install -e ./plugins/view/imageGradients + - if [ "$WITH_PLUGINS" != "false" ]; then find ./plugins/*/* -maxdepth 0 -type d | xargs -n1 pip install -e; fi script: - ./digits-test -v diff --git a/LICENSE b/LICENSE index aa450a092..61e21d27a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/README.md b/README.md index a7dcbdb13..434ccae73 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ DIGITS (the **D**eep Learning **G**PU **T**raining **S**ystem) is a webapp for t | Installation method | Supported platform[s] | Available versions | Instructions | | --- | --- | --- | --- | -| Deb packages | Ubuntu 14.04 | [14.04 repo](http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1404/x86_64) | [docs/UbuntuInstall.md](docs/UbuntuInstall.md) | +| Deb packages | Ubuntu 14.04, 16.04 | [14.04 repo](http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1404/x86_64), [16.04 repo](http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64) | [docs/UbuntuInstall.md](docs/UbuntuInstall.md) | | Docker | Linux | [DockerHub tags](https://hub.docker.com/r/nvidia/digits/tags/) | [nvidia-docker wiki](https://github.com/NVIDIA/nvidia-docker/wiki/DIGITS) | | Source | Ubuntu 14.04, 16.04 | [GitHub tags](https://github.com/NVIDIA/DIGITS/releases) | [docs/BuildDigits.md](docs/BuildDigits.md) | diff --git a/digits-devserver b/digits-devserver index 604f07af7..642fdd0ca 100755 --- a/digits-devserver +++ b/digits-devserver @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. set -e diff --git a/digits-lint b/digits-lint index e70be10f7..b11b50021 100755 --- a/digits-lint +++ b/digits-lint @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. set -e diff --git a/digits-test b/digits-test index a4aae59c5..3dbc8005c 100755 --- a/digits-test +++ b/digits-test @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. set -e diff --git a/digits-walkthrough b/digits-walkthrough deleted file mode 100755 index 290baccfa..000000000 --- a/digits-walkthrough +++ /dev/null @@ -1,240 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. - -import argparse -import json -import os -import requests -import socket -import sys -import time -from urlparse import urlparse - -from selenium import webdriver -from selenium.webdriver.common.action_chains import ActionChains -from selenium.webdriver.common.keys import Keys - -wait_time = 2 - - -def wait(s=wait_time): - time.sleep(s) - - -def get_page(driver, url): - driver.get(url) - wait() - - -def create_dataset(driver, name, folder): - dropdown_elements = driver.find_elements_by_class_name('dropdown-toggle') - dropdown_dataset = dropdown_elements[0] - dropdown_dataset.click() - wait() - - dropdown_menu = driver.find_elements_by_class_name('dropdown-menu') - dropdown_menu_dataset = dropdown_menu[0] - dataset_link = dropdown_menu_dataset.find_element_by_tag_name('a') - dataset_link.click() - wait() - - folder_train_tooltip = driver.find_element_by_name('folder_train_explanation') - folder_train_tooltip.click() - wait() - - folder_train = driver.find_element_by_name('folder_train') - folder_train.send_keys(folder) - wait() - - resize_channels_tooltip = driver.find_element_by_name('resize_channels_explanation') - resize_channels_tooltip.click() - wait() - - image_type = driver.find_element_by_name('resize_channels') - image_type.click() - wait() - for option in image_type.find_elements_by_tag_name('option'): - if option.text == 'Grayscale': - image_type.click() - option.click() - break - wait() - - resize_width_tooltip = driver.find_element_by_name('resize_dims_explanation') - resize_width_tooltip.click() - wait() - - resize_width = driver.find_element_by_name('resize_width') - resize_width.clear() - resize_width.send_keys('28') - wait() - - resize_height = driver.find_element_by_name('resize_height') - resize_height.clear() - resize_height.send_keys('28') - wait() - - dataset_name = driver.find_element_by_name('dataset_name') - dataset_name.click() - dataset_name.send_keys(name) - wait() - - create_button = driver.find_element_by_name('create-dataset') - create_button.click() - - job_url = driver.current_url.replace('datasets', 'jobs') - status_url = job_url + '/status' - done = False - while not done: - r = requests.get(status_url) - status = json.loads(r.content) - done = status['status'] == 'Done' - wait() - wait() - - -def create_model(driver, name, dataset_name, test_image): - dropdown_elements = driver.find_elements_by_class_name('dropdown-toggle') - dropdown_model = dropdown_elements[1] - dropdown_model.click() - wait() - - dropdown_menu = driver.find_elements_by_class_name('dropdown-menu') - dropdown_menu_model = dropdown_menu[1] - model_link = dropdown_menu_model.find_element_by_tag_name('a') - model_link.click() - # move to 0,0 so we don't accidentally select a hover element - body = driver.find_element_by_css_selector('body') - body.click() - wait() - - dataset_tooltip = driver.find_element_by_name('dataset_explanation') - dataset_tooltip.click() - wait() - - datasets = driver.find_element_by_name('dataset') - for option in datasets.find_elements_by_tag_name('option'): - if option.text == dataset_name: - option.click() - break - wait() - - standard_networks = driver.find_elements_by_name('standard_networks') - lenet = standard_networks[0] - lenet.click() - wait() - - model_name = driver.find_element_by_name('model_name') - model_name.click() - model_name.send_keys(name) - wait() - - create_button = driver.find_element_by_name('create-model') - create_button.click() - - job_url = driver.current_url.replace('models', 'jobs') - status_url = job_url + '/status' - done = False - while not done: - r = requests.get(status_url) - status = json.loads(r.content) - done = status['status'] == 'Done' - wait() - # driver.refresh() - - # test image - print 'Testing...' - image_path = driver.find_element_by_name('image_url') - image_path.send_keys(test_image) - wait() - - show_visualizations_tooltip = driver.find_element_by_name('show_visualizations_explanation') - show_visualizations_tooltip.click() - wait() - - show_visualizations = driver.find_element_by_name('show_visualizations') - show_visualizations.click() - wait() - - test_button = driver.find_element_by_name('classify-one-btn') - test_button.click() - - # Opens in a new window - switch to it - driver.close() - driver.switch_to_window(driver.window_handles[-1]) - - -def main(argv): - parser = argparse.ArgumentParser(description='Run a Selenium demo of DIGITS') - - # Positional arguments - - parser.add_argument('mnist_image_folder', - type=str, - help='Path to the MNIST dataset folder') - parser.add_argument('test_image', - type=str, - help='Image to test with') - - # Optional arguments - - parser.add_argument('-p', '--port', - type=int, - default=80, - help='Port the server is running on (default 80)') - - args = vars(parser.parse_args()) - - home_page = 'http://0.0.0.0:%d/' % args['port'] - dataset_path = args['mnist_image_folder'] - dataset_name = 'MNIST Dataset' - model_name = 'MNIST Model' - test_image = args['test_image'] - - r = requests.get(home_page) - assert r.status_code == requests.codes.ok, 'page "%s" does not exist - are you looking on the wrong port?' % home_page - - # Start selenium driver. - driver = webdriver.Firefox() - print 'Firefox webdriver started.' - mouse = webdriver.ActionChains(driver) - - try: - driver.maximize_window() - - get_page(driver, home_page) - - print 'Creating dataset...' - create_dataset(driver, dataset_name, dataset_path) - - get_page(driver, home_page) - - print 'Creating model...' - create_model(driver, model_name, dataset_name, test_image) - - print 'Done.' - - # display an alert message - get_page(driver, "javascript:alert('Completed Walkthrough!');void(0);") - wait() - driver.switch_to_alert().accept() - - # wait until the window is closed - while True: - try: - get_page(driver, "javascript:console.log('Waiting...');void(0);") - except Exception as e: - print e - break - wait() - - except KeyboardInterrupt: - pass - finally: - try: - driver.quit() - except socket.error: - pass - -if __name__ == '__main__': - main(sys.argv) diff --git a/digits/__init__.py b/digits/__init__.py index c5b2642fd..0eb5e59f9 100644 --- a/digits/__init__.py +++ b/digits/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .version import __version__ diff --git a/digits/__main__.py b/digits/__main__.py index 95c453424..0bbfac5bf 100644 --- a/digits/__main__.py +++ b/digits/__main__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. import argparse import os.path diff --git a/digits/config/__init__.py b/digits/config/__init__.py index 3495ed6c2..060d7b36c 100644 --- a/digits/config/__init__.py +++ b/digits/config/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import # Create this object before importing the following imports, since they edit the list diff --git a/digits/config/caffe.py b/digits/config/caffe.py index d389397ce..db8aedc94 100644 --- a/digits/config/caffe.py +++ b/digits/config/caffe.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import imp diff --git a/digits/config/gpu_list.py b/digits/config/gpu_list.py index 9cc9f37de..32c9b6e41 100644 --- a/digits/config/gpu_list.py +++ b/digits/config/gpu_list.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from . import option_list diff --git a/digits/config/jobs_dir.py b/digits/config/jobs_dir.py index cf654fb45..e28d5ea68 100644 --- a/digits/config/jobs_dir.py +++ b/digits/config/jobs_dir.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os diff --git a/digits/config/log_file.py b/digits/config/log_file.py index edbb35ef5..fe469052a 100644 --- a/digits/config/log_file.py +++ b/digits/config/log_file.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import logging diff --git a/digits/config/server_name.py b/digits/config/server_name.py index 44a9fa54d..169465883 100644 --- a/digits/config/server_name.py +++ b/digits/config/server_name.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os diff --git a/digits/config/store_option.py b/digits/config/store_option.py index 87df162c0..474152e5d 100644 --- a/digits/config/store_option.py +++ b/digits/config/store_option.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os @@ -29,7 +29,7 @@ def load_url_list(): if 'DIGITS_MODEL_STORE_URL' in os.environ: url_list = os.environ['DIGITS_MODEL_STORE_URL'] else: - url_list = "" + url_list = "http://developer.download.nvidia.com/compute/machine-learning/modelstore/5.0" return validate(url_list).split(',') diff --git a/digits/config/torch.py b/digits/config/torch.py index 36862ad3f..2d04fe5e0 100644 --- a/digits/config/torch.py +++ b/digits/config/torch.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os diff --git a/digits/dataset/__init__.py b/digits/dataset/__init__.py index 3e3f880f0..218933bc8 100644 --- a/digits/dataset/__init__.py +++ b/digits/dataset/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .images import ImageClassificationDatasetJob, GenericImageDatasetJob diff --git a/digits/dataset/forms.py b/digits/dataset/forms.py index aca2a4539..e8133ff75 100644 --- a/digits/dataset/forms.py +++ b/digits/dataset/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from flask.ext.wtf import Form diff --git a/digits/dataset/generic/__init__.py b/digits/dataset/generic/__init__.py index 9dce4cff5..850b095b4 100644 --- a/digits/dataset/generic/__init__.py +++ b/digits/dataset/generic/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .job import GenericDatasetJob diff --git a/digits/dataset/generic/forms.py b/digits/dataset/generic/forms.py index 73f4f5905..5ade5301f 100644 --- a/digits/dataset/generic/forms.py +++ b/digits/dataset/generic/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import wtforms diff --git a/digits/dataset/generic/job.py b/digits/dataset/generic/job.py index 5dea7b0a5..e40b0d44d 100644 --- a/digits/dataset/generic/job.py +++ b/digits/dataset/generic/job.py @@ -1,11 +1,11 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from ..job import DatasetJob from digits.dataset import tasks from digits.utils import subclass, override, constants -# NOTE: Increment this everytime the pickled object changes +# NOTE: Increment this every time the pickled object changes PICKLE_VERSION = 1 diff --git a/digits/dataset/generic/test_views.py b/digits/dataset/generic/test_views.py index 89c6eb31d..b80148baf 100644 --- a/digits/dataset/generic/test_views.py +++ b/digits/dataset/generic/test_views.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import json @@ -199,6 +199,12 @@ def setUpClass(cls, **kwargs): class GenericViewsTest(BaseViewsTest): + @classmethod + def setUpClass(cls, **kwargs): + if extensions.data.get_extension(cls.EXTENSION_ID) is None: + raise unittest.SkipTest('Extension "%s" is not installed' % cls.EXTENSION_ID) + super(GenericViewsTest, cls).setUpClass() + def test_page_dataset_new(self): rv = self.app.get('/datasets/generic/new/%s' % self.EXTENSION_ID) print rv.data diff --git a/digits/dataset/generic/views.py b/digits/dataset/generic/views.py index 1669c17ae..9ef3ac87e 100644 --- a/digits/dataset/generic/views.py +++ b/digits/dataset/generic/views.py @@ -1,6 +1,7 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import +import os # Find the best implementation available try: from cStringIO import StringIO @@ -147,8 +148,9 @@ def explore(): db = job.path(flask.request.args.get('db')) db_path = job.path(db) - if COLOR_PALETTE_ATTRIBUTE in job.extension_userdata \ - and job.extension_userdata[COLOR_PALETTE_ATTRIBUTE]: + if (os.path.basename(db_path) == 'labels' and + COLOR_PALETTE_ATTRIBUTE in job.extension_userdata and + job.extension_userdata[COLOR_PALETTE_ATTRIBUTE]): # assume single-channel 8-bit palette palette = job.extension_userdata[COLOR_PALETTE_ATTRIBUTE] palette = np.array(palette).reshape((len(palette) / 3, 3)) / 255. diff --git a/digits/dataset/images/__init__.py b/digits/dataset/images/__init__.py index 68614e717..10592e541 100644 --- a/digits/dataset/images/__init__.py +++ b/digits/dataset/images/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .classification import * # noqa diff --git a/digits/dataset/images/classification/__init__.py b/digits/dataset/images/classification/__init__.py index f5dc36b05..71bb756d4 100644 --- a/digits/dataset/images/classification/__init__.py +++ b/digits/dataset/images/classification/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .job import ImageClassificationDatasetJob diff --git a/digits/dataset/images/classification/forms.py b/digits/dataset/images/classification/forms.py index 0d84f50cd..6b31fcec0 100644 --- a/digits/dataset/images/classification/forms.py +++ b/digits/dataset/images/classification/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os.path diff --git a/digits/dataset/images/classification/job.py b/digits/dataset/images/classification/job.py index 8e69b879c..eb61e7e41 100644 --- a/digits/dataset/images/classification/job.py +++ b/digits/dataset/images/classification/job.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os @@ -8,7 +8,7 @@ from digits.status import Status from digits.utils import subclass, override, constants -# NOTE: Increment this everytime the pickled object changes +# NOTE: Increment this every time the pickled object changes PICKLE_VERSION = 2 diff --git a/digits/dataset/images/classification/test_imageset_creator.py b/digits/dataset/images/classification/test_imageset_creator.py index e1e621693..1c5fcbd2b 100755 --- a/digits/dataset/images/classification/test_imageset_creator.py +++ b/digits/dataset/images/classification/test_imageset_creator.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. """ Functions for creating temporary datasets Used in test_views diff --git a/digits/dataset/images/classification/test_views.py b/digits/dataset/images/classification/test_views.py index ee5cc07cb..b3d7a1205 100644 --- a/digits/dataset/images/classification/test_views.py +++ b/digits/dataset/images/classification/test_views.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import json diff --git a/digits/dataset/images/classification/views.py b/digits/dataset/images/classification/views.py index 76948807d..42b201029 100644 --- a/digits/dataset/images/classification/views.py +++ b/digits/dataset/images/classification/views.py @@ -1,7 +1,8 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os +import shutil # Find the best implementation available try: @@ -156,12 +157,14 @@ def from_files(job, form): """ # labels if form.textfile_use_local_files.data: - job.labels_file = form.textfile_local_labels_file.data.strip() + labels_file_from = form.textfile_local_labels_file.data.strip() + labels_file_to = os.path.join(job.dir(), utils.constants.LABELS_FILE) + shutil.copyfile(labels_file_from, labels_file_to) else: flask.request.files[form.textfile_labels_file.name].save( os.path.join(job.dir(), utils.constants.LABELS_FILE) ) - job.labels_file = utils.constants.LABELS_FILE + job.labels_file = utils.constants.LABELS_FILE shuffle = bool(form.textfile_shuffle.data) backend = form.backend.data diff --git a/digits/dataset/images/forms.py b/digits/dataset/images/forms.py index b7032bdaa..72eac5a40 100644 --- a/digits/dataset/images/forms.py +++ b/digits/dataset/images/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import wtforms diff --git a/digits/dataset/images/generic/__init__.py b/digits/dataset/images/generic/__init__.py index 3804042dd..3145d6c9a 100644 --- a/digits/dataset/images/generic/__init__.py +++ b/digits/dataset/images/generic/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .job import GenericImageDatasetJob diff --git a/digits/dataset/images/generic/forms.py b/digits/dataset/images/generic/forms.py index 8783566d1..509c79aa0 100644 --- a/digits/dataset/images/generic/forms.py +++ b/digits/dataset/images/generic/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os.path diff --git a/digits/dataset/images/generic/job.py b/digits/dataset/images/generic/job.py index 14eec9e67..afb40bba6 100644 --- a/digits/dataset/images/generic/job.py +++ b/digits/dataset/images/generic/job.py @@ -1,11 +1,11 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from ..job import ImageDatasetJob from digits.dataset import tasks from digits.utils import subclass, override, constants -# NOTE: Increment this everytime the pickled object changes +# NOTE: Increment this every time the pickled object changes PICKLE_VERSION = 1 diff --git a/digits/dataset/images/generic/test_lmdb_creator.py b/digits/dataset/images/generic/test_lmdb_creator.py index 19a90a210..b7b0a2145 100755 --- a/digits/dataset/images/generic/test_lmdb_creator.py +++ b/digits/dataset/images/generic/test_lmdb_creator.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. """ Functions for creating temporary LMDBs Used in test_views diff --git a/digits/dataset/images/generic/test_views.py b/digits/dataset/images/generic/test_views.py index 81fe0cf6f..85b4ec593 100644 --- a/digits/dataset/images/generic/test_views.py +++ b/digits/dataset/images/generic/test_views.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import json diff --git a/digits/dataset/images/generic/views.py b/digits/dataset/images/generic/views.py index 651c8cc0f..e7a0c944f 100644 --- a/digits/dataset/images/generic/views.py +++ b/digits/dataset/images/generic/views.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import flask diff --git a/digits/dataset/images/job.py b/digits/dataset/images/job.py index beb76ec96..6b351dce3 100644 --- a/digits/dataset/images/job.py +++ b/digits/dataset/images/job.py @@ -1,9 +1,9 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from ..job import DatasetJob -# NOTE: Increment this everytime the pickled object changes +# NOTE: Increment this every time the pickled object changes PICKLE_VERSION = 1 diff --git a/digits/dataset/images/views.py b/digits/dataset/images/views.py index 9f9a17731..fdef36c36 100644 --- a/digits/dataset/images/views.py +++ b/digits/dataset/images/views.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os.path diff --git a/digits/dataset/job.py b/digits/dataset/job.py index e75a39d0e..12aa79112 100644 --- a/digits/dataset/job.py +++ b/digits/dataset/job.py @@ -1,10 +1,10 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from digits.job import Job from digits.utils import subclass -# NOTE: Increment this everytime the pickled object changes +# NOTE: Increment this every time the pickled object changes PICKLE_VERSION = 1 diff --git a/digits/dataset/tasks/__init__.py b/digits/dataset/tasks/__init__.py index 52b984bc4..7b7831334 100644 --- a/digits/dataset/tasks/__init__.py +++ b/digits/dataset/tasks/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .analyze_db import AnalyzeDbTask diff --git a/digits/dataset/tasks/analyze_db.py b/digits/dataset/tasks/analyze_db.py index 9c197b675..360af2a40 100644 --- a/digits/dataset/tasks/analyze_db.py +++ b/digits/dataset/tasks/analyze_db.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os.path @@ -9,7 +9,7 @@ from digits.task import Task from digits.utils import subclass, override -# NOTE: Increment this everytime the pickled object +# NOTE: Increment this every time the pickled object PICKLE_VERSION = 1 diff --git a/digits/dataset/tasks/create_db.py b/digits/dataset/tasks/create_db.py index 81777def0..48538bee5 100644 --- a/digits/dataset/tasks/create_db.py +++ b/digits/dataset/tasks/create_db.py @@ -1,7 +1,6 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import -import operator import os.path import re import sys @@ -11,7 +10,7 @@ from digits.task import Task from digits.utils import subclass, override -# NOTE: Increment this everytime the pickled version changes +# NOTE: Increment this every time the pickled version changes PICKLE_VERSION = 3 @@ -62,6 +61,7 @@ def __init__(self, input_file, db_name, backend, image_dims, **kwargs): self.image_channel_order = None self.entries_count = None + self.entries_error = None self.distribution = None self.create_db_log_file = "create_%s.log" % db_name @@ -100,6 +100,14 @@ def __setstate__(self, state): if not hasattr(self, 'compression') or self.compression is None: self.compression = 'none' + if not hasattr(self, 'entries_error'): + self.entries_error = 0 + for key in self.distribution.keys(): + self.distribution[key] = { + 'count': self.distribution[key], + 'error_count': 0 + } + @override def name(self): if self.db_name == utils.constants.TRAIN_DB or 'train' in self.db_name.lower(): @@ -170,8 +178,6 @@ def task_arguments(self, resources, env): @override def process_output(self, line): - from digits.webapp import socketio - self.create_db_log.write('%s\n' % line) self.create_db_log.flush() @@ -192,19 +198,22 @@ def process_output(self, line): if not hasattr(self, 'distribution') or self.distribution is None: self.distribution = {} - self.distribution[match.group(1)] = int(match.group(2)) - - data = self.distribution_data() - if data: - socketio.emit('task update', - { - 'task': self.html_id(), - 'update': 'distribution', - 'data': data, - }, - namespace='/jobs', - room=self.job_id, - ) + self.distribution[match.group(1)] = { + 'count': int(match.group(2)), + 'error_count': 0 + } + self.update_distribution_graph() + return True + + # add errors to the distribution + match = re.match(r'\[(.+) (\d+)\] LoadImageError: (.+)', message) + if match: + self.distribution[match.group(2)]['count'] -= 1 + self.distribution[match.group(2)]['error_count'] += 1 + if self.entries_error is None: + self.entries_error = 0 + self.entries_error += 1 + self.update_distribution_graph() return True # result @@ -302,20 +311,32 @@ def distribution_data(self): if len(self.distribution.keys()) != len(labels): return None - values = ['Count'] + label_count = 'Count' + label_error = 'LoadImageError' + + error_values = [label_error] + count_values = [label_count] titles = [] for key, value in sorted( self.distribution.items(), - key=operator.itemgetter(1), + key=lambda item: item[1]['count'], reverse=True): - values.append(value) + count_values.append(value['count']) + error_values.append(value['error_count']) titles.append(labels[int(key)]) + # distribution graph always displays the Count data + data = {'columns': [count_values], 'type': 'bar'} + + # only display error data if any error occurred + if sum(error_values[1:]) > 0: + data['columns'] = [count_values, error_values] + data['groups'] = [[label_count, label_error]] + data['colors'] = {label_count: '#1F77B4', label_error: '#B73540'} + data['order'] = 'false' + return { - 'data': { - 'columns': [values], - 'type': 'bar' - }, + 'data': data, 'axis': { 'x': { 'type': 'category', @@ -323,3 +344,18 @@ def distribution_data(self): } }, } + + def update_distribution_graph(self): + from digits.webapp import socketio + data = self.distribution_data() + + if data: + socketio.emit('task update', + { + 'task': self.html_id(), + 'update': 'distribution', + 'data': data, + }, + namespace='/jobs', + room=self.job_id, + ) diff --git a/digits/dataset/tasks/create_generic_db.py b/digits/dataset/tasks/create_generic_db.py index 7d890096c..1ec8a96f8 100644 --- a/digits/dataset/tasks/create_generic_db.py +++ b/digits/dataset/tasks/create_generic_db.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os @@ -9,7 +9,7 @@ from digits.task import Task from digits.utils import subclass, override -# NOTE: Increment this everytime the pickled version changes +# NOTE: Increment this every time the pickled version changes PICKLE_VERSION = 1 diff --git a/digits/dataset/tasks/parse_folder.py b/digits/dataset/tasks/parse_folder.py index 8181e89e5..1450801a6 100644 --- a/digits/dataset/tasks/parse_folder.py +++ b/digits/dataset/tasks/parse_folder.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os.path @@ -10,7 +10,7 @@ from digits.task import Task from digits.utils import subclass, override -# NOTE: Increment this everytime the pickled object +# NOTE: Increment this every time the pickled object PICKLE_VERSION = 1 diff --git a/digits/dataset/views.py b/digits/dataset/views.py index cb0a42244..7a0751e9c 100644 --- a/digits/dataset/views.py +++ b/digits/dataset/views.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import flask diff --git a/digits/device_query.py b/digits/device_query.py index f7d140085..9f13a09cd 100755 --- a/digits/device_query.py +++ b/digits/device_query.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import argparse diff --git a/digits/download_data/__main__.py b/digits/download_data/__main__.py index 38a67aea3..83498e249 100644 --- a/digits/download_data/__main__.py +++ b/digits/download_data/__main__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. import argparse import sys diff --git a/digits/download_data/cifar10.py b/digits/download_data/cifar10.py index 30290206a..0d50b3787 100644 --- a/digits/download_data/cifar10.py +++ b/digits/download_data/cifar10.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. import cPickle import os diff --git a/digits/download_data/cifar100.py b/digits/download_data/cifar100.py index 8c17b9579..1ede1ce76 100644 --- a/digits/download_data/cifar100.py +++ b/digits/download_data/cifar100.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. import cPickle import os diff --git a/digits/download_data/downloader.py b/digits/download_data/downloader.py index e481e1b5b..ea3157906 100644 --- a/digits/download_data/downloader.py +++ b/digits/download_data/downloader.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. import os import shutil diff --git a/digits/download_data/mnist.py b/digits/download_data/mnist.py index fa83fc41a..e858b5ddb 100644 --- a/digits/download_data/mnist.py +++ b/digits/download_data/mnist.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. import gzip import os diff --git a/digits/extensions/__init__.py b/digits/extensions/__init__.py index 680b3dfe2..dc4cfe3a2 100644 --- a/digits/extensions/__init__.py +++ b/digits/extensions/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .data import * # noqa diff --git a/digits/extensions/data/__init__.py b/digits/extensions/data/__init__.py index 305eefca1..56f3b8a37 100644 --- a/digits/extensions/data/__init__.py +++ b/digits/extensions/data/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import copy diff --git a/digits/extensions/data/imageProcessing/__init__.py b/digits/extensions/data/imageProcessing/__init__.py index 79071170e..9bf25978c 100644 --- a/digits/extensions/data/imageProcessing/__init__.py +++ b/digits/extensions/data/imageProcessing/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .data import DataIngestion diff --git a/digits/extensions/data/imageProcessing/data.py b/digits/extensions/data/imageProcessing/data.py index cd3bc72a6..cb03a19be 100644 --- a/digits/extensions/data/imageProcessing/data.py +++ b/digits/extensions/data/imageProcessing/data.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import math @@ -148,7 +148,7 @@ def make_image_list(self, folder): for dirpath, dirnames, filenames in os.walk(folder, followlinks=True): for filename in filenames: if filename.lower().endswith(image.SUPPORTED_EXTENSIONS): - image_files.append('%s' % os.path.join(folder, filename)) + image_files.append('%s' % os.path.join(dirpath, filename)) if len(image_files) == 0: raise ValueError("Unable to find supported images in %s" % folder) return sorted(image_files) diff --git a/digits/extensions/data/imageProcessing/forms.py b/digits/extensions/data/imageProcessing/forms.py index 9a9aa574e..257ce7679 100644 --- a/digits/extensions/data/imageProcessing/forms.py +++ b/digits/extensions/data/imageProcessing/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os diff --git a/digits/extensions/data/imageProcessing/template.html b/digits/extensions/data/imageProcessing/template.html index 86b4799c5..d6c99da54 100644 --- a/digits/extensions/data/imageProcessing/template.html +++ b/digits/extensions/data/imageProcessing/template.html @@ -1,4 +1,4 @@ -{# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. #} +{# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} {% from "helper.html" import print_flashes %} {% from "helper.html" import print_errors %} diff --git a/digits/extensions/data/imageSegmentation/__init__.py b/digits/extensions/data/imageSegmentation/__init__.py index 79071170e..9bf25978c 100644 --- a/digits/extensions/data/imageSegmentation/__init__.py +++ b/digits/extensions/data/imageSegmentation/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .data import DataIngestion diff --git a/digits/extensions/data/imageSegmentation/data.py b/digits/extensions/data/imageSegmentation/data.py index f013b0f63..fca14f4a1 100644 --- a/digits/extensions/data/imageSegmentation/data.py +++ b/digits/extensions/data/imageSegmentation/data.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import math @@ -213,7 +213,7 @@ def make_image_list(self, folder): for dirpath, dirnames, filenames in os.walk(folder, followlinks=True): for filename in filenames: if filename.lower().endswith(image.SUPPORTED_EXTENSIONS): - image_files.append('%s' % os.path.join(folder, filename)) + image_files.append('%s' % os.path.join(dirpath, filename)) if len(image_files) == 0: raise ValueError("Unable to find supported images in %s" % folder) return sorted(image_files) diff --git a/digits/extensions/data/imageSegmentation/forms.py b/digits/extensions/data/imageSegmentation/forms.py index 39f18fe1b..6cc50aeba 100644 --- a/digits/extensions/data/imageSegmentation/forms.py +++ b/digits/extensions/data/imageSegmentation/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import os diff --git a/digits/extensions/data/imageSegmentation/template.html b/digits/extensions/data/imageSegmentation/template.html index 1cb27276f..ae93330ea 100644 --- a/digits/extensions/data/imageSegmentation/template.html +++ b/digits/extensions/data/imageSegmentation/template.html @@ -1,4 +1,4 @@ -{# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. #} +{# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} {% from "helper.html" import print_flashes %} {% from "helper.html" import print_errors %} diff --git a/digits/extensions/data/interface.py b/digits/extensions/data/interface.py index 9c17b65e4..3de7bc12b 100644 --- a/digits/extensions/data/interface.py +++ b/digits/extensions/data/interface.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import diff --git a/digits/extensions/data/objectDetection/README.md b/digits/extensions/data/objectDetection/README.md index ca3bae154..f3c4974e5 100644 --- a/digits/extensions/data/objectDetection/README.md +++ b/digits/extensions/data/objectDetection/README.md @@ -150,7 +150,7 @@ All classes which don't exist in the provided mapping are implicitly mapped to 0 DetectNet is a single-class object detection network, and only cares about the "Car" class, which is expected to be ID 1. You can change the mapping in the DetectNet prototxt, but it's simplest to just make the class you care about map to 1. -Custom class mappings may be used by specifiying a comma-separated list of class names in the Object Detection dataset creation form. +Custom class mappings may be used by specifying a comma-separated list of class names in the Object Detection dataset creation form. All labels are converted to lower-case, so the matching is case-insensitive. For example, if you only want to detect pedestrians, enter `dontcare,pedestrian` in the "Custom classes" field to generate this mapping: diff --git a/digits/extensions/data/objectDetection/__init__.py b/digits/extensions/data/objectDetection/__init__.py index 79071170e..9bf25978c 100644 --- a/digits/extensions/data/objectDetection/__init__.py +++ b/digits/extensions/data/objectDetection/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .data import DataIngestion diff --git a/digits/extensions/data/objectDetection/data.py b/digits/extensions/data/objectDetection/data.py index e558bbafb..31cdc1859 100644 --- a/digits/extensions/data/objectDetection/data.py +++ b/digits/extensions/data/objectDetection/data.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import csv @@ -223,7 +223,7 @@ def make_image_list(self, folder): for dirpath, dirnames, filenames in os.walk(folder, followlinks=True): for filename in filenames: if filename.lower().endswith(digits.utils.image.SUPPORTED_EXTENSIONS): - image_files.append('%s' % os.path.join(folder, filename)) + image_files.append('%s' % os.path.join(dirpath, filename)) if len(image_files) == 0: raise ValueError("Unable to find supported images in %s" % folder) # shuffle diff --git a/digits/extensions/data/objectDetection/forms.py b/digits/extensions/data/objectDetection/forms.py index c57225348..68333a489 100644 --- a/digits/extensions/data/objectDetection/forms.py +++ b/digits/extensions/data/objectDetection/forms.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from flask.ext.wtf import Form diff --git a/digits/extensions/data/objectDetection/template.html b/digits/extensions/data/objectDetection/template.html index 188444439..667aa9833 100644 --- a/digits/extensions/data/objectDetection/template.html +++ b/digits/extensions/data/objectDetection/template.html @@ -1,4 +1,4 @@ -{# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. #} +{# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} {% from "helper.html" import print_flashes %} {% from "helper.html" import print_errors %} diff --git a/digits/extensions/data/objectDetection/utils.py b/digits/extensions/data/objectDetection/utils.py index 9695f42f4..9312c92e5 100644 --- a/digits/extensions/data/objectDetection/utils.py +++ b/digits/extensions/data/objectDetection/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. import csv import os @@ -49,7 +49,7 @@ class GroundTruthObj: truncated refers to the object leaving image boundaries. -1 corresponds to a don't care region. 1 occluded Integer (-1,0,1,2) indicating occlusion state: - -1 = unkown, 0 = fully visible, + -1 = unknown, 0 = fully visible, 1 = partly occluded, 2 = largely occluded 1 alpha Observation angle of object, ranging [-pi..pi] 4 bbox 2D bounding box of object in the image (0-based index): diff --git a/digits/extensions/view/__init__.py b/digits/extensions/view/__init__.py index f57fe754b..28d4e9b87 100644 --- a/digits/extensions/view/__init__.py +++ b/digits/extensions/view/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import import copy diff --git a/digits/extensions/view/boundingBox/__init__.py b/digits/extensions/view/boundingBox/__init__.py index af82aa2f8..2802b262c 100644 --- a/digits/extensions/view/boundingBox/__init__.py +++ b/digits/extensions/view/boundingBox/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. from __future__ import absolute_import from .view import Visualization diff --git a/digits/extensions/view/boundingBox/app_begin_template.html b/digits/extensions/view/boundingBox/app_begin_template.html index 3a4ce6f17..c59ef717e 100644 --- a/digits/extensions/view/boundingBox/app_begin_template.html +++ b/digits/extensions/view/boundingBox/app_begin_template.html @@ -1,4 +1,4 @@ - + diff --git a/digits/extensions/view/imageSegmentation/static/css/app.css b/digits/extensions/view/imageSegmentation/static/css/app.css index 0cfd8aed2..91573587b 100644 --- a/digits/extensions/view/imageSegmentation/static/css/app.css +++ b/digits/extensions/view/imageSegmentation/static/css/app.css @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. */ +/* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. */ div.vis-div { position: relative; diff --git a/digits/extensions/view/imageSegmentation/static/js/app.js b/digits/extensions/view/imageSegmentation/static/js/app.js index 3cb47637d..7560c59ca 100644 --- a/digits/extensions/view/imageSegmentation/static/js/app.js +++ b/digits/extensions/view/imageSegmentation/static/js/app.js @@ -1,4 +1,4 @@ -// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. // Angularjs app, visualization_app var app = angular.module('visualization_app', ['ngStorage']); diff --git a/digits/extensions/view/imageSegmentation/view.py b/digits/extensions/view/imageSegmentation/view.py index 26aa78b80..eb425d57f 100644 --- a/digits/extensions/view/imageSegmentation/view.py +++ b/digits/extensions/view/imageSegmentation/view.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +"""Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.""" from __future__ import absolute_import import json @@ -25,11 +25,16 @@ @subclass class Visualization(VisualizationInterface): - """ - A visualization extension to display the network output as an image - """ + """A visualization extension to display the network output as an image.""" def __init__(self, dataset, **kwargs): + """Constructor for Visualization class. + + :param dataset: + :type dataset: + :param kwargs: + :type kwargs: + """ # memorize view template for later use extension_dir = os.path.dirname(os.path.abspath(__file__)) self.view_template = open( @@ -64,11 +69,16 @@ def __init__(self, dataset, **kwargs): @staticmethod def get_config_form(): + """Utility function. + + returns: ConfigForm(). + """ return ConfigForm() @staticmethod def get_config_template(form): - """ + """Get the template and context. + parameters: - form: form returned by get_config_form(). This may be populated with values if the job was cloned @@ -84,8 +94,8 @@ def get_config_template(form): return (template, {'form': form}) def get_legend_for(self, found_classes, skip_classes=[]): - """ - Return the legend color image squares and text for each class + """Return the legend color image squares and text for each class. + :param found_classes: list of class indices :param skip_classes: list of class indices to skip :return: list of dicts of text hex_color for each class @@ -111,9 +121,7 @@ def get_legend_for(self, found_classes, skip_classes=[]): @override def get_header_template(self): - """ - Implements get_header_template() method from view extension interface - """ + """Implement get_header_template method from view extension interface.""" extension_dir = os.path.dirname(os.path.abspath(__file__)) template = open( os.path.join(extension_dir, HEADER_TEMPLATE), "r").read() @@ -122,9 +130,7 @@ def get_header_template(self): @override def get_ng_templates(self): - """ - Implements get_ng_templates() method from view extension interface - """ + """Implement get_ng_templates method from view extension interface.""" extension_dir = os.path.dirname(os.path.abspath(__file__)) header = open(os.path.join(extension_dir, APP_BEGIN_TEMPLATE), "r").read() footer = open(os.path.join(extension_dir, APP_END_TEMPLATE), "r").read() @@ -132,19 +138,23 @@ def get_ng_templates(self): @staticmethod def get_id(): + """returns: id string that identifies the extension.""" return 'image-segmentation' @staticmethod def get_title(): + """returns: name string to display in html.""" return 'Image Segmentation' @staticmethod def get_dirname(): + """returns: extension dir name to locate static dir.""" return 'imageSegmentation' @override def get_view_template(self, data): - """ + """Get the view template. + returns: - (template, context) tuple - template is a Jinja template to use for rendering config options @@ -165,9 +175,7 @@ def get_view_template(self, data): @override def process_data(self, input_id, input_data, output_data): - """ - Process one inference and return data to visualize - """ + """Process one inference and return data to visualize.""" # assume the only output is a CHW image where C is the number # of classes, H and W are the height and width of the image class_data = output_data[output_data.keys()[0]].astype('float32') @@ -226,6 +234,8 @@ def normalize(array): max_distance = np.maximum(max_distance, distance + 128) line_data[:, :, 3] = line_mask * 255 + max_distance = np.maximum(max_distance, np.zeros(max_distance.shape, dtype=float)) + max_distance = np.minimum(max_distance, np.zeros(max_distance.shape, dtype=float) + 255) seg_data[:, :, 3] = max_distance # Input image with outlines diff --git a/digits/extensions/view/imageSegmentation/view_template.html b/digits/extensions/view/imageSegmentation/view_template.html index 977823ca8..b586af8b6 100644 --- a/digits/extensions/view/imageSegmentation/view_template.html +++ b/digits/extensions/view/imageSegmentation/view_template.html @@ -1,4 +1,4 @@ -{# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. #} +{# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} {[ set_binary('{{ is_binary }}' == 'True');'' ]}
Network | diff --git a/digits/templates/models/images/generic/show.html b/digits/templates/models/images/generic/show.html index 6e98e1d81..e40d42e5a 100644 --- a/digits/templates/models/images/generic/show.html +++ b/digits/templates/models/images/generic/show.html @@ -1,4 +1,4 @@ -{# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. #} +{# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. #} {% extends "job.html" %} {% from "helper.html" import serve_file %} diff --git a/digits/templates/models/large_graph.html b/digits/templates/models/large_graph.html index 61f9387c4..69d009f12 100644 --- a/digits/templates/models/large_graph.html +++ b/digits/templates/models/large_graph.html @@ -1,4 +1,4 @@ -{# Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. #} +{# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. #} {% extends "layout.html" %} diff --git a/digits/templates/models/python_layer_explanation.html b/digits/templates/models/python_layer_explanation.html index aedacc78e..26a57ac61 100644 --- a/digits/templates/models/python_layer_explanation.html +++ b/digits/templates/models/python_layer_explanation.html @@ -1,4 +1,4 @@ -{# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. #} +{# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. #}
---|