我想使用Theano训练一个简单的卷积自动编码器,这种方法工作得很好。但是,我看不到conv2d
使用二次采样(步幅)时如何反转命令。有使用步幅时有效“反转”卷积命令的有效方法,如下图所示?
例如,我想更改以下内容...
from theano.tensor.nnet.conv import conv2d
x = T.tensor4('x')
y = T.tanh( conv2d( x, W, border_mode='valid', subsample = (1,1) ) )
z = conv2d( y, Wprime, border_mode='full', subsample = (1,1) )
...进入那里的情况subsample = (2,2)
。第一层将按预期工作。但是,第二层将有效地“使用步幅1进行卷积,然后丢弃一半的输出”。显然这是与我正在寻找的不同的操作-z
甚至不会有与长度相同的神经元数量x
。第二个conv2d
命令应该是“重构”原始命令x
?
由此推论,您打算拥有权重,即,如果第一个操作是与的矩阵乘法W
,则输出将与W.T
伴随矩阵生成。因此,在您的情况下,您将寻找卷积运算符的伴随,然后进行二次采样。
(编辑:我错误地推论,只要正确地选择形状,您就可以使用任何过滤器进行“反卷积”。尽管如此,谈论伴随关系仍然是有益的。此后您可以放宽假设。)
由于卷积算子和二次采样算子是线性算子,让我们分别用C
和表示它们,S
并观察到卷积+二次采样的图像x
将是
S C x
并且y
(的居住空间与相同S C x
)上的伴随运算将是
C.T S.T y
现在,ST就是通过在的所有条目周围添加零y
直到获得正确的大小来对原始图像大小进行上采样。
从您的帖子中,您似乎已经知道步幅(1,1)的卷积运算符的伴随性-它是具有反向过滤器和反向的卷积border_mode
,即具有filters.dimshuffle(1, 0, 2, 3)[:, :, ::-1, ::-1]
和从切换border_mode='valid'
到border_mode='full'
。
串联上采样和反向滤波器卷积,即可获得所需的伴随。
注意:可能有多种利用梯度T.grad
或T.jacobian
自动获取梯度的方法,但我不确定如何做到这一点。
编辑:那里,我写下来了:)
import theano
import theano.tensor as T
import numpy as np
filters = theano.shared(np.random.randn(4, 3, 6, 5).astype('float32'))
inp1 = T.tensor4(dtype='float32')
subsampled_convolution = T.nnet.conv2d(inp1, filters, border_mode='valid', subsample=(2, 2))
inp2 = T.tensor4(dtype='float32')
shp = inp2.shape
upsample = T.zeros((shp[0], shp[1], shp[2] * 2, shp[3] * 2), dtype=inp2.dtype)
upsample = T.set_subtensor(upsample[:, :, ::2, ::2], inp2)
upsampled_convolution = T.nnet.conv2d(upsample,
filters.dimshuffle(1, 0, 2, 3)[:, :, ::-1, ::-1], border_mode='full')
f1 = theano.function([inp1], subsampled_convolution)
f2 = theano.function([inp2], upsampled_convolution)
x = np.random.randn(1, 3, 10, 10).astype(np.float32)
f1x = f1(x)
y = np.random.randn(*f1x.shape).astype(np.float32)
f2y = f2(y)
p1 = np.dot(f1x.ravel(), y.ravel())
p2 = np.dot(x.ravel(), f2y[:, :, :-1].ravel())
print p1 - p2
p1
等于p2
证明f2是f1的伴随
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句