TensorflowJS之Tensor

可以将Tensor当作一个数据结构,里面的数据可以是一个数,也可以是1维数组,2维的矩阵,以及更高维的矩阵。

CPU GPU模型

TensorflowJS支持CPU和GPU两种后端。虽然输入的数据都是Tensor,但是对数据的处理有较大的差异。如果是CPU,数据的处理相对简单,如下图所示:

TensorflowJS之Tensor_第1张图片
如果是GPU,则需要将Tensor里面的数据上传到一个WebGL Texture里面。然后在GPU处理结束后,将数据写回这个输出的Tensor:
TensorflowJS之Tensor_第2张图片

DataStorage

无论是CPU方式还是GPU方式,数据的读写都要经过DataStorage。DataStorage的核心是一个WeakMap的数据成员(所谓WeakMap,指的是当一个成员没有被引用的时候,它就会成为GC的目标):

private data = new WeakMap();

WeakMap提供了数据的get/set。里面的成员是。注意DataId必须是Object。T则是任意。事实上,如果跟踪下DataStorage.set的调用stack,会发现DataId其实是Tensor.dataId。T其实是Tensor的Shape以及DataType。

DataStorage.set (tf-core.js:formatted:4387)
MathBackendWebGL.register (tf-core.js:formatted:11056)
Engine.registerTensor (tf-core.js:formatted:2435)
Tensor (tf-core.js:formatted:1022)
Tensor.make (tf-core.js:formatted:1028)

以及一个DataMover成员(TODO:这种方式定义成员的参考文献):

constructor(private dataMover: DataMover) {}

DataMover虽然只有一个简单的接口,但是其逻辑却比较复杂:

export interface DataMover {
  /**
   * To be called by backends whenever they see a dataId that they don't own.
   * Upon calling this method, the mover will fetch the tensor from another
   * backend and register it with the current active backend.
   */
  moveData(dataId: DataId): void;
}

注释的意思是,如果DataStorage在get一个DataId(其实就是一个Tensor)的时候不存在,则会从另一个“正确的Backend”(TODO:正确的Backend是什么时候指定的?作者目前尚没有碰到这个场景)获取:

readSync(dataId: DataId): DataValues {
  // Route the read to the correct backend.
  const info = this.tensorInfo.get(dataId);
  return info.backend.readSync(dataId);
}

你可能感兴趣的:(TensorFlowJS)