Я хотел бы использовать theano.scan в pymc3. Я сталкиваюсь с проблемами, когда добавляю более двух переменных как sequences
. Вот простой пример:
import numpy as np
import pymc3 as pm
import theano
import theano.tensor as T
a = np.ones(5)
b = np.ones(5)
basic_model = pm.Model()
with basic_model:
a_plus_b, _ = theano.scan(fn=lambda a, b: a + b, sequences=[a, b])
приводит к следующей ошибке:
Traceback (most recent call last):
File "StackOverflowExample.py", line 23, in <module>
sequences=[a, b])
File "\Anaconda3\lib\site-packages\theano\scan_module\scan.py", line 586, in scan
scan_seqs = [seq[:actual_n_steps] for seq in scan_seqs]
File "\Anaconda3\lib\site-packages\theano\scan_module\scan.py", line 586, in <listcomp>
scan_seqs = [seq[:actual_n_steps] for seq in scan_seqs]
TypeError: slice indices must be integers or None or have an __index__ method
Однако, когда я запускаю тот же theano.scan вне блока модели pymc, все работает нормально:
a = T.vector('a')
b = T.vector('b')
a_plus_b, update = theano.scan(fn=lambda a, b: a + b, sequences=[a, b])
a_plus_b_function = theano.function(inputs=[a, b], outputs=a_plus_b, updates=update)
a = np.ones(5)
b = np.ones(5)
print(a_plus_b_function(a, b))
печатает [2. 2. 2. 2. 2.]
, как и должно быть.
Кроме того, проблема заключается в добавлении более одного sequences
. Все отлично работает, когда одна переменная sequences
и одна переменная non-sequences
. Работает следующий код:
a = np.ones(5)
c = 2
basic_model = pm.Model()
with basic_model:
a_plus_c, _ = theano.scan(fn=lambda a, c: a + c, sequences=[a], non_sequences=[c])
a_plus_c_print = T.printing.Print('a_plus_c')(a_plus_c)
печатает a_plus_c __str__ = [ 3. 3. 3. 3. 3.]
, как и ожидалось.
Примечание : Я не могу просто использовать a + b вместо theano.scan, потому что моя реальная функция более сложная. Я действительно хочу иметь что-то вроде этого:
rewards = np.array([1, 1, 1, 1]) # reward (1) or no reward (0)
choices = np.array([1, 0, 1, 0]) # action left (1) or right (0)
Q_old = 0 # initial Q-value
alpha = 0.1 # learning rate
def update_Q(reward, choice, Q_old, alpha):
return Q_old + choice * alpha * (reward - Q_old)
Q_left, _ = theano.scan(fn=update_Q,
sequences=[rewards, choices],
outputs_info=[Q_old],
non_sequences=[alpha])