简体   繁体   English

TensorFlow CNN教程:如何编辑顶层以进行本地连接?

[英]TensorFlow CNN Tutorial: How to edit top layer to be locally connected?

I have some background in machine learning and python, but I am just learning TensorFlow. 我有一些机器学习和python的背景,但我只是学习TensorFlow。 I am going through the tutorial on deep convolutional neural nets to teach myself how to use it for image classification. 我正在阅读深度卷积神经网络教程 ,教我自己如何使用它进行图像分类。 Along the way there is an exercise, which I am having trouble completing. 一路上有一个练习,我很难完成。

EXERCISE: The model architecture in inference() differs slightly from the CIFAR-10 model specified in cuda-convnet. 练习:推理()中的模型体系结构与cuda-convnet中指定的CIFAR-10模型略有不同。 In particular, the top layers of Alex's original model are locally connected and not fully connected. 特别是,Alex的原始模型的顶层是本地连接的,并没有完全连接。 Try editing the architecture to exactly reproduce the locally connected architecture in the top layer. 尝试编辑体系结构以准确再现顶层中的本地连接体系结构。

The exercise refers to the inference() function in the cifar10.py model . 练习引用cifar10.py模型中的inference()函数。 The 2nd to last layer (called local4) has a shape=[384, 192], and the top layer has a shape=[192, NUM_CLASSES], where NUM_CLASSES=10 of course. 第二层到最后一层(称为local4)的形状为[384,192],顶层的形状为[192,NUM_CLASSES],其中NUM_CLASSES = 10。 I think the code that we are asked to edit is somewhere in the code defining the top layer: 我认为我们要编辑的代码位于定义顶层的代码中的某个位置:

with tf.variable_scope('softmax_linear') as scope:
    weights = _variable_with_weight_decay('weights', [192, NUM_CLASSES],
                                      stddev=1/192.0, wd=0.0)
    biases = _variable_on_cpu('biases', [NUM_CLASSES],
                          tf.constant_initializer(0.0))
    softmax_linear = tf.add(tf.matmul(local4, weights), biases,name=scope.name
    _activation_summary(softmax_linear)

But I don't see any code that determines the probability of connecting between layers, so I don't know how we can change the model from fully connected to locally connected. 但我没有看到任何代码确定层之间连接的可能性,因此我不知道如何将模型从完全连接更改为本地连接。 Does somebody know how to do this? 有人知道怎么做吗?

I'm also working on this exercise. 我也在做这个练习。 I'll try and explain my approach properly, rather than just give the solution. 我会尝试正确解释我的方法,而不是仅仅给出解决方案。 It's worth looking back at the mathematics of a fully connected layer ( https://www.tensorflow.org/get_started/mnist/beginners ). 值得回顾完全连接层的数学( https://www.tensorflow.org/get_started/mnist/beginners )。

So the linear algebra for a fully connected layer is: 因此,完全连接层的线性代数是:

y = W * x + b y = W * x + b

where x is the n dimensional input vector, b is an n dimensional vector of biases, and W is an n -by- n matrix of weights. 其中x是n维输入向量, b是偏差的n维向量, W是权重的n- by- n矩阵。 The i th element of y is the sum of the i th row of W multiplied element-wise with x . y的i个元素是第i行W与元素乘以x的和

So....if you only want y[i] connected to x[i-1] , x[i] , and x[i+1] , you simply set all values in the i th row of W to zero, apart from the (i-1) th, i th and (i+1) th column of that row. 所以....如果你只想让y [i]连接到x [i-1]x [i]x [i + 1] ,你只需将第iW中的所有值都设置为零,除了该行的第(i-1),i和第(i + 1)列之外。 Therefore to create a locally connected layer, you simply enforce W to be a banded matrix ( https://en.wikipedia.org/wiki/Band_matrix ), where the size of the band is equal to the size of the locally connected neighbourhoods you want. 因此,要创建一个本地连接的图层,您只需将W强制为带状矩阵( https://en.wikipedia.org/wiki/Band_matrix ),其中波段的大小等于本地连接的邻域的大小想。 Tensorflow has a function for setting a matrix to be banded ( tf.batch_matrix_band_part(input, num_lower, num_upper, name=None) ). Tensorflow具有设置要绑定的矩阵的功能( tf.batch_matrix_band_part(input, num_lower, num_upper, name=None) )。

This seems to me to be the simplest mathematical solution to the exercise. 在我看来,这是练习中最简单的数学解决方案。

I'll try to answer your question although I'm not 100% I got it right as well. 我会尝试回答你的问题,虽然我不是100%我也是正确的。

Looking at the cuda-convnet architecture we can see that the TensorFlow and cuda-convnet implementations start to differ after the second pooling layer. 看看cuda-convnet 架构,我们可以看到TensorFlow和cuda-convnet实现在第二个池之后开始有所不同。

TensorFlow implementation implements two fully connected layers and softmax classifier. TensorFlow实现实现了两个完全连接的层和s​​oftmax分类器。

cuda-convnet implements two locally connected layers, one fully connected layer and softmax classifier. cuda-convnet实现了两个本地连接的层,一个完全连接的层和s​​oftmax分类器。

The code snippet you included refers only to the softmax classifier and is in fact shared between the two implementations. 您包含的代码段仅指softmax分类器,实际上是在两个实现之间共享。 To reproduce the cuda-convnet implementation using TensorFlow we have to replace the existing fully connected layers with two locally connected layers and a fully connected one. 要使用TensorFlow重现cuda-convnet实现,我们必须用两个本地连接的层和一个完全连接的层替换现有的完全连接的层。

Since Tensor doesn't have locally connected layers as part of the SDK we have to figure out a way to implement it using the existing tools. 由于Tensor没有本地连接的图层作为SDK的一部分,我们必须找到一种使用现有工具实现它的方法。 Here is my attempt to implement the first locally connected layers: 这是我尝试实现第一个本地连接的层:

  with tf.variable_scope('local3') as scope:
    shape = pool2.get_shape()
    h = shape[1].value
    w = shape[2].value

    sz_local = 3 # kernel size
    sz_patch = (sz_local**2)*shape[3].value
    n_channels = 64

    # Extract 3x3 tensor patches
    patches = tf.extract_image_patches(pool2, [1,sz_local,sz_local,1], [1,1,1,1], [1,1,1,1], 'SAME')
    weights = _variable_with_weight_decay('weights', shape=[1,h,w,sz_patch, n_channels], stddev=5e-2, wd=0.0)
    biases = _variable_on_cpu('biases', [h,w,n_channels], tf.constant_initializer(0.1))

    # "Filter" each patch with its own kernel 
    mul = tf.multiply(tf.expand_dims(patches, axis=-1), weights)
    ssum = tf.reduce_sum(mul, axis=3)
    pre_activation = tf.add(ssum, biases)
    local3 = tf.nn.relu(pre_activation, name=scope.name)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM