Problem/error 'Property ''xs' 在 angular 项目 tensorflow.js 的类型 'TensorContainer' 上不存在

Problem/error 'Property ''xs' does not exist on type 'TensorContainer' in angular project with tensorflow.js

我正在尝试从我现有的 angular 项目中的 tensorflow.js-网站 运行 获取 tensorflow.js 示例。我基本上是从网站上复制代码并将其集成到我的组件中,但我收到一条错误消息。

由于我是 angular 的新手,所以我不知道如何修复错误。

export class MotionAnalysisComponent implements OnInit{
async run() { 
// We want to predict the column "medv", which represents a median value of 
// a home (in 00s), so we mark it as a label.
const csvUrl = 'https://storage.googleapis.com/tfjs-examples/multivariate-linear-regression/data/boston-housing-train.csv';
const csvDataset = tf.data.csv(
csvUrl, {
  columnConfigs: {
    medv: {
      isLabel: true
    }
  }
});

// Number of features is the number of column names minus one for the label column.

const numOfFeatures = (await csvDataset.columnNames()).length - 1;

// Prepare the Dataset for training.
const flattenedDataset =
  csvDataset
   .map(({xs, ys}) =>
    {
    // Convert xs(features) and ys(labels) from object form (keyed by
    // column name) to array form.
    return {xs:Object.keys(xs), ys:Object.keys(ys)};
  })
.batch(10);

// Define the model.
const model = tf.sequential();
model.add(tf.layers.dense({
  inputShape: [numOfFeatures],
  units: 1
}));
model.compile({
  optimizer: tf.train.sgd(0.000001),
  loss: 'meanSquaredError'
});

// Fit the model using the prepared Dataset
return model.fitDataset(flattenedDataset, {
  epochs: 10,
  callbacks: {
    onEpochEnd: async (epoch, logs) => {
      console.log(epoch + ':' + logs.loss);
    }
  }
});
}
}

我收到以下两条错误消息:

可以通过将 map 参数设置为 any

来避免打字错误

然后您需要强制转换 xsys 以允许类型完成。这里 xsys 只是键值元素的对象。

.map((val: any) => {
    const {xs, ys} = val // can cast xs and ys to appropriate type
    // for instance it can be const {xs, ys} = val as {xs: Object, ys: Object}
     return {xs:Object.keys(xs), ys:Object.keys(ys)};
})

或者也可以通过转换map

的类型-参数来避免
.map((val: {xs: Object, ys: Object}) => {
     return {xs:Object.keys(xs), ys:Object.keys(ys)};
})

要彻底xsys应该分别有数据集的特征类型和标签。

给定boston-housing.csv的数据,类型Features可以如下

interface Features {
  crim: number;
  zn: number;
  inus: number
  ...
}

以及标签类型

interface Features {
  medv: number
}

使用这些类型进行转换,如有必要,前面的代码将在 xs 和 ys 上自动完成 属性

.map((val: any) => {
        const {xs, ys} = val as {xs: Features, ys: Labels}
         return {xs:Object.keys(xs), ys:Object.keys(ys)};
 })
 // or 
.map(((val: {xs: Features, ys: Labels }) => {
        const {xs, ys} = val as {xs: Features, ys: Labels}
         return {xs:Object.keys(xs), ys:Object.keys(ys)};
 })

当然,在这些场景中准确键入特征或标签并没有多大用处,因为人们只对返回数据集的值感兴趣。如果要将此方法用作将 csv 数据集转换为张量批次的通用方法,则留下 xsys 类型 Object 应该是可行的方法。

更进一步,如果创建的数据集的类型与 csv 的字段完全匹配,则可能会为数据集创建 dataType

interface DataType {
    xs: Features;
    ys: Labels;
}    

const csvDataset = tf.data.csv(/* ... */) as unknown as Dataset<DataType>;

问题

问题是您的数据集 Datasets in Tensorflow.js are by default of type tf.data.Dataset<TensorContainer>, which means that TypeScript assumes an object of TensorContainer

解决方案

为了帮助 TypeScript,您可以在创建 DataSet 时为其指定特定类型。当您正在读取内部具有多个属性的对象时,您可以扩展接口 TensorContainerObject.

代码示例

import { TensorContainerObject } from '@tensorflow/tfjs';
import { Dataset } from '@tensorflow/tfjs-data';

interface DataType extends TensorContainerObject {
    xs: tf.Tensor;
    ys: tf.Tensor;
}

const csvDataset = tf.data.csv(/* ... */) as any as Dataset<DataType>;
csvDataset.map(({xs, ys}) => {
    // ...
});

不幸的是,由于 Tensorflow.js 对其数据集类型非常自以为是(因为联合用于默认 TensorContainer),您必须先使用 any 强制转换将其转换为实际的 Dataset<DataType> 界面。

但是在转换之后,所有在 DataSet 上工作的函数,如 map 都会自动知道正确的类型。除了使用上面的 tf.Tensor,您甚至可以使用 tf.Tensor1D 这样的类型来更加具体。

替代解决方案:让错误消失

正如其他答案中所述:如果您不关心类型和 TypeScript,只想让错误消失,您可以将任何有问题的变量转换为 any.

代码示例

csvDataset.map(({xs, ys}: any) => {
    // ...
});

请记住,这将禁用对变量的任何类型检查。