对PyMC3确定性变量的后验预测(Posterior Predictive Check on PyMC3 Deterministic Variable)
TL; DR
对
pm.Deterministic
进行后验预测检查的正确方法是什么?使用随机性(确定性也是随机的)作为输入的确定性变量?太短; 不明白
假设我们有一个像这样的
pymc3
模型:import pymc3 as pm with pm.Model() as model: # Arbitrary, trainable distributions. dist1 = pm.Normal("dist1", 0, 1) dist2 = pm.Normal("dist2", dist1, 1) # Arbitrary, deterministic theano math. val1 = pm.Deterministic("val1", arb1(dist2)) # Arbitrary custom likelihood. cdist = pm.DensityDistribution("cdist", logp(val1), observed=get_data()) # Arbitrary, deterministic theano math. val2 = pm.Deterministic("val2", arb2(val1))
我可能会误解,但我的意图是对
dist1
和dist2
进行抽样,并将这些样本输入到确定性变量中。 后验预测检查是否只能在观察到的随机变量上进行?使用
pymc3.sampling.sample_ppc
从dist2
和其他随机变量中获得后验预测样本是dist2
pymc3.sampling.sample_ppc
,但是我的模型的大部分值是从val1
和val2
的状态得出的,给出了这些样本。问题出现在
pm.Deterministic(.)
似乎返回th.TensorVariable
。 所以,当这被称为:ppc = pm.sample_ppc(_trace, vars=[val1, val2])["val1", "val2"]
...和
pymc3
尝试这段代码:410 for var in vars: --> 411 ppc[var.name].append(var.distribution.random(point=param, 412 size=size))
...它抱怨,因为
th.TensorVariable
显然没有.distribution
。那么,通过确定性来推导随机样本后验样本的正确方法是什么? 我是否需要明确地创建一个采用随机后验样本并计算确定性值的
th.function
函数? 这看起来很愚蠢,因为pymc3
已经有了这个图表。TL; DR
What's the right way to do posterior predictive checks on
pm.Deterministic
variables that take stochastics (rendering the deterministic also stochastic) as input?Too Short; Didn't Understand
Say we have a
pymc3
model like this:import pymc3 as pm with pm.Model() as model: # Arbitrary, trainable distributions. dist1 = pm.Normal("dist1", 0, 1) dist2 = pm.Normal("dist2", dist1, 1) # Arbitrary, deterministic theano math. val1 = pm.Deterministic("val1", arb1(dist2)) # Arbitrary custom likelihood. cdist = pm.DensityDistribution("cdist", logp(val1), observed=get_data()) # Arbitrary, deterministic theano math. val2 = pm.Deterministic("val2", arb2(val1))
I may be misunderstanding, but my intention is for the posteriors of
dist1
anddist2
to be sampled, and for those samples to fed into the deterministic variables. Is the posterior predictive check only possible on observed random variables?It's straightforward to get posterior predictive samples from
dist2
and other random variables usingpymc3.sampling.sample_ppc
, but the majority of my model's value is derived from the state ofval1
andval2
, given those samples.The problem arises in that
pm.Deterministic(.)
seems to return ath.TensorVariable
. So, when this is called:ppc = pm.sample_ppc(_trace, vars=[val1, val2])["val1", "val2"]
...and
pymc3
attempts this block of code inpymc3.sampling
:410 for var in vars: --> 411 ppc[var.name].append(var.distribution.random(point=param, 412 size=size))
...it complains because a
th.TensorVariable
obviously doesn't have a.distribution
.So, what is the right way to carry the posterior samples of stochastics through deterministics? Do I need to explicitly create a
th.function
that takes stochastic posterior samples and calculates the deterministic values? That seems silly given the fact thatpymc3
already has the graph in place.
原文:https://stackoverflow.com/questions/42151292
最满意答案
这里有一个逻辑问题。 您最初使用
calloc
为一个对象分配空间,然后调用add_entry
并将count等于0。然后在索引
current_count
处添加新条目,该条目在此处为0。 然后你用current_count + 1
调整内存大小,这也是1.所以你根本没有调整内存的大小。在下一次迭代中,
entry_count
为1,并在entries[1]
处添加一个新元素。 这就是问题所在,你正在越界访问内存,因为此时你只剩下一个对象的空间。而不是通过
current_count + 1
重新分配,您应该通过current_count + 2
重新分配,以便下一次迭代有空间将新元素放在内存末尾。void *add_entry(Entry *entries, int current_count) { Entry entry; printf("Enter name: "); scanf(" %[^\n]s", entry.name); printf("Enter number: "); scanf(" %[^\n]s", entry.number); printf("\n"); entries[current_count] = entry; return realloc(entries, sizeof(Entry) * (current_count + 2)); // <-- +2 }
请注意,您的
current_count
变量总是比实际分配的大小落后一步,这就是为什么您需要+2
编辑
还要注意更自然的方式是先调整大小,然后插入新的对象。 所以我会用
NULL
初始化内存,并像这样做:int main() { size_t entry_count = 0; Entry *entries = NULL, *tmp; int choice = 0; while (1) { printf("Options:\n1) Add Entry\n2) Modify Entry\n3) Print Entries\n4) Exit\n\nSelect an option: "); scanf(" %d", &choice); switch (choice) { case 1: tmp = add_entry(entries, &entry_count); if(tmp == NULL) { // error handling // entries still point to the old memory // could be useful in error handling free(entries); return 1; } entries = tmp; break; // ... } } } void *add_entry(Entry *entries, size_t *current_count) { if(current_count == NULL) return NULL; Entry entry; printf("Enter name: "); scanf(" %[^\n]s", entry.name); printf("Enter number: "); scanf(" %[^\n]s", entry.number); printf("\n"); if(entries == NULL) *current_count = 0; Entry *tmp = realloc(entries, (*current_count + 1) * sizeof *entries); if(tmp == NULL) return NULL; entries = tmp; entries[(*current_count)++] = entry; return entries; }
请注意,计数变量的
realloc
和增量发生在同一个函数中。 只有当一切顺利时,你才应该增加计数器。 还要注意,entries
初始化为NULL
,因为realloc(NULL, size)
等价于malloc(size)
。There is a logic problem here. You initially allocate space for one object with
calloc
then calladd_entry
with the count equals to 0.Then you add the new entry at index
current_count
which is 0 at this point. Then you resize the memory withcurrent_count + 1
, which is also 1. So you are not resizing the memory at all.In the next iteration,
entry_count
is 1 and you add a new element atentries[1]
. And that's the problem, you are accessing the memory out of bounds, because you still have space for only one object at this time.Instead of reallocating by
current_count + 1
, you should reallocate bycurrent_count + 2
, so that the next iteration has space to put the new elements at the end of the memory.void *add_entry(Entry *entries, int current_count) { Entry entry; printf("Enter name: "); scanf(" %[^\n]s", entry.name); printf("Enter number: "); scanf(" %[^\n]s", entry.number); printf("\n"); entries[current_count] = entry; return realloc(entries, sizeof(Entry) * (current_count + 2)); // <-- +2 }
Note that your
current_count
variable is always one step behind the real size of the allocation, that's why you need the+2
edit
Note also that the more natural way would be to resize first, and then insert the new object. So I would initialize the memory with
NULL
and do it like this:int main() { size_t entry_count = 0; Entry *entries = NULL, *tmp; int choice = 0; while (1) { printf("Options:\n1) Add Entry\n2) Modify Entry\n3) Print Entries\n4) Exit\n\nSelect an option: "); scanf(" %d", &choice); switch (choice) { case 1: tmp = add_entry(entries, &entry_count); if(tmp == NULL) { // error handling // entries still point to the old memory // could be useful in error handling free(entries); return 1; } entries = tmp; break; // ... } } } void *add_entry(Entry *entries, size_t *current_count) { if(current_count == NULL) return NULL; Entry entry; printf("Enter name: "); scanf(" %[^\n]s", entry.name); printf("Enter number: "); scanf(" %[^\n]s", entry.number); printf("\n"); if(entries == NULL) *current_count = 0; Entry *tmp = realloc(entries, (*current_count + 1) * sizeof *entries); if(tmp == NULL) return NULL; entries = tmp; entries[(*current_count)++] = entry; return entries; }
Note here that the
realloc
and the increment of the counting variable happens in the same function. Only when everything goes OK, you should increase the counter. Also note thatentries
is initialized withNULL
, becauserealloc(NULL, size)
is equivalent tomalloc(size)
.
相关问答
更多-
您可以在源( SIGTRAP信号的触发器)或事实发生后解决问题(请参阅此答案忽略某些SIGTRAP)。 下面我将解释如何处理第一种情况(避免触发)。 如果您有以下代码: void debug_break() { asm("int3"); } 然后你可以设置一个断点,命令立即返回: break debug_break commands return continue end 如果由于代码混合而无法返回: /* some code here */ asm("int3"); print_error ...
-
陷阱os.Exit在golang(trap os.Exit in golang)[2023-12-09]
你不能。 来自TFM: 该计划立即终止; 延迟函数不会运行。 You can't. from TFM: The program terminates immediately; deferred functions are not run. -
调试断点是否导致“EXC_BREAKPOINT(SIGTRAP)”异常? 其他方式实际上是:一个SIGTRAP(trace trap)会导致调试器中断你的程序,就像一个实际的断点一样。 但是这是因为调试器总是在崩溃中崩溃,SIGTRAP(像其他几个信号 )是一种崩溃。 SIGTRAP通常是由NSExceptions被抛出的,但并不总是 - 甚至可以直接提出一个自己。 我现在注意到我忘了删除一些调试断点,包括_NSLockError,[NSException raise]和objc_exception_thr ...
-
奇怪的GDB错误无法追踪(strange GDB error unable to trace)[2022-02-10]
您可以尝试以下操作以查看错误CALayer的分配位置: (gdb) info malloc 0x911c2a0 我不知道gdb是否能与僵尸对象很好地配合,但很明显,它似乎有一些局限性。 I've got the solution to the problem. The problem was due to a view Controller. The view controller was released and then after the method was called. But strange ... -
realloc:编程接收到的信号SIGTRAP,跟踪/断点陷阱(realloc: Program received signal SIGTRAP, Trace/breakpoint trap)[2023-10-23]
这里有一个逻辑问题。 您最初使用calloc为一个对象分配空间,然后调用add_entry并将count等于0。 然后在索引current_count处添加新条目,该条目在此处为0。 然后你用current_count + 1调整内存大小,这也是1.所以你根本没有调整内存的大小。 在下一次迭代中, entry_count为1,并在entries[1]处添加一个新元素。 这就是问题所在,你正在越界访问内存,因为此时你只剩下一个对象的空间。 而不是通过current_count + 1重新分配,您应该通过cur ... -
这个SIGTRAP是什么意思?(What does this SIGTRAP mean?)[2022-11-19]
当它试图在NSUserDefaults中设置对象时,问题似乎源于我的密钥某种程度上是nil。 有趣的是,它不会在模拟器中崩溃。 The problem seems to have originated from my key somehow being nil when it tried to set the object in the NSUserDefaults. Interestingly enough, it doesn't crash in the simulator. -
获取“程序接收到的信号:”SIGABRT“”在iphone SDK中(Getting “Program received signal: “SIGABRT”” in iphone sdk)[2022-11-04]
它告诉你问题是什么:当它已经完成时你可以释放内存,可能是通过向对象发送太多的释放消息。 在调试模式下运行,它可能会立即停止在正确的代码行。 然后,追溯你做那个对象。 It tells you what the problem is: You are free'ing memory when it has already been done, probably by sending too many release messages to an object. Run in debug mode and it ... -
我通过删除对第二个NSFileHandle方法的调用来解决它。 所以,而不是这个: [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadCompletionNotification object:[outputPipe fileHandleForReading]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@se ...
-
编程接收到的信号SIGTRAP,跟踪/断点陷阱。(Program received signal SIGTRAP, Trace/breakpoint trap. [Switching to Thread 6])[2022-11-18]
有效地,这是你的其他问题的重复。 正如我在评论中所说的那样,你没有提供足够的信息来帮助你。 细节很重要 ,而你却扣留他们。 GDB和gdbserver的版本很重要,您如何调用GDB和gdbserver,您从GDB收到的警告(如果有)很重要。 现在,这个错误信息: Program received signal SIGTRAP, Trace/breakpoint trap. [Switching to Thread 6] 通常意味着gdbserver没有附加你的进程的一个线程,并且该线程试图执行断点指令(在 ... -
GDB不支持它。 通常,将命令脚本附加到signal是没有意义的 - 您的程序可能在任何数量的位置接收SIGTRAP ,并且命令将不知道特定的SIGTRAP是否在预期的上下文中进入。 GDB doesn't support it. In general, attaching a command script to signal makes little sense -- your program could be receiving SIGTRAP in any number of places, and ...