From b8cc2974fc557fa163187e9ce0a879d0e13833b4 Mon Sep 17 00:00:00 2001 From: Yangqing Jia Date: Tue, 17 Mar 2015 10:50:42 -0700 Subject: [PATCH] [examples] flickr fine-tuning notebook --- .../Finetune with Flickr Style Data.ipynb | 951 ++++++++++++++++++ .../finetune_flickr_style/assemble_data.py | 8 + .../finetune_flickr_style/train_val.prototxt | 1 + 3 files changed, 960 insertions(+) create mode 100644 examples/Finetune with Flickr Style Data.ipynb diff --git a/examples/Finetune with Flickr Style Data.ipynb b/examples/Finetune with Flickr Style Data.ipynb new file mode 100644 index 00000000..d8cfc7a3 --- /dev/null +++ b/examples/Finetune with Flickr Style Data.ipynb @@ -0,0 +1,951 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Finetune a Pretrained Network with Flickr Style Data\n", + "\n", + "In this example, we'll explore a common approach that is particularly useful in real-world applications: take a pre-trained Caffe network, and finetune the last few layers using your custom data.\n", + "\n", + "The upside of such approach is that, since pre-trained networks are trained on a large set of images, the intermediate layers capture the \"semantics\" of the general visual appearance. Think of it as a very powerful feature that you can treat as a black box. On top of that, only a few layers will be needed to obtain a very good performance of the data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, we will need to prepare the data. This involves the following parts:\n", + "(1) Get the ImageNet ilsvrc pretrained model with the provided shell scripts.\n", + "(2) Download a subset of the overall Flickr style dataset for this demo.\n", + "(3) Compile the downloaded Flickr dataset into a database that Caffe can then consume." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jiayq/Research/caffe\n" + ] + } + ], + "source": [ + "import os\n", + "os.chdir('..')\n", + "import sys\n", + "sys.path.insert(0, './python')\n", + "print os.getcwd()\n", + "\n", + "import caffe\n", + "import numpy as np\n", + "from pylab import *\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading...\n", + "--2015-03-17 10:51:07-- http://dl.caffe.berkeleyvision.org/caffe_ilsvrc12.tar.gz\n", + "Resolving dl.caffe.berkeleyvision.org (dl.caffe.berkeleyvision.org)... 169.229.222.251\n", + "Connecting to dl.caffe.berkeleyvision.org (dl.caffe.berkeleyvision.org)|169.229.222.251|:80... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 17858008 (17M) [application/octet-stream]\n", + "Saving to: ‘caffe_ilsvrc12.tar.gz’\n", + "\n", + "100%[======================================>] 17,858,008 287KB/s in 55s \n", + "\n", + "2015-03-17 10:52:02 (318 KB/s) - ‘caffe_ilsvrc12.tar.gz’ saved [17858008/17858008]\n", + "\n", + "Unzipping...\n", + "Done.\n", + "Model already exists.\n", + "Downloading 2000 images with 3 workers...\n", + "Writing train/val for 1903 successfully downloaded images.\n" + ] + } + ], + "source": [ + "# This downloads the ilsvrc auxiliary data (mean file, etc),\n", + "# and a subset of 2000 images for the style recognition task.\n", + "\n", + "# You won't need to run this - we should have already created it for you.\n", + "!data/ilsvrc12/get_ilsvrc_aux.sh\n", + "!scripts/download_model_binary.py models/bvlc_reference_caffenet\n", + "!python examples/finetune_flickr_style/assemble_data.py \\\n", + " --workers=-1 --images=2000 --seed=1701 --label=5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's show what is the difference between the finetune network and the original caffe model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1c1\r\n", + "< name: \"CaffeNet\"\r\n", + "---\r\n", + "> name: \"FlickrStyleCaffeNet\"\r\n", + "4c4\r\n", + "< type: \"Data\"\r\n", + "---\r\n", + "> type: \"ImageData\"\r\n", + "15,26c15,19\r\n", + "< # mean pixel / channel-wise mean instead of mean image\r\n", + "< # transform_param {\r\n", + "< # crop_size: 227\r\n", + "< # mean_value: 104\r\n", + "< # mean_value: 117\r\n", + "< # mean_value: 123\r\n", + "< # mirror: true\r\n", + "< # }\r\n", + "< data_param {\r\n", + "< source: \"examples/imagenet/ilsvrc12_train_lmdb\"\r\n", + "< batch_size: 256\r\n", + "< backend: LMDB\r\n", + "---\r\n", + "> image_data_param {\r\n", + "> source: \"data/flickr_style/train.txt\"\r\n", + "> batch_size: 50\r\n", + "> new_height: 256\r\n", + "> new_width: 256\r\n", + "31c24\r\n", + "< type: \"Data\"\r\n", + "---\r\n", + "> type: \"ImageData\"\r\n", + "42,51c35,36\r\n", + "< # mean pixel / channel-wise mean instead of mean image\r\n", + "< # transform_param {\r\n", + "< # crop_size: 227\r\n", + "< # mean_value: 104\r\n", + "< # mean_value: 117\r\n", + "< # mean_value: 123\r\n", + "< # mirror: true\r\n", + "< # }\r\n", + "< data_param {\r\n", + "< source: \"examples/imagenet/ilsvrc12_val_lmdb\"\r\n", + "---\r\n", + "> image_data_param {\r\n", + "> source: \"data/flickr_style/test.txt\"\r\n", + "53c38,39\r\n", + "< backend: LMDB\r\n", + "---\r\n", + "> new_height: 256\r\n", + "> new_width: 256\r\n", + "323a310\r\n", + "> # Note that lr_mult can be set to 0 to disable any fine-tuning of this, and any other, layer\r\n", + "360c347\r\n", + "< name: \"fc8\"\r\n", + "---\r\n", + "> name: \"fc8_flickr\"\r\n", + "363c350,351\r\n", + "< top: \"fc8\"\r\n", + "---\r\n", + "> top: \"fc8_flickr\"\r\n", + "> # lr_mult is set to higher than for other layers, because this layer is starting from random while the others are already trained\r\n", + "365c353\r\n", + "< lr_mult: 1\r\n", + "---\r\n", + "> lr_mult: 10\r\n", + "369c357\r\n", + "< lr_mult: 2\r\n", + "---\r\n", + "> lr_mult: 20\r\n", + "373c361\r\n", + "< num_output: 1000\r\n", + "---\r\n", + "> num_output: 20\r\n", + "384a373,379\r\n", + "> name: \"loss\"\r\n", + "> type: \"SoftmaxWithLoss\"\r\n", + "> bottom: \"fc8_flickr\"\r\n", + "> bottom: \"label\"\r\n", + "> top: \"loss\"\r\n", + "> }\r\n", + "> layer {\r\n", + "387c382\r\n", + "< bottom: \"fc8\"\r\n", + "---\r\n", + "> bottom: \"fc8_flickr\"\r\n", + "393,399d387\r\n", + "< }\r\n", + "< layer {\r\n", + "< name: \"loss\"\r\n", + "< type: \"SoftmaxWithLoss\"\r\n", + "< bottom: \"fc8\"\r\n", + "< bottom: \"label\"\r\n", + "< top: \"loss\"\r\n" + ] + } + ], + "source": [ + "!diff models/bvlc_reference_caffenet/train_val.prototxt models/finetune_flickr_style/train_val.prototxt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For your record, if you want to train the network in pure C++ tools, here is the command:\n", + "\n", + "\n", + "build/tools/caffe train \\\n", + " -solver models/finetune_flickr_style/solver.prototxt \\\n", + " -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel \\\n", + " -gpu 0\n", + "\n", + "\n", + "However, we will train using Python in this example." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iter 0, loss=3.786610, scratch_loss=3.163587\n", + "iter 10, loss=2.556661, scratch_loss=8.774073\n", + "iter 20, loss=2.035326, scratch_loss=2.266603\n", + "iter 30, loss=1.943101, scratch_loss=1.703273\n", + "iter 40, loss=1.982698, scratch_loss=1.831079\n", + "iter 50, loss=1.559268, scratch_loss=2.041238\n", + "iter 60, loss=1.464433, scratch_loss=1.836157\n", + "iter 70, loss=1.481868, scratch_loss=1.705826\n", + "iter 80, loss=1.394870, scratch_loss=1.695532\n", + "iter 90, loss=1.055422, scratch_loss=1.867379\n", + "iter 100, loss=1.407976, scratch_loss=1.881758\n", + "iter 110, loss=1.569579, scratch_loss=1.701803\n", + "iter 120, loss=0.951682, scratch_loss=1.764299\n", + "iter 130, loss=0.905122, scratch_loss=1.879305\n", + "iter 140, loss=1.020678, scratch_loss=1.746009\n", + "iter 150, loss=0.784985, scratch_loss=1.739624\n", + "iter 160, loss=0.911735, scratch_loss=1.673230\n", + "iter 170, loss=0.965255, scratch_loss=1.725484\n", + "iter 180, loss=1.028102, scratch_loss=1.676103\n", + "iter 190, loss=0.905020, scratch_loss=1.885763\n", + "done\n" + ] + } + ], + "source": [ + "niter = 200\n", + "# losses will also be stored in the log\n", + "train_loss = np.zeros(niter)\n", + "scratch_train_loss = np.zeros(niter)\n", + "\n", + "caffe.set_device(0)\n", + "caffe.set_mode_gpu()\n", + "# We create a solver that finetunes from a previously trained network.\n", + "solver = caffe.SGDSolver('models/finetune_flickr_style/solver.prototxt')\n", + "solver.net.copy_from('models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel')\n", + "# For reference, we also create a solver that does no finetuning.\n", + "scratch_solver = caffe.SGDSolver('models/finetune_flickr_style/solver.prototxt')\n", + "\n", + "# We run the solver for niter times, and record the training loss.\n", + "for it in range(niter):\n", + " solver.step(1) # SGD by Caffe\n", + " scratch_solver.step(1)\n", + " # store the train loss\n", + " train_loss[it] = solver.net.blobs['loss'].data\n", + " scratch_train_loss[it] = scratch_solver.net.blobs['loss'].data\n", + " if it % 10 == 0:\n", + " print 'iter %d, loss=%f, scratch_loss=%f' % (it, train_loss[it], scratch_train_loss[it])\n", + "print 'done'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's look at the training loss produced by the two training procedures respectively." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": [ + "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\n", + "ra0pAAAAAElFTkSuQmCC\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot(np.vstack([train_loss, scratch_train_loss]).T)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice how the fine-tuning procedure produces a more smooth loss function change, and ends up at a better loss. A closer look at small values, clipping to avoid showing too large loss during training:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": [ + "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\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot(np.vstack([train_loss, scratch_train_loss]).clip(0, 4).T)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's take a look at the testing accuracy after running 200 iterations. Note that we are running a classification task of 5 classes, thus a chance accuracy is 20%. As we will reasonably expect, the finetuning result will be much better than the one from training from scratch. Let's see." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy for fine-tuning: 0.570000001788\n", + "Accuracy for training from scratch: 0.224000000954\n" + ] + } + ], + "source": [ + "test_iters = 10\n", + "accuracy = 0\n", + "scratch_accuracy = 0\n", + "for it in arange(test_iters):\n", + " solver.test_nets[0].forward()\n", + " accuracy += solver.test_nets[0].blobs['accuracy'].data\n", + " scratch_solver.test_nets[0].forward()\n", + " scratch_accuracy += scratch_solver.test_nets[0].blobs['accuracy'].data\n", + "accuracy /= test_iters\n", + "scratch_accuracy /= test_iters\n", + "print 'Accuracy for fine-tuning:', accuracy\n", + "print 'Accuracy for training from scratch:', scratch_accuracy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Huzzah! So we did finetuning and it is awesome. Let's take a look at what kind of results we are able to get with a longer, more complete run of the style recognition dataset. Note: the below URL might be occassionally down because it is run on a research machine.\n", + "\n", + "http://demo.vislab.berkeleyvision.org/" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/examples/finetune_flickr_style/assemble_data.py b/examples/finetune_flickr_style/assemble_data.py index b4c995e8..09bfa261 100755 --- a/examples/finetune_flickr_style/assemble_data.py +++ b/examples/finetune_flickr_style/assemble_data.py @@ -9,6 +9,7 @@ import hashlib import argparse import numpy as np import pandas as pd +from skimage import io import multiprocessing # Flickr returns a special image if the request is unavailable. @@ -27,6 +28,7 @@ def download_image(args_tuple): urllib.urlretrieve(url, filename) with open(filename) as f: assert hashlib.sha1(f.read()).hexdigest() != MISSING_IMAGE_SHA1 + test_read_image = io.imread(filename) return True except KeyboardInterrupt: raise Exception() # multiprocessing doesn't catch keyboard exceptions @@ -48,6 +50,10 @@ if __name__ == '__main__': '-w', '--workers', type=int, default=-1, help="num workers used to download images. -x uses (all - x) cores [-1 default]." ) + parser.add_argument( + '-l', '--labels', type=int, default=0, + help="if set to a positive value, only sample images from the first number of labels." + ) args = parser.parse_args() np.random.seed(args.seed) @@ -56,6 +62,8 @@ if __name__ == '__main__': csv_filename = os.path.join(example_dirname, 'flickr_style.csv.gz') df = pd.read_csv(csv_filename, index_col=0, compression='gzip') df = df.iloc[np.random.permutation(df.shape[0])] + if args.labels > 0: + df = df.loc[df['label'] < args.labels] if args.images > 0 and args.images < df.shape[0]: df = df.iloc[:args.images] diff --git a/models/finetune_flickr_style/train_val.prototxt b/models/finetune_flickr_style/train_val.prototxt index aa9c73e1..848a426c 100644 --- a/models/finetune_flickr_style/train_val.prototxt +++ b/models/finetune_flickr_style/train_val.prototxt @@ -374,6 +374,7 @@ layer { type: "SoftmaxWithLoss" bottom: "fc8_flickr" bottom: "label" + top: "loss" } layer { name: "accuracy"