【发布时间】:2015-09-02 20:02:13
【问题描述】:
我想使用 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 以用于实验的折叠。我使用我自己构建的 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 库开放。
【问题讨论】:
-
你搞砸过管道吗?
-
是的,我正在使用管道将数据加载到实例中并将它们传递给 CRF 训练器。但是,我的管道很简单,所以我没有看到将代码添加到我的问题有任何好处,因为我的问题很快就会变得冗长而混乱。我在线程本身中创建了我的管道、ACRF 对象和 CRF 训练器,并且只收集来自每个线程的预测以用于评估目的。然而,CRF 培训师本身是并行运行的,这似乎是导致问题的原因。可能是训练器对象以不假设多线程的方式在 JVM 堆栈上缓存数据。
-
为了使用FST一直在搞乱管道,发现可以直接通过token.setFeatureValue()设置double类型的token特征值。这就是你要找的东西吗?
-
不错,听起来确实可行,我试试看。由于某种原因,我的印象是 fst 根本不支持连续变量,但现在我再次检查,我找不到任何提到 fst 不支持它们。
-
相同。当我有机会时,我会在下面的答案中将我想出的一些内容发布到 github。
标签: java multithreading machine-learning