Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python TensorFlow CNN教程:如何编辑要本地连接的顶层?_Python_Tensorflow_Conv Neural Network - Fatal编程技术网

Python TensorFlow CNN教程:如何编辑要本地连接的顶层?

Python TensorFlow CNN教程:如何编辑要本地连接的顶层?,python,tensorflow,conv-neural-network,Python,Tensorflow,Conv Neural Network,我有一些机器学习和python方面的背景,但我只是在学习TensorFlow。我正在学习如何将其用于图像分类。一路上有一个练习,我很难完成 练习:推理()中的模型体系结构与cuda convnet中指定的CIFAR-10模型略有不同。特别是,Alex原始模型的顶层是局部连接的,而不是完全连接的。尝试编辑架构,以便在顶层准确地再现本地连接的架构 此练习涉及中的推理()函数。从第二层到最后一层(称为local4)有一个shape=[384192],顶层有一个shape=[192,NUM_CLASSE

我有一些机器学习和python方面的背景,但我只是在学习TensorFlow。我正在学习如何将其用于图像分类。一路上有一个练习,我很难完成

练习:推理()中的模型体系结构与cuda convnet中指定的CIFAR-10模型略有不同。特别是,Alex原始模型的顶层是局部连接的,而不是完全连接的。尝试编辑架构,以便在顶层准确地再现本地连接的架构

此练习涉及中的推理()函数。从第二层到最后一层(称为local4)有一个shape=[384192],顶层有一个shape=[192,NUM_CLASSES],其中NUM_CLASSES=10。我认为要求我们编辑的代码在定义顶层的代码中的某个地方:

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)

但是我没有看到任何代码决定层间连接的概率,因此我不知道如何将模型从完全连接更改为本地连接。有人知道怎么做吗?

我会尽力回答你的问题,尽管我不是100%正确

查看cuda convnet,我们可以看到TensorFlow和cuda convnet实现在第二个池层之后开始有所不同

TensorFlow实现实现了两个完全连接的层和softmax分类器

cuda convnet实现了两个本地连接层,一个完全连接层和softmax分类器

您包含的代码片段仅引用softmax分类器,并且实际上在两个实现之间共享。为了使用TensorFlow重现cuda convnet实现,我们必须用两个本地连接层和一个完全连接层替换现有的完全连接层

由于Tensor没有本地连接的层作为SDK的一部分,我们必须找到一种使用现有工具实现它的方法。下面是我实现第一个本地连接层的尝试:

  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)

我也在做这个练习。我将尝试正确地解释我的方法,而不仅仅是给出解决方案。值得回顾一下完全连接层()的数学知识

因此,完全连接层的线性代数为:

y=W*x+b

其中x是n维输入向量,b是n维偏差向量,W是n×n权重矩阵。y的第i个元素是W的第i行与x按元素相乘的和

因此……如果您只希望y[i]连接到x[i-1]、x[i]和x[i+1],只需将W的第i行中的所有值设置为零,除了该行的第(i-1)列、第i列和第(i+1)列。因此,要创建一个局部连接的层,只需将W强制为带状矩阵(),其中带状的大小等于所需的局部连接邻域的大小。Tensorflow有一个函数,用于设置要绑定的矩阵(
tf.批处理矩阵带部分(输入,num\u下限,num\u上限,name=None)


在我看来,这似乎是这个练习最简单的数学解。

这个答案不能解决这个练习。W矩阵必须是“多条带”。例如,如果过滤器为3x3,则应该有3个对角线带,每个带3个元素宽。tf.matrix_band_part()只允许一个频带。而且,W的维数会改变,我们不能只取原始的W,然后将一些元素设置为零。具体而言,W中的行数必须等于展平输出特征贴图的长度。我认为Xyand的答案是一个更好的方法:提取图像补丁,并将每个补丁乘以它自己的内核,这样权重张量就获得了两个额外的维度(变成6D)。这就足够了。这只是我试图掌握一些数学知识,以给出如何解决这个问题的线索。我想他们做练习的原因是为了让人们自己思考,所以我并不是真的试图给出一些可以复制/粘贴的代码,而是为了帮助人们从理论上理解如何实现这一点。我发现在使用神经网络时,理解一些线性代数是很有帮助的,而不仅仅是工程。自从我处理这个局部连接层以来,已经有一段时间了。但是@DavidPickup的方法实际上可以通过用一个全矩阵乘以一个常数指示矩阵来模拟多带矩阵来工作,即W的大小应该是(W_outh_out)X(W_inh_in*d_in)。然而,这似乎相当浪费。我遗漏了什么吗?当然,我们可以通过定期插入多个单波段矩阵来构建这样的指标矩阵。除了更大(但稀疏)的W之外,我们还将引入额外的计算:反向传播将尝试更新这些零权重值,因此我们必须在每次权重更新后执行WI(或在每次更新前执行W_梯度)。这种开销可能很大:如果我们假设WI和Wx一样昂贵,我们必须比仅仅向前和向后传递多做约33%的工作(掩蔽、向前传递、向后传递)。权重形状中的h和w维度应该指输出特征映射的高度和宽度,而不是指输入特征映射。