ML.NET 在 Unity 中

ML.NET in Unity

我不知道如何在 Unity 中使用 ML.NET。

我做了什么: 将我的项目转换为与框架 4.x 兼容。 已将 api 兼容性级别转换为框架 4.x。 创建 assets/plugins/ml 文件夹并放入 Microsoft.ML apis 和相应的 xmls。 将所有 ml.dlls 平台设置标记为仅 86_64 兼容(这是多余的)。

我现在可以: 调用 ML apis 并创建 MlContext、TextLoader,并进行模型训练。训练模型后,我还可以评估训练后的模型,但是...

我不能: 尝试从模型中获取预测时出现错误: github comment on issue from 28.12.18(那里还有一个完整的项目,你可以在那里看到代码) 相同的代码适用于 visual studio 解决方案。

 public float TestSinglePrediction(List<double> signal, MLContext mlContext, string modelPath)
{
    ITransformer loadedModel;
    using (var stream = new FileStream(modelPath, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        loadedModel = mlContext.Model.Load(stream);
    }
    var predictionFunction = loadedModel.MakePredictionFunction<AbstractSignal, PredictedRfd>(mlContext);
    var abstractSignal = new AbstractSignal()
    {
        Sig1 = (float)signal[0],
        Sig2 = (float)signal[1],
        Sig3 = (float)signal[2],
        Sig4 = (float)signal[3],
        Sig5 = (float)signal[4],
        Sig6 = (float)signal[5],
        Sig7 = (float)signal[6],
        Sig8 = (float)signal[7],
        Sig9 = (float)signal[8],
        Sig10 = (float)signal[9],
        Sig11 = (float)signal[10],
        Sig12 = (float)signal[11],
        Sig13 = (float)signal[12],
        Sig14 = (float)signal[13],
        Sig15 = (float)signal[14],
        Sig16 = (float)signal[15],
        Sig17 = (float)signal[16],
        Sig18 = (float)signal[17],
        Sig19 = (float)signal[18],
        Sig20 = (float)signal[19],
        RfdX = 0

    };
    var prediction = predictionFunction.Predict(abstractSignal);
    return prediction.RfdX;
}

这是returns错误行的方法: var predictionFunction = loadedModel.MakePredictionFunction<AbstractSignal, PredictedRfd>(mlContext);

从 Unity 2018.1 开始,unity 可以面向 .net 4.x。因此,您需要将 .net 版本设置为 .NET 4.x Equivalent,或 .net standard 2.0 (https://blogs.unity3d.com/2018/03/28/updated-scripting-runtime-in-unity-2018-1-what-does-the-future-hold/),并确保将您的 dll 作为参考添加到项目中 visual studio.如果你不添加它作为参考,那么 visual sudio 不知道它。

正如 Nick 在他的 post** 中所说,如果您按照这些步骤操作,它应该可以与 Unity 一起使用。

但是,在我撰写此文时 post,ML.NET 团队尚未对 Unity 进行全面测试,因此它无法开箱即用也就不足为奇了。 This issue has been opened on the ML.NET Github repository。我建议密切关注该问题以了解 Unity 支持的状态。

** 尼克: Starting with Unity 2018.1, unity can target .net 4.x. So you would need to set the .net version to .NET 4.x Equivalent, or .net standard 2.0 (https://blogs.unity3d.com/2018/03/28/updated-scripting-runtime-in-unity-2018-1-what-does-the-future-hold/) and make sure you add your dll to the project as a reference in visual studio. If you don't add it as a reference, then visual sudio doesn't know about it.

如下是 Iris Example 来自 https://docs.microsoft.com/en-us/dotnet/machine-learning/tutorials/iris-clustering 的一些修改(由于某些 ML API 更改,该示例不再起作用)

  1. 首先确保您安装了最新的 .net 版本并且您的 Unity 版本至少为 2019.2.0f1(这是预览版)或更高版本。
  2. Creste 一个新的统一项目。在 Assets 文件夹中创建一个 Plugins 文件夹。将所有 ML .Net APIs 导入该文件夹(这可能是一件愚蠢的事情,但我已经正式创建了一个 visual studio 解决方案并通过 nuget 添加了所有这些 APIs 到该解决方案,而不是将这些 dll 文件复制到我的统一项目中的 Assets/Plugins 文件夹)。
  3. 在 Assets 文件夹中创建一个 Data 文件夹,并将 https://github.com/dotnet/machinelearning/blob/master/test/data/iris.data 中的 iris.data 文件粘贴到其中。
  4. 创建一个名为 MLuTest 的脚本并将以下代码粘贴到其中:

    public class MLuTest:MonoBehaviour{

        static readonly string _dataPath = Path.Combine(Environment.CurrentDirectory, "Assets", "Data", "iris.data");
        static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Assets", "Data", "IrisClusteringModel.zip");
        MLContext mlContext;
        void Start()
        {
            Debug.Log("starting...");
            mlContext = new MLContext(seed: 0);
            IDataView dataView = mlContext.Data.ReadFromTextFile<IrisData>(_dataPath, hasHeader: false, separatorChar: ',');
            string featuresColumnName = "Features";
            var pipeline = mlContext.Transforms
                .Concatenate(featuresColumnName, "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")
                .Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName, clustersCount: 3));//read and format flowery data
            var model = pipeline.Fit(dataView);//train
            using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))//save trained model
            {
                mlContext.Model.Save(model, fileStream);
            }
            var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model);//predict
            IrisData Setosa = new IrisData
            {
                SepalLength = 5.1f,
                SepalWidth = 3.5f,
                PetalLength = 1.4f,
                PetalWidth = 0.2f
            };
            Debug.Log(predictor.Predict(Setosa).PredictedClusterId);
            Debug.Log("...done predicting, now do what u like with it");
        }
    }
    
    public class IrisData
    {
        [LoadColumn(0)]
        public float SepalLength;
    
        [LoadColumn(1)]
        public float SepalWidth;
    
        [LoadColumn(2)]
        public float PetalLength;
    
        [LoadColumn(3)]
        public float PetalWidth;
    }
    public class ClusterPrediction
    {
        [ColumnName("PredictedLabel")]
        public uint PredictedClusterId;
    
        [ColumnName("Score")]
        public float[] Distances;
    }
    

这应该开箱即用……对我来说确实如此。您可能会搞砸的地方是在获取 api 文件时,它们可能与我的版本不同,或者只是与某些 .net 框架兼容。所以获取我的插件文件夹的内容(请注意,所有这些 api 可能不是必需的,自己挑选):https://github.com/dotnet/machinelearning/issues/1886 过去(在以前的统一版本中)必须更改某些播放器设置,但我不必这样做。但是 anhoo 这是我的:

我希望这对您有所帮助,自从 Unity 更新 19.2 以来,我没有遇到过此线程中之前帖子中提到的任何问题。