我正在尝试使用C#中的BayesServer library为Unity3D游戏构建动态贝叶斯网络。我有以下实现网络的方法
// numberOfDistractors and levelId will be used later for added complexity in modeling
void InitializeNetworkForLevel(int numberOfDistractors, int levelId)
{
beliefNet = new BayesServer.Network();
// add a knowledge node which is a latent variable (parameter to be learned from observed values
KTrue = new State("KTrue");
KFalse = new State("KFalse");
knowledge = new Variable("Knowledge", KTrue, KFalse);
knowledgeNode = new Node(knowledge)
{
TemporalType = TemporalType.Temporal // this is a time series node, hence re-used for each time slice
};
beliefNet.Nodes.Add(knowledgeNode);
// add a question node, which denotes the oberved variable whether the question is answered correctly or not
// this node has two states, namely correct or incorrect
QTrue = new State("QTrue");
QFalse = new State("QFalse");
question = new Variable("Question", QTrue, QFalse);
questionNode = new Node(question)
{
TemporalType = TemporalType.Temporal // this is a time series node, hence re-used for each time slice
};
beliefNet.Nodes.Add(questionNode);
// add a link from knowledge node to question node
beliefNet.Links.Add(new Link(knowledgeNode, questionNode, 0));
for (int i = 1; i <= 5; i++)
beliefNet.Links.Add(new Link(knowledgeNode, knowledgeNode, i)); // time series link (order/lag i)
QueryNetwork(true);
}
然后是另一种推断方法:
void QueryNetwork(bool isAnswerCOrrect)
{
StateContext kTrueTime0 = new StateContext(KTrue, 0);
StateContext kFalseTime0 = new StateContext(KFalse, 0);
Table priorKnowledge = knowledgeNode.NewDistribution(0).Table;
priorKnowledge[kTrueTime0] = 0.5;
priorKnowledge[kFalseTime0] = 0.5;
// NewDistribution does not assign the new distribution, so it still must be assigned
knowledgeNode.Distribution = priorKnowledge;
// the second is specified for time >= 1
Table learnRate = knowledgeNode.NewDistribution(1).Table;
// when specifying temporal distributions, variables which belong to temporal nodes must have times associated
// NOTE: Each time is specified relative to the current point in time which is defined as zero,
// therefore the time for variables at the previous time step is -1
StateContext kTrueTime1 = new StateContext(KTrue, -1);
StateContext kFalseTime1 = new StateContext(KFalse, -1);
learnRate[kTrueTime1, kTrueTime0] = 0.5;
learnRate[kFalseTime1, kTrueTime0] = 0.5;
learnRate[kTrueTime1, kFalseTime0] = 0.5;
learnRate[kFalseTime1, kFalseTime0] = 0.5;
knowledgeNode.Distributions[1] = learnRate;
Table answerStatus = questionNode.NewDistribution().Table;
StateContext qTrue = new StateContext(QTrue, 0);
StateContext qFalse = new StateContext(QFalse, 0);
answerStatus[qTrue, kTrueTime0] = 0.5;
answerStatus[qFalse, kTrueTime0] = 0.5;
answerStatus[qTrue, kFalseTime0] = 0.5;
answerStatus[qFalse, kFalseTime0] = 0.5;
questionNode.Distribution = answerStatus;
// optional check to validate network
beliefNet.Validate(new ValidationOptions());
// at this point the network has been fully specified
// we will now perform some queries on the network
RelevanceTreeInference inference = new RelevanceTreeInference(beliefNet);
RelevanceTreeQueryOptions queryOptions = new RelevanceTreeQueryOptions();
RelevanceTreeQueryOutput queryOutput = new RelevanceTreeQueryOutput();
// set some temporal evidence
if (isAnswerCOrrect)
inference.Evidence.Set(question, new double?[] { 1, 0 }, 0, 0, 2);
else
inference.Evidence.Set(question, new double?[] { 0, 1 }, 0, 0, 2);
queryOptions.LogLikelihood = true; // only ask for this if you really need it
inference.Query(queryOptions, queryOutput); // note that this can raise an exception (see help for details)
Debug.Log("LogLikelihood: " + queryOutput.LogLikelihood.Value);
}
但是,在尝试使用QueryNetwork
方法验证网络时出现以下异常:
InvalidNetworkException:节点[知识]的分配为空。
BayesServer.Network.Validate(BayesServer.ValidationOptions选项) (在:0处)
BayesNet.QueryNetwork(System.Boolean isAnswerCOrrect)(在 资产/脚本/BayesNet.cs:97)
BayesNet.InitializeNetworkForLevel(System.Int32 numberOfDistractors, System.Int32 levelId)(在Assets / Scripts / BayesNet.cs:59处)
BayesNet.Start()(位于Assets / Scripts / BayesNet.cs:21)
当我已经在QueryNetwork
方法中指定知识节点时,为什么会说知识节点具有空分布。尽管我可以使用以下代码来解决此问题:
ValidationOptions opt = new ValidationOptions();
opt.AllowNullDistributions = true;
// optional check to validate network
beliefNet.Validate(opt);
此外,我假设第一级的所有概率为50%,如何根据第一级的推论更改这些值?
答案 0 :(得分:1)
当我怀疑您在潜在节点上只需要滞后1时,您似乎在添加滞后1至5。尽管推理不是必需的,但为了进行测试,我建议在用户界面中展开网络以检查DBN是否符合您的期望。请注意,仅添加滞后1不会限制时间步长,只是每个步长仅连接到前一个时间步长。