tensorflow:与 theano 相比,卷积的奇怪结果(虽然不是翻转)

tensorflow: Strange result from convolution compared to theano (not flipping, though)

我正在尝试使用 tensorflow 实现一些深度神经网络。但是我在第一步就遇到了问题。

当我使用 theano.tensor.nnet.conv2d 键入以下内容时,我得到了预期的结果:

import theano.tensor as T
import theano
import numpy as np
# Theano expects input of shape (batch_size, channels, height, width)
# and filters of shape (out_channel, in_channel, height, width)
x = T.tensor4()
w = T.tensor4()
c = T.nnet.conv2d(x, w, filter_flip=False)
f = theano.function([x, w], [c], allow_input_downcast=True)
base = np.array([[1, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1]]).T
i = base[np.newaxis, np.newaxis, :, :]
print f(i, i) # -> results in 3 as expected because np.sum(i*i) = 3

然而,当我在 tf.nn.conv2d 中做同样的事情时,我的结果是不同的:

import tensorflow as tf
import numpy as np
# TF expects input of (batch_size, height, width, channels)
# and filters of shape (height, width, in_channel, out_channel)
x = tf.placeholder(tf.float32, shape=(1, 4, 3, 1), name="input")
w = tf.placeholder(tf.float32, shape=(4, 3, 1, 1), name="weights")
c = tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='VALID')
with tf.Session() as sess:
    base = np.array([[1, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1]]).T
    i = base[np.newaxis, :, :, np.newaxis]
    weights = base[:, :, np.newaxis, np.newaxis]
    res = sess.run(c, feed_dict={x: i, w: weights})
    print res # -> results in -5.31794233e+37

tensorflow中卷积运算的布局与theano略有不同,这也是输入看起来略有不同的原因。 但是,由于 Theano 中的步幅默认为 (1,1,1,1) 并且有效卷积也是默认值,因此这应该是完全相同的输入。

此外,tensorflow 不会翻转内核(实现互相关)。

您知道为什么结果不一样吗?

提前致谢,

罗马

好的,我找到了一个解决方案,尽管它不是真正的解决方案,因为我自己也不明白。 首先,对于我试图解决的任务,TheanoTensorflow 似乎使用了不同的卷积。 手头的任务是“1.5 维卷积”,这意味着在输入(这里是 DNA 序列)上仅在一个方向上滑动内核。

Theano 中,我使用与内核具有相同行数的 conv2d 操作解决了这个问题,并且工作正常。

但是,Tensorflow(可能是正确的)希望我为此使用 conv1d,将行解释为通道。

因此,以下内容应该有效但一开始没有:

import tensorflow as tf
import numpy as np

# TF expects input of (batch_size, height, width, channels)
# and filters of shape (height, width, in_channel, out_channel)
x = tf.placeholder(tf.float32, shape=(1, 4, 3, 1), name="input")
w = tf.placeholder(tf.float32, shape=(4, 3, 1, 1), name="weights")

x_star = tf.reshape(x, [1, 4, 3])
w_star = tf.reshape(w, [4, 3, 1])
c = tf.nn.conv1d(x_star, w_star, stride=1, padding='VALID')
with tf.Session() as sess:
    base = np.array([[1, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1]]).T
    i = base[np.newaxis, :, :, np.newaxis]
    weights = base[:, :, np.newaxis, np.newaxis]
    res = sess.run(c, feed_dict={x: i, w: weights})
    print res # -> produces 3 after updating tensorflow

这段代码产生了 NaN,直到我将 Tensorflow 更新到版本 1.0.1,从那时起,它产生了预期的输出。

总而言之,我的问题通过使用 1D 卷积而不是 2D 卷积得到了部分解决,但仍然需要更新框架。对于第二部分,我完全不知道一开始是什么导致了错误的行为。

编辑:我在原始问题中发布的代码现在也可以正常工作。因此,不同的行为仅来自 TF 的旧版本(可能已损坏)。