├── .github └── CONTRIBUTING.md ├── .gitignore ├── .gjslintrc ├── .travis.yml ├── CLA ├── LICENSE ├── MANIFEST.in ├── README.md ├── digits-devserver ├── digits-lint ├── digits-test ├── digits ├── .gitignore ├── __init__.py ├── __main__.py ├── config │ ├── __init__.py │ ├── caffe.py │ ├── gpu_list.py │ ├── jobs_dir.py │ ├── log_file.py │ ├── server_name.py │ ├── store_option.py │ ├── tensorflow.py │ ├── torch.py │ └── url_prefix.py ├── dataset │ ├── __init__.py │ ├── forms.py │ ├── generic │ │ ├── __init__.py │ │ ├── forms.py │ │ ├── job.py │ │ ├── test_views.py │ │ └── views.py │ ├── images │ │ ├── __init__.py │ │ ├── classification │ │ │ ├── __init__.py │ │ │ ├── forms.py │ │ │ ├── job.py │ │ │ ├── test_imageset_creator.py │ │ │ ├── test_views.py │ │ │ └── views.py │ │ ├── forms.py │ │ ├── generic │ │ │ ├── __init__.py │ │ │ ├── forms.py │ │ │ ├── job.py │ │ │ ├── test_lmdb_creator.py │ │ │ ├── test_views.py │ │ │ └── views.py │ │ ├── job.py │ │ └── views.py │ ├── job.py │ ├── tasks │ │ ├── __init__.py │ │ ├── analyze_db.py │ │ ├── create_db.py │ │ ├── create_generic_db.py │ │ ├── parse_folder.py │ │ └── parse_s3.py │ └── views.py ├── device_query.py ├── download_data │ ├── __init__.py │ ├── __main__.py │ ├── cifar10.py │ ├── cifar100.py │ ├── downloader.py │ └── mnist.py ├── extensions │ ├── __init__.py │ ├── data │ │ ├── __init__.py │ │ ├── imageProcessing │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── forms.py │ │ │ └── template.html │ │ ├── imageSegmentation │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── forms.py │ │ │ └── template.html │ │ ├── interface.py │ │ └── objectDetection │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── forms.py │ │ │ ├── template.html │ │ │ └── utils.py │ └── view │ │ ├── __init__.py │ │ ├── boundingBox │ │ ├── __init__.py │ │ ├── app_begin_template.html │ │ ├── app_end_template.html │ │ ├── config_template.html │ │ ├── forms.py │ │ ├── header_template.html │ │ ├── view.py │ │ └── view_template.html │ │ ├── imageOutput │ │ ├── __init__.py │ │ ├── config_template.html │ │ ├── forms.py │ │ ├── view.py │ │ └── view_template.html │ │ ├── imageSegmentation │ │ ├── __init__.py │ │ ├── app_begin_template.html │ │ ├── app_end_template.html │ │ ├── config_template.html │ │ ├── forms.py │ │ ├── header_template.html │ │ ├── static │ │ │ ├── css │ │ │ │ └── app.css │ │ │ └── js │ │ │ │ └── app.js │ │ ├── view.py │ │ └── view_template.html │ │ ├── interface.py │ │ └── rawData │ │ ├── __init__.py │ │ ├── config_template.html │ │ ├── forms.py │ │ ├── header_template.html │ │ ├── view.py │ │ └── view_template.html ├── frameworks │ ├── __init__.py │ ├── caffe_framework.py │ ├── errors.py │ ├── framework.py │ ├── tensorflow_framework.py │ └── torch_framework.py ├── inference │ ├── __init__.py │ ├── errors.py │ ├── images │ │ ├── __init__.py │ │ └── job.py │ ├── job.py │ └── tasks │ │ ├── __init__.py │ │ └── inference.py ├── job.py ├── log.py ├── model │ ├── __init__.py │ ├── forms.py │ ├── images │ │ ├── __init__.py │ │ ├── classification │ │ │ ├── __init__.py │ │ │ ├── forms.py │ │ │ ├── job.py │ │ │ ├── test_views.py │ │ │ └── views.py │ │ ├── forms.py │ │ ├── generic │ │ │ ├── __init__.py │ │ │ ├── forms.py │ │ │ ├── job.py │ │ │ ├── test_views.py │ │ │ └── views.py │ │ ├── job.py │ │ └── views.py │ ├── job.py │ ├── tasks │ │ ├── __init__.py │ │ ├── caffe_train.py │ │ ├── tensorflow_train.py │ │ ├── test_caffe_sanity_checks.py │ │ ├── test_caffe_train.py │ │ ├── torch_train.py │ │ └── train.py │ └── views.py ├── pretrained_model │ ├── __init__.py │ ├── job.py │ ├── tasks │ │ ├── __init__.py │ │ ├── caffe_upload.py │ │ ├── tensorflow_upload.py │ │ ├── torch_upload.py │ │ └── upload_pretrained.py │ ├── test_views.py │ └── views.py ├── scheduler.py ├── standard-networks │ ├── caffe │ │ ├── alexnet.prototxt │ │ ├── googlenet.prototxt │ │ └── lenet.prototxt │ ├── tensorflow │ │ ├── alexnet.py │ │ ├── googlenet.py │ │ ├── lenet.py │ │ └── vgg16.py │ └── torch │ │ ├── ImageNet-Training │ │ ├── alexnet.lua │ │ └── googlenet.lua │ │ └── lenet.lua ├── static │ ├── css │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.min.css │ │ ├── buttons.bootstrap.min.css │ │ ├── c3.min.css │ │ ├── fixedHeader.bootstrap.min.css │ │ ├── style.css │ │ └── table_selection.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── images │ │ ├── mona_lisa.jpg │ │ ├── nvidia-logo.png │ │ └── nvidia.ico │ ├── js │ │ ├── 3rdparty │ │ │ ├── ace-1.2.3.min.js │ │ │ ├── ace.ext-searchbox-1.2.3.min.js │ │ │ ├── ace.mode-lua-1.2.3.min.js │ │ │ ├── ace.mode-python-1.2.3.min.js │ │ │ ├── ace.theme-chrome-1.2.3.min.js │ │ │ ├── angular-1.5.3.min.js │ │ │ ├── bootbox-4.3.0.min.js │ │ │ ├── bootstrap-3.3.6.min.js │ │ │ ├── buttons.bootstrap-1.0.3.min.js │ │ │ ├── buttons.colVis-1.0.0.min.js │ │ │ ├── c3-0.4.10.min.js │ │ │ ├── d3-3.5.5.min.js │ │ │ ├── jquery-1.11.1.min.js │ │ │ ├── jquery.autocomplete-1.2.21.min.js │ │ │ ├── jquery.dataTables-1.10.8.min.js │ │ │ ├── jquery.elevateZoom-3.0.8.min.js │ │ │ ├── jquery.sparkline-2.1.2.min.js │ │ │ ├── ngStorage-0.3.10.min.js │ │ │ ├── socket.io-1.4.5.min.js │ │ │ ├── ui-bootstrap-tpls-1.3.2.min.js │ │ │ └── underscore-1.8.3.min.js │ │ ├── PretrainedModel.js │ │ ├── digits.js │ │ ├── file_field.js │ │ ├── home_app.js │ │ ├── model-graphs.js │ │ ├── store.js │ │ ├── time_filters.js │ │ └── timeline-tracing.js │ └── tb │ │ ├── summary-icon.svg │ │ ├── tf-graph-basic.build.html │ │ ├── tf-graph-basic.build.js │ │ └── trace_viewer_full.html ├── status.py ├── store │ ├── __init__.py │ └── views.py ├── task.py ├── templates │ ├── datasets │ │ ├── generic │ │ │ ├── new.html │ │ │ ├── show.html │ │ │ └── summary.html │ │ └── images │ │ │ ├── classification │ │ │ ├── new.html │ │ │ ├── show.html │ │ │ └── summary.html │ │ │ ├── explore.html │ │ │ └── generic │ │ │ ├── new.html │ │ │ ├── show.html │ │ │ └── summary.html │ ├── error.html │ ├── helper.html │ ├── home.html │ ├── job.html │ ├── layout.html │ ├── login.html │ ├── models │ │ ├── data_augmentation.html │ │ ├── gpu_utilization.html │ │ ├── images │ │ │ ├── classification │ │ │ │ ├── classify_many.html │ │ │ │ ├── classify_one.html │ │ │ │ ├── custom_network_explanation.html │ │ │ │ ├── new.html │ │ │ │ ├── partials │ │ │ │ │ └── new │ │ │ │ │ │ ├── network_tab_pretrained.html │ │ │ │ │ │ ├── network_tab_previous.html │ │ │ │ │ │ └── network_tab_standard.html │ │ │ │ ├── show.html │ │ │ │ └── top_n.html │ │ │ └── generic │ │ │ │ ├── custom_network_explanation.html │ │ │ │ ├── infer_db.html │ │ │ │ ├── infer_extension.html │ │ │ │ ├── infer_many.html │ │ │ │ ├── infer_one.html │ │ │ │ ├── large_graph.html │ │ │ │ ├── new.html │ │ │ │ ├── partials │ │ │ │ └── new │ │ │ │ │ ├── network_tab_pretrained.html │ │ │ │ │ ├── network_tab_previous.html │ │ │ │ │ └── network_tab_standard.html │ │ │ │ └── show.html │ │ ├── large_graph.html │ │ ├── python_layer_explanation.html │ │ └── timeline_tracing.html │ ├── partials │ │ └── home │ │ │ ├── datasets_pane.html │ │ │ ├── model_pane.html │ │ │ ├── pretrained_model_pane.html │ │ │ └── upload_pretrained_model.html │ ├── socketio.html │ ├── status_updates.html │ └── store.html ├── test_device_query.py ├── test_scheduler.py ├── test_status.py ├── test_utils.py ├── test_version.py ├── test_views.py ├── tools │ ├── __init__.py │ ├── analyze_db.py │ ├── create_db.py │ ├── create_generic_db.py │ ├── inference.py │ ├── mock_s3_walker.py │ ├── parse_folder.py │ ├── parse_s3.py │ ├── resize_image.py │ ├── s3_walker.py │ ├── tensorflow │ │ ├── caffe_tf.proto │ │ ├── caffe_tf_pb2.py │ │ ├── gan_grid.py │ │ ├── gandisplay.py │ │ ├── lr_policy.py │ │ ├── main.py │ │ ├── model.py │ │ ├── tf_data.py │ │ └── utils.py │ ├── test_analyze_db.py │ ├── test_create_db.py │ ├── test_create_generic_db.py │ ├── test_parse_folder.py │ ├── test_parse_s3.py │ ├── test_resize_image.py │ ├── test_s3_walker.py │ ├── torch │ │ ├── LRPolicy.lua │ │ ├── Optimizer.lua │ │ ├── README.txt │ │ ├── data.lua │ │ ├── datum.proto │ │ ├── logmessage.lua │ │ ├── main.lua │ │ ├── test.lua │ │ ├── utils.lua │ │ └── wrapper.lua │ ├── upload_config.cfg │ └── upload_s3_data.py ├── utils │ ├── __init__.py │ ├── auth.py │ ├── constants.py │ ├── errors.py │ ├── filesystem.py │ ├── forms.py │ ├── image.py │ ├── lmdbreader.py │ ├── routing.py │ ├── store.py │ ├── test_filesystem.py │ ├── test_image.py │ ├── test_time_filters.py │ ├── test_utils.py │ └── time_filters.py ├── version.py ├── views.py └── webapp.py ├── docs ├── API.md ├── BuildCaffe.md ├── BuildDigits.md ├── BuildDigitsWindows.md ├── BuildProtobuf.md ├── BuildTensorflow.md ├── BuildTorch.md ├── Configuration.md ├── DevelopmentSetup.md ├── GettingStarted.md ├── GettingStartedTensorflow.md ├── GettingStartedTorch.md ├── ImageFolderFormat.md ├── InstallCuda.md ├── ModelStore.md ├── StandardDatasets.md ├── UbuntuInstall.md └── images │ ├── Select_TensorFlow.png │ ├── TensorBoard.png │ ├── classified-one-image.jpg │ ├── classifying-one-image.jpg │ ├── creating-dataset.jpg │ ├── home-page-1.jpg │ ├── home-page-2.jpg │ ├── job-dir.png │ ├── login.jpg │ ├── model-store │ ├── custom.jpg │ ├── home.jpg │ └── official.png │ ├── new-dataset.jpg │ ├── new-model.jpg │ ├── standard-datasets │ └── html-form.jpg │ ├── torch-selection.png │ ├── training-model.jpg │ ├── visualize-btn.png │ └── visualize_button.png ├── examples ├── autoencoder │ ├── README.md │ ├── autoencoder-TF.py │ ├── compressed-image.png │ ├── create-generic-dataset-form.png │ ├── create-generic-dataset.png │ ├── create-model-form.png │ ├── create-model.png │ ├── mnist-classification-dataset.png │ ├── normalized-image.png │ ├── original-image.png │ ├── reconstructed-image.png │ ├── tensorflow-settings.png │ ├── test-single-image.png │ └── training-loss.png ├── binary-segmentation │ ├── README.md │ ├── binary_segmentation-TF.py │ ├── create-dataset.png │ ├── create_images.py │ ├── dont-resize.png │ ├── in-example.png │ ├── label-example.png │ ├── network-topology.png │ ├── segmentation-model.lua │ ├── segmentation-model.prototxt │ ├── select-dataset.png │ ├── select-model.png │ ├── select-visualization.png │ ├── test-db.png │ ├── test-grid.png │ ├── test-one.png │ └── training-loss.png ├── classification │ ├── README.md │ ├── example.py │ ├── requirements.txt │ └── use_archive.py ├── fine-tuning │ ├── README.md │ ├── create-dataset.png │ ├── create_dataset.sh │ ├── lenet-fine-tune-tf.py │ ├── lenet-fine-tune.lua │ ├── lenet-fine-tune.prototxt │ ├── lenet-from-scratch-caffe.png │ ├── loss-finetuned.png │ └── loss-function-from-scratch.png ├── gan │ ├── README.md │ ├── celeba-analogy-form.png │ ├── celeba-analogy.png │ ├── celeba-dataset-form.png │ ├── celeba-embeddings.gif │ ├── celeba-encode-list-form.png │ ├── celeba-encode-list.png │ ├── celeba-loss.png │ ├── celeba-select-image-output.png │ ├── celeba-set-attributes-form.png │ ├── celeba-set-attributes.png │ ├── create-mnist-generic-dataset.png │ ├── create-mnist-model.png │ ├── exploring-celeba.png │ ├── gan-grid-animated.gif │ ├── gan_embeddings.py │ ├── gan_features.py │ ├── mnist-animated.gif │ ├── mnist-chi-square.png │ ├── mnist-class-sweep.png │ ├── mnist-classification-dataset.png │ ├── mnist-encode-image-form.png │ ├── mnist-encode-image.png │ ├── mnist-encoder-loss.png │ ├── mnist-graph.png │ ├── mnist-inference-form-class-sweep.png │ ├── mnist-loss.png │ ├── mnist-style-sweep.png │ ├── mnist-styled-class-sweep-form.png │ ├── mnist-styled-class-sweep.png │ ├── mnist-tb-samples.png │ ├── network-celebA-encoder.py │ ├── network-celebA.py │ ├── network-mnist-encoder.py │ └── network-mnist.py ├── medical-imaging │ ├── README.md │ ├── create-dataset.png │ ├── fcn-8s-inference.png │ ├── fcn-8s-training.png │ ├── fcn-alexnet-inference.png │ ├── fcn-alexnet-pretrained-inference.png │ ├── fcn-alexnet-pretrained-training.png │ ├── fcn-alexnet-training-with-dice.png │ ├── fcn-alexnet-training.png │ ├── pretrain-mismatch-error.png │ ├── sample-feature.png │ ├── sample-label.png │ ├── select-dataset.png │ ├── select-model.png │ └── sunnybrook-shapes.png ├── object-detection │ ├── .gitignore │ ├── README.md │ ├── batch-accumulation.jpg │ ├── click-visualize.jpg │ ├── dataset-review.jpg │ ├── detectnet.jpg │ ├── display-options-menu.jpg │ ├── form-object-detection-dataset.jpg │ ├── prepare_kitti_data.py │ ├── select-gpus.jpg │ ├── select-object-detection-dataset.jpg │ ├── select-object-detection-model.jpg │ ├── select-visualization.jpg │ ├── test-many.jpg │ ├── test-one.jpg │ └── training-loss.jpg ├── python-layer │ ├── README.md │ ├── alexnet-activations.jpg │ ├── create-model.jpg │ ├── image-after-occlusion.jpg │ ├── image-before-occlusion.jpg │ ├── lenet-activations.jpg │ ├── network-visualization.jpg │ └── two-small-squares.jpg ├── regression │ ├── README.md │ ├── create-dataset-using-extension.png │ ├── create-generic-dataset.png │ ├── create-model.png │ ├── create-regression-dataset.png │ ├── regression-TF.py │ ├── regression-loss.png │ ├── regression-output.png │ ├── regression-test-one.png │ ├── select-gradient-data-extension.png │ ├── select-gradient-view-extension.png │ ├── test-db-inference.png │ ├── test-db.png │ └── test.png ├── s3 │ ├── README.md │ ├── complete.png │ ├── dataset-properties.png │ ├── new-dataset.png │ └── s3-tab.png ├── semantic-segmentation │ ├── README.md │ ├── alexnet-layers.png │ ├── click-explore-db.png │ ├── dataset-form-1.png │ ├── dataset-form-2.png │ ├── example.png │ ├── explore-features.png │ ├── explore-labels.png │ ├── fcn-alexnet-layers.png │ ├── fcn_alexnet.deploy.prototxt │ ├── fcn_alexnet.prototxt │ ├── image-example.jpg │ ├── inference-form.png │ ├── label-example.png │ ├── net_surgery.py │ ├── network.png │ ├── pascal-voc-classes.txt │ ├── prepare_pascal_voc_data.sh │ ├── select-dataset.png │ ├── select-model.png │ ├── select-visualization.png │ ├── test-one-ground-truth.png │ ├── test-one.png │ └── training-loss.png ├── siamese │ ├── README.md │ ├── create-dataset-form.png │ ├── create-generic-dataset.png │ ├── create-model.png │ ├── create_db.py │ ├── different-class-channels.png │ ├── different-class.png │ ├── feature_clusters_contrastive.png │ ├── feature_clusters_contrastive_tf.png │ ├── feature_clusters_cosembedding.png │ ├── mnist-classification-dataset.png │ ├── mnist_siamese.lua │ ├── mnist_siamese_train_test.prototxt │ ├── network-topology.png │ ├── same-class.png │ ├── siamese-TF.py │ └── siamese-loss.png ├── text-classification │ ├── README.md │ ├── create-dataset.png │ ├── create_dataset.py │ ├── dbpedia-confusion-matrix.png │ ├── dbpedia-dataset-creation.png │ ├── dbpedia-generic-dataset-creation.png │ ├── dbpedia-generic-inference.png │ ├── dbpedia-loss.png │ ├── inference-form.png │ ├── inference.png │ ├── select-data-plugin.png │ └── text-classification-model.lua ├── weight-init │ ├── README.md │ ├── lenet-wi-constant.png │ ├── lenet-wi-kaiming.png │ ├── lenet-wi-torch-default.png │ ├── lenet-wi-uniform-0.5.png │ ├── lenet-wi-uniform.png │ └── lenet-wi-xavier.png └── writing-plugins │ ├── README.md │ └── select-dataset.png ├── packaging └── deb │ ├── .gitignore │ ├── Dockerfile │ ├── build.sh │ ├── extras │ ├── custom_http_errors │ │ ├── 413.shtml │ │ └── 502.html │ └── digits.nginx-site │ ├── private.key.enc │ └── templates │ ├── compat │ ├── control │ ├── copyright │ ├── digits.config │ ├── digits.dirs │ ├── digits.install │ ├── digits.lintian-overrides │ ├── digits.postinst │ ├── digits.postrm │ ├── digits.preinst │ ├── digits.prerm │ ├── digits.service │ ├── digits.templates │ ├── digits.upstart │ ├── pydist-overrides │ ├── rules │ └── source.lintian-overrides ├── plugins ├── data │ ├── bAbI │ │ ├── MANIFEST.in │ │ ├── README │ │ ├── digitsDataPluginBAbI │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── forms.py │ │ │ ├── templates │ │ │ │ ├── dataset_template.html │ │ │ │ ├── inference_template.html │ │ │ │ └── template.html │ │ │ └── utils.py │ │ └── setup.py │ ├── gan │ │ ├── MANIFEST.in │ │ ├── README │ │ ├── digitsDataPluginGan │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── forms.py │ │ │ └── templates │ │ │ │ ├── dataset_template.html │ │ │ │ ├── inference_template.html │ │ │ │ └── template.html │ │ └── setup.py │ ├── imageGradients │ │ ├── MANIFEST.in │ │ ├── README │ │ ├── digitsDataPluginImageGradients │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── forms.py │ │ │ └── templates │ │ │ │ ├── inference_template.html │ │ │ │ └── template.html │ │ └── setup.py │ ├── sunnybrook │ │ ├── MANIFEST.in │ │ ├── README │ │ ├── digitsDataPluginSunnybrook │ │ │ ├── __init__.py │ │ │ ├── data.py │ │ │ ├── forms.py │ │ │ └── templates │ │ │ │ ├── dataset_template.html │ │ │ │ ├── inference_template.html │ │ │ │ └── template.html │ │ └── setup.py │ └── textClassification │ │ ├── MANIFEST.in │ │ ├── README │ │ ├── digitsDataPluginTextClassification │ │ ├── __init__.py │ │ ├── data.py │ │ ├── forms.py │ │ └── templates │ │ │ ├── dataset_template.html │ │ │ ├── inference_template.html │ │ │ └── template.html │ │ └── setup.py └── view │ ├── gan │ ├── MANIFEST.in │ ├── README │ ├── digitsViewPluginGan │ │ ├── __init__.py │ │ ├── forms.py │ │ ├── templates │ │ │ ├── config_template.html │ │ │ ├── header_template.html │ │ │ └── view_template.html │ │ └── view.py │ └── setup.py │ ├── imageGradients │ ├── MANIFEST.in │ ├── README │ ├── digitsViewPluginImageGradients │ │ ├── __init__.py │ │ ├── forms.py │ │ ├── templates │ │ │ ├── config_template.html │ │ │ └── view_template.html │ │ └── view.py │ └── setup.py │ └── textClassification │ ├── MANIFEST.in │ ├── README │ ├── digitsViewPluginTextClassification │ ├── __init__.py │ ├── forms.py │ ├── templates │ │ ├── config_template.html │ │ └── view_template.html │ └── view.py │ └── setup.py ├── requirements.txt ├── requirements_test.txt ├── scripts └── travis │ ├── bust-cache.sh │ ├── install-caffe.sh │ ├── install-protobuf.sh │ ├── install-tensorflow.sh │ ├── install-torch.sh │ └── ppa-upload.sh ├── setup.cfg └── setup.py /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | DIGITS is open-source, under the 3-clause BSD license (see [LICENSE](LICENSE)). 4 | 5 | We welcome your suggestions and feedback! 6 | 7 | ## Mailing list 8 | 9 | **Before creating an issue on GitHub**, check to see if you should be using the [mailing list](https://groups.google.com/d/forum/digits-users) instead. 10 | The mailing list is for questions relating to: 11 | 12 | * Problems installing DIGITS or its dependencies 13 | * Understanding how to use a feature in DIGITS 14 | 15 | Please go to https://groups.google.com/d/forum/digits-users and create a "New Question". 16 | 17 | ## Issue tracker 18 | 19 | The [issue tracker](https://github.com/NVIDIA/DIGITS/issues) on GitHub is for: 20 | 21 | * Suggesting an improvement to the documentation 22 | * Requesting a new feature 23 | * Reporting a bug 24 | * Please provide as much detail as possible about how others can reproduce the bug. 25 | 26 | Go to https://github.com/NVIDIA/DIGITS/issues and create a "New Issue". 27 | 28 | ## Pull requests 29 | 30 | If you would like to directly contribute to the codebase of DIGITS, open a pull request instead of an issue. 31 | Or, even better, submit a fix for an existing issue in the tracker! Please follow these guidelines: 32 | 33 | 1. Send a signed copy of the [Contributor License Agreement](../CLA) (CLA) to digits@nvidia.com. 34 | 2. Follow [these instructions](https://help.github.com/articles/fork-a-repo) to create your own fork of DIGITS. 35 | 3. Make your changes in a new branch and push them to your fork. 36 | 3. Follow [these instructions](https://help.github.com/articles/using-pull-requests) to create a pull request. 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Temporary files 2 | *.swp 3 | *~ 4 | .DS_Store 5 | TAGS 6 | 7 | # Compiled / optimized files 8 | *.py[cod] 9 | 10 | # Tests 11 | /.coverage 12 | 13 | # virtualenv 14 | /venv/ 15 | 16 | # setuptools 17 | /build/ 18 | /dist/ 19 | *.egg-info/ 20 | 21 | #Intellij files 22 | .idea/ 23 | 24 | #vscode 25 | .vscode/ 26 | 27 | #.project 28 | .project 29 | /.project 30 | 31 | #.tb 32 | .tb/ 33 | -------------------------------------------------------------------------------- /.gjslintrc: -------------------------------------------------------------------------------- 1 | --max_line_length=120 2 | --exclude_directories=3rdparty,tb 3 | --disable=0121,0220 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of NVIDIA CORPORATION nor the names of its 12 | contributors may be used to endorse or promote products derived 13 | from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 19 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements*.txt 2 | recursive-include digits/templates * 3 | recursive-include digits/static * 4 | recursive-include digits/standard-networks * 5 | recursive-include digits/tools/torch * 6 | recursive-include digits/tools/tensorflow * 7 | recursive-include digits/extensions *.css 8 | recursive-include digits/extensions *.html 9 | recursive-include digits/extensions *.js 10 | -------------------------------------------------------------------------------- /digits-devserver: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 3 | 4 | set -e 5 | 6 | python2 -m digits $@ 7 | -------------------------------------------------------------------------------- /digits-lint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 3 | 4 | set -e 5 | 6 | echo "=== Checking for Python lint ..." 7 | if which flake8 >/dev/null 2>&1; then 8 | python2 `which flake8` --exclude ./digits/jobs . 9 | else 10 | python2 -m flake8 --exclude ./digits/jobs . 11 | fi 12 | 13 | echo "=== Checking for JavaScript lint ..." 14 | gjslint --flagfile .gjslintrc --recurse . 15 | 16 | echo "=== No lint found." 17 | -------------------------------------------------------------------------------- /digits-test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 3 | 4 | set -e 5 | 6 | function set_exe { 7 | # Sets a global variable to the location of an executable 8 | # Arguments: 9 | # $1 -- the variable name 10 | # $2 -- the executable 11 | 12 | # Check to make sure the executable exists 13 | hash $2 2>/dev/null || { echo >&2 "ERROR: \"$2\" executable not found!"; exit 1; } 14 | # Print the path to the executable 15 | local __resultvar=$1 16 | eval $__resultvar="'$(command -v $2)'" 17 | } 18 | 19 | # Some hacking necessary to respect virtualenv installations 20 | set_exe PYTHON_EXE python2 21 | set_exe NOSE_EXE nosetests 22 | 23 | DIGITS_MODE_TEST=1 $PYTHON_EXE $NOSE_EXE \ 24 | --no-path-adjustment $@ 25 | -------------------------------------------------------------------------------- /digits/.gitignore: -------------------------------------------------------------------------------- 1 | /digits.cfg 2 | /jobs/ 3 | /digits.log* 4 | -------------------------------------------------------------------------------- /digits/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .version import __version__ 5 | 6 | __all__ = ['__version__'] 7 | -------------------------------------------------------------------------------- /digits/config/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | # Create this object before importing the following imports, since they edit the list 5 | option_list = {} 6 | 7 | from . import ( # noqa 8 | caffe, 9 | gpu_list, 10 | jobs_dir, 11 | log_file, 12 | torch, 13 | server_name, 14 | store_option, 15 | tensorflow, 16 | url_prefix, 17 | ) 18 | 19 | 20 | def config_value(option): 21 | """ 22 | Return the current configuration value for the given option 23 | """ 24 | return option_list[option] 25 | -------------------------------------------------------------------------------- /digits/config/gpu_list.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from . import option_list 5 | import digits.device_query 6 | 7 | 8 | option_list['gpu_list'] = ','.join([str(x) for x in xrange(len(digits.device_query.get_devices()))]) 9 | -------------------------------------------------------------------------------- /digits/config/jobs_dir.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import os 5 | import tempfile 6 | 7 | from . import option_list 8 | import digits 9 | 10 | 11 | if 'DIGITS_MODE_TEST' in os.environ: 12 | value = tempfile.mkdtemp() 13 | elif 'DIGITS_JOBS_DIR' in os.environ: 14 | value = os.environ['DIGITS_JOBS_DIR'] 15 | else: 16 | value = os.path.join(os.path.dirname(digits.__file__), 'jobs') 17 | 18 | 19 | try: 20 | value = os.path.abspath(value) 21 | if os.path.exists(value): 22 | if not os.path.isdir(value): 23 | raise IOError('No such directory: "%s"' % value) 24 | if not os.access(value, os.W_OK): 25 | raise IOError('Permission denied: "%s"' % value) 26 | if not os.path.exists(value): 27 | os.makedirs(value) 28 | except: 29 | print '"%s" is not a valid value for jobs_dir.' % value 30 | print 'Set the envvar DIGITS_JOBS_DIR to fix your configuration.' 31 | raise 32 | 33 | 34 | option_list['jobs_dir'] = value 35 | -------------------------------------------------------------------------------- /digits/config/server_name.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import os 5 | import platform 6 | 7 | from . import option_list 8 | 9 | if 'DIGITS_SERVER_NAME' in os.environ: 10 | value = os.environ['DIGITS_SERVER_NAME'] 11 | else: 12 | value = platform.node() 13 | 14 | option_list['server_name'] = value 15 | -------------------------------------------------------------------------------- /digits/config/store_option.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import os 5 | from urlparse import urlparse 6 | 7 | from . import option_list 8 | 9 | 10 | def validate(value): 11 | if value == '': 12 | return value 13 | valid_url_list = list() 14 | if isinstance(value, str): 15 | url_list = value.split(',') 16 | for url in url_list: 17 | if url is not None and urlparse(url).scheme != "" and not os.path.exists(url): 18 | valid_url_list.append(url) 19 | else: 20 | raise ValueError('"%s" is not a valid URL' % url) 21 | return ','.join(valid_url_list) 22 | 23 | 24 | def load_url_list(): 25 | """ 26 | Return Model Store URL's as a list 27 | Verify if each URL is valid 28 | """ 29 | if 'DIGITS_MODEL_STORE_URL' in os.environ: 30 | url_list = os.environ['DIGITS_MODEL_STORE_URL'] 31 | else: 32 | url_list = "http://developer.download.nvidia.com/compute/machine-learning/modelstore/6.0" 33 | 34 | return validate(url_list).split(',') 35 | 36 | option_list['model_store'] = { 37 | 'url_list': load_url_list() 38 | } 39 | -------------------------------------------------------------------------------- /digits/config/tensorflow.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | from . import option_list 4 | 5 | 6 | def test_tf_import(): 7 | """ 8 | Tests if tensorflow can be imported, returns if it went okay and optional error. 9 | """ 10 | try: 11 | import tensorflow # noqa 12 | return True 13 | except (ImportError, TypeError): 14 | return False 15 | 16 | tf_enabled = test_tf_import() 17 | 18 | if not tf_enabled: 19 | print('Tensorflow support disabled.') 20 | 21 | if tf_enabled: 22 | option_list['tensorflow'] = { 23 | 'enabled': True 24 | } 25 | else: 26 | option_list['tensorflow'] = { 27 | 'enabled': False 28 | } 29 | -------------------------------------------------------------------------------- /digits/config/url_prefix.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import os 5 | 6 | from . import option_list 7 | 8 | option_list['url_prefix'] = os.environ.get('DIGITS_URL_PREFIX', '') 9 | -------------------------------------------------------------------------------- /digits/dataset/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .images import ImageClassificationDatasetJob, GenericImageDatasetJob 5 | from .generic import GenericDatasetJob 6 | from .job import DatasetJob 7 | 8 | __all__ = [ 9 | 'ImageClassificationDatasetJob', 10 | 'GenericImageDatasetJob', 11 | 'GenericDatasetJob', 12 | 'DatasetJob', 13 | ] 14 | -------------------------------------------------------------------------------- /digits/dataset/forms.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from flask_wtf import Form 5 | from wtforms.validators import DataRequired 6 | 7 | from digits import utils 8 | 9 | 10 | class DatasetForm(Form): 11 | """ 12 | Defines the form used to create a new Dataset 13 | (abstract class) 14 | """ 15 | 16 | dataset_name = utils.forms.StringField(u'Dataset Name', 17 | validators=[DataRequired()] 18 | ) 19 | 20 | group_name = utils.forms.StringField('Group Name', 21 | tooltip="An optional group name for organization on the main page." 22 | ) 23 | -------------------------------------------------------------------------------- /digits/dataset/generic/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .job import GenericDatasetJob 5 | 6 | __all__ = ['GenericDatasetJob'] 7 | -------------------------------------------------------------------------------- /digits/dataset/images/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .classification import * # noqa 5 | from .generic import * # noqa 6 | from .job import ImageDatasetJob 7 | 8 | __all__ = ['ImageDatasetJob'] 9 | -------------------------------------------------------------------------------- /digits/dataset/images/classification/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .job import ImageClassificationDatasetJob 5 | 6 | __all__ = ['ImageClassificationDatasetJob'] 7 | -------------------------------------------------------------------------------- /digits/dataset/images/generic/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .job import GenericImageDatasetJob 5 | 6 | __all__ = ['GenericImageDatasetJob'] 7 | -------------------------------------------------------------------------------- /digits/dataset/images/job.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from ..job import DatasetJob 5 | 6 | # NOTE: Increment this every time the pickled object changes 7 | PICKLE_VERSION = 1 8 | 9 | 10 | class ImageDatasetJob(DatasetJob): 11 | """ 12 | A Job that creates an image dataset 13 | """ 14 | 15 | def __init__(self, **kwargs): 16 | """ 17 | Keyword arguments: 18 | image_dims -- (height, width, channels) 19 | resize_mode -- used in utils.image.resize_image() 20 | """ 21 | self.image_dims = kwargs.pop('image_dims', None) 22 | self.resize_mode = kwargs.pop('resize_mode', None) 23 | 24 | super(ImageDatasetJob, self).__init__(**kwargs) 25 | self.pickver_job_dataset_image = PICKLE_VERSION 26 | 27 | @staticmethod 28 | def resize_mode_choices(): 29 | return [ 30 | ('crop', 'Crop'), 31 | ('squash', 'Squash'), 32 | ('fill', 'Fill'), 33 | ('half_crop', 'Half crop, half fill'), 34 | ] 35 | 36 | def resize_mode_name(self): 37 | c = dict(self.resize_mode_choices()) 38 | return c[self.resize_mode] 39 | -------------------------------------------------------------------------------- /digits/dataset/tasks/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .analyze_db import AnalyzeDbTask 5 | from .create_db import CreateDbTask 6 | from .create_generic_db import CreateGenericDbTask 7 | from .parse_folder import ParseFolderTask 8 | from .parse_s3 import ParseS3Task 9 | 10 | __all__ = [ 11 | 'AnalyzeDbTask', 12 | 'CreateDbTask', 13 | 'CreateGenericDbTask', 14 | 'ParseFolderTask', 15 | 'ParseS3Task', 16 | ] 17 | -------------------------------------------------------------------------------- /digits/download_data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/digits/download_data/__init__.py -------------------------------------------------------------------------------- /digits/download_data/__main__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | import argparse 4 | import sys 5 | import time 6 | 7 | from cifar10 import Cifar10Downloader 8 | from cifar100 import Cifar100Downloader 9 | from mnist import MnistDownloader 10 | 11 | if __name__ == '__main__': 12 | parser = argparse.ArgumentParser(description='Download-Data tool - DIGITS') 13 | 14 | # Positional arguments 15 | 16 | parser.add_argument('dataset', 17 | help='mnist/cifar10/cifar100' 18 | ) 19 | parser.add_argument('output_dir', 20 | help='The output directory for the data' 21 | ) 22 | 23 | # Optional arguments 24 | 25 | parser.add_argument('-c', '--clean', 26 | action='store_true', 27 | help='clean out the directory first (if it exists)' 28 | ) 29 | 30 | args = vars(parser.parse_args()) 31 | 32 | dataset = args['dataset'].lower() 33 | 34 | start = time.time() 35 | if dataset == 'mnist': 36 | d = MnistDownloader( 37 | outdir=args['output_dir'], 38 | clean=args['clean']) 39 | d.getData() 40 | elif dataset == 'cifar10': 41 | d = Cifar10Downloader( 42 | outdir=args['output_dir'], 43 | clean=args['clean']) 44 | d.getData() 45 | elif dataset == 'cifar100': 46 | d = Cifar100Downloader( 47 | outdir=args['output_dir'], 48 | clean=args['clean']) 49 | d.getData() 50 | else: 51 | print 'Unknown dataset "%s"' % args['dataset'] 52 | sys.exit(1) 53 | 54 | print 'Done after %s seconds.' % (time.time() - start) 55 | -------------------------------------------------------------------------------- /digits/extensions/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .data import * # noqa 5 | from .view import * # noqa 6 | -------------------------------------------------------------------------------- /digits/extensions/data/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import copy 5 | from pkg_resources import iter_entry_points 6 | 7 | from . import imageProcessing 8 | from . import imageSegmentation 9 | from . import objectDetection 10 | 11 | # Entry point group (this is the key we use to register and 12 | # find installed plug-ins) 13 | GROUP = "digits.plugins.data" 14 | 15 | # built-in extensions 16 | builtin_data_extensions = [ 17 | imageProcessing.DataIngestion, 18 | imageSegmentation.DataIngestion, 19 | objectDetection.DataIngestion, 20 | ] 21 | 22 | 23 | def get_extensions(): 24 | """ 25 | return set of data data extensions 26 | """ 27 | extensions = copy.copy(builtin_data_extensions) 28 | # find installed extension plug-ins 29 | for entry_point in iter_entry_points(group=GROUP, name=None): 30 | extensions.append(entry_point.load()) 31 | 32 | return extensions 33 | 34 | 35 | def get_extension(extension_id): 36 | """ 37 | return extension associated with specified extension_id 38 | """ 39 | for extension in get_extensions(): 40 | if extension.get_id() == extension_id: 41 | return extension 42 | return None 43 | -------------------------------------------------------------------------------- /digits/extensions/data/imageProcessing/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .data import DataIngestion 5 | 6 | __all__ = ['DataIngestion'] 7 | -------------------------------------------------------------------------------- /digits/extensions/data/imageSegmentation/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .data import DataIngestion 5 | 6 | __all__ = ['DataIngestion'] 7 | -------------------------------------------------------------------------------- /digits/extensions/data/objectDetection/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .data import DataIngestion 5 | 6 | __all__ = ['DataIngestion'] 7 | -------------------------------------------------------------------------------- /digits/extensions/view/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import copy 5 | from pkg_resources import iter_entry_points 6 | 7 | from . import boundingBox 8 | from . import imageOutput 9 | from . import imageSegmentation 10 | from . import rawData 11 | 12 | # Entry point group (this is the key we use to register and 13 | # find installed plug-ins) 14 | GROUP = "digits.plugins.view" 15 | 16 | 17 | # built-in extensions 18 | builtin_view_extensions = [ 19 | boundingBox.Visualization, 20 | imageOutput.Visualization, 21 | imageSegmentation.Visualization, 22 | rawData.Visualization, 23 | ] 24 | 25 | 26 | def get_default_extension(): 27 | """ 28 | return the default view extension 29 | """ 30 | return rawData.Visualization 31 | 32 | 33 | def get_extensions(): 34 | """ 35 | return set of data data extensions 36 | """ 37 | extensions = copy.copy(builtin_view_extensions) 38 | # find installed extension plug-ins 39 | for entry_point in iter_entry_points(group=GROUP, name=None): 40 | extensions.append(entry_point.load()) 41 | 42 | return extensions 43 | 44 | 45 | def get_extension(extension_id): 46 | """ 47 | return extension associated with specified extension_id 48 | """ 49 | for extension in get_extensions(): 50 | if extension.get_id() == extension_id: 51 | return extension 52 | return None 53 | -------------------------------------------------------------------------------- /digits/extensions/view/boundingBox/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .view import Visualization 5 | 6 | __all__ = ['Visualization'] 7 | -------------------------------------------------------------------------------- /digits/extensions/view/boundingBox/app_end_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /digits/extensions/view/boundingBox/config_template.html: -------------------------------------------------------------------------------- 1 | {# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} 2 | 3 | {% from "helper.html" import print_flashes %} 4 | {% from "helper.html" import print_errors %} 5 | {% from "helper.html" import mark_errors %} 6 | 7 | Draw a bounding box around a detected object. The expected network output is a dictionary, keyed by class, where the values are lists of bounding boxes for that image. e.g. {'class1': [[l, t, r, b, confidence], ...], ...} 8 | -------------------------------------------------------------------------------- /digits/extensions/view/boundingBox/forms.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from digits.utils import subclass 5 | from flask_wtf import Form 6 | 7 | 8 | @subclass 9 | class ConfigForm(Form): 10 | pass 11 | -------------------------------------------------------------------------------- /digits/extensions/view/boundingBox/header_template.html: -------------------------------------------------------------------------------- 1 | {# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} 2 | 3 | Found {{ bbox_count }} bounding box{% if bbox_count != 1 %}es{% endif %}{% if image_count != 1 %} in {{ image_count }} images{% endif %}. 4 | -------------------------------------------------------------------------------- /digits/extensions/view/boundingBox/view_template.html: -------------------------------------------------------------------------------- 1 | {# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} 2 | 12 | 13 |
18 | 19 | 20 | 21 | {[key]} 22 | 23 | 24 |
25 |The server may be down.
'; 8 | } else { 9 | title = response.status + ': ' + response.statusText; 10 | msg = response.responseText ? response.responseText : response.data; 11 | } 12 | bootbox.alert({ 13 | title: title, 14 | message: msg, 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /digits/static/js/file_field.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | $(document).on('change', '.btn-file :file', function() { 4 | var input = $(this), 5 | numFiles = input.get(0).files ? input.get(0).files.length : 1, 6 | label = input.val().replace(/\\/g, '/').replace(/.*\//, ''); 7 | input.trigger('fileselect', [numFiles, label]); 8 | }); 9 | 10 | $(document).ready(function() { 11 | $('.btn-file :file').on('fileselect', function(event, numFiles, label) { 12 | 13 | var input = $(this).parents('.input-group').find(':text'), 14 | log = numFiles > 1 ? numFiles + ' files selected' : label; 15 | 16 | if (input.length) { 17 | input.val(log); 18 | } else { 19 | if (log) alert(log); 20 | } 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /digits/static/js/timeline-tracing.js: -------------------------------------------------------------------------------- 1 | //# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | 'use strict'; 3 | var TimelineTrace = function(cont_id) { 4 | var container = document.createElement('track-view-container'); 5 | container.id = 'track_view_container'; 6 | this.viewer = document.createElement('tr-ui-timeline-view'); 7 | this.viewer.track_view_container = container; 8 | Polymer.dom(this.viewer).appendChild(container); 9 | this.viewer.id = 'trace-viewer'; 10 | this.viewer.globalMode = false; 11 | this.viewer.viewTitle = 'No Trace Selected'; 12 | Polymer.dom(document.getElementById(cont_id)).appendChild(this.viewer); 13 | }; 14 | 15 | TimelineTrace.prototype.onResult = function(step, result) { 16 | var model = new tr.Model(); 17 | var viewer = this.viewer; 18 | var i = new tr.importer.Import(model); 19 | var p = i.importTracesWithProgressDialog([result]); 20 | function onModelLoaded() { 21 | viewer.model = model; 22 | viewer.viewTitle = 'Trace #' + step; 23 | } 24 | function onImportFail() { 25 | var overlay = new tr.ui.b.Overlay(); 26 | overlay.textContent = tr.b.normalizeException(err).message; 27 | overlay.title = 'Import error'; 28 | overlay.visible = true; 29 | } 30 | p.then(onModelLoaded, onImportFail); 31 | }; 32 | -------------------------------------------------------------------------------- /digits/static/tb/summary-icon.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /digits/store/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/digits/store/__init__.py -------------------------------------------------------------------------------- /digits/templates/datasets/generic/summary.html: -------------------------------------------------------------------------------- 1 | {# Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. #} 2 | 3 |9 | {{dataset.status.name}} 10 | {% if not dataset.status.is_running() %} 11 | 12 | {{dataset.status_history[-1][1]|print_time}} 13 | 14 | {% endif %} 15 |
16 |9 | {{dataset.status.name}} 10 | {% if not dataset.status.is_running() %} 11 | 12 | {{dataset.status_history[-1][1]|print_time}} 13 | 14 | {% endif %} 15 |
16 |9 | {{dataset.status.name}} 10 | {% if not dataset.status.is_running() %} 11 | 12 | {{dataset.status_history[-1][1]|print_time}} 13 | 14 | {% endif %} 15 |
16 |{{message}}
15 | {% endautoescape %} 16 | {% endif %} 17 | {% if description %} 18 |{{description}}
19 | {% endif %} 20 | {% if trace %} 21 |22 | {% autoescape false %} 23 | {{trace}} 24 | {% endautoescape %} 25 |26 | {% endif %} 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /digits/templates/login.html: -------------------------------------------------------------------------------- 1 | {# Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. #} 2 | 3 | {% from "helper.html" import print_flashes %} 4 | 5 | {% extends "layout.html" %} 6 | 7 | {% block content %} 8 |
Classification failed, see job log
19 |Category | 30 |Top images for this category | 31 |
---|---|
{{result[0]}} |
35 |
36 | |
38 |
Pretrained Model | 11 |12 | |
---|---|
18 | {{network}} 19 | {{network.label}} 20 | | 21 |Customize | 22 |
None | 26 |
Network | 5 |Details | 6 |Intended image size | 7 |8 | |
---|
22 | {{traceback}} 23 |24 | {% endif %} 25 | {% endif %} 26 | 27 | -------------------------------------------------------------------------------- /digits/test_device_query.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import mock 5 | import platform 6 | import unittest 7 | 8 | from . import device_query 9 | from digits import test_utils 10 | 11 | 12 | test_utils.skipIfNotFramework('none') 13 | 14 | 15 | class TestGetDevices(): 16 | """ 17 | tests for device_query.get_devices() 18 | """ 19 | @classmethod 20 | def tearDownClass(cls): 21 | # Reload the normal list of devices 22 | device_query.get_devices(True) 23 | 24 | @unittest.skipIf(platform.system() not in ['Linux', 'Darwin'], 25 | 'Platform not supported') 26 | @mock.patch('digits.device_query.ctypes.cdll') 27 | def test_no_cudart(self, mock_cdll): 28 | mock_cdll.LoadLibrary.return_value = None 29 | assert device_query.get_devices(True) == [], 'Devices found even when CUDA disabled!' 30 | 31 | 32 | class TestGetNvmlInfo(): 33 | """ 34 | tests for device_query.get_nvml_info() 35 | """ 36 | @classmethod 37 | def setUpClass(cls): 38 | if device_query.get_nvml() is None: 39 | raise unittest.SkipTest('NVML not found') 40 | 41 | @unittest.skipIf(len(device_query.get_devices(True)) == 0, 42 | 'No GPUs on system') 43 | def test_memory_info_exists(self): 44 | for index, device in enumerate(device_query.get_devices(True)): 45 | assert 'memory' in device_query.get_nvml_info( 46 | index), 'NVML should have memory information for "%s"' % device.name 47 | -------------------------------------------------------------------------------- /digits/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/digits/tools/__init__.py -------------------------------------------------------------------------------- /digits/tools/tensorflow/caffe_tf.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. 2 | // This file is a subset of the caffe.proto file from the Caffe project. 3 | // It is meant to reduce the dependency on Caffe from the Tensorflow wrapper 4 | // For NVIDIA DIGITS 5 | 6 | syntax = "proto2"; 7 | 8 | // Specifies the shape (dimensions) of a Blob. 9 | message BlobShape { 10 | repeated int64 dim = 1 [packed = true]; 11 | } 12 | 13 | message BlobProto { 14 | optional BlobShape shape = 7; 15 | repeated float data = 5 [packed = true]; 16 | repeated float diff = 6 [packed = true]; 17 | repeated double double_data = 8 [packed = true]; 18 | repeated double double_diff = 9 [packed = true]; 19 | 20 | // 4D dimensions -- deprecated. Use "shape" instead. 21 | optional int32 num = 1 [default = 0]; 22 | optional int32 channels = 2 [default = 0]; 23 | optional int32 height = 3 [default = 0]; 24 | optional int32 width = 4 [default = 0]; 25 | } 26 | 27 | // The BlobProtoVector is simply a way to pass multiple blobproto instances 28 | // around. 29 | message BlobProtoVector { 30 | repeated BlobProto blobs = 1; 31 | } 32 | 33 | message Datum { 34 | optional int32 channels = 1; 35 | optional int32 height = 2; 36 | optional int32 width = 3; 37 | // the actual image data, in bytes 38 | optional bytes data = 4; 39 | optional int32 label = 5; 40 | // Optionally, the datum could also hold float data. 41 | repeated float float_data = 6; 42 | optional bool encoded = 7 [default = false]; 43 | } 44 | -------------------------------------------------------------------------------- /digits/tools/torch/datum.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | message Datum { 3 | optional int32 channels = 1; 4 | optional int32 height = 2; 5 | optional int32 width = 3; 6 | // the actual image data, in bytes 7 | optional bytes data = 4; 8 | optional int32 label = 5; 9 | // Optionally, the datum could also hold float data. 10 | repeated float float_data = 6; 11 | optional bool encoded = 7 [default = false]; 12 | } 13 | -------------------------------------------------------------------------------- /digits/tools/torch/logmessage.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | -- This file contains the logic of printing log messgages 4 | local logmessage = torch.class('logmessage') 5 | 6 | ------------------------------------------------------------------------------------------------------------- 7 | -- display function accepts two input parameters: 8 | -- parameter_name format description 9 | -- levelcode number specifies the severity of message i.e., 0=info, 1=warn, 2=error. 10 | -- message string message to be displayed 11 | 12 | -- Usage: 13 | -- require 'logmessage' 14 | -- logmessage.display(0,'This is informational message as the levelcode is 0') 15 | ------------------------------------------------------------------------------------------------------------- 16 | function logmessage.display(levelcode, message) 17 | local levelname=nil 18 | if levelcode == 0 then 19 | levelname="INFO " 20 | elseif levelcode == 1 then 21 | levelname="WARNING" 22 | elseif levelcode == 2 then 23 | levelname="ERROR" 24 | elseif levelcode == 3 then 25 | levelname="FAIL" 26 | end 27 | print(os.date("%Y-%m-%d %H:%M:%S") .. ' [' .. levelname .. '] ' .. message) 28 | end 29 | 30 | -------------------------------------------------------------------------------- /digits/tools/torch/wrapper.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | -- retrieve path to this script so we can import and invoke scripts that 4 | -- are in the same directory 5 | local path = debug.getinfo(1,"S").source 6 | local dir_path = path:match[[^@?(.*[\/])[^\/]-$]] 7 | assert(dir_path ~= nil) 8 | package.path = dir_path .."?.lua;".. package.path 9 | 10 | require 'logmessage' 11 | 12 | -- custom error handler prints error using logmessage API 13 | function err (x) 14 | logmessage.display(3, x) 15 | print(debug.traceback('DIGITS Lua Error',2)) 16 | return "DIGITS error" 17 | end -- err 18 | 19 | if #arg < 1 then 20 | logmessage.display(3, 'Usage: ' .. path .. ' script.lua [args]') 21 | os.exit(1) 22 | end 23 | 24 | -- invoke script within xpcall() to catch errors 25 | if xpcall(function() dofile(dir_path .. arg[1]) end, err) then 26 | -- OK 27 | os.exit(0) 28 | else 29 | -- an error occurred 30 | os.exit(1) 31 | end 32 | 33 | 34 | -------------------------------------------------------------------------------- /digits/tools/upload_config.cfg: -------------------------------------------------------------------------------- 1 | [S3 Config] 2 | endpoint = http://your-endpoint-here:80 3 | accesskey = 0123456789abcde 4 | secretkey = PrIclctP80KrMi6+UPO9ZYNrkg6ByFeFRR6484qL 5 | bucket = digits 6 | prefix = mnist 7 | -------------------------------------------------------------------------------- /digits/tools/upload_s3_data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | import os 6 | import ConfigParser 7 | from s3_walker import S3Walker 8 | 9 | config = ConfigParser.RawConfigParser() 10 | config.read('upload_config.cfg') 11 | endpoint = config.get('S3 Config', 'endpoint') 12 | accesskey = config.get('S3 Config', 'accesskey') 13 | secretkey = config.get('S3 Config', 'secretkey') 14 | bucket_name = config.get('S3 Config', 'bucket') 15 | path_prefix = config.get('S3 Config', 'prefix') 16 | if not (path_prefix.endswith('/')): 17 | path_prefix += '/' 18 | 19 | # mnist 20 | # - train 21 | # -- 0 ... 9 22 | # --- XXX.png 23 | try: 24 | mnist_folder = sys.argv[1] 25 | except IndexError: 26 | print('mnist folder should be passed') 27 | sys.exit(1) 28 | 29 | walker = S3Walker(endpoint, accesskey, secretkey) 30 | walker.connect() 31 | 32 | # Create bucket 33 | print('Creating bucket') 34 | walker.create_bucket(bucket_name) 35 | 36 | mnist_train_folder = os.path.join(mnist_folder, 'train') 37 | digits = os.listdir(mnist_train_folder) 38 | for digit in digits: 39 | digit_folder = os.path.join(mnist_train_folder, digit) 40 | if os.path.isfile(digit_folder): 41 | continue 42 | files = os.listdir(digit_folder) 43 | for f in files: 44 | if not f.endswith('.png'): 45 | continue 46 | file = os.path.join(digit_folder, f) 47 | key = path_prefix + file[file.index('train'):] 48 | walker.put(bucket_name, key, file) 49 | print('uploaded ' + file + ' ==> ' + key) 50 | -------------------------------------------------------------------------------- /digits/utils/constants.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | # Datasets 4 | TRAIN_FILE = 'train.txt' 5 | TRAIN_DB = 'train_db' 6 | VAL_FILE = 'val.txt' 7 | VAL_DB = 'val_db' 8 | TEST_FILE = 'test.txt' 9 | TEST_DB = 'test_db' 10 | MEAN_FILE_IMAGE = 'mean.jpg' 11 | 12 | # Classification jobs 13 | LABELS_FILE = 'labels.txt' 14 | DEFAULT_BATCH_SIZE = 16 15 | 16 | # Caffe Protocol Buffers 17 | MEAN_FILE_CAFFE = 'mean.binaryproto' 18 | 19 | # Color Palette attribute 20 | COLOR_PALETTE_ATTRIBUTE = 'color_palette' 21 | -------------------------------------------------------------------------------- /digits/utils/errors.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | 4 | class DigitsError(Exception): 5 | """ 6 | DIGITS custom exception 7 | """ 8 | pass 9 | 10 | 11 | class DeleteError(DigitsError): 12 | """ 13 | Errors that occur when deleting a job 14 | """ 15 | pass 16 | 17 | 18 | class LoadImageError(DigitsError): 19 | """ 20 | Errors that occur while loading an image 21 | """ 22 | pass 23 | 24 | 25 | class UnsupportedPlatformError(DigitsError): 26 | """ 27 | Errors that occur while performing tasks in unsupported platforms 28 | """ 29 | pass 30 | -------------------------------------------------------------------------------- /digits/utils/lmdbreader.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import lmdb 5 | 6 | 7 | class DbReader(object): 8 | """ 9 | Reads a database 10 | """ 11 | 12 | def __init__(self, location): 13 | """ 14 | Arguments: 15 | location -- where is the database 16 | """ 17 | self._db = lmdb.open( 18 | location, 19 | map_size=1024**3, # 1MB 20 | readonly=True, 21 | lock=False) 22 | 23 | with self._db.begin() as txn: 24 | self.total_entries = txn.stat()['entries'] 25 | 26 | self.txn = self._db.begin() 27 | 28 | def entries(self): 29 | """ 30 | Generator returning all entries in the DB 31 | """ 32 | with self._db.begin() as txn: 33 | cursor = txn.cursor() 34 | for item in cursor: 35 | yield item 36 | 37 | def entry(self, key): 38 | """Return single entry""" 39 | return self.txn.get(key) 40 | -------------------------------------------------------------------------------- /digits/utils/routing.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | import flask 5 | import werkzeug.exceptions 6 | 7 | 8 | def job_from_request(): 9 | """ 10 | Returns the job after grabbing job_id from request.args or request.form 11 | Raises werkzeug.exceptions 12 | """ 13 | from digits.webapp import scheduler 14 | 15 | job_id = get_request_arg('job_id') 16 | if job_id is None: 17 | raise werkzeug.exceptions.BadRequest('job_id is a required field') 18 | 19 | job = scheduler.get_job(job_id) 20 | if job is None: 21 | raise werkzeug.exceptions.NotFound('Job not found') 22 | else: 23 | return job 24 | 25 | # Adapted from http://flask.pocoo.org/snippets/45/ 26 | 27 | 28 | def request_wants_json(): 29 | """ 30 | Returns True if the response should be JSON 31 | """ 32 | if flask.request.base_url.endswith('/json'): 33 | return True 34 | best = flask.request.accept_mimetypes \ 35 | .best_match(['application/json', 'text/html']) 36 | # Some browsers accept on */* and we don't want to deliver JSON to an ordinary browser 37 | return best == 'application/json' and \ 38 | flask.request.accept_mimetypes[best] > \ 39 | flask.request.accept_mimetypes['text/html'] 40 | 41 | # check for arguments pass to url 42 | 43 | 44 | def get_request_arg(key): 45 | value = None 46 | if key in flask.request.args: 47 | value = flask.request.args[key] 48 | elif key in flask.request.form: 49 | value = flask.request.form[key] 50 | return value 51 | -------------------------------------------------------------------------------- /digits/utils/store.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from HTMLParser import HTMLParser 5 | import time 6 | 7 | 8 | class StoreCache(): 9 | 10 | def __init__(self, ttl=86400): 11 | self.expiration_time = time.time() + ttl 12 | self.ttl = ttl 13 | self.cache = None 14 | 15 | def reset(self): 16 | self.expiration_time = time.time() + self.ttl 17 | self.cache = None 18 | 19 | def read(self): 20 | if self.expiration_time < time.time(): 21 | self.reset() 22 | return self.cache 23 | 24 | def write(self, data): 25 | self.expiration_time = time.time() + self.ttl 26 | self.cache = data 27 | 28 | 29 | class StoreParser(HTMLParser): 30 | 31 | def __init__(self): 32 | HTMLParser.__init__(self) 33 | self.starting = False 34 | self.dirs = list() 35 | self.reset() 36 | 37 | def read(self, data): 38 | self.reset() 39 | self.clean() 40 | self.feed(data) 41 | 42 | def clean(self): 43 | pass 44 | 45 | def handle_starttag(self, tag, attrs): 46 | if tag == 'td' or tag == 'a': 47 | self.starting = True 48 | 49 | def handle_endtag(self, tag): 50 | if tag == 'td' or tag == 'a': 51 | self.starting = False 52 | 53 | def handle_data(self, data): 54 | if self.starting and data[-1] == '/': 55 | self.dirs.append(data) 56 | 57 | def get_child_dirs(self): 58 | return self.dirs 59 | -------------------------------------------------------------------------------- /digits/version.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 | 3 | __version__ = '6.1.1' 4 | -------------------------------------------------------------------------------- /docs/BuildProtobuf.md: -------------------------------------------------------------------------------- 1 | # Building Protobuf 2 | 3 | To be able to run Caffe and Tensorflow inside DIGITS side by side, protobuf 3 must be built from source. Caffe can be installed from debian packages but if it were to be run with tensorflow, some features such as python layers will not work properly. It is highly suggested to build protobuf from source to ensure DIGITS to work properly. 4 | 5 | This guide is based on [google's protobuf installation guide](https://github.com/google/protobuf/blob/master/src/README.md). 6 | 7 | ## Dependencies 8 | 9 | These Deb packages must be installed to build Protobuf 3 10 | ``` 11 | sudo apt-get install autoconf automake libtool curl make g++ git python-dev python-setuptools unzip 12 | ``` 13 | 14 | ## Download Source 15 | 16 | DIGITS is currently compatiable with Protobuf 3.2.x 17 | 18 | ```sh 19 | # example location - can be customized 20 | export PROTOBUF_ROOT=~/protobuf 21 | git clone https://github.com/google/protobuf.git $PROTOBUF_ROOT -b '3.2.x' 22 | ``` 23 | 24 | ## Building Protobuf 25 | 26 | ```sh 27 | cd $PROTOBUF_ROOT 28 | ./autogen.sh 29 | ./configure 30 | make "-j$(nproc)" 31 | make install 32 | ldconfig 33 | cd python 34 | python setup.py install --cpp_implementation 35 | ``` 36 | 37 | This will ensure that Protobuf 3 is installed. -------------------------------------------------------------------------------- /docs/Configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | DIGITS uses environment variables for configuration. 4 | 5 | > NOTE: Prior to [#1091](https://github.com/NVIDIA/DIGITS/pull/1091) (up to DIGITS 4.0), DIGITS used configuration files instead of environment variables. 6 | 7 | 8 | ## Environment Variables 9 | 10 | | Variable | Example value | Description | 11 | | --- | --- | --- | 12 | | `DIGITS_JOBS_DIR` | ~/digits-jobs | Location where job files are stored. Default is `$DIGITS_ROOT/digits/jobs`. | 13 | | `CAFFE_ROOT` | ~/caffe | Path to your local Caffe build. Should contain `build/tools/caffe` and `python/caffe/`. If unset, looks for `caffe` in PATH and PYTHONPATH.| 14 | | `TORCH_ROOT` | ~/torch | Path to your local Torch build. Should contain `install/bin/th`. If unset, looks for `th` in PATH. | 15 | | `DIGITS_LOGFILE_FILENAME` | ~/digits.log | File for saving log messages. Default is `$DIGITS_ROOT/digits/digits.log`. | 16 | | `DIGITS_LOGFILE_LEVEL` | DEBUG | Minimum log message level to be saved (DEBUG/INFO/WARNING/ERROR/CRITICAL). Default is INFO. | 17 | | `DIGITS_SERVER_NAME` | The Big One | The name of the server (accessible in the UI under "Info"). Default is the system hostname. | 18 | | `DIGITS_MODEL_STORE_URL` | http://localhost/modelstore | A list of URL's, separated by comma. Default is the official NVIDIA store. | 19 | | `DIGITS_URL_PREFIX` | /custom-prefix | A path to prepend before every URL. Sets the home-page to be at "http://localhost/custom-prefix" instead of "http://localhost/"/ | 20 | -------------------------------------------------------------------------------- /docs/DevelopmentSetup.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | The source code for DIGITS is available on [github](https://github.com/NVIDIA/DIGITS). 4 | 5 | To have access to your local machine, you may clone from the github repository with 6 | ``` 7 | git clone https://github.com/NVIDIA/DIGITS.git 8 | ``` 9 | Or you may download the source code as a zip file from the github website. 10 | 11 | ## Running DIGITS in Development 12 | 13 | DIGITS comes with the script to run for a development server. 14 | To run the development server, use 15 | ``` 16 | ./digits-devserver 17 | ``` 18 | 19 | ## Running unit tests for DIGITS 20 | 21 | To successfully run all the unit tests, the following plugins have to be installed 22 | ``` 23 | sudo pip install -r ./requirements_test.txt 24 | ``` 25 | 26 | To run all the tests for DIGITS, use 27 | ``` 28 | ./digits-test 29 | ``` 30 | 31 | If you would like to have a verbose output with the name of the tests, use 32 | ``` 33 | ./digits-test -v 34 | ``` -------------------------------------------------------------------------------- /docs/images/Select_TensorFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/Select_TensorFlow.png -------------------------------------------------------------------------------- /docs/images/TensorBoard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/TensorBoard.png -------------------------------------------------------------------------------- /docs/images/classified-one-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/classified-one-image.jpg -------------------------------------------------------------------------------- /docs/images/classifying-one-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/classifying-one-image.jpg -------------------------------------------------------------------------------- /docs/images/creating-dataset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/creating-dataset.jpg -------------------------------------------------------------------------------- /docs/images/home-page-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/home-page-1.jpg -------------------------------------------------------------------------------- /docs/images/home-page-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/home-page-2.jpg -------------------------------------------------------------------------------- /docs/images/job-dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/job-dir.png -------------------------------------------------------------------------------- /docs/images/login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/login.jpg -------------------------------------------------------------------------------- /docs/images/model-store/custom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/model-store/custom.jpg -------------------------------------------------------------------------------- /docs/images/model-store/home.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/model-store/home.jpg -------------------------------------------------------------------------------- /docs/images/model-store/official.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/model-store/official.png -------------------------------------------------------------------------------- /docs/images/new-dataset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/new-dataset.jpg -------------------------------------------------------------------------------- /docs/images/new-model.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/new-model.jpg -------------------------------------------------------------------------------- /docs/images/standard-datasets/html-form.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/standard-datasets/html-form.jpg -------------------------------------------------------------------------------- /docs/images/torch-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/torch-selection.png -------------------------------------------------------------------------------- /docs/images/training-model.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/training-model.jpg -------------------------------------------------------------------------------- /docs/images/visualize-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/visualize-btn.png -------------------------------------------------------------------------------- /docs/images/visualize_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/docs/images/visualize_button.png -------------------------------------------------------------------------------- /examples/autoencoder/autoencoder-TF.py: -------------------------------------------------------------------------------- 1 | # Tensorflow MNIST autoencoder model using TensorFlow-Slim 2 | from model import Tower 3 | from utils import model_property 4 | import tensorflow as tf 5 | import tensorflow.contrib.slim as slim 6 | import utils as digits 7 | 8 | 9 | class UserModel(Tower): 10 | 11 | @model_property 12 | def inference(self): 13 | 14 | with slim.arg_scope([slim.fully_connected], 15 | weights_initializer=tf.contrib.layers.xavier_initializer(), 16 | weights_regularizer=slim.l2_regularizer(0.0005)): 17 | const = tf.constant(0.00390625) 18 | model = tf.multiply(self.x, const) 19 | model = tf.reshape(model, shape=[-1, 784]) # equivalent to `model = slim.flatten(_x)` 20 | model = slim.fully_connected(model, 300, scope='fc1') 21 | model = slim.fully_connected(model, 50, scope='fc2') 22 | model = slim.fully_connected(model, 300, scope='fc3') 23 | model = slim.fully_connected(model, 784, activation_fn=None, scope='fc4') 24 | model = tf.reshape(model, shape=[-1, self.input_shape[0], self.input_shape[1], self.input_shape[2]]) 25 | 26 | # The below image summary makes it very easy to review your result 27 | tf.summary.image(self.x.op.name, self.x, max_outputs=5, collections=['summaries']) 28 | tf.summary.image(model.op.name, model, max_outputs=5, collections=['summaries']) 29 | 30 | return model 31 | 32 | @model_property 33 | def loss(self): 34 | return digits.mse_loss(self.inference, self.x) 35 | -------------------------------------------------------------------------------- /examples/autoencoder/compressed-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/compressed-image.png -------------------------------------------------------------------------------- /examples/autoencoder/create-generic-dataset-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/create-generic-dataset-form.png -------------------------------------------------------------------------------- /examples/autoencoder/create-generic-dataset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/create-generic-dataset.png -------------------------------------------------------------------------------- /examples/autoencoder/create-model-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/create-model-form.png -------------------------------------------------------------------------------- /examples/autoencoder/create-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/create-model.png -------------------------------------------------------------------------------- /examples/autoencoder/mnist-classification-dataset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/mnist-classification-dataset.png -------------------------------------------------------------------------------- /examples/autoencoder/normalized-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/normalized-image.png -------------------------------------------------------------------------------- /examples/autoencoder/original-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/original-image.png -------------------------------------------------------------------------------- /examples/autoencoder/reconstructed-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/reconstructed-image.png -------------------------------------------------------------------------------- /examples/autoencoder/tensorflow-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/tensorflow-settings.png -------------------------------------------------------------------------------- /examples/autoencoder/test-single-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/test-single-image.png -------------------------------------------------------------------------------- /examples/autoencoder/training-loss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/autoencoder/training-loss.png -------------------------------------------------------------------------------- /examples/binary-segmentation/binary_segmentation-TF.py: -------------------------------------------------------------------------------- 1 | # Tensorflow Triangle binary segmentation model using TensorFlow-Slim 2 | from model import Tower 3 | from utils import model_property 4 | import tensorflow as tf 5 | import tensorflow.contrib.slim as slim 6 | import utils as digits 7 | 8 | 9 | class UserModel(Tower): 10 | 11 | @model_property 12 | def inference(self): 13 | _x = tf.reshape(self.x, shape=[-1, self.input_shape[0], self.input_shape[1], self.input_shape[2]]) 14 | with slim.arg_scope([slim.conv2d, slim.conv2d_transpose], 15 | weights_initializer=tf.contrib.layers.xavier_initializer(), 16 | weights_regularizer=slim.l2_regularizer(0.05)): 17 | 18 | # 1*H*W -> 32*H*W 19 | model = slim.conv2d(_x, 32, [3, 3], padding='SAME', scope='conv1') 20 | # 32*H*W -> 1024*H/16*W/16 21 | model = slim.conv2d(model, 1024, [16, 16], padding='VALID', scope='conv2', stride=16) 22 | model = slim.conv2d_transpose(model, self.input_shape[2], [16, 16], 23 | stride=16, padding='VALID', activation_fn=None, scope='deconv_1') 24 | return model 25 | 26 | @model_property 27 | def loss(self): 28 | y = tf.reshape(self.y, shape=[-1, self.input_shape[0], self.input_shape[1], self.input_shape[2]]) 29 | 30 | # For a fancy tensorboard summary: put the input, label and model side by side (sbs) for a fancy image summary: 31 | # tf.summary.image(sbs.op.name, sbs, max_outputs=3, collections=["training summary"]) 32 | return digits.mse_loss(self.inference, y) 33 | -------------------------------------------------------------------------------- /examples/binary-segmentation/create-dataset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/create-dataset.png -------------------------------------------------------------------------------- /examples/binary-segmentation/dont-resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/dont-resize.png -------------------------------------------------------------------------------- /examples/binary-segmentation/in-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/in-example.png -------------------------------------------------------------------------------- /examples/binary-segmentation/label-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/label-example.png -------------------------------------------------------------------------------- /examples/binary-segmentation/network-topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/network-topology.png -------------------------------------------------------------------------------- /examples/binary-segmentation/select-dataset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/select-dataset.png -------------------------------------------------------------------------------- /examples/binary-segmentation/select-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/select-model.png -------------------------------------------------------------------------------- /examples/binary-segmentation/select-visualization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/select-visualization.png -------------------------------------------------------------------------------- /examples/binary-segmentation/test-db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/test-db.png -------------------------------------------------------------------------------- /examples/binary-segmentation/test-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/test-grid.png -------------------------------------------------------------------------------- /examples/binary-segmentation/test-one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/test-one.png -------------------------------------------------------------------------------- /examples/binary-segmentation/training-loss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/binary-segmentation/training-loss.png -------------------------------------------------------------------------------- /examples/classification/requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow>=2.3.0 2 | numpy>=1.7 3 | scipy>=0.13.3 4 | protobuf>=2.5.0 5 | -------------------------------------------------------------------------------- /examples/fine-tuning/create-dataset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/examples/fine-tuning/create-dataset.png -------------------------------------------------------------------------------- /examples/fine-tuning/create_dataset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 3 | 4 | if [ "$#" -ne 2 ] || ! [ -d "$2" ]; then 5 | echo "Usage: $0
6 | You attempted to upload a file that exceeded the limit allowed by the 7 | NGINX reverse proxy server. 8 |
9 |10 | You can try uploading your file directly to the DIGITS server running at 11 | :34448/">http://:34448/. 13 |
14 |15 | You can also try increasing the value of the client_max_body_size setting 16 | in /etc/nginx/sites-available/digits.nginx-site. 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /packaging/deb/extras/custom_http_errors/502.html: -------------------------------------------------------------------------------- 1 | 2 |8 | On Ubuntu 14.04, use this command to restart the server: 9 |
10 |11 | sudo service digits restart 12 |13 |
14 | On Ubuntu 16.04, use this command to restart the server: 15 |
16 |17 | sudo systemctl restart digits 18 |19 | 20 |
22 | If you are still encountering problems after restarting, check the logs for errors. 23 |
24 |25 | cat /var/log/digits/digits.log 26 |27 | 28 |
29 | For additional messsages on Ubuntu 14.04: 30 |
31 |32 | cat /var/log/upstart/digits.log 33 |34 |
35 | For additional messages on Ubuntu 16.04: 36 |
37 |38 | journalctl -u digits.service 39 |40 | 41 | 42 | -------------------------------------------------------------------------------- /packaging/deb/extras/digits.nginx-site: -------------------------------------------------------------------------------- 1 | # DIGITS NGINX site 2 | 3 | server { 4 | listen 80; #AUTOCONFIG port (DO NOT DELETE THIS LINE) 5 | 6 | # Main server 7 | location / { 8 | client_max_body_size 500M; # Increase this if you receive error 413 9 | 10 | proxy_pass http://127.0.0.1:34448; 11 | proxy_redirect off; 12 | 13 | proxy_set_header Host $host:$server_port; 14 | proxy_set_header X-Real-IP $remote_addr; 15 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 16 | 17 | error_page 413 /custom_http_errors/413.shtml; 18 | error_page 502 /custom_http_errors/502.html; 19 | } 20 | 21 | # Socketio 22 | location /socket.io { 23 | proxy_pass http://127.0.0.1:34448/socket.io; 24 | proxy_redirect off; 25 | proxy_buffering off; 26 | 27 | proxy_set_header Host $host; 28 | proxy_set_header X-Real-IP $remote_addr; 29 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 30 | 31 | proxy_http_version 1.1; 32 | proxy_set_header Upgrade $http_upgrade; 33 | proxy_set_header Connection "Upgrade"; 34 | } 35 | 36 | # Custom error pages 37 | location /custom_http_errors { 38 | ssi on; 39 | alias /usr/share/digits/custom_http_errors; 40 | } 41 | 42 | # Static files 43 | location /static { 44 | alias /usr/lib/python2.7/dist-packages/digits/static; 45 | } 46 | location /files { 47 | alias /var/lib/digits/jobs; #AUTOCONFIG jobs_dir (DO NOT DELETE THIS LINE) 48 | autoindex on; 49 | autoindex_exact_size off; 50 | autoindex_localtime on; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packaging/deb/private.key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/DIGITS/e99d664eaf01081ee7ae744331d75d4247df15c6/packaging/deb/private.key.enc -------------------------------------------------------------------------------- /packaging/deb/templates/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /packaging/deb/templates/control: -------------------------------------------------------------------------------- 1 | Source: digits 2 | Section: universe/misc 3 | Maintainer: #USERNAME# <#EMAIL#> 4 | Homepage: https://developer.nvidia.com/digits 5 | Vcs-Browser: https://github.com/NVIDIA/DIGITS 6 | Priority: optional 7 | Build-Depends: debhelper (>= 9), dh-python, dh-systemd, python-all, python-setuptools, debconf 8 | Standards-Version: #POLICY# 9 | 10 | Package: digits 11 | Architecture: all 12 | Depends: ${misc:Depends}, ${python:Depends}, 13 | caffe-nv (>= 0.13), 14 | graphviz, 15 | nginx, 16 | python-caffe-nv (>= 0.13), 17 | python-flaskext.socketio (>= 2.6), 18 | python-flaskext.wtf (>= 0.11), 19 | python-lmdb (>= 0.87), 20 | python-setuptools, 21 | python-wtforms (>= 2.0.1) 22 | Recommends: torch7-nv 23 | Conflicts: digits-devbox-config (<< 3.0.0), torch7 24 | Description: NVIDIA DIGITS webserver 25 | This package installs the DIGITS webserver as a service. 26 | . 27 | DIGITS is the Deep Learning GPU Training System from NVIDIA. It provides an 28 | interactive environment for training, evaluating and experimenting with neural 29 | networks. 30 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.config: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Source debconf library 5 | . /usr/share/debconf/confmodule 6 | 7 | port_is_valid() { 8 | case "$1" in 9 | '-1') return 0 ;; 10 | [0-9]*) 11 | if [ "$1" -le "65535" ] 2>/dev/null 12 | then 13 | return 0 14 | fi 15 | ;; 16 | esac 17 | return 1 18 | } 19 | 20 | # Get current value for port (or default) 21 | # Since the priority is medium, this won't show up by default 22 | db_input medium digits/port || true 23 | db_go 24 | db_get digits/port 25 | PORT="$RET" 26 | 27 | 28 | if port_is_valid $PORT 29 | then 30 | PORT_VALID=true 31 | else 32 | PORT_VALID=false 33 | fi 34 | 35 | # loop until we have a valid port, or the same value is entered twice 36 | while [ "$PORT_VALID" = false ] 37 | do 38 | # Add error messages 39 | if [ "$PORT_VALID" = false ] 40 | then 41 | db_reset digits/port-invalid 42 | db_input critical digits/port-invalid || true 43 | fi 44 | 45 | # Ask for the port 46 | db_fset digits/port seen false 47 | db_input critical digits/port || true 48 | db_go 49 | db_get digits/port 50 | NEW_PORT="$RET" 51 | 52 | # Exit if value unchanged 53 | if [ "$NEW_PORT" = "$PORT" ] 54 | then 55 | echo Port unchanged. Aborting. 56 | exit 1 57 | fi 58 | 59 | # Recalculate valid/bound 60 | PORT="$NEW_PORT" 61 | if port_is_valid $PORT 62 | then 63 | PORT_VALID=true 64 | else 65 | PORT_VALID=false 66 | fi 67 | done 68 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.dirs: -------------------------------------------------------------------------------- 1 | /var/lib/digits/jobs 2 | /var/log/digits 3 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.install: -------------------------------------------------------------------------------- 1 | debian/digits.nginx-site /etc/nginx/sites-available 2 | debian/custom_http_errors /usr/share/digits 3 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.lintian-overrides: -------------------------------------------------------------------------------- 1 | python-script-but-no-python-dep 2 | postrm-does-not-call-updaterc.d-for-init.d-script 3 | init.d-script-not-included-in-package 4 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Read port from debconf 5 | . /usr/share/debconf/confmodule 6 | db_get digits/port 7 | PORT="$RET" 8 | db_stop 9 | 10 | #DEBHELPER# 11 | 12 | case "$1" in 13 | configure) 14 | # Update permissions on new directories 15 | chown www-data /var/lib/digits/jobs /var/log/digits 16 | 17 | # Disable default NGINX site 18 | NGINX_NEEDS_RELOAD=false 19 | DEFAULT_SITE=/etc/nginx/sites-enabled/default 20 | if [ -L "$DEFAULT_SITE" ] 21 | then 22 | echo WARNING - Disabling default nginx site at $DEFAULT_SITE 23 | rm -f $DEFAULT_SITE 24 | NGINX_NEEDS_RELOAD=true 25 | fi 26 | 27 | # Enable nginx site 28 | SITE_FILE=/etc/nginx/sites-available/digits.nginx-site 29 | SITE_LINK=/etc/nginx/sites-enabled/digits.nginx-site 30 | if [ "$PORT" != "-1" ] 31 | then 32 | sed "s/.*AUTOCONFIG port.*/ listen ${PORT}; #AUTOCONFIG port (DO NOT DELETE THIS LINE)/" $SITE_FILE -i 33 | rm -f $SITE_LINK 34 | ln -s $SITE_FILE $SITE_LINK 35 | NGINX_NEEDS_RELOAD=true 36 | fi 37 | if [ "$NGINX_NEEDS_RELOAD" = true ] 38 | then 39 | service nginx reload 40 | fi 41 | ;; 42 | 43 | abort-upgrade|abort-remove|abort-deconfigure) 44 | ;; 45 | 46 | *) 47 | echo "postinst called with unknown argument \`$1'" >&2 48 | exit 1 49 | ;; 50 | esac 51 | 52 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | case "$1" in 5 | purge) 6 | # Remove all job data 7 | rm -rf /var/lib/digits/jobs /var/log/digits 8 | ;; 9 | 10 | remove|upgrade|disappear|failed-upgrade|abort-install|abort-upgrade) 11 | ;; 12 | 13 | *) 14 | echo "postrm called with unknown argument \`$1'" >&2 15 | exit 1 16 | ;; 17 | esac 18 | 19 | #DEBHELPER# 20 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.preinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | case "$1" in 5 | install|upgrade) 6 | if [ -d /usr/share/digits/digits/jobs ]; then 7 | # Copy job data from previous install 8 | mkdir -p /var/lib/digits 9 | mv /usr/share/digits/digits/jobs /var/lib/digits/ 10 | fi 11 | ;; 12 | 13 | abort-upgrade) 14 | ;; 15 | 16 | *) 17 | echo "preinst called with unknown argument \`$1'" >&2 18 | exit 1 19 | ;; 20 | esac 21 | 22 | #DEBHELPER# 23 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | case "$1" in 5 | remove) 6 | # Disable NGINX site 7 | SITE_LINK=/etc/nginx/sites-enabled/digits-nginx.site 8 | if [ -L "$SITE_LINK" ] 9 | then 10 | rm -f $SITE_LINK 11 | service nginx reload 12 | fi 13 | ;; 14 | 15 | upgrade|deconfigure|failed-upgrade) 16 | ;; 17 | 18 | *) 19 | echo "prerm called with unknown argument \`$1'" >&2 20 | exit 1 21 | ;; 22 | esac 23 | 24 | 25 | #DEBHELPER# 26 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.service: -------------------------------------------------------------------------------- 1 | # DIGITS systemd service 2 | [Unit] 3 | Description=DIGITS server 4 | After=local-fs.target network.target 5 | 6 | [Service] 7 | User=www-data 8 | Environment="DIGITS_JOBS_DIR=/var/lib/digits/jobs" 9 | Environment="DIGITS_LOGFILE_FILENAME=/var/log/digits/digits.log" 10 | ExecStart=/usr/bin/python -m digits -p 34448 11 | Restart=on-failure 12 | ExecStop=/bin/kill -INT $MAINPID 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.templates: -------------------------------------------------------------------------------- 1 | Template: digits/port 2 | Type: string 3 | Default: 80 4 | Description: DIGITS front-end port for NGINX reverse proxy (0-65535): 5 | The DIGITS backend server runs on port 34448 (DIGIT), but this package also 6 | configures NGINX to function as a reverse proxy for DIGITS. 7 | . 8 | If you don't want to use NGINX as a reverse proxy, choose "-1" and the NGINX 9 | site will not be installed. 10 | 11 | Template: digits/port-invalid 12 | Type: note 13 | Description: ERROR - the port you chose is invalid 14 | Valid values are 0-65535 or -1. 15 | -------------------------------------------------------------------------------- /packaging/deb/templates/digits.upstart: -------------------------------------------------------------------------------- 1 | # DIGITS upstart service 2 | description "DIGITS server" 3 | setuid www-data 4 | start on started networking 5 | start on runlevel [2345] 6 | kill signal INT 7 | respawn 8 | 9 | env DIGITS_JOBS_DIR=/var/lib/digits/jobs 10 | env DIGITS_LOGFILE_FILENAME=/var/log/digits/digits.log 11 | exec python -m digits -p 34448 12 | -------------------------------------------------------------------------------- /packaging/deb/templates/pydist-overrides: -------------------------------------------------------------------------------- 1 | flask-socketio python-flaskext.socketio 2 | scikit-fmm python-skfmm 3 | -------------------------------------------------------------------------------- /packaging/deb/templates/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ --parallel --with=python2,systemd --buildsystem=pybuild 5 | 6 | override_dh_auto_test: 7 | : 8 | -------------------------------------------------------------------------------- /packaging/deb/templates/source.lintian-overrides: -------------------------------------------------------------------------------- 1 | source-is-missing 2 | untranslatable-debconf-templates 3 | not-using-po-debconf 4 | -------------------------------------------------------------------------------- /plugins/data/bAbI/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include digitsDataPluginBAbI *.html 2 | -------------------------------------------------------------------------------- /plugins/data/bAbI/README: -------------------------------------------------------------------------------- 1 | This DIGITS plug-in demonstrates how to load data from the bAbI dataset. 2 | The dataset may be found on https://research.facebook.com/research/babi/ 3 | -------------------------------------------------------------------------------- /plugins/data/bAbI/digitsDataPluginBAbI/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 2 | from __future__ import absolute_import 3 | 4 | from .data import DataIngestion 5 | 6 | __all__ = ['DataIngestion'] 7 | -------------------------------------------------------------------------------- /plugins/data/bAbI/digitsDataPluginBAbI/templates/dataset_template.html: -------------------------------------------------------------------------------- 1 | {# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. #} 2 | 3 | {% from "helper.html" import print_flashes %} 4 | {% from "helper.html" import print_errors %} 5 | {% from "helper.html" import mark_errors %} 6 | 7 |
22 |
23 | |
24 | {% endfor %}
25 |
19 | |
21 |
22 | |
24 | 25 | {{z}} 26 | | 27 |
33 | |
35 |
39 |
40 | {% for attribute in top5 %}
41 | {{attribute[1]}} {{ attribute[0] }}
42 | 43 | {% endfor %} 44 | |
45 |
{{input}} | 16 | 17 |
18 | {% for r in predictions %}
19 | {{r[0]}}
20 | 21 | {% endfor %} 22 | |
23 | {% for r in predictions %}
24 | {{r[1]}}%
25 | 26 | {% endfor %} 27 | |
28 |
29 |