Java中支持连续变量的线程安全或多线程CRF?

Java中支持连续变量的线程安全或多线程CRF?,java,multithreading,machine-learning,Java,Multithreading,Machine Learning,我想使用Mallet在一个相当大的数据集上,以一种离开一个序列的方式运行条件随机场。因此,我需要多线程计算来处理这种计算,1)并行训练多个CRF,每个CRF在单个线程上训练,或2)以多线程方式训练每个CRF 在Mallet API中,我找到了CRF培训师的多线程版本cc.Mallet.fst.CRFTrainerByThreadedLabelLikelihood.java,它实现了选项2。然而,在我的情况下,我需要对连续变量的支持,fst似乎不支持连续变量,GRMM似乎需要连续变量。通过一个小的

我想使用Mallet在一个相当大的数据集上,以一种离开一个序列的方式运行条件随机场。因此,我需要多线程计算来处理这种计算,1)并行训练多个CRF,每个CRF在单个线程上训练,或2)以多线程方式训练每个CRF

在Mallet API中,我找到了CRF培训师的多线程版本cc.Mallet.fst.CRFTrainerByThreadedLabelLikelihood.java,它实现了选项2。然而,在我的情况下,我需要对连续变量的支持,fst似乎不支持连续变量,GRMM似乎需要连续变量。通过一个小的调整,我设法让GRMM处理连续的输入。然而,对于GRMM,就我所能找到的而言,似乎不支持通过选项2进行多线程训练,就像在fst中一样

作为替代方案,我实现了选项1,在该选项中,我在不同的线程中并行地训练CRF进行实验的折叠。我使用我自己的Minmo/Mallet github版本Mallet,于2015年8月26日签出。然而,GRMM代码似乎不是线程安全的,因为当我并行运行代码时会抛出异常,而当我使用单个线程运行同一代码时不会抛出这些异常。此外,当并行训练CRF时,预测精度显著降低,因为我只是捕获异常并让执行继续。在多个线程上执行时引发的异常如下:

java.lang.IndexOutOfBoundsException: Assignment does not give a value for variable I216_VAR[f=0][tm=38]
    at cc.mallet.grmm.types.Assignment.get(Assignment.java:337)
    at cc.mallet.grmm.types.Assignment.get(Assignment.java:315)
    at cc.mallet.grmm.types.LogTableFactor.rawValue(LogTableFactor.java:255)
    at cc.mallet.grmm.types.LogTableFactor.logValue(LogTableFactor.java:219)
    at cc.mallet.grmm.inference.AbstractBeliefPropagation.lookupLogJoint(AbstractBeliefPropagation.java:553)
    at cc.mallet.grmm.learning.ACRF$MaximizableACRF.computeLogLikelihood(ACRF.java:1348)
    at cc.mallet.grmm.learning.ACRF$MaximizableACRF.getValue(ACRF.java:1270)
    at cc.mallet.optimize.LimitedMemoryBFGS.optimize(LimitedMemoryBFGS.java:99)
    at cc.mallet.grmm.learning.DefaultAcrfTrainer.train(DefaultAcrfTrainer.java:207)
    at cc.mallet.grmm.learning.DefaultAcrfTrainer.train(DefaultAcrfTrainer.java:119)

有没有办法绕过这些问题,以多线程的方式训练具有连续变量的条件随机场,或者训练每个CRF多线程,或者同时训练不同线程中的多个CRF?最好是使用Mallet(fst或GRMM),因为这样可以保证我切换的时间,但我也愿意使用任何其他CRF/PGM Java库。

我最近一直在处理同样的问题,我认为我找到了一个不错的解决方案。查看并让我知道它是否有帮助。通过指定连续特性需要在正则表达式“[a-Z]+=”后面有一个前缀,我能够设置一个管道,该管道(松散地)设置为它后面的双精度。我想我还有一些测试要验证,但也许它会给你一些启发

你把管道弄得一团糟了吗?是的,我正在使用管道将数据加载到实例中,并将其传递给CRF培训师。然而,我的管道很简单,所以我没有看到在我的问题中添加代码的任何好处,因为我的问题很快就会变得冗长和混乱。我在线程本身中创建我的管道、ACRF对象和CRF培训器,并且仅收集每个线程的预测以进行评估。然而,CRF培训师本身是并行运行的,这似乎是造成问题的原因。它可能是trainer对象以一种不采用多线程的方式在JVM堆栈上缓存数据。为了使用FST,我一直在摆弄管道,发现可以通过token.setFeatureValue()直接设置double类型的token功能值。这就是你想要的东西吗?很好,听起来确实可能有用,我来试试。出于某种原因,我觉得fst根本不支持连续变量,但现在我再次检查,我找不到任何提到fst不支持连续变量的地方。当我有机会的时候,我会在下面的回答中把我的一些想法发布到github。