diff --git a/digits/extensions/view/boundingBox/app_begin_template.html b/digits/extensions/view/boundingBox/app_begin_template.html index c59ef717e..43f892b11 100644 --- a/digits/extensions/view/boundingBox/app_begin_template.html +++ b/digits/extensions/view/boundingBox/app_begin_template.html @@ -40,7 +40,7 @@ }; // Add a bounding box draw method to the canvas - CanvasRenderingContext2D.prototype.draw_bbox = function(bbox, color, opacity) { + CanvasRenderingContext2D.prototype.draw_bbox = function(bbox, color, opacity) { this.globalAlpha = opacity; this.fillStyle = color; this.fillRect(bbox[0], @@ -147,7 +147,7 @@ // Draw the image and the bounding boxes with line_width and desaturated by desaturation. $scope.draw_bboxes = function(image, bboxes) { - var canvas = document.getElementById($scope.canvas_id); + var canvas = document.getElementById($scope.canvas_id); var context = canvas.getContext('2d'); // first set the size of the canvas @@ -171,14 +171,11 @@ // rectangle fill opacity var opacity = $rootScope.storage.opacity / 100.0; - // draw the bounding boxes - var keys = Object.keys(bboxes); - keys.sort(); - for (var k = 0; k < keys.length; k++) { - var color = $scope.get_color(k); - for (var i = 0; i < bboxes[keys[k]].length; i++) { - context.draw_bbox(bboxes[keys[k]][i], color, opacity); - } + // draw the bounding boxes + for (var b = 0; b < bboxes.length; b++) { + var color = $scope.get_color(b); + var key = Object.keys(bboxes[b])[0]; + context.draw_bbox(bboxes[b][key], color, opacity); } } diff --git a/digits/extensions/view/boundingBox/view.py b/digits/extensions/view/boundingBox/view.py index 0d26102d4..fad30cc86 100644 --- a/digits/extensions/view/boundingBox/view.py +++ b/digits/extensions/view/boundingBox/view.py @@ -114,15 +114,21 @@ def process_data( # create arrays in expected format keys = inference_data.keys() - bboxes = dict(zip(keys, [[] for x in range(0, len(keys))])) + bboxes = [] for key, outputs in inference_data.items(): + added = False # last number is confidence - bboxes[key] = [list(o) for o in outputs if o[-1] > 0] - self.bbox_count += len(bboxes[key]) + for o in outputs: + if o[-1]>0: + bboxes.append({key: list(o)}) + self.bbox_count += 1 + added = True + if not added: + bboxes.append({key: "null"}) image_html = digits.utils.image.embed_image_html(image) return { 'image': image_html, - 'bboxes': bboxes, + 'bboxes': sorted(bboxes), 'index': self.image_count, } diff --git a/digits/extensions/view/boundingBox/view_template.html b/digits/extensions/view/boundingBox/view_template.html index 467a3aae7..808c40754 100644 --- a/digits/extensions/view/boundingBox/view_template.html +++ b/digits/extensions/view/boundingBox/view_template.html @@ -15,11 +15,13 @@ style="max-width:100%;" resize>

- - - - {[key]} - + + + + + {[key]} + +

diff --git a/docs/BuildDigits.md b/docs/BuildDigits.md index d0e7c19a1..e0096b7e3 100644 --- a/docs/BuildDigits.md +++ b/docs/BuildDigits.md @@ -1,93 +1,183 @@ -# Building DIGITS +# Building DIGITS for Ubuntu Server 16.04 -The following instructions will walk you through building the latest version of DIGITS from source. -**These instructions are for installation on Ubuntu 14.04 and 16.04.** +I've built Ubuntu Server instances for DIGITS multiple times and have compiled a list of steps that seems to work well for me. Configuring all the dependencies and installing all the prerequisites can be tricky so I thought I'd share it in one place with some notes. It does depend somewhat on the compute capability of your Nvidia card. -Alternatively, see [this guide](BuildDigitsWindows.md) for setting up DIGITS and Caffe on Windows machines. +## Prerequisites -Other platforms are not officially supported, but users have successfully installed DIGITS on Ubuntu 12.04, CentOS, OSX, and possibly more. -Since DIGITS itself is a pure Python project, installation is usually pretty trivial regardless of the platform. -The difficulty comes from installing all the required dependencies for Caffe, Torch7 , Tensorflow, and configuring the builds. -Doing so is your own adventure. +You need an NVIDIA driver to begin with of course ([details and instructions](InstallCuda.md#driver)). -## Prerequisites +## Install Ubuntu 16.04 64-bit Server +I do the typical installation using LVM to encrypt the whole drive. No automatic updates. Basic installation packages plus SSH server and really nothing else (at first). -You need an NVIDIA driver ([details and instructions](InstallCuda.md#driver)). +### Basic updates/upgrades after installation - modify for your editor of choice +``` +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install emacs #sorry vim fanboys +``` -Run the following commands to get access to some package repositories: -```sh -# For Ubuntu 14.04 -CUDA_REPO_PKG=http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_8.0.61-1_amd64.deb -ML_REPO_PKG=http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1404/x86_64/nvidia-machine-learning-repo-ubuntu1404_4.0-2_amd64.deb +### I like to try and request a specific IP. Insert the following lines into dhclient.conf. If you can get a static IP even better. +``` +sudo emacs /etc/dhcp/dhclient.conf + #try to get a specific ip; dhclient -r -v to request again if it fails on startup + send dhcp-requested-address XXX.XX.XXX.XXX; +``` -# For Ubuntu 16.04 -CUDA_REPO_PKG=http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb +### Install CUDA which will pull the latest Nvidia driver. I am currently using 9.0 with DIGITS 6.1. +``` +cd /tmp +sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub +CUDA_REPO_PKG=http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.0.176-1_amd64.deb ML_REPO_PKG=http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb - -# Install repo packages wget "$CUDA_REPO_PKG" -O /tmp/cuda-repo.deb && sudo dpkg -i /tmp/cuda-repo.deb && rm -f /tmp/cuda-repo.deb wget "$ML_REPO_PKG" -O /tmp/ml-repo.deb && sudo dpkg -i /tmp/ml-repo.deb && rm -f /tmp/ml-repo.deb - -# Download new list of packages sudo apt-get update +sudo apt-get install cuda-9-0 +sudo apt-mark hold cuda-9-0 +wget https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/2/cuda-repo-ubuntu1604-9-0-local-cublas-performance-update-2_1.0-1_amd64-deb +sudo dpkg -i cuda-repo-ubuntu1604-9-0-local-cublas-performance-update-2_1.0-1_amd64-deb +sudo apt-mark hold nvidia-390 ``` -## Dependencies - -Install some dependencies with Deb packages: -```sh -sudo apt-get install --no-install-recommends git graphviz python-dev python-flask python-flaskext.wtf python-gevent python-h5py python-numpy python-pil python-pip python-scipy python-tk +### Since we are using Nvidia, don't use Nouveau. Make a few changes to not try to boot to the GUI but command line instead. ``` - -Follow [these instructions](BuildCaffe.md) to build Caffe (**required**). - -Follow [these instructions](BuildTorch.md) to build Torch7 (*suggested*). - -Follow [these instructions](BuildTensorflow.md) to build Tensorflow (*suggseted*). - -## Download source - -```sh -# example location - can be customized -DIGITS_ROOT=~/digits -git clone https://github.com/NVIDIA/DIGITS.git $DIGITS_ROOT +sudo emacs /etc/modprobe.d/blacklist-nouveau.conf + blacklist nouveau + blacklist lbm-nouveau + alias nouveau off + alias lbm-nouveau off +sudo emacs /etc/default/grub + GRUB_CMDLINE_LINUX_DEFAULT="text" + GRUB_CMDLINE_LINUX="text" +sudo systemctl set-default multi-user.target +sudo reboot now ``` -Throughout the docs, we'll refer to your install location as `DIGITS_ROOT` (`~/digits` in this case), though you don't need to actually set that environment variable. - -## Python packages - -Several PyPI packages need to be installed: -```sh -sudo pip install -r $DIGITS_ROOT/requirements.txt +### After reboot, double check. The first command should show stuff, the second not (if successful). The check packages and upgrade. +``` +lsmod | grep nvidia +lsmod | grep nouveau +sudo apt-get update +sudo apt-get ugprade ``` -# [Optional] Enable support for plug-ins +## Dependencies - I choose to put everything in /usr/local but this is up to personal preference. +### Protobuf - in some cases I had trouble with git:// endpoints so I modified to always use https in the second line. 3.2.x is what appears to be compatible with DIGITS - newer versions gave me Caffe errors. +``` +sudo apt-get install autoconf automake libtool curl make g++ git python-dev python-setuptools unzip +git config --global url."https://".insteadOf git:// +export PROTOBUF_ROOT=/usr/local/protobuf +sudo -H git clone https://github.com/google/protobuf.git $PROTOBUF_ROOT -b '3.2.x' +cd $PROTOBUF_ROOT +sudo -H ./autogen.sh +sudo -H ./configure +sudo -H make "-j$(nproc)" +sudo -H make install +sudo -H ldconfig +cd python +sudo -H python setup.py install --cpp_implementation +protoc --version #should say "libprotoc 3.2.0" +``` -DIGITS needs to be installed to enable loading data and visualization plug-ins: +### Caffe. Update: the ubuntu libcudnn libraries are not found when you try and build Caffe. It's possible you could set environment variables to find them, but now I'm building from scratch using cudnn v. 7.0.5 for cuda 9.0 as follows. Detectnet requires caffe version 0.15. Note that you need to add an environment variable to the .bashrc file for whatever user will be running DIGITS so it knows where Caffe is. ``` -sudo pip install -e $DIGITS_ROOT +# download ubuntu cudnn packages from https://developer.nvidia.com/rdp/cudnn-download to match your version of CUDA and Ubuntu +sudo dpkg -i libcudnn7_7.0.5.15-1+cuda9.0_amd64.deb +sudo dpkg -i libcudnn7-dev_7.0.5.15-1+cuda9.0_amd64.deb +sudo dpkg -i libcudnn7-doc_7.0.5.15-1+cuda9.0_amd64.deb +# test your cudnn installation +cd /tmp +cp -r /usr/src/cudnn_samples_v7/ . +cd cudnn_samples_v7/mnistCUDNN/ +make clean +make +./mnistCUDNN #should say "Test Passed!" +rm -rf /tmp/cudnn_samples_v7 +sudo -H apt-get install --no-install-recommends build-essential cmake git gfortran libatlas-base-dev libboost-filesystem-dev libboost-python-dev libboost-system-dev libboost-thread-dev libgflags-dev libgoogle-glog-dev libhdf5-serial-dev libleveldb-dev liblmdb-dev libopencv-dev libsnappy-dev python-all-dev python-dev python-h5py python-matplotlib python-numpy python-opencv python-pil python-pydot python-scipy python-skimage python-sklearn libnccl-dev libboost-regex-dev libturbojpeg libopenblas-dev +emacs ~/.bashrc + export CAFFE_ROOT=/usr/local/caffe +source ~/.bashrc +sudo -H pip install pip --upgrade +sudo -H git clone https://github.com/NVIDIA/caffe.git $CAFFE_ROOT -b 'caffe-0.15' +sudo -H pip install -r $CAFFE_ROOT/python/requirements.txt #you seem to need root access at least for some of these libraries +sudo -H pip install numpy --upgrade +cd $CAFFE_ROOT +sudo -H mkdir build +cd build +sudo -H cmake .. +sudo -H make -j"$(nproc)" +sudo -H make install ``` -# Starting the server +### Torch +``` +sudo apt-get install --no-install-recommends git software-properties-common +export TORCH_ROOT=/usr/local/torch +sudo git clone https://github.com/torch/distro.git $TORCH_ROOT --recursive +cd $TORCH_ROOT +sudo su +./install-deps +export TORCH_NVCC_FLAGS="-D__CUDA_NO_HALF_OPERATORS__" #something with cuda 9.0? needs to be in root environment +./install.sh -b +exit #exit root +sudo apt-get install --no-install-recommends libhdf5-serial-dev liblmdb-dev +source ~/.bashrc +sudo su +source /usr/local/torch/install/bin/torch-activate +git config --global url."https://".insteadOf git:// #because you need to do this as root as well for the following +luarocks install tds +luarocks install "https://raw.github.com/deepmind/torch-hdf5/master/hdf5-0-0.rockspec" +luarocks install "https://raw.github.com/Neopallium/lua-pb/master/lua-pb-scm-0.rockspec" +luarocks install lightningmdb 0.9.18.1-1 LMDB_INCDIR=/usr/include LMDB_LIBDIR=/usr/lib/x86_64-linux-gnu +luarocks install "https://raw.githubusercontent.com/ngimel/nccl.torch/master/nccl-scm-1.rockspec" +exit #exit root +``` -```sh -./digits-devserver +### Tensorflow. Using 1.5 currently. Some of this depends on the compute capability of your card - I think must be at least 3.5 for tensorflow 1.5. +``` +sudo -H pip install tensorflow-gpu==1.5 +#test tensorflow if you want +python + import tensorflow as tf + hello = tf.constant('Hello, TensorFlow!') + sess = tf.Session() + print(sess.run(hello)) #should get "Hello, TensorFlow!" ``` -Starts a server at `http://localhost:5000/`. +### DIGITS. Note that I've given control to the local user for the jobs directory and digits log file. This depends on what user will be running the DIGITS server. +``` +DIGITS_ROOT=/usr/local/digits +sudo git clone https://github.com/NVIDIA/DIGITS.git $DIGITS_ROOT +sudo -H pip install -r $DIGITS_ROOT/requirements.txt +sudo -H pip install -e $DIGITS_ROOT +sudo apt-get install python-tk +sudo mkdir /usr/local/digits/digits/jobs +sudo chown : /usr/local/digits/digits/jobs +sudo touch /usr/local/digits/digits/digits.log +sudo chown : /usr/local/digits/digits/digits.log ``` -$ ./digits-devserver --help -usage: __main__.py [-h] [-p PORT] [-d] [--version] -DIGITS development server +## Now you should have everything installed and can start DIGITS using the digits-devserver executable. Good idea to test here to be sure. I like to create a startup job as follows. -optional arguments: - -h, --help show this help message and exit - -p PORT, --port PORT Port to run app on (default 5000) - -d, --debug Run the application in debug mode (reloads when the - source changes and gives more detailed error messages) - --version Print the version number and exit +``` +sudo emacs /lib/systemd/system/digits.service + [Unit] + Description=Start Digits + + [Service] + User= + Environment=CAFFE_ROOT=/usr/local/caffe + Environment=TORCH_ROOT=/usr/local/torch + WorkingDirectory=/usr/local/digits + ExecStart=/bin/bash digits-devserver + Restart=always + RestartSec=30 + + [Install] + WantedBy=multi-user.target +sudo systemctl daemon-reload +sudo systemctl enable digits +sudo systemctl start digits ``` # Getting started