Classifying MNIST digits is the "Hello World" of Deep Learning. There are a few nice example files delivered with Caffe and we will build on them here. 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 administrator to get the necessary packages installed for you. We are also assuming that you know how to clone repositories and compile software.
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 and then follow the installation instructions here. A more detailed description is given in the Caffe Wiki.
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
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. This can be done via a script provided with Caffe. From CAFFE_ROOT, do the following:
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. For this tutorial, we will use lmdb files. There is also a script distributed with Caffe 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.
It is necessary to start this script from CAFFE_ROOT, as the locations of the source and target files are given relative to this path in the script.
Now feel free to have a look into the CAFFE_ROOT/examples/mnist folder. Among multiple .prototxt and a few other files there should now exist 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. In there you can find some more information about what the layers are for and what all of 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 to, you can give Caffe a trial run. From the CAFFE_ROOT folder start a first training session:
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 OptimizationI1205 10:33:46.013741 26502 solver.cpp:272] Solving LeNetI1205 10:33:46.013743 26502 solver.cpp:273] Learning Rate Policy: invI1205 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.0809I1205 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.32711I1205 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.01I1205 10:33:46.467631 26502 solver.cpp:218] Iteration 100 (304.923 iter/s, 0.327951s/100 iters), loss = 0.233396I1205 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.00992565I1205 10:33:46.772743 26502 solver.cpp:218] Iteration 200 (327.809 iter/s, 0.305056s/100 iters), loss = 0.149696I1205 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.00985258I1205 10:33:47.078146 26502 solver.cpp:218] Iteration 300 (327.486 iter/s, 0.305356s/100 iters), loss = 0.160374I1205 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.00978075I1205 10:33:47.383550 26502 solver.cpp:218] Iteration 400 (327.505 iter/s, 0.305338s/100 iters), loss = 0.0551729I1205 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.00971013I1205 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.9737I1205 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.061902I1205 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.00964069I1205 10:33:48.100355 26502 solver.cpp:218] Iteration 600 (325.753 iter/s, 0.306981s/100 iters), loss = 0.110864I1205 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.0095724I1205 10:33:48.405812 26502 solver.cpp:218] Iteration 700 (327.44 iter/s, 0.3054s/100 iters), loss = 0.129114I1205 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 that 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.
Note: If you do not have a CUDA-compatible GPU or have built Caffe in a CPU-only version, you need to change the device parameter in the solver file to cpu instead of gpu.
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.
Barista needs a few python packages being installed. This can be done automatically using PIP:
cd Baristapip2 install -r requirements.txt
If you get error 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.
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:
The first message you will see will look like this:
In order for Barista to run properly, it needs to know where your Caffe installation is. From this, Barista will extract available layers and solver types as well as all of the parameters. 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 of what you have changed. Just provide the new CAFFE_ROOT and everything should be alright.
Your window should now look like this:
The next window you will see, is the startup dialog:
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 and type in a name for the project at the bottom of the dialog. A new directory will be created within the project root folder with the project 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:
Any Barista project contains at least one session. A specific network design, solver settings, as well as training results are saved in a separate session, making sure you do not lose 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
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.
You can click on Show Details... if you want to see what network you are importing and what it looks like in prototxt form. As we like to get started quickly, 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 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.
You can also see the inputs and outputs of the layers being connected via blobs. A bottom blob (Caffe's name for an input which is shown in Barista at the left side of a layer) automatically receives its name from the top blob (i.e., a Caffe output of a layer) 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 of its properties, i.e. parameters:
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 which settings make sense, so especially on the upper level, the list of available parameter groups is relatively large. Very often the name of the parameters and groups give a good hint if you should apply them to the current layer.
You will frequently 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 to change.
Load the Databases
When looking at the session list, you will notice 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 will appear, but does not show any available data sources:
Now select Add new Database, and Browse to CAFFE_ROOT/examples/mnist. In this folder you will find the two directories we created before. 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 meaningful, like MNIST Train and MNIST Test. Your Input Manager should now look like this:
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 can just double-click on a layer to assign the database to it. In brackets you can also see the training phases they are assigned to.
After assignment, you will find the name of the layer and its phase next to the arrow you have just clicked.
You can now close the Input Manager again.
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:
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 is worth checking the console output on the lower left, since 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 would 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.
Note: If you do not have a CUDA-compatible GPU or have built Caffe in a CPU-only version, you need to change the device parameter in the solver properties to CPU-mode. This can be done directly via the solver properties dock in Barista.
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 have been.
Watch the progress
In the Data Section we have already seen how the training output looks like on the console for a running session. As you can imagine, it is relatively 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:
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:
If you now click the play button in the session list again, you will see how the plot is updated in real time during training.
Furthermore, you can select the weight visualization option to get a basic 2D visualization of the weights of each convolutional 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.
The next steps
For more information on Barista's functionality (such as training on remote machines) please refer to the manual.