Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-bounding box labeling fix while also preserving order; All-on-one Ubuntu 16.04 server instructions #1984

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions digits/extensions/view/boundingBox/app_begin_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}

Expand Down
14 changes: 10 additions & 4 deletions digits/extensions/view/boundingBox/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
12 changes: 7 additions & 5 deletions digits/extensions/view/boundingBox/view_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
style="max-width:100%;"
resize></canvas>
<p align="center">
<span ng-repeat="(key, boxes) in bboxes">
<span ng-if="boxes.length > 0" style="display:inline-block;">
<span style="display:inline-block; width:10px;height:10px;border:1px solid #000; background-color: {[get_color($index)]}"></span>
<span style="display:inline-block; padding-right:10px">{[key]}</span>
</span>
<span ng-repeat="(idx,boxobj) in bboxes">
<span ng-repeat="(key,boxes) in boxobj">
<span ng-if="boxes!='null'" style="display:inline-block;">
<span style="display:inline-block; width:10px;height:10px;border:1px solid #000; background-color: {[get_color(idx)]}"></span>
<span style="display:inline-block; padding-right:10px">{[key]}</span>
</span>
</span>
</span>
</p>
</div>
214 changes: 152 additions & 62 deletions docs/BuildDigits.md
Original file line number Diff line number Diff line change
@@ -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 <user>:<user> /usr/local/digits/digits/jobs
sudo touch /usr/local/digits/digits/digits.log
sudo chown <user>:<user> /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=<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
Expand Down