4

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

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

我现在可以:调用 ML api 并创建 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;
}

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

4

3 回答 3

1

从 Unity 2018.1 开始,unity 可以针对 .net 4.x。因此,您需要将 .net 版本设置为 .NET 4.x 等效版本或 .net 标准 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 不知道它。

于 2018-12-14T14:14:09.030 回答
1

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

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

    公共类 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 它曾经是(在以前的统一版本中)必须更改某些播放器设置,但我不必这样做。但是这里是我的: 斯利卡

我希望这会有所帮助,自从 Unity 更新 19.2 以来,我在该线程的先前帖子中没有遇到任何问题。

于 2019-08-10T14:37:30.693 回答
1

正如尼克在他的帖子中所说的**,如果您遵循这些步骤,它应该可以与 Unity 一起使用。

然而,在我写这篇文章的时候,ML.NET 团队还没有对 Unity 进行全面的测试,所以它不能开箱即用也就不足为奇了。此问题已在ML.NET Github 存储库上打开。我建议密切关注 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.

于 2018-12-17T22:34:39.237 回答