我构建了一个使用lasagne的LSTM经常性NNet,它基于这个blog post中的体系结构松散地构建。我的输入是一个文本文件,它有大约1,000,000个句子和一个2,000个词的词汇表。通常,当我构建网络的图像识别我的输入层看起来像以下:在计算N个损失计算后,计算Theano中的更新
l_in = nn.layers.InputLayer((32, 3, 128, 128))
(其中尺寸为批量大小,信道,高度和宽度),因为所有的图像是相同的,其是方便所以我可以批量处理它们。由于我的LSTM网络中的每个实例具有变化的句长,我有如下所示的输入层:
l_in = nn.layers.InputLayer((None, None, 2000))
如在上文引用的博客文章所描述的,
面罩:
因为不是每个小批次中的所有序列将总是具有相同的长度,所以在 千层面中的所有复发层接受具有形状 (batch_size,n_time_steps)的单独掩模输入 ,其被填充,使得 掩模[I,J] = 1 时 Ĵ< =(序列的长度i) 和 掩模[I,J] = 0 当 J>时序列(长度 我) 。 未提供掩码时,假定小批量中的所有序列长度为 n_time_steps。
我的问题是:是否有办法来处理这种类型的小批量网络的不使用口罩?
这里是一个简化版本,如果我的网络。
# -*- coding: utf-8 -*-
import theano
import theano.tensor as T
import lasagne as nn
softmax = nn.nonlinearities.softmax
def build_model():
l_in = nn.layers.InputLayer((None, None, 2000))
lstm = nn.layers.LSTMLayer(l_in, 4096, grad_clipping=5)
rs = nn.layers.SliceLayer(lstm, 0, 0)
dense = nn.layers.DenseLayer(rs, num_units=2000, nonlinearity=softmax)
return l_in, dense
model = build_model()
l_in, l_out = model
all_params = nn.layers.get_all_params(l_out)
target_var = T.ivector("target_output")
output = nn.layers.get_output(l_out)
loss = T.nnet.categorical_crossentropy(output, target_var).sum()
updates = nn.updates.adagrad(loss, all_params, 0.005)
train = theano.function([l_in.input_var, target_var], cost, updates=updates)
从那里我有发电机,其吐出(X, y)
对和我计算train(X, y)
以及更新与每个迭代的梯度。我想要做的是做N个训练步骤,并且然后用平均梯度更新参数。
要做到这一点,我试图创建一个compute_gradient
功能:
gradient = theano.grad(loss, all_params)
compute_gradient = theano.function(
[l_in.input_var, target_var],
output=gradient
)
,然后在几个训练实例循环,从而创建一个“批量”,收集梯度计算到列表:
grads = []
for _ in xrange(1024):
X, y = train_gen.next() # generator for producing training data
grads.append(compute_gradient(X, y))
这产生一个清单清单
>>> grads
[[<CudaNdarray at 0x7f83b5ff6d70>,
<CudaNdarray at 0x7f83b5ff69f0>,
<CudaNdarray at 0x7f83b5ff6270>,
<CudaNdarray at 0x7f83b5fc05f0>],
[<CudaNdarray at 0x7f83b5ff66f0>,
<CudaNdarray at 0x7f83b5ff6730>,
<CudaNdarray at 0x7f83b5ff6b70>,
<CudaNdarray at 0x7f83b5ff64f0>] ...
从这里我会需要在每一层取平均值,然后更新模型参数。这是可能的,像这样做梯度计算/参数更新需要发生在一个theano函数中吗?
谢谢。
你不会在编译时需要定义一个将batch_size渐变作为输入的theano函数,取其意义并将变化应用于共享值params? – user2255757
@ user2255757是的,这听起来像我以后。我只是不确定如何使用符号CudaNdarray实例列表来做这件事。如果他们是数组中的实际值的numpy数组,我只需要'map(np.mean,zip(* grads))'然后更新参数,但他们不是这样,我不知道如何继续。 – gobrewers14
我更新了我的问题答案,希望对您有所帮助 – user2255757