NVIDIA DIGITS2 Deep Convolutional Feature Visualization

相信大家对Digits 这个框架的简单、易上手印象深刻,本人也认为其测试的特征可视化结果较为醒目:


但是该框架是如何实现的呢?

通过https://groups.google.com/forum/#!topic/digits-users/eRGijUu9q30,发现位于digits-2.0/digits/model/tasks中 caffe_train.py  


https://groups.google.com/forum/#!topic/digits-users/eRGijUu9q30
def classify_one(self,image,snapshot_eppoch=None,layers=None)
"""
Classify an image
Returns (predictions,visualizations)

..........
.....
<pre name="code" class="python">visualizations = []
        if layers and layers != 'none':
            if layers == 'all':
                added_activations = []
                for layer in self.network.layer:
                    print 'Computing visualizations for "%s"...' % layer.name
                    if not layer.type.endswith(('Data', 'Loss', 'Accuracy')):
                        for bottom in layer.bottom:
                            if bottom in net.blobs and bottom not in added_activations:
                                data = net.blobs[bottom].data[0]
                                vis = self.get_layer_visualization(data)
                                mean, std, hist = self.get_layer_statistics(data)
                                visualizations.append(
                                        {
                                            'name': str(bottom),
                                            'type': 'Activations',
                                            'mean': mean,
                                            'stddev': std,
                                            'histogram': hist,
                                            'image_html': utils.image.embed_image_html(vis),
                                            }
                                        )
                                added_activations.append(bottom)
                        if layer.name in net.params:
                            data = net.params[layer.name][0].data
                            if layer.type not in ['InnerProduct']:
                                vis = self.get_layer_visualization(data)
                            else:
                                vis = None
                            mean, std, hist = self.get_layer_statistics(data)
                            visualizations.append(
                                    {
                                        'name': str(layer.name),
                                        'type': 'Weights (%s layer)' % layer.type,
                                        'mean': mean,
                                        'stddev': std,
                                        'histogram': hist,
                                        'image_html': utils.image.embed_image_html(vis),
                                        }
                                    )
                        for top in layer.top:
                            if top in net.blobs and top not in added_activations:
                                data = net.blobs[top].data[0]
                                normalize = True
                                # don't normalize softmax layers
                                if layer.type == 'Softmax':
                                    normalize = False
                                vis = self.get_layer_visualization(data, normalize=normalize)
                                mean, std, hist = self.get_layer_statistics(data)
                                visualizations.append(
                                        {
                                            'name': str(top),
                                            'type': 'Activation',
                                            'mean': mean,
                                            'stddev': std,
                                            'histogram': hist,
                                            'image_html': utils.image.embed_image_html(vis),
                                            }
                                        )
                                added_activations.append(top)
            else:
                raise NotImplementedError

        return (predictions, visualizations)

    def get_layer_visualization(self, data,
            normalize = True,
            max_width = 600,
            ):
        """
        Returns a vis_square for the given layer data
        Arguments:
        data -- a np.ndarray
        Keyword arguments:
        normalize -- whether to normalize the data when visualizing
        max_width -- maximum width for the vis_square
        """
        #print 'data.shape is %s' % (data.shape,)

        if data.ndim == 1:
            # interpret as 1x1 grayscale images
            # (N, 1, 1)
            data = data[:, np.newaxis, np.newaxis]
        elif data.ndim == 2:
            # interpret as 1x1 grayscale images
            # (N, 1, 1)
            data = data.reshape((data.shape[0]*data.shape[1], 1, 1))
        elif data.ndim == 3:
            if data.shape[0] == 3:
                # interpret as a color image
                # (1, H, W,3)
                data = data[[2,1,0],...] # BGR to RGB (see issue #59)
                data = data.transpose(1,2,0)
                data = data[np.newaxis,...]
            else:
                # interpret as grayscale images
                # (N, H, W)
                pass
        elif data.ndim == 4:
            if data.shape[0] == 3:
                # interpret as HxW color images
                # (N, H, W, 3)
                data = data.transpose(1,2,3,0)
                data = data[:,:,:,[2,1,0]] # BGR to RGB (see issue #59)
            elif data.shape[1] == 3:
                # interpret as HxW color images
                # (N, H, W, 3)
                data = data.transpose(0,2,3,1)
                data = data[:,:,:,[2,1,0]] # BGR to RGB (see issue #59)
            else:
                # interpret as HxW grayscale images
                # (N, H, W)
                data = data.reshape((data.shape[0]*data.shape[1], data.shape[2], data.shape[3]))
        else:
            raise RuntimeError('unrecognized data shape: %s' % (data.shape,))

        # chop off data so that it will fit within max_width
        padsize = 0
        width = data.shape[2]
        if width > max_width:
            data = data[0,:max_width,:max_width]
        else:
            if width > 1:
                padsize = 1
                width += 1
            n = max_width/width
            n *= n
            data = data[:n]

        #print 'data.shape now %s' % (data.shape,)
        return utils.image.vis_square(data,
                padsize     = padsize,
                normalize   = normalize,
                )


 

其中,vis_square位于 digits-2.0/digits/digits/utils image.py

def vis_square(images,
        padsize=1,
        normalize=False,
        colormap='jet',
        ):
    """
    Visualize each image in a grid of size approx sqrt(n) by sqrt(n)
    Returns a np.array image
    (Based on Caffe's filter_visualization notebook)
    Arguments:
    images -- an array of shape (N, H, W) or (N, H, W, C)
            if C is not set, a heatmap is computed for the result
    Keyword arguments:
    padsize -- how many pixels go inbetween the tiles
    normalize -- if true, scales (min, max) across all images out to (0, 1)
    colormap -- a string representing one of the suppoted colormaps
    """
    assert 3 <= images.ndim <= 4, 'images.ndim must be 3 or 4'
    # convert to float since we're going to do some math
    images = images.astype('float32')
    if normalize:
        images -= images.min()
        if images.max() > 0:
            images /= images.max()
            images *= 255

    if images.ndim == 3:
        # they're grayscale - convert to a colormap
        redmap, greenmap, bluemap = get_color_map(colormap)

        red = np.interp(images*(len(redmap)-1)/255.0, xrange(len(redmap)), redmap)
        green = np.interp(images*(len(greenmap)-1)/255.0, xrange(len(greenmap)), greenmap)
        blue = np.interp(images*(len(bluemap)-1)/255.0, xrange(len(bluemap)), bluemap)

        # Slap the channels back together
        images = np.concatenate( (red[...,np.newaxis], green[...,np.newaxis], blue[...,np.newaxis]), axis=3 )
        images = np.minimum(images,255)
        images = np.maximum(images,0)

    # convert back to uint8
    images = images.astype('uint8')

    # Compute the output image matrix dimensions
    n = int(np.ceil(np.sqrt(images.shape[0])))
    ny = n
    nx = n
    length = images.shape[0]
    if n*(n-1) >= length:
        nx = n-1

    # Add padding between the images
    padding = ((0, nx*ny - length), (0, padsize), (0, padsize)) + ((0, 0),) * (images.ndim - 3)
    padded = np.pad(images, padding, mode='constant', constant_values=255)

    # Tile the images beside each other
    tiles = padded.reshape( (ny, nx) + padded.shape[1:]).transpose( (0,2,1,3) + tuple(range(4, padded.ndim + 1)))
    tiles = tiles.reshape((ny * tiles.shape[1], nx * tiles.shape[3]) + tiles.shape[4:])

    return tiles

def get_color_map(name):
    """
    Return a colormap as (redmap, greenmap, bluemap)
    Arguments:
    name -- the name of the colormap. If unrecognized, will default to 'jet'.
    """
    redmap = [0]
    greenmap = [0]
    bluemap = [0]
    if name == 'white':
        # essentially a noop
        redmap      = [0,1]
        greenmap    = [0,1]
        bluemap     = [0,1]
    elif name == 'simple':
        redmap      = [0,1,1,1]
        greenmap    = [0,0,1,1]
        bluemap     = [0,0,0,1]
    elif name == 'hot':
        redmap = [0, 0.03968253968253968, 0.07936507936507936, 0.119047619047619, 0.1587301587301587, 0.1984126984126984, 0.2380952380952381, 0.2777777777777778, 0.3174603174603174, 0.3571428571428571, 0.3968253968253968, 0.4365079365079365, 0.4761904761904762, 0.5158730158730158, 0.5555555555555556, 0.5952380952380952, 0.6349206349206349, 0.6746031746031745, 0.7142857142857142, 0.753968253968254, 0.7936507936507936, 0.8333333333333333, 0.873015873015873, 0.9126984126984127, 0.9523809523809523, 0.992063492063492, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        greenmap = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03174603174603163, 0.0714285714285714, 0.1111111111111112, 0.1507936507936507, 0.1904761904761905, 0.23015873015873, 0.2698412698412698, 0.3095238095238093, 0.3492063492063491, 0.3888888888888888, 0.4285714285714284, 0.4682539682539679, 0.5079365079365079, 0.5476190476190477, 0.5873015873015872, 0.6269841269841268, 0.6666666666666665, 0.7063492063492065, 0.746031746031746, 0.7857142857142856, 0.8253968253968254, 0.8650793650793651, 0.9047619047619047, 0.9444444444444442, 0.984126984126984, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        bluemap = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.04761904761904745, 0.1269841269841265, 0.2063492063492056, 0.2857142857142856, 0.3650793650793656, 0.4444444444444446, 0.5238095238095237, 0.6031746031746028, 0.6825396825396828, 0.7619047619047619, 0.8412698412698409, 0.92063492063492, 1]
    elif name == 'rainbow':
        redmap = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9365079365079367, 0.8571428571428572, 0.7777777777777777, 0.6984126984126986, 0.6190476190476191, 0.53968253968254, 0.4603174603174605, 0.3809523809523814, 0.3015873015873018, 0.2222222222222223, 0.1428571428571432, 0.06349206349206415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03174603174603208, 0.08465608465608465, 0.1375661375661377, 0.1904761904761907, 0.2433862433862437, 0.2962962962962963, 0.3492063492063493, 0.4021164021164023, 0.4550264550264553, 0.5079365079365079, 0.5608465608465609, 0.6137566137566139, 0.666666666666667]
        greenmap = [0, 0.03968253968253968, 0.07936507936507936, 0.119047619047619, 0.1587301587301587, 0.1984126984126984, 0.2380952380952381, 0.2777777777777778, 0.3174603174603174, 0.3571428571428571, 0.3968253968253968, 0.4365079365079365, 0.4761904761904762, 0.5158730158730158, 0.5555555555555556, 0.5952380952380952, 0.6349206349206349, 0.6746031746031745, 0.7142857142857142, 0.753968253968254, 0.7936507936507936, 0.8333333333333333, 0.873015873015873, 0.9126984126984127, 0.9523809523809523, 0.992063492063492, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9841269841269842, 0.9047619047619047, 0.8253968253968256, 0.7460317460317465, 0.666666666666667, 0.587301587301587, 0.5079365079365079, 0.4285714285714288, 0.3492063492063493, 0.2698412698412698, 0.1904761904761907, 0.1111111111111116, 0.03174603174603208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        bluemap = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01587301587301582, 0.09523809523809534, 0.1746031746031744, 0.2539682539682535, 0.333333333333333, 0.412698412698413, 0.4920634920634921, 0.5714285714285712, 0.6507936507936507, 0.7301587301587302, 0.8095238095238093, 0.8888888888888884, 0.9682539682539679, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    elif name == 'winter':
        greenmap = [0, 1]
        bluemap = [1, 0.5]
    else:
        if name != 'jet':
            print 'Warning: colormap "%s" not supported. Using jet instead.' % name
        redmap      = [0,0,0,0,0.5,1,1,1,0.5]
        greenmap    = [0,0,0.5,1,1,1,0.5,0,0]
        bluemap     = [0.5,1,1,1,0.5,0,0,0,0]
    return 255.0 * np.array(redmap), 255.0 * np.array(greenmap), 255.0 * np.array(bluemap)
具体实现效果可以在python上参考以上代码



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值