【问题标题】:ML.NET - crashing when multithreadedML.NET - 多线程时崩溃
【发布时间】:2020-10-30 23:53:01
【问题描述】:

我使用 ml.net 模型构建器制作了一个简单的图像识别程序,但是当我转到多线程同时检查多个文件夹中的图像时,它崩溃了。它返回“Test.exe 中 0x00007FFAB191F155 (tensorflow.dll) 处引发的异常:0xC0000005:访问冲突读取位置 0x0000000002020202。”

代码只是 ml.net 模型构建器自动生成的代码:

public class ModelInput {
    [ColumnName("Label"), LoadColumn(0)]
    public string Label { get; set; }


    [ColumnName("ImageSource"), LoadColumn(1)]
    public string ImageSource { get; set; }
}

 public class ModelOutput {
    // ColumnName attribute is used to change the column name from
    // its default value, which is the name of the field.
    [ColumnName("PredictedLabel")]
    public String Prediction { get; set; }
    public float[] Score { get; set; }
}

class ConsumeModel {
    private static Lazy<PredictionEngine<ModelInput, ModelOutput>> PredictionEngine = new Lazy<PredictionEngine<ModelInput, ModelOutput>>(CreatePredictionEngine);

    public static string MLNetModelPath = Path.GetFullPath("MLModel.zip");

    public static ModelOutput Predict(ModelInput input) {

            ModelOutput result = PredictionEngine.Value.Predict(input);
            return result;
       
    }

    public static PredictionEngine<ModelInput, ModelOutput> CreatePredictionEngine() {
        // Create new MLContext
        MLContext mlContext = new MLContext();

        // Load model & create prediction engine
        ITransformer mlModel = mlContext.Model.Load(MLNetModelPath, out var modelInputSchema);
        var predEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);
        return predEngine;
    }
}

我用来确定图像标签和多线程机制的代码如下:

    public static void determine(string Dictpath) {
        for (int j = 0; j < 9; j++) {
            ModelInput sampleData = new ModelInput() {
                ImageSource = Directory.GetFiles(Dictpath)[j],
            };
            var predictionResult = ConsumeModel.Predict(sampleData);
            Console.WriteLine(predictionResult.Prediction);
        }
    }

为了应用程序的多线程,我正在使用:

  string[] Directories = Directory.GetDirectories("Saved/");
   for (int i = 0; i < 10; i++) {
            Task.Run(() => {
                determine(Directories[i]);
            });
        }

我尝试减慢启动每个线程所需的时间,但我仍然得到相同的结果。它似乎只在它是单线程的情况下才有效,如果它是多线程的,它就会崩溃。

【问题讨论】:

    标签: c# multithreading ml.net


    【解决方案1】:

    您正在同时使用来自多个线程的同一 PredictionEngine 实例,而没有同步。这仅在PredictionEngine 类是线程安全的情况下才可行。除非文档明确声明“类的所有公共和受保护成员都是安全的,并且可以从多个线程同时使用”,否则您应该假设该类不是线程安全的,并且不要使用它这边走。否则你会得到未定义的行为。您可以使用lock 或其他方式同步对单个实例的所有访问,也可以为每个线程创建一个专用实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-04
      • 1970-01-01
      相关资源
      最近更新 更多