Привет, спасибо за интерес к Gen! :)
Адреса трассы комбинированной модели
Комбинированная модель из учебника выглядит так:
@gen function combined_model(xs::Vector{Float64})
if @trace(bernoulli(0.5), :is_line)
@trace(line_model_2(xs))
else
@trace(sine_model_2(xs))
end
end;
Его следы будут иметь следующие адреса:
:is_line
, сохраняя логическое значение, указывающее, был ли сгенерированный набор данных линейным или нет.
- Любые адреса от
line_model_2
или sine_model_2
, в зависимости от того, который был вызван.
Обратите внимание, что трассы line_model_2
и sine_model_2
содержат адреса (:y, i)
для каждого целого числа i
между 1
и length(xs)
. Из-за этого также будут отслеживаться combined_model
: это адреса, представляющие окончательные выборочные значения y
, независимо от того, какой из двух процессов их сгенерировал.
Создание нового набора данных
Вопрос о «построении набора данных, для которого неоднозначно, является ли линейная или синусоидальная модель наилучшим», не требует написания новой порождающей функции (с @gen
), а скорее составляет список xs
и список ys
(в простой Джулии), который, по вашему мнению, может сделать набор данных с неоднозначными затруднениями. Затем вы можете передать свои xs
и ys
в функцию do_inference
, определенную ранее в записной книжке, чтобы увидеть, что система делает вывод о вашем наборе данных. Обратите внимание, что функция do_inference
создает карту выбора constraint , которая ограничивает каждый (:y, i)
значением ys[i]
из набора данных, который вы передали. Это работает, потому что (:y, i)
всегда является именем i-го назначения данных , независимо от значения :is_line
.
Обновление / управление следами
Вы пишете:
Я бы ожидал, что смогу исследовать трассу синуса / line_model из комбо и делать поэлементное добавление к трассе, чтобы получить новую трассу. И не нужно случайным образом выбирать число, близкое к: intercept,: phase и т. Д., Чтобы я мог включить его в свой след позже.
Вы можете, конечно, дважды вызвать simulate
, чтобы получить две трассировки, кроме порождающей функции, такой как combo
. Но трассировками нельзя манипулировать произвольными способами (например, «поэлементное сложение»): в качестве структур данных трассировки поддерживают определенные инварианты, например всегда знают точную вероятность их текущих значений в модели, которая их сгенерировала, и всегда содержат значения, которые на самом деле могли иметь был сгенерирован из модели.
Словарная структура данных, которую вы ищете, является картой выбора. Карты выбора являются изменяемыми и могут быть созданы для включения произвольных значений по произвольным адресам. Например, вы можете написать:
observations = Gen.choicemap()
for (i, y) in enumerate(ys)
observations[(:y, i)] = y
end
Карты выбора могут использоваться в качестве ограничений для генерации новых трасс (с использованием Gen.generate
), в качестве аргументов низкоуровневого метода Gen * Gen.update
(с позволяет обновлять трассировку при повторном вычислении любых релевантных вероятностей и с ошибками, если ваши обновления недействительны) и в некоторых других местах.
Надеюсь, это поможет:)