Add the feature and filter visualization example (Lena) to docs
authorJonathan L Long <jonlong@cs.berkeley.edu>
Tue, 18 Mar 2014 04:11:36 +0000 (21:11 -0700)
committerJonathan L Long <jonlong@cs.berkeley.edu>
Tue, 18 Mar 2014 04:57:53 +0000 (21:57 -0700)
30 files changed:
docs/index.md
docs/lena_imagenet.md [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_10_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_14_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_14_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_16_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_16_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_18_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_18_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_20_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_20_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_22_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_22_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_24_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_24_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_26_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_26_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_28_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_28_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_30_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_30_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_32_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_32_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_34_0.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_34_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_36_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_36_1.png [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_36_1.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_39_0.text [new file with mode: 0644]
docs/lena_imagenet_files/lena_imagenet_8_0.text [new file with mode: 0644]

index 49c3327..95d7ce5 100644 (file)
@@ -37,6 +37,7 @@ Quick Links
 * [Training ImageNet](imagenet_training.html): tutorial on end-to-end training of an ImageNet classifier.
 * [Running Pretrained ImageNet](imagenet_pretrained.html): simply runs in Python!
 * [Running Detection](imagenet_detection.html): run a pretrained model as a detector.
+* [Visualizing Features and Filters](lena_imagenet.html): Lena viewed layer-by-layer.
 
 
 Citing Caffe
diff --git a/docs/lena_imagenet.md b/docs/lena_imagenet.md
new file mode 100644 (file)
index 0000000..db4e2df
--- /dev/null
@@ -0,0 +1,280 @@
+---
+layout: default
+title: Caffe
+---
+
+Visualizing ImageNet Features and Filters
+=========================================
+
+[View this page as an IPython Notebook](http://nbviewer.ipython.org/github/BVLC/caffe/blob/master/examples/filter_visualization/lena_imagenet.ipynb)
+
+---
+
+Here we visualize filters and outputs using the network architecture proposed by
+Krizhevsky et al. for ImageNet and implemented in `caffe`.
+
+(This page follows the DeCAF visualizations originally by Yangqing Jia.)
+
+First, import required modules and set plotting parameters
+
+
+    import numpy as np
+    import matplotlib.pyplot as plt
+    %matplotlib inline
+    
+    # normally this file is located in caffe/examples/filter_visualization
+    caffe_root = '../../'
+    import sys
+    sys.path.insert(0, caffe_root + 'python')
+    
+    import caffe
+    import caffe.imagenet
+    
+    plt.rcParams['figure.figsize'] = (10, 10)
+    plt.rcParams['image.interpolation'] = 'nearest'
+    plt.rcParams['image.cmap'] = 'gray'
+
+Load the net and specify test phase (since we are doing classification) and CPU
+mode
+
+
+    net = caffe.imagenet.ImageNetClassifier(caffe_root + 'models/imagenet.prototxt',
+                                            caffe_root + 'models/caffe_reference_imagenet_model')
+    net.caffenet.set_phase_test()
+    net.caffenet.set_mode_cpu()
+
+Run a classification pass
+
+
+    scores = net.predict(caffe_root + 'examples/filter_visualization/lena.png')
+
+The layer features and their shapes (10 is the batch size, corresponding to the
+the ten subcrops used by Krizhevsky et al.)
+
+
+    [(k, v.data.shape) for k, v in net.caffenet.blobs.items()]
+
+
+
+
+    [('data', (10, 3, 227, 227)),
+     ('conv1', (10, 96, 55, 55)),
+     ('pool1', (10, 96, 27, 27)),
+     ('norm1', (10, 96, 27, 27)),
+     ('conv2', (10, 256, 27, 27)),
+     ('pool2', (10, 256, 13, 13)),
+     ('norm2', (10, 256, 13, 13)),
+     ('conv3', (10, 384, 13, 13)),
+     ('conv4', (10, 384, 13, 13)),
+     ('conv5', (10, 256, 13, 13)),
+     ('pool5', (10, 256, 6, 6)),
+     ('fc6', (10, 4096, 1, 1)),
+     ('fc7', (10, 4096, 1, 1)),
+     ('fc8', (10, 1000, 1, 1)),
+     ('prob', (10, 1000, 1, 1))]
+
+
+
+The parameters and their shapes (each of these layers also has biases which are
+omitted here)
+
+
+    [(k, v[0].data.shape) for k, v in net.caffenet.params.items()]
+
+
+
+
+    [('conv1', (96, 3, 11, 11)),
+     ('conv2', (256, 48, 5, 5)),
+     ('conv3', (384, 256, 3, 3)),
+     ('conv4', (384, 192, 3, 3)),
+     ('conv5', (256, 192, 3, 3)),
+     ('fc6', (1, 1, 4096, 9216)),
+     ('fc7', (1, 1, 4096, 4096)),
+     ('fc8', (1, 1, 1000, 4096))]
+
+
+
+Helper functions for visualization
+
+
+    # our network takes BGR images, so we need to switch color channels
+    def showimage(im):
+        if im.ndim == 3:
+            im = im[:, :, ::-1]
+        plt.imshow(im)
+        
+    # take an array of shape (n, height, width) or (n, height, width, channels)
+    #  and visualize each (height, width) thing in a grid of size approx. sqrt(n) by sqrt(n)
+    def vis_square(data, padsize=1, padval=0):
+        data -= data.min()
+        data /= data.max()
+        
+        # force the number of filters to be square
+        n = int(np.ceil(np.sqrt(data.shape[0])))
+        padding = ((0, n ** 2 - data.shape[0]), (0, padsize), (0, padsize)) + ((0, 0),) * (data.ndim - 3)
+        data = np.pad(data, padding, mode='constant', constant_values=(padval, padval))
+        
+        # tile the filters into an image
+        data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
+        data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])
+        
+        showimage(data)
+
+The input image
+
+
+    # index four is the center crop
+    image = net.caffenet.blobs['data'].data[4].copy()
+    image -= image.min()
+    image /= image.max()
+    showimage(image.transpose(1, 2, 0))
+
+
+![png](lena_imagenet_files/lena_imagenet_14_0.png)
+
+
+The first layer filters, `conv1`
+
+
+    # the parameters are a list of [weights, biases]
+    filters = net.caffenet.params['conv1'][0].data
+    vis_square(filters.transpose(0, 2, 3, 1))
+
+
+![png](lena_imagenet_files/lena_imagenet_16_0.png)
+
+
+The first layer output, `conv1` (rectified responses of the filters above, first
+36 only)
+
+
+    feat = net.caffenet.blobs['conv1'].data[4, :36]
+    vis_square(feat, padval=1)
+
+
+![png](lena_imagenet_files/lena_imagenet_18_0.png)
+
+
+The second layer filters, `conv2`
+
+There are 128 filters, each of which has dimension 5 x 5 x 48. We show only the
+first 48 filters, with each channel shown separately, so that each filter is a
+row.
+
+
+    filters = net.caffenet.params['conv2'][0].data
+    vis_square(filters[:48].reshape(48**2, 5, 5))
+
+
+![png](lena_imagenet_files/lena_imagenet_20_0.png)
+
+
+The second layer output, `conv2` (rectified, only the first 36 of 256 channels)
+
+
+    feat = net.caffenet.blobs['conv2'].data[4, :36]
+    vis_square(feat, padval=1)
+
+
+![png](lena_imagenet_files/lena_imagenet_22_0.png)
+
+
+The third layer output, `conv3` (rectified, all 384 channels)
+
+
+    feat = net.caffenet.blobs['conv3'].data[4]
+    vis_square(feat, padval=0.5)
+
+
+![png](lena_imagenet_files/lena_imagenet_24_0.png)
+
+
+The fourth layer output, `conv4` (rectified, all 384 channels)
+
+
+    feat = net.caffenet.blobs['conv4'].data[4]
+    vis_square(feat, padval=0.5)
+
+
+![png](lena_imagenet_files/lena_imagenet_26_0.png)
+
+
+The fifth layer output, `conv5` (rectified, all 256 channels)
+
+
+    feat = net.caffenet.blobs['conv5'].data[4]
+    vis_square(feat, padval=0.5)
+
+
+![png](lena_imagenet_files/lena_imagenet_28_0.png)
+
+
+The fifth layer after pooling, `pool5`
+
+
+    feat = net.caffenet.blobs['pool5'].data[4]
+    vis_square(feat, padval=1)
+
+
+![png](lena_imagenet_files/lena_imagenet_30_0.png)
+
+
+The first fully connected layer, `fc6` (rectified)
+
+We show the output values and the histogram of the positive values
+
+
+    feat = net.caffenet.blobs['fc6'].data[4]
+    plt.subplot(2, 1, 1)
+    plt.plot(feat.flat)
+    plt.subplot(2, 1, 2)
+    _ = plt.hist(feat.flat[feat.flat > 0], bins=100)
+
+
+![png](lena_imagenet_files/lena_imagenet_32_0.png)
+
+
+The second fully connected layer, `fc7` (rectified)
+
+
+    feat = net.caffenet.blobs['fc7'].data[4]
+    plt.subplot(2, 1, 1)
+    plt.plot(feat.flat)
+    plt.subplot(2, 1, 2)
+    _ = plt.hist(feat.flat[feat.flat > 0], bins=100)
+
+
+![png](lena_imagenet_files/lena_imagenet_34_0.png)
+
+
+The final probability output, `prob`
+
+
+    feat = net.caffenet.blobs['prob'].data[4]
+    plt.plot(feat.flat)
+
+
+
+
+    [<matplotlib.lines.Line2D at 0x9a24190>]
+
+
+
+
+![png](lena_imagenet_files/lena_imagenet_36_1.png)
+
+
+And the top 5 predicted labels
+
+
+    labels = np.loadtxt(caffe_root + 'data/ilsvrc12/synset_words.txt', str, delimiter='\t')
+
+
+    top_k = net.caffenet.blobs['prob'].data[4].flatten().argsort()[-1:-6:-1]
+    print labels[top_k]
+
+    ['n02808304 bath towel' 'n02869837 bonnet, poke bonnet'
+     'n03124170 cowboy hat, ten-gallon hat' 'n04259630 sombrero'
+     'n04209133 shower cap']
+
diff --git a/docs/lena_imagenet_files/lena_imagenet_10_0.text b/docs/lena_imagenet_files/lena_imagenet_10_0.text
new file mode 100644 (file)
index 0000000..4c6065c
--- /dev/null
@@ -0,0 +1,8 @@
+[('conv1', (96, 3, 11, 11)),
+ ('conv2', (256, 48, 5, 5)),
+ ('conv3', (384, 256, 3, 3)),
+ ('conv4', (384, 192, 3, 3)),
+ ('conv5', (256, 192, 3, 3)),
+ ('fc6', (1, 1, 4096, 9216)),
+ ('fc7', (1, 1, 4096, 4096)),
+ ('fc8', (1, 1, 1000, 4096))]
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_14_0.png b/docs/lena_imagenet_files/lena_imagenet_14_0.png
new file mode 100644 (file)
index 0000000..4fe56fe
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_14_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_14_0.text b/docs/lena_imagenet_files/lena_imagenet_14_0.text
new file mode 100644 (file)
index 0000000..fd15f59
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x4c7f710>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_16_0.png b/docs/lena_imagenet_files/lena_imagenet_16_0.png
new file mode 100644 (file)
index 0000000..11e5a47
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_16_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_16_0.text b/docs/lena_imagenet_files/lena_imagenet_16_0.text
new file mode 100644 (file)
index 0000000..a862f09
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x4c96090>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_18_0.png b/docs/lena_imagenet_files/lena_imagenet_18_0.png
new file mode 100644 (file)
index 0000000..ba8a8d7
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_18_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_18_0.text b/docs/lena_imagenet_files/lena_imagenet_18_0.text
new file mode 100644 (file)
index 0000000..7f0ef20
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x96e0a50>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_20_0.png b/docs/lena_imagenet_files/lena_imagenet_20_0.png
new file mode 100644 (file)
index 0000000..2f68985
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_20_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_20_0.text b/docs/lena_imagenet_files/lena_imagenet_20_0.text
new file mode 100644 (file)
index 0000000..bcf8298
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x96b3690>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_22_0.png b/docs/lena_imagenet_files/lena_imagenet_22_0.png
new file mode 100644 (file)
index 0000000..05a3eaf
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_22_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_22_0.text b/docs/lena_imagenet_files/lena_imagenet_22_0.text
new file mode 100644 (file)
index 0000000..0c25d57
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x96e8b50>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_24_0.png b/docs/lena_imagenet_files/lena_imagenet_24_0.png
new file mode 100644 (file)
index 0000000..85b6e9e
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_24_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_24_0.text b/docs/lena_imagenet_files/lena_imagenet_24_0.text
new file mode 100644 (file)
index 0000000..2a654e6
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x4c83710>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_26_0.png b/docs/lena_imagenet_files/lena_imagenet_26_0.png
new file mode 100644 (file)
index 0000000..11bf0b1
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_26_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_26_0.text b/docs/lena_imagenet_files/lena_imagenet_26_0.text
new file mode 100644 (file)
index 0000000..7e26ebe
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x96ec250>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_28_0.png b/docs/lena_imagenet_files/lena_imagenet_28_0.png
new file mode 100644 (file)
index 0000000..f4d9edf
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_28_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_28_0.text b/docs/lena_imagenet_files/lena_imagenet_28_0.text
new file mode 100644 (file)
index 0000000..c46e63f
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x96e8110>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_30_0.png b/docs/lena_imagenet_files/lena_imagenet_30_0.png
new file mode 100644 (file)
index 0000000..3aaafbf
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_30_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_30_0.text b/docs/lena_imagenet_files/lena_imagenet_30_0.text
new file mode 100644 (file)
index 0000000..be2dfdd
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x97c1050>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_32_0.png b/docs/lena_imagenet_files/lena_imagenet_32_0.png
new file mode 100644 (file)
index 0000000..eb2e780
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_32_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_32_0.text b/docs/lena_imagenet_files/lena_imagenet_32_0.text
new file mode 100644 (file)
index 0000000..9ded984
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x96c0250>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_34_0.png b/docs/lena_imagenet_files/lena_imagenet_34_0.png
new file mode 100644 (file)
index 0000000..b7202f1
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_34_0.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_34_0.text b/docs/lena_imagenet_files/lena_imagenet_34_0.text
new file mode 100644 (file)
index 0000000..15547e6
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0x97bf190>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_36_0.text b/docs/lena_imagenet_files/lena_imagenet_36_0.text
new file mode 100644 (file)
index 0000000..1f4f707
--- /dev/null
@@ -0,0 +1 @@
+[<matplotlib.lines.Line2D at 0x9a24190>]
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_36_1.png b/docs/lena_imagenet_files/lena_imagenet_36_1.png
new file mode 100644 (file)
index 0000000..fd4f04c
Binary files /dev/null and b/docs/lena_imagenet_files/lena_imagenet_36_1.png differ
diff --git a/docs/lena_imagenet_files/lena_imagenet_36_1.text b/docs/lena_imagenet_files/lena_imagenet_36_1.text
new file mode 100644 (file)
index 0000000..8101849
--- /dev/null
@@ -0,0 +1 @@
+<matplotlib.figure.Figure at 0xedaf3d0>
\ No newline at end of file
diff --git a/docs/lena_imagenet_files/lena_imagenet_39_0.text b/docs/lena_imagenet_files/lena_imagenet_39_0.text
new file mode 100644 (file)
index 0000000..7592550
--- /dev/null
@@ -0,0 +1,3 @@
+['n02808304 bath towel' 'n02869837 bonnet, poke bonnet'
+ 'n03124170 cowboy hat, ten-gallon hat' 'n04259630 sombrero'
+ 'n04209133 shower cap']
diff --git a/docs/lena_imagenet_files/lena_imagenet_8_0.text b/docs/lena_imagenet_files/lena_imagenet_8_0.text
new file mode 100644 (file)
index 0000000..6ee9335
--- /dev/null
@@ -0,0 +1,15 @@
+[('data', (10, 3, 227, 227)),
+ ('conv1', (10, 96, 55, 55)),
+ ('pool1', (10, 96, 27, 27)),
+ ('norm1', (10, 96, 27, 27)),
+ ('conv2', (10, 256, 27, 27)),
+ ('pool2', (10, 256, 13, 13)),
+ ('norm2', (10, 256, 13, 13)),
+ ('conv3', (10, 384, 13, 13)),
+ ('conv4', (10, 384, 13, 13)),
+ ('conv5', (10, 256, 13, 13)),
+ ('pool5', (10, 256, 6, 6)),
+ ('fc6', (10, 4096, 1, 1)),
+ ('fc7', (10, 4096, 1, 1)),
+ ('fc8', (10, 1000, 1, 1)),
+ ('prob', (10, 1000, 1, 1))]
\ No newline at end of file