ZFNet文章复现

ZFNet:Visualizing and Understanding Convolutional Networks

摘要:
大型卷积网络模型在ImageNet分类任务上表现出非常好的性能[AlexNet]。但是却没有明确的认识,为什么性能如此优异,或者,性能还能怎么被提高。在本篇文章,我们解决了这两个问题。我们引入了一个神奇的可视化技术,它使我们能可视化网络中间的特征层和分类器的运算。作为一种诊断技术来使用,这些可视化允许我们去探究AlexNet的模型架构。我们同时实施了一个ablation study去发现不同模型层带来的性能提升。我们展示了我们的ImageNet上的AlexNet模型泛化的很好:当softmax分类器被重新训练后,它轻而易举地击败了当前Caltech-101和Caltech-256上的state of art结果。

为什么要进行反卷积:
为了解释卷积神经网络为什么有效,我们需要解释CNN的每一层学习到了什么东西。为了理解网络中间的每一层提取到了什么特征。文章中通过反卷积的方法,进行可视化。反卷积网络可以看成是卷积网络的逆过程。反卷积网络在文章《Adaptive deconvolutional networks for mid and high level feature learning》中被提出,是用于无监督学习的。然而本文的反卷积过程并不具备学习的能力,仅仅用于对一个已经训练好的卷积网络模型进行可视化。

反卷积的可视化以各层得到的特征图作为输入,进行反卷积,得到反卷积结果,用以验证显示各层提取到的特征图。举个例子:假如你想要查看Alexnet 的conv5提取到了什么东西,我们就用conv5的特征图后面接一个反卷积网络,然后通过:反池化、反激活、反卷积,这样的一个过程,将本来13*13大小的特征图(conv5的feature map大小为13*13),通过反卷积网络,最后得到一张与原始输入图片一样大小的图片(224*224)。

可视化技术的关键部分:

反池化:
卷积网络中的max_pool操作是不可逆的,但是可用一组switch变量来记录每一个pooling region的最大值的位置来设计一个近似的反卷积。在解卷积过程中,反池化在switch变量位置放置上述最大值,其余值用0填充。

ReLU激活:
卷积网络使用ReLU,它使得feature maps为正值。为了获得每一层的重构(值应该为正值),我们将重构也进行ReLU激活。

反卷积:
卷积网络使用learned filter来对上一层的feature maps进行卷积。为了进行invert卷积,解卷积网络使用上面filter的转置作为解卷积过程中的filter。在实践中,转置即将filter进行竖直和水平翻转。

下图就是解卷积的示意图:
反卷积示意图

上图中,右边为卷积过程,左边为解卷积过程。

总的来说算法主要有两个关键点:1、反池化 2、反卷积。再次叮嘱:反池化和反卷积是可视化的核心。

下面我们将从代码的角度来解释这两个关键点。
研究TensorFlow和keras里的反池化和反卷积:

import tensorflow as tf
keras = tf.keras
# 反池化
# 反池化主要用tf.nn.max_pool_with_argmax_and_mask和tf.nn.max_unpool两个函数。这两个函数的用法如下:
#def max_pool(inp, k=2):  
#    return tf.nn.max_pool_with_argmax_and_mask(inp, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding="SAME")
#def max_unpool(inp, argmax, argmax_mask, k=2):  
#    return tf.nn.max_unpool(inp, argmax, argmax_mask, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding="SAME")
# 上面的代码只能在GPU上实施。
# 在CPU上无法运行
# Keras里可以用上采样代替反池化:keras.layers.UpSampling2D
'''TF里可以用tf.image.resize_images来近似实现反池化,但是不计最大值的位置'''
# 下面给一个实例:
def unpool2d(images, size, method=0, align_corners=False):
  '''
  images: 输入
  size: 反池化后的shape
  method: 填充方法
  '''
  return tf.image.resize_images(
      images=images, size=size, method=method, align_corners=align_corners)
#================================================================================
# 反卷积小实验
# 使用的函数是tf.nn.conv2d_transpose
x = tf.placeholder(tf.float32, [None, 30, 30, 1])
kernel = tf.random_uniform([3,3,1,3])
# 卷积
x_conv = tf.nn.conv2d(x, kernel, [1,1,1,1], padding='SAME')
# 解卷积----其实就是卷积的转置,并不是真正的解卷积
x_deconv = tf.nn.conv2d_transpose(x_conv, 
                                  filter=kernel,
                                  output_shape=[tf.shape(x)[0],30,30,1], 
                                  strides=[1,1,1,1],
                                  padding='SAME')

import numpy as np
np.random.seed(0)
a = np.arange(900).reshape(-1,10)
np.random.shuffle(a)
a = np.reshape(a,[1,30,30,1])
sess = tf.Session()
x_con = sess.run(x_conv, feed_dict={x:a})
x_dec = sess.run(x_deconv, feed_dict={x:a})

a = np.reshape(a, [30,30])
x_dec = np.reshape(x_dec, [30,30])

import matplotlib.pyplot as plt
plt.imshow(a)
plt.figure()
plt.imshow(x_dec)

名词解释
ablation study:这是一种验证某一网络部件是否有效的方法。说白了,就是加上和去掉某一结构,然后比较性能的变化。

注意:使用本博客的代码,请添加引用


猜你喜欢

转载自blog.csdn.net/u014061630/article/details/80260614