我想使用Mallet在一个相当大的数据集上以Leave-One-Sequence-Out方式运行条件随机字段。因此,我需要多线程计算来计算这个,或者通过1)并行训练多个CRF,每个CRF在单个线程上训练,或者2)以多线程方式训练每个CRF。
在Mallet API中,我找到了一个CRF培训师的多线程版本,cc.mallet.fst.CRFTrainerByThreadedLabelLikelihood.java,它实现了选项2.但是,在我的情况下,我需要支持连续变量,对于fst似乎没有获得支持,似乎需要GRMM。通过小调整,我设法让GRMM处理连续输入。然而,对于GRMM,据我所知,似乎没有像fst那样通过选项2支持多线程训练。
作为替代方案,我实现了选项1,其中我在不同的线程中并行训练CRF用于实验的折叠。我使用自己构建的Mallet的Minmo / Mallet github版本,于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库。
答案 0 :(得分:1)
我最近一直在讨论同样的问题,并认为我提出了一个不错的解决方案。查看this repo并告诉我它是否有帮助。通过指定连续特征需要具有跟在正则表达式'[A-Z] + ='之后的前缀,我能够设置一个(松散地)设置为跟随它的双精度的管道。我想我还有一些测试可以验证,但也许它会给你一些灵感。