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

标签 java multithreading machine-learning

我想使用 Mallet 在相当大的数据集上以留一序列方式运行条件随机字段。因此,我需要多线程计算来处理这个计算问题,要么通过 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 日 checkout 。然而,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 库。

最佳答案

我最近一直在解决同样的问题,并认为我想出了一个不错的解决方案。查看this repo并告诉我是否有帮助。通过指定连续特征需要有一个遵循正则表达式“[A-Z]+=”的前缀,我能够设置一个管道,该管道(松散地)设置为其后面的 double 值。我想我还需要做一些测试来验证,但也许它会给你一些启发。

关于java - Java 中的线程安全或多线程 CRF 支持连续变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32362084/

相关文章:

java - ArrayList 上的 Junit 测试

java - 如何将java层的数据组装成一个字符串

c# - 在 WPF 中,如何在另一个线程(另一个调度程序)上设置窗口的窗口所有者

c++ - 将参数传递给线程

java - 如何仅使用本地目录作为存储库在 gradle 上设置 springframework?

java - 嵌套循环的实现

java - Android 从内部和 asynctask 中获取 asynctask 的结果

python - 无法使用 Pandas 在 Python 中导入数据

python - 执行 scikit-learn 线性回归模型时出现问题

python - Sklearn 数据集