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 更改,该示例不再起作用)
- 首先确保您安装了最新的 .net 版本并且您的 Unity 版本至少为 2019.2.0f1(这是预览版)或更高版本。
- Creste 一个新的统一项目。在 Assets 文件夹中创建一个 Plugins 文件夹。将所有 ML .Net APIs 导入该文件夹(这可能是一件愚蠢的事情,但我已经正式创建了一个 visual studio 解决方案并通过 nuget 添加了所有这些 APIs 到该解决方案,而不是将这些 dll 文件复制到我的统一项目中的 Assets/Plugins 文件夹)。
- 在 Assets 文件夹中创建一个 Data 文件夹,并将 https://github.com/dotnet/machinelearning/blob/master/test/data/iris.data 中的 iris.data 文件粘贴到其中。
创建一个名为 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 以来,我没有遇到过此线程中之前帖子中提到的任何问题。
我不知道如何在 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 更改,该示例不再起作用)
- 首先确保您安装了最新的 .net 版本并且您的 Unity 版本至少为 2019.2.0f1(这是预览版)或更高版本。
- Creste 一个新的统一项目。在 Assets 文件夹中创建一个 Plugins 文件夹。将所有 ML .Net APIs 导入该文件夹(这可能是一件愚蠢的事情,但我已经正式创建了一个 visual studio 解决方案并通过 nuget 添加了所有这些 APIs 到该解决方案,而不是将这些 dll 文件复制到我的统一项目中的 Assets/Plugins 文件夹)。
- 在 Assets 文件夹中创建一个 Data 文件夹,并将 https://github.com/dotnet/machinelearning/blob/master/test/data/iris.data 中的 iris.data 文件粘贴到其中。
创建一个名为 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 以来,我没有遇到过此线程中之前帖子中提到的任何问题。