def multi_scale_conv_encoder(tparams, state_below, options, prefix='conv_enc',
one_step=False, init_state=None, width=None, nkernels=None, pool_window=None, pool_stride=None, **kwargs):
# state_below.shape = (maxlen_x_pad + 2*pool_stride, n_samples, dim_word_src)
# mask.shape = (maxlen_x_pad/pool_stride, n_samples)
assert len(width) == len(nkernels)
data = state_below.dimshuffle(1,2,0,'x')
# data.shape = (n_samples, dim_word_src, maxlen_x_pad + 2*pool_stride, 1)
W = [tparams[_p(prefix, 'convW')+str(idx)] for idx in range(len(width))]
b = [tparams[_p(prefix, 'convB')+str(idx)] for idx in range(len(width))]
output = []
for idx in range(len(width)):
curr_width = width[idx]
output.append(dnn_conv(data, W[idx], border_mode='half', precision='float32'))
# output[idx].shape = (n_samples, nkernels[idx], (maxlen_x_pad + 2*pool_stride), 1)
if curr_width % 2 == 0:
output[idx] = (output[idx])[:,:,:-1,:] # for filters with an even numbered width, half convolution yields an output whose length is 1 longer than the input, hence discarding the last one here. For more detail, consult http://deeplearning.net/software/theano/library/tensor/nnet/conv.html#theano.tensor.nnet.conv2d
output[idx] = tensor.nnet.relu(output[idx] + b[idx].dimshuffle('x',0,'x','x'))
result = tensor.concatenate(output, axis=1)
# result.shape = (n_samples, sum(nkernels), (maxlen_x_pad + 2*pool_stride), 1)
result = dnn_pool(result, (pool_window, 1), stride=(pool_stride, 1), mode='max', pad=(0, 0))
# result.shape = (n_samples, sum(nkernels), (maxlen_x_pad/pool_stride + 2), 1)
result = result.dimshuffle(2,0,1,3)[1:-1,:,:,0]
# We get rid of the first and the last result and shuffle.
# result.shape = (maxlen_x_pad/pool_stride, n_samples, sum(nkernels))
return result
评论列表
文章目录