Ошибка вероятности Tensorflow: OperatorNotAllowedInGraphError: повторение по tf.Tensor запрещено

Я пытаюсь оценить модель в тензорном потоке с помощью NUTS, предоставив ей функцию правдоподобия. Я проверил, что функция правдоподобия возвращает разумные значения. Я слежу за настройкой здесь для настройки NUTS: https://rlhick.people.wm.edu/posts/custom-likes-tensorflow.html.

и некоторые из приведенных здесь примеров для настройки приоритетов и т. д .: https://github.com/tensorflow/probability/blob/master/tensorflow_probability/examples/jupyter_notebooks/Multilevel_Modeling_Primer.ipynb

Мой код находится в записной книжке colab здесь: https://drive.google.com/file/d/1L9JQPLO57g3OhxaRCB29do2m808ZUeex/view?usp=sharing

Я получаю сообщение об ошибке: OperatorNotAllowedInGraphError: iterating overtf.Tensoris not allowed: AutoGraph did not convert this function. Try decorating it directly with @tf.function. Я впервые использую тензорный поток, и я совершенно не понимаю эту ошибку. Также было бы идеально, если бы я мог передавать значения начальных параметров как один ввод (пример, над которым я работаю, не делает этого, но я предполагаю, что это возможно).

Обновить Похоже, мне пришлось изменить положение декоратора @ tf.function. Теперь сэмплер работает, но дает мне одно и то же значение для всех сэмплов по каждому из параметров. Обязательно ли передавать совместное распределение через функцию log_prob ()? Я явно чего-то упускаю. Я могу проверить вероятность с помощью оптимизации bfgs и получить разумные результаты (я оценил модель с помощью максимальной вероятности с фиксированными параметрами в другом программном обеспечении). Похоже, мне нужно определить функцию для возврата совместного распределения и вызова log_prob (). Я могу сделать это, если настрою его как логистическую регрессию (модель выбора логита логистически распределена в различиях). Однако я теряю стандартную закрытую форму.

Моя функция такова:

 @tf.function
def mmnl_log_prob(init_mu_b_time,init_sigma_b_time,init_a_car,init_a_train,init_b_cost,init_scale):

    # Create priors for hyperparameters
    mu_b_time = tfd.Sample(tfd.Normal(loc=init_mu_b_time, scale=init_scale),sample_shape=1).sample()
    # HalfCauchy distributions are too wide for logit discrete choice

    sigma_b_time = tfd.Sample(tfd.Normal(loc=init_sigma_b_time, scale=init_scale),sample_shape=1).sample()


    # Create priors for parameters
    a_car = tfd.Sample(tfd.Normal(loc=init_a_car, scale=init_scale),sample_shape=1).sample()
    a_train = tfd.Sample(tfd.Normal(loc=init_a_train, scale=init_scale),sample_shape=1).sample()

    # a_sm = tfd.Sample(tfd.Normal(loc=init_a_sm, scale=init_scale),sample_shape=1).sample()

    b_cost = tfd.Sample(tfd.Normal(loc=init_b_cost, scale=init_scale),sample_shape=1).sample()
    # Define a heterogeneous random parameter model with MultivariateNormalDiag()
    # Use MultivariateNormalDiagPlusLowRank() to define nests, etc.

    b_time = tfd.Sample(tfd.MultivariateNormalDiag(  # b_time
          loc=mu_b_time,
          scale_diag=sigma_b_time),sample_shape=num_idx).sample()


    # Definition of the utility functions

    V1 = a_train + tfm.multiply(b_time,TRAIN_TT_SCALED) + b_cost * TRAIN_COST_SCALED
    V2 = tfm.multiply(b_time,SM_TT_SCALED) + b_cost * SM_COST_SCALED
    V3 = a_car + tfm.multiply(b_time,CAR_TT_SCALED) + b_cost * CAR_CO_SCALED
    print("Vs",V1,V2,V3)

    # Definition of loglikelihood
    eV1 = tfm.multiply(tfm.exp(V1),TRAIN_AV_SP)
    eV2 = tfm.multiply(tfm.exp(V2),SM_AV_SP)
    eV3 = tfm.multiply(tfm.exp(V3),CAR_AV_SP)
    eVD = eV1 + eV2 +
 eV3
    print("eVs",eV1,eV2,eV3,eVD)

    l1 = tfm.multiply(tfm.truediv(eV1,eVD),tf.cast(tfm.equal(CHOICE,1),tf.float32))
    l2 = tfm.multiply(tfm.truediv(eV2,eVD),tf.cast(tfm.equal(CHOICE,2),tf.float32))
    l3 = tfm.multiply(tfm.truediv(eV3,eVD),tf.cast(tfm.equal(CHOICE,3),tf.float32))
    ll = tfm.reduce_sum(tfm.log(l1+l2+l3))

    print("ll",ll)

    return ll

Функция вызывается следующим образом:

    nuts_samples = 1000
nuts_burnin = 500
chains = 4
## Initial step size
init_step_size=.3
init = [0.,0.,0.,0.,0.,.5]

##
## NUTS (using inner step size averaging step)
##
@tf.function
def nuts_sampler(init):
    nuts_kernel = tfp.mcmc.NoUTurnSampler(
      target_log_prob_fn=mmnl_log_prob, 
      step_size=init_step_size,
      )
    adapt_nuts_kernel = tfp.mcmc.DualAveragingStepSizeAdaptation(
  inner_kernel=nuts_kernel,
  num_adaptation_steps=nuts_burnin,
  step_size_getter_fn=lambda pkr: pkr.step_size,
  log_accept_prob_getter_fn=lambda pkr: pkr.log_accept_ratio,
  step_size_setter_fn=lambda pkr, new_step_size: pkr._replace(step_size=new_step_size)
       )

    samples_nuts_, stats_nuts_ = tfp.mcmc.sample_chain(
  num_results=nuts_samples,
  current_state=init,
  kernel=adapt_nuts_kernel,
  num_burnin_steps=100,
  parallel_iterations=5)
    return samples_nuts_, stats_nuts_

samples_nuts, stats_nuts = nuts_sampler(init)

person Jason Hawkins    schedule 31.03.2020    source источник
comment
Перекрестно размещено здесь: groups.google.com/a /tensorflow.org/forum/#!topic/tfprobability/   -  person Jason Hawkins    schedule 02.04.2020


Ответы (1)


У меня есть ответ на свой вопрос! Просто дело в другой номенклатуре. Мне нужно определить мою модель как функцию softmax, которую я знал, это то, что я бы назвал «логит-моделью», но для меня это просто не было щелчком. Следующее сообщение в блоге дало мне прозрение: http://khakieconomics.github.io/2019/03/17/Putting-it-all-toобщежития.html

person Jason Hawkins    schedule 06.04.2020
comment
См. Мой обновленный вопрос: https://stackoverflow.com/questions/61236004/specification-of-multinomial-model-in-tensorflow-probability - person Jason Hawkins; 15.04.2020