gpt4 book ai didi

java - 在多线程应用程序中使用共享的 Weka 分类器导致异常

转载 作者:行者123 更新时间:2023-11-29 03:39:12 25 4
gpt4 key购买 nike

我正在运行一个多线程 Java 应用程序,它获取对实例进行分类的请求。为了能够同时运行多个线程,我的应用程序在线程之间共享一个 Classifier 对象和一个 Instances 对象。 Instances 对象只包含属性的相关数据,没有任何与之关联的实例。

当我的应用程序收到分类请求时,我使用请求的属性数据创建一个 Instance 对象,并使用 将预先生成的 Instances 对象设置为数据集Instance.setDataset(),例如:

myNewInstance.setDataset(sharedInstances);

然后 myNewInstance 被发送到共享的 Classifier

它似乎在大多数情况下都运行良好。然而,有时当发生 2 个并发请求时,Classifier.distributionForInstance() 会抛出异常。不幸的是,错误消息并不清楚,但是我看到了 2 个不同的异常:

Caused by: java.lang.RuntimeException: Queue is empty
at weka.core.Queue.pop(Queue.java:194)
at weka.filters.Filter.output(Filter.java:563)
at weka.filters.unsupervised.attribute.PrincipalComponents.convertInstance(PrincipalComponents.java:626)
at weka.filters.unsupervised.attribute.PrincipalComponents.input(PrincipalComponents.java:812)
at weka.classifiers.meta.RotationForest.convertInstance(RotationForest.java:1114)
at weka.classifiers.meta.RotationForest.distributionForInstance(RotationForest.java:1147)

Caused by: java.lang.NullPointerException
at weka.filters.unsupervised.attribute.Standardize.convertInstance(Standardize.java:238)
at weka.filters.unsupervised.attribute.Standardize.input(Standardize.java:142)
at weka.filters.unsupervised.attribute.PrincipalComponents.convertInstance(PrincipalComponents.java:635)
at weka.filters.unsupervised.attribute.PrincipalComponents.input(PrincipalComponents.java:812)
at weka.classifiers.meta.RotationForest.convertInstance(RotationForest.java:1114)
at weka.classifiers.meta.RotationForest.distributionForInstance(RotationForest.java:1147)

如您所见,当最新消息发生时,它会附带一个空消息字符串。

据我所知,我不能使对象不可变,而且我宁愿不将这部分包装在关键部分中以充分利用并发性。我尝试使用构造函数 Instances(Instances dataset) 为每个分类请求创建不同的“实例”对象,但是,它并没有产生不同的结果。使用不同的 Classifier 不是一种选择,因为构建对象需要花费太多时间并且需要快速响应(最多 10 到 20 毫秒),据我所知,问题并不在于此.

我假设问题出在使用相同的 Instances 对象。基于 Instances 的文档构造函数只复制对头信息的引用,这解释了为什么通过创建另一个对象没有解决问题。是否可以选择基于先前的对象创建完全不同的实例对象,而无需实时遍历所有属性?

任何其他以性能为导向的解决方案也将受到高度赞赏。

谢谢!

最佳答案

可能您现在已经解决了这个问题。这仅适用于面临类似问题的人。我在多线程 Java 应用程序中测试实例,我遇到了同样的异常。要分解问题,您的情况有两个问题:

  • 第一个是您使用相同的 Instances 对象为每个请求设置数据。有了这个,您很可能会遇到并发问题,这些问题可能不会破坏代码,但会产生错误的结果。因为来自不同请求的数据可能会混淆。最好的办法是为每个请求创建一个新的 Instances 对象。但是,这不是产生您所面临的异常的原因。这是第二期。
  • 第二个问题是您使用的是相同的 Classifier,这就是产生异常的原因。在我的例子中,我构建了分类器并序列化并写入文件,因为我构建了它们。一旦我需要对测试集进行分类,我就会在每个线程中反序列化对象,给我一个新的实例。但是,解决此问题的正确方法是使用 weka.classifiers.Classifier.makeCopy(model) 静态方法为每个请求创建一个副本,该方法在内部使用序列化。

关于java - 在多线程应用程序中使用共享的 Weka 分类器导致异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13938909/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com