|
|
|
# Tutorial - Getting started using MNIST
|
|
|
|
|
|
|
|
## Introduction <a id="Introduction"></a>
|
|
|
|
Classifying MNIST digits is the Hello World of Deep Learning. There are a few nice example files delivered with *Caffe* and we want to build on them. The following Tutorial will guide you through all the steps needed to get a classifier running. For this Tutorial we will assume you are using a Linux machine and you have the permissions to install packages. If you are not among the sudoers, please contact your admin to get the necessary packages installed for you. We are also assuming, that you know how to clone repositories and compile software.
|
|
|
|
|
|
|
|
## Install caffe <a id="Caffe"></a>
|
|
|
|
Before you can work with Barista, you need to install the *Caffe* framework. Although there is now an apt package available for Ubuntu >= 17.04, we would advice to download and **build** the most current Version **from source**.
|
|
|
|
|
|
|
|
Please clone the *Caffe* repository from [GitHub](https://github.com/BVLC/caffe) and then follow the installation instructions [here](http://caffe.berkeleyvision.org/install_apt.html). A more detailed description is given [in the *Caffe* Wiki](https://github.com/BVLC/caffe/wiki/Ubuntu-16.04-or-15.10-Installation-Guide).
|
|
|
|
Please make a (mental) note which folder you have cloned *Caffe* into, we will refer to this as CAFFE_ROOT later on.
|
|
|
|
The behaviour of Barista is independent of the settings you choose for the *Caffe* building process, hence, choose whatever fits your machine and your needs.
|
|
|
|
Building and testing your version of *Caffe* might take a while. If you haven't done yet, this is a good point to browse through the remainders of this tutorial to get an idea of what you have to expect.
|
|
|
|
|
|
|
|
## Get the data <a id="Data"></a>
|
|
|
|
As usual before you can start training your network, you need to get the data and the labels. Getting those is a two step process, first you have to download the binary date from Yann LeCuns [website](http://yann.lecun.com/). This can be done via script, from CAFFE_ROOT do the following:
|
|
|
|
|
|
|
|
cd data/mnist
|
|
|
|
./get_mnist.sh
|
|
|
|
|
|
|
|
Now you should find four new files in this folder. Those contain the data and the labels for the training and testing dataset.
|
|
|
|
|
|
|
|
In order to be able to use them with *Caffe*, we have to convert the data into one of the supported database formats, this tutorial will use lmdb files. There is also a script to get the conversion done for you. Make sure you are in the CAFFE_ROOT folder again. We assume that you are still in the mnist folder, hence we have to traverse up two nodes in the directory tree.
|
|
|
|
|
|
|
|
cd ../..
|
|
|
|
./examples/mnist/create_mnist.sh
|
|
|
|
|
|
|
|
It is necessary to start this script from CAFFE_ROOT, as the locations of the source and target files are given relativ to this path in the script.
|
|
|
|
|
|
|
|
Now feel free to have a look into the `CAFFE_ROOT/examples/mnist` folder, among many `prototxt` and a few other files there should now be two folders: `mnist_test_lmdb` and `mnist_train_lmdb`. Both again contain two files respectively: `data.mdb` and `lock.mdb`.
|
|
|
|
|
|
|
|
If this is the case for you, we are finished setting up our databases.
|
|
|
|
|
|
|
|
**Note:** There is also a file [`readme.md`](https://github.com/BVLC/caffe/blob/master/examples/mnist/readme.md). In there you can find some more information what the layers are for and what all the parameters are doing. Don't be bothered with writing all the protobuf definitions though, this is exactly what Barista was made for.
|
|
|
|
|
|
|
|
If you want, you can give *Caffe* a trial run. From the CAFFE_ROOT folder start a first training session:
|
|
|
|
|
|
|
|
./examples/mnist/train_lenet.sh
|
|
|
|
|
|
|
|
After a lot of console output, you should eventually see something that looks like this:
|
|
|
|
|
|
|
|
```
|
|
|
|
I1205 10:33:46.013505 26502 solver.cpp:56] Solver scaffolding done.
|
|
|
|
I1205 10:33:46.013736 26502 caffe.cpp:248] Starting Optimization
|
|
|
|
I1205 10:33:46.013741 26502 solver.cpp:272] Solving LeNet
|
|
|
|
I1205 10:33:46.013743 26502 solver.cpp:273] Learning Rate Policy: inv
|
|
|
|
I1205 10:33:46.013875 26502 solver.cpp:330] Iteration 0, Testing net (#0)
|
|
|
|
I1205 10:33:46.132484 26518 data_layer.cpp:73] Restarting data prefetching from start.
|
|
|
|
I1205 10:33:46.135725 26502 solver.cpp:397] Test net output #0: accuracy = 0.0809
|
|
|
|
I1205 10:33:46.135751 26502 solver.cpp:397] Test net output #1: loss = 2.34046 (* 1 = 2.34046 loss)
|
|
|
|
I1205 10:33:46.139636 26502 solver.cpp:218] Iteration 0 (0 iter/s, 0.125866s/100 iters), loss = 2.32711
|
|
|
|
I1205 10:33:46.139662 26502 solver.cpp:237] Train net output #0: loss = 2.32711 (* 1 = 2.32711 loss)
|
|
|
|
I1205 10:33:46.139686 26502 sgd_solver.cpp:105] Iteration 0, lr = 0.01
|
|
|
|
I1205 10:33:46.467631 26502 solver.cpp:218] Iteration 100 (304.923 iter/s, 0.327951s/100 iters), loss = 0.233396
|
|
|
|
I1205 10:33:46.467671 26502 solver.cpp:237] Train net output #0: loss = 0.233396 (* 1 = 0.233396 loss)
|
|
|
|
I1205 10:33:46.467676 26502 sgd_solver.cpp:105] Iteration 100, lr = 0.00992565
|
|
|
|
I1205 10:33:46.772743 26502 solver.cpp:218] Iteration 200 (327.809 iter/s, 0.305056s/100 iters), loss = 0.149696
|
|
|
|
I1205 10:33:46.772774 26502 solver.cpp:237] Train net output #0: loss = 0.149696 (* 1 = 0.149696 loss)
|
|
|
|
I1205 10:33:46.772779 26502 sgd_solver.cpp:105] Iteration 200, lr = 0.00985258
|
|
|
|
I1205 10:33:47.078146 26502 solver.cpp:218] Iteration 300 (327.486 iter/s, 0.305356s/100 iters), loss = 0.160374
|
|
|
|
I1205 10:33:47.078196 26502 solver.cpp:237] Train net output #0: loss = 0.160374 (* 1 = 0.160374 loss)
|
|
|
|
I1205 10:33:47.078202 26502 sgd_solver.cpp:105] Iteration 300, lr = 0.00978075
|
|
|
|
I1205 10:33:47.383550 26502 solver.cpp:218] Iteration 400 (327.505 iter/s, 0.305338s/100 iters), loss = 0.0551729
|
|
|
|
I1205 10:33:47.383590 26502 solver.cpp:237] Train net output #0: loss = 0.055173 (* 1 = 0.055173 loss)
|
|
|
|
I1205 10:33:47.383595 26502 sgd_solver.cpp:105] Iteration 400, lr = 0.00971013
|
|
|
|
I1205 10:33:47.684309 26502 solver.cpp:330] Iteration 500, Testing net (#0)
|
|
|
|
I1205 10:33:47.786654 26518 data_layer.cpp:73] Restarting data prefetching from start.
|
|
|
|
I1205 10:33:47.790012 26502 solver.cpp:397] Test net output #0: accuracy = 0.9737
|
|
|
|
I1205 10:33:47.790040 26502 solver.cpp:397] Test net output #1: loss = 0.0863938 (* 1 = 0.0863938 loss)
|
|
|
|
I1205 10:33:47.793319 26502 solver.cpp:218] Iteration 500 (244.073 iter/s, 0.409714s/100 iters), loss = 0.061902
|
|
|
|
I1205 10:33:47.793372 26502 solver.cpp:237] Train net output #0: loss = 0.061902 (* 1 = 0.061902 loss)
|
|
|
|
I1205 10:33:47.793380 26502 sgd_solver.cpp:105] Iteration 500, lr = 0.00964069
|
|
|
|
I1205 10:33:48.100355 26502 solver.cpp:218] Iteration 600 (325.753 iter/s, 0.306981s/100 iters), loss = 0.110864
|
|
|
|
I1205 10:33:48.100394 26502 solver.cpp:237] Train net output #0: loss = 0.110864 (* 1 = 0.110864 loss)
|
|
|
|
I1205 10:33:48.100411 26502 sgd_solver.cpp:105] Iteration 600, lr = 0.0095724
|
|
|
|
I1205 10:33:48.405812 26502 solver.cpp:218] Iteration 700 (327.44 iter/s, 0.3054s/100 iters), loss = 0.129114
|
|
|
|
I1205 10:33:48.405840 26502 solver.cpp:237] Train net output #0: loss = 0.129114 (* 1 = 0.129114 loss)
|
|
|
|
I1205 10:33:48.405846 26502 sgd_solver.cpp:105] Iteration 700, lr = 0.00950522
|
|
|
|
```
|
|
|
|
|
|
|
|
How long this takes highly depends on your hardware, especially whether you use a GPU or a CPU.
|
|
|
|
However, this is proof, that everything is set up correctly and your net is actually learning something (the loss decreases while the accuracy increases). If something goes wrong here, please refer to the *Caffe* documentation to fix any problems.
|
|
|
|
|
|
|
|
You can stop the training by pressing `Ctrl+C`.
|
|
|
|
|
|
|
|
|
|
|
|
## Install Barista <a id="Install"></a>
|
|
|
|
So, finally we can start and have a look at *Barista*. First thing we have to do is clone the repository. If you want to have a look at it first, you can look at the repository [webpage](https://go.wwu.de/barista).
|
|
|
|
|
|
|
|
Or you can just clone the code using git:
|
|
|
|
|
|
|
|
git clone https://zivgitlab.uni-muenster.de/pria/Barista.git
|
|
|
|
|
|
|
|
A folder `Barista` will automatically be created in your current working directory. We will refer to this as BARISTA_ROOT later on.
|
|
|
|
|
|
|
|
Before trying to run *Barista*, make sure you have python, pip, qt5 and pyqt installed on your machine, if this is not the case, get them:
|
|
|
|
|
|
|
|
sudo apt-get install python python-pip
|
|
|
|
sudo apt-get install python-pyqt5 qt5-default
|
|
|
|
|
|
|
|
*Barista* needs a few python packages being installed, that can be done automatically, using PIP:
|
|
|
|
|
|
|
|
cd Barista
|
|
|
|
pip install -r requirements.txt
|
|
|
|
|
|
|
|
If you get arror messages because you don't have write permissions, you can try to add the `--user` flag to the command, so packages are installed for the current user, only.
|
|
|
|
|
|
|
|
By the way, the file `requirements.txt` is human readable, hence you can easily check what dependencies do currently exist.
|
|
|
|
|
|
|
|
If you did not see any error messages you are now ready to start *Barista* for the first time.
|
|
|
|
|
|
|
|
## Start Barista <a id="Barista"></a>
|
|
|
|
To run *Barista* start the file `main.py` in BARISTA_ROOT. You can either do this in your favorite file manager or from a terminal:
|
|
|
|
|
|
|
|
cd Barista
|
|
|
|
./main.py
|
|
|
|
|
|
|
|
The first message you will see will look like this:
|
|
|
|
|
|
|
|
![Caffepath](Caffepath.png)
|
|
|
|
|
|
|
|
In order for *Barista* to run properly, it needs to know where your *Caffe* installation is. From this the available layers and solver types as well as all the parameters will be extracted. Please select the CAFFE_ROOT folder and click `Save and start Barista`.
|
|
|
|
If you selected an invalid folder, you will see a warning. Please make sure, that you provide the path to a valid *Caffe* installation.
|
|
|
|
|
|
|
|
**Note:** If, for some reason, you move your installation of *Caffe* to a different directory, *Barista* will notify you on the next start. The Current default path will be displayed, hopefully reminding you, what you have changed. Just provide the new CAFFE_ROOT and everything should be alright.
|
|
|
|
|
|
|
|
The next window you will see, is the startup dialog:
|
|
|
|
|
|
|
|
![startup dialog](BaristaStart.png)
|
|
|
|
|
|
|
|
This dialog is always the first thing you will see when starting up Barista (and your *Caffe* installation did not change).
|
|
|
|
Barista stores networks and training results on a project basis, hence you have to set up a project first. We suggest to create a folder `barista-projects` where you can then create a new directory for every project. However, you are completely free in your choice.
|
|
|
|
|
|
|
|
So, click on `New Project` and select the project root folder. Then select the project name at the bottom of the dialog. A new directory will be created within the project root folder with exactly the same name. If later on you want to copy all your training to another machine or show it to a colleague or friend, all you have to do is copy the project folder. We have chosen `myFirstProject` as the name.
|
|
|
|
|
|
|
|
Now you've made it to the main window of Barista. For now, you will only see an empty network and and invalid session on the right:
|
|
|
|
|
|
|
|
![empty project](BaristaEmptyProject.png)
|
|
|
|
|
|
|
|
Any *Barista* project contains at least one session. A specific network design, solver settings and training results are saved in a separate session, making sure you do not loose any results when trying out different topologies and settings.
|
|
|
|
On the left hand side, the list of available layers is displayed. You can drag and drop them to the canvas in the center. Add Blobs to them and build your own Network from scratch. However, we would first like to give you an impression of a working network.
|
|
|
|
|
|
|
|
|
|
|
|
## Load the Network Design and Solver <a id="Import"></a>
|
|
|
|
|
|
|
|
Looking at the Session list at the right side, you can see, that the current session is invalid because we have not defined any solver parameters, yet. When hovering over the session status, you will get some more detailed information, giving some guidance what you can do now.
|
|
|
|
|
|
|
|
We are now importing the solver for the mnist lenet network. Select File --> Import Solver. In the new dialog, browse to CAFFE_ROOT and further on to `examples/mnist` in there, select the `lenet_solver.prototxt`.
|
|
|
|
Once confirmed, *Barista* loads all solver settings. It also recognizes, that the solver is linked to a specific network, hence you can directly import this network as well.
|
|
|
|
|
|
|
|
![import solver](BaristaImport.png)
|
|
|
|
|
|
|
|
You can click on `Show Details...` if you want to see what network you are importing and how it looks like in prototxt. As we want to get started fast, we select `Yes` to import the referenced network.
|
|
|
|
|
|
|
|
You will now see the Lenet network topology on the canvas, different layer types are color coded to make larger nets a bit easier to browse. Data flows through the net from left to right, hence the data layers are on the left while loss and accuracy are calculated on the outer right.
|
|
|
|
|
|
|
|
![LeNet no input](BaristaLenetNoInput.png)
|
|
|
|
|
|
|
|
You can also see the inputs and outputs of the layers being connected via blobs. A bottom blob automatically gets its name from the top blob it is connected to. Hence, if you want to change the naming, just adjust the name of the top blob in the producing layer. You can do this via layer properties.
|
|
|
|
|
|
|
|
If you select the `Layer Properties` tab on the right hand dock, and then click on the conv1 layer, you will see all its properties:
|
|
|
|
|
|
|
|
![layer properties](LayerProperties.png)
|
|
|
|
|
|
|
|
###Outlook:
|
|
|
|
If you would want to change the output blob name, you could do it right at the bottom. If you do so, you can also observe, that the input of the following layer (`pool1`) automatically changes its name.
|
|
|
|
|
|
|
|
Below the current settings overview, you can also add new properties. You can select from all available parameters and parameter groups, hence you do not have to memorize all available parameters. However, it is not possible to automatically derive what settings make sense, so especially on the upper level, the list of available parameter groups is pretty large. Very often the name of the parameters and groups give a good hint if you should apply them to the current layer.
|
|
|
|
|
|
|
|
Very often you will build your net from layers with similar settings. To speed up your design phase, you can Copy&Paste layers on the canvas and only adjust the settings you want.
|
|
|
|
|
|
|
|
## Load the Databases <a id="Databases"></a>
|
|
|
|
When looking back at the Session list, you can see, that the current session is still invalid because the data layers cannot find the databases. Nothing to worry, we can do something about that as well.
|
|
|
|
|
|
|
|
In the menu bar, select `Edit` -> `Input Manager` (or press Ctrl+I or click on the Input Manager icon in the menu bar). the Input Manager appears and does not show any available data sources:
|
|
|
|
|
|
|
|
![input manager empty](InputManEmpty.png)
|
|
|
|
|
|
|
|
Now select Add new Database, and Browse to CAFFE_ROOT`/examples/mnist`. In this folder you will find the two directories we created [before](#Data). Select the `mnist_test_lmdb` directory and add `data.mdb` as input. Repeat those steps for `mnist_train_lmdb`.
|
|
|
|
|
|
|
|
Now, you have two data sources named LMDB Database. By clicking on the pencil icon, you can change the name to something more meaningfull, like `MNIST Train` and `MNIST Test`. Your Input Manager should now look like this:
|
|
|
|
|
|
|
|
![input manager MNIST](InputManMNIST.png)
|
|
|
|
|
|
|
|
As a final step you can now click on the arrow pointing right to assign each database to a data layer. All available data layers are shown in a list and you cann just double-click to assign. In brackets you can also see the training [phases](https://github.com/BVLC/caffe/wiki/Excluding-Layers:-Train-and-Test-Phase) they are assigned to.
|
|
|
|
|
|
|
|
After assignment, you wil find the name of the layer and it's phase next to the arrow you've just clicked.
|
|
|
|
|
|
|
|
You can now close the Input Manager again.
|
|
|
|
|
|
|
|
## Start Training <a id="Training"></a>
|
|
|
|
Finally we have everything we need to train our Neural Network. This is indicated by the ready status in the session list, colored in blue:
|
|
|
|
|
|
|
|
![session ready](SessionReady.png)
|
|
|
|
|
|
|
|
Now, just click the play button and let the training begin. The Status label turns green and shows `Running`.
|
|
|
|
|
|
|
|
If the label turns red and shows `Failed` it's worth checking the console Output on the lower left, most probably something went wrong within *Caffe*. If you ever have a failed session, you cannot bring it back to life again. This is because something is wrong with this session but *Barista* can not determine what it is. Hence, it will again be set to `Ready` and most probably fail for the same (yet unknown) reason whenever you try to run it again. Of course your work was not in vain. If you have determined and solved the Problem, you can select your failed Session and click the `New` Button on top of the session list. This will create a new session for you, which will be set to `Ready` and you can start it again. Hopefully with more success this time.
|
|
|
|
|
|
|
|
Assuming everything worked fine, please pause your training again using the very same button you have just clicked, which now shows a pause symbol. We are doing this because training MNIST usually is pretty quick and we want to show you some more things you can do.
|
|
|
|
|
|
|
|
Please note, that *Barista* automatically saves a snapshot of the training status whenever you pause a session. Hence, you can always resume the training from where you've been.
|
|
|
|
|
|
|
|
## Watch the progress <a id="Plotter"></a>
|
|
|
|
In the [Data Section](#Data) we have already seen how the training output looks like on the console for a running session. As you can imagine it is pretty hard to keep track of whats going on during training and to decide when to stop.
|
|
|
|
|
|
|
|
The Plotter offers a more comprehensible representation of the training progress. By default, the plotter can be found in the bottom right corner. There you can find a settings button. Here you can decide what should be plotted.
|
|
|
|
|
|
|
|
After clicking on `Settings` you will see the following options:
|
|
|
|
![plotter settings](PlotterSettings.png)
|
|
|
|
|
|
|
|
Sessions are added automatically when they are started. The Keys are all deselected by default. In the screenshot above we have selected all keys that allow us a good monitoring of the Training.
|
|
|
|
|
|
|
|
Now, the potter area shows the course of accuracy and loss over training iterations:
|
|
|
|
![plotter](Plotter.png)
|
|
|
|
|
|
|
|
If you now click the play button in the session list again, you will see how the plot is updated in real tim during training.
|
|
|
|
|
|
|
|
Furthermore, you can select the weight visualization option to get a basic 2D visualization of the weights of each layer. This helps in spotting overfitting, or wrong gradient descent directions. Visualized weights are only available for snapshots taken by caffe. This can be done using the snapshot button (camera symbol next to play/pause), pausing the session or automatically by setting the snapshot property for the solver.
|
|
|
|
|
|
|
|
|
|
|
|
## Networking <a id="Hosts"></a>
|
|
|
|
|
|
|
|
Yet to come... |