Реализация LSTM с помощью theano scan, намного медленнее, чем использование циклов
Я использую Theano/Pylearn2 для реализации модели LSTM в моей собственной сети. Однако я обнаружил, что сканирование Theano намного, намного медленнее, чем использование простых циклов. Я использовал профилировщик Theano
<% time> <sum %> <apply time> <time per call> <type> <#call> <#apply> <Class name>
95.4% 95.4% 25.255s 4.31e-02s Py 586 3 theano.scan_module.scan_op.Scan
1.8% 97.2% 0.466s 4.72e-05s C 9864 41 theano.sandbox.cuda.basic_ops.GpuElemwise
0.8% 97.9% 0.199s 8.75e-05s C 2276 10 theano.sandbox.cuda.basic_ops.GpuAlloc
0.7% 98.7% 0.196s 1.14e-04s C 1724 8 theano.sandbox.cuda.blas.GpuDot22
0.3% 99.0% 0.087s 1.06e-04s C 828 3 theano.sandbox.cuda.basic_ops.GpuIncSubtensor
0.2% 99.2% 0.051s 1.66e-04s Py 310 2 theano.sandbox.cuda.basic_ops.GpuAdvancedSubtensor1
и Ops,
<% time> <sum %> <apply time> <time per call> <type> <#call> <#apply> <Op name>
77.2% 77.2% 20.433s 7.40e-02s Py 276 1 forall_inplace,gpu,grad_of_lstm__layers}
18.2% 95.4% 4.822s 1.56e-02s Py 310 2 forall_inplace,gpu,lstm__layers}
Так много и много времени уходит на сканирование (что вроде как и ожидалось, но я не ожидал, что это будет слишком медленно).
Основная часть моего кода
def fprop(self, state_below, state_prev = 0, cell_prev = 0):
if state_prev == None:
state_prev = self.state_prev;
if cell_prev == None:
cell_prev = self.cell_prev;
i_gate = T.nnet.sigmoid(T.dot(state_below,self.Wi) +
T.dot(state_prev,self.Ui));
f_gate = T.nnet.sigmoid(T.dot(state_below,self.Wf) +
T.dot(state_prev,self.Uf));
C = T.tanh(T.dot(state_below, self.Wc) +
T.dot(state_prev, self.Uc));
C = i_gate * C + f_gate * cell_prev;
o_gate = T.nnet.sigmoid(T.dot(state_below,self.Wo) +
T.dot(state_prev,self.Uo) +
T.dot(C, self.Vo));
h_out = o_gate * T.tanh(C);
return h_out, C
И я написал свой скан как:
[h,c,out], _ = theano.scan(fn=self.fprop_with_output,
sequences=[X.T,Y[:,1:].T],
outputs_info=[dict(initial=h_,taps=[-1]), dict(initial=c_,taps=[-1]),None],n_steps=X.shape[1]-1);
Одна вещь, которую я заметил, заключается в том, что тип сканирования Theano использует реализацию Python (?) В том, что причина этого смехотворно медленная? или я что то не так сделал? Почему в Theano Python используется реализация Scan вместо C?
(Я сказал, что использование циклов быстрее, но быстрее во время выполнения, для большой модели мне не удалось скомпилировать версию использования циклов за разумное время).
2 ответа
Это было задано некоторое время назад, но у меня была / есть та же проблема. Ответ в том, что сканирование на GPU идет медленно.
Разработчикам Theano требуется время, чтобы реализовать сканирование и градиент сканирования с использованием C и GPU, потому что это намного сложнее, чем другие функции. Вот почему при профилировании он показывает GpuElemwise, GpuGemv, GpuDot22 и т. Д., Но вы не видите GpuScan или GpuGradofScan.
Между тем, вы можете использовать только петли.