我正在尝试使用多个特征来训练和预测一个模型。我们将我的数据称为“直方图”,它有一个浮点类型的目标值,以及从Sensor1
到Sensor6
的传感器,这些传感器是float[64]
类型。
数据是从CSV文件加载的,第一列是目标值,然后1-64列是Sensor1,65-129列是Sensor2,依此类推。
直方图类如下:
class Histogram{ [LoadColumn(0)] public float Target; [LoadColumn(1, 64), ColumnName("Sensor1")] public float[] Sensor1; [LoadColumn(65, 129), ColumnName("Sensor2")] public float[] Sensor2; [LoadColumn(130, 193), ColumnName("Sensor3")] public float[] Sensor3; [LoadColumn(194, 257), ColumnName("Sensor4")] public float[] Sensor4; [LoadColumn(258, 321), ColumnName("Sensor5")] public float[] Sensor5; [LoadColumn(322, 385), ColumnName("Sensor6")] public float[] Sensor6;}
训练完成后,在创建预测引擎时使用以下代码:
var predictor = trainedModel.CreatePredictionEngine<Histogram, PredictedTarget>(mlCtx);
会抛出以下异常:
System.ArgumentOutOfRangeException: '输入列'Sensor1'的架构不匹配:预期标量或已知大小的R4向量,但得到的是可变大小的向量参数名称:inputSchema'
我创建处理管道的代码如下:
IDataView baseTrainingDataView = mlCtx.Data.LoadFromTextFile<Histogram>(trainDataPath, hasHeader: true, separatorChar: ',');var dataProcessPipeline = mlCtx.Transforms .CopyColumns(DefaultColumnNames.Label, nameof(Histogram.Target)) .Append(mlCtx.Transforms.Normalize(nameof(Histogram.Sensor1), "Sensor1")) .Append(mlCtx.Transforms.Normalize(nameof(Histogram.Sensor2), "Sensor2")) .Append(mlCtx.Transforms.Normalize(nameof(Histogram.Sensor3), "Sensor3")) .Append(mlCtx.Transforms.Normalize(nameof(Histogram.Sensor4), "Sensor4")) .Append(mlCtx.Transforms.Normalize(nameof(Histogram.Sensor5), "Sensor5")) .Append(mlCtx.Transforms.Normalize(nameof(Histogram.Sensor6), "Sensor6")) .Append(mlCtx.Transforms.Concatenate(DefaultColumnNames.Features, "Sensor1", "Sensor2", "Sensor3", "Sensor4", "Sensor5", "Sensor6"));
因为这是我第一次尝试使用ML.NET,所以我还不确定需要提供哪些额外信息。我会根据需要进行编辑!谢谢你。
回答:
大多数ML.NET训练器期望固定大小的向量。你可以使用VectorType属性来指定特征是一个向量。以下是添加了VectorType属性的直方图类的样子。
class Histogram{ [LoadColumn(0)] public float Target; [LoadColumn(1, 64), ColumnName("Sensor1"), VectorType(64)] public float[] Sensor1; [LoadColumn(65, 129), ColumnName("Sensor2"), VectorType(64)] public float[] Sensor2; [LoadColumn(130, 193), ColumnName("Sensor3"), VectorType(64)] public float[] Sensor3; [LoadColumn(194, 257), ColumnName("Sensor4"), VectorType(64)] public float[] Sensor4; [LoadColumn(258, 321), ColumnName("Sensor5"), VectorType(64)] public float[] Sensor5; [LoadColumn(322, 385), ColumnName("Sensor6"), VectorType(64)] public float[] Sensor6;}
另外,Normalize()方法的签名是Normalize(outputColumnName, inputColumnName)。尽管在这个例子中可能无关紧要,因为输入列名和输出列名解析为相同的值(例如:Sensor1),但为了安全起见,最好在调用时包含参数名,因为Normalize()有多种带有默认参数的重载。虽然啰嗦,但明确包含参数名可以使你的意图更清晰。
....Append(mlCtx.Transforms.Normalize(outputColumnName: "Sensor1", inputColumnName: nameof(Histogram.Sensor1)))...