分享好友 人工智能首页 频道列表

TensorFlow源码分析——Tensor与Eigen tensorflow 开源

tensorflow教程  2023-02-09 19:196930

TensorFlow底层操作的数据结构是Tensor(张量),可以表示多维的数据,其实现在core/framework/tensor.h中,对于tensor的理解主要分两大块:

1.Tensor的组成成分

2.Tensor是如何进行数学运算的(TensorFlow本质就是处理大量训练数据集,在底层要实现深度学习常用的算法,自然涉及到一些数学运算,例如:Tensor相加、相减,softmax,reduction等操作)

 

Tensor的组成:

Tensor的组成可以分成3部分:DataType、TensorShape、TensorBuf. 即数据类型、张量的形状和存储数据的内存.

DataType:Tensor数据的类型,float、double、int等

TensorShape: Tensor的形状. 这里要表示维度需存储两种元素,第一种是维数、第二种是每个维度的大小. 例如:一个矩阵的大小为3×4,那么其维数为2,第一个维度大小是3,第二个是4. 

TensorBuf:就是存储数据的内存地址,比如一个Tensor是3×4的矩阵,并且类型时float,那么其TensorBuf就float*类型,并且长度是12,在实现上是基于模板实现的.

 

Tensor的运算:

Tensor的运算主要由kernels完成,每个kernel都完成不同的运算。其中CPU版本的kernel大部分都使用Eigen库来实现,GPU版本的kernel少部分使用Eigen,大部分使用cuda编程实现。

Eigen unsupported模块提供了同样叫Tensor的类,主要就是能完成各种复杂的数学计算,并且是并行实现的(主要使用线程池或cuda),效率很高. 其API文档可参考 https://github.com/PX4/eigen/blob/master/unsupported/Eigen/CXX11/src/Tensor/README.md. TensorFlow使用Eigen进行计算时,首先要将其自己实现的Tensor类的对象转换成Eigen支持的Tensor对象. 可以再core/framework/tensor_types.h下面看到Eigen支持的各种数据类型,主要是TensorMap类. 并进行了重命名,其源码如下所示:

struct TTypes {
  // Rank-<NDIMS> tensor of scalar type T.
  typedef Eigen::TensorMap<Eigen::Tensor<T, NDIMS, Eigen::RowMajor, IndexType>,
                           Eigen::Aligned>
      Tensor;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, NDIMS, Eigen::RowMajor, IndexType>, Eigen::Aligned>
      ConstTensor;

  // Unaligned Rank-<NDIMS> tensor of scalar type T.
  typedef Eigen::TensorMap<Eigen::Tensor<T, NDIMS, Eigen::RowMajor, IndexType> >
      UnalignedTensor;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, NDIMS, Eigen::RowMajor, IndexType> >
      UnalignedConstTensor;

  typedef Eigen::TensorMap<Eigen::Tensor<T, NDIMS, Eigen::RowMajor, int>,
                           Eigen::Aligned>
      Tensor32Bit;

  // Scalar tensor (implemented as a rank-0 tensor) of scalar type T.
  typedef Eigen::TensorMap<
      Eigen::TensorFixedSize<T, Eigen::Sizes<>, Eigen::RowMajor, IndexType>,
      Eigen::Aligned>
      Scalar;
  typedef Eigen::TensorMap<Eigen::TensorFixedSize<const T, Eigen::Sizes<>,
                                                  Eigen::RowMajor, IndexType>,
                           Eigen::Aligned>
      ConstScalar;

  // Unaligned Scalar tensor of scalar type T.
  typedef Eigen::TensorMap<
      Eigen::TensorFixedSize<T, Eigen::Sizes<>, Eigen::RowMajor, IndexType> >
      UnalignedScalar;
  typedef Eigen::TensorMap<Eigen::TensorFixedSize<const T, Eigen::Sizes<>,
                                                  Eigen::RowMajor, IndexType> >
      UnalignedConstScalar;

  // Rank-1 tensor (vector) of scalar type T.
  typedef Eigen::TensorMap<Eigen::Tensor<T, 1, Eigen::RowMajor, IndexType>,
                           Eigen::Aligned>
      Flat;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, 1, Eigen::RowMajor, IndexType>, Eigen::Aligned>
      ConstFlat;
  typedef Eigen::TensorMap<Eigen::Tensor<T, 1, Eigen::RowMajor, IndexType>,
                           Eigen::Aligned>
      Vec;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, 1, Eigen::RowMajor, IndexType>, Eigen::Aligned>
      ConstVec;

  // Unaligned Rank-1 tensor (vector) of scalar type T.
  typedef Eigen::TensorMap<Eigen::Tensor<T, 1, Eigen::RowMajor, IndexType> >
      UnalignedFlat;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, 1, Eigen::RowMajor, IndexType> >
      UnalignedConstFlat;
  typedef Eigen::TensorMap<Eigen::Tensor<T, 1, Eigen::RowMajor, IndexType> >
      UnalignedVec;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, 1, Eigen::RowMajor, IndexType> >
      UnalignedConstVec;

  // Rank-2 tensor (matrix) of scalar type T.
  typedef Eigen::TensorMap<Eigen::Tensor<T, 2, Eigen::RowMajor, IndexType>,
                           Eigen::Aligned>
      Matrix;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, 2, Eigen::RowMajor, IndexType>, Eigen::Aligned>
      ConstMatrix;

  // Unaligned Rank-2 tensor (matrix) of scalar type T.
  typedef Eigen::TensorMap<Eigen::Tensor<T, 2, Eigen::RowMajor, IndexType> >
      UnalignedMatrix;
  typedef Eigen::TensorMap<
      Eigen::Tensor<const T, 2, Eigen::RowMajor, IndexType> >
      UnalignedConstMatrix;
};

 

在tensor.h可以看到一些转换函数,比如:flat(拉伸)、vec(向量化)、matrix(矩阵化)等。部分源码如下所示:

template <typename T>
  typename TTypes<T>::Vec vec() {
    return tensor<T, 1>();
  }

  template <typename T>
  typename TTypes<T>::Matrix matrix() {
    return tensor<T, 2>();
  }

  template <typename T, size_t NDIMS>
  typename TTypes<T, NDIMS>::Tensor tensor();

template <typename T>
  typename TTypes<T>::Flat flat() {
    return shaped<T, 1>({NumElements()});
  }

调用这些函数就能将tensor转换成Eigen支持的类型,就可以直接使用Eigen提供的API进行计算. 像矩阵乘、二元操作、一元操作等都是通过调用Eigen实现的. 所以只要了解了Eigen的基本数据类型,就能轻松看懂tensor这部分源码. 了解了Eigen操作基本类型的API就能看懂kernels的代码. 

注:这里为什么不直接用Eigen::Tensor?原因是Eigen::Tensor只提供了最基本的数学运算,而有时候我们在运算的时候要进行不同程度的预处理,可以参考源码中的cwise_ops_common.h中的

BinaryOp class以及reduction_ops_common.h中的ReductionOp class,这两个kernels都在运算前进行了预处理. 如果没有把Eigen::Tensor包装成我们自己的Tensor,我们就需要调用大量的Eigen的API,代码更难理解,这样包装之后,我们就只需要调用Eigen计算的一些API,而不用考虑获取一些属性. 另一个原因就是Tensor有一些属性和方法,用Eigen::Tensor的API并不好实现,并且Eigen的Tensor在声明的时候,维度是模板参数,因此只能为常量,这样就带来很多不便之处.  总之多包装一层代码层次感就更强,阅读起来就更容易一些.

查看更多关于【tensorflow教程】的文章

展开全文
相关推荐
反对 0
举报 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
tensorflow2.0——LSTM,GRU(Sequential层版)
前面都是写的cell版本的GRU和LSTM,比较底层,便于理解原理。下面的Sequential版不用自定义state参数的形状,使用更简便: import tensorflow as tfimport osos.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'assert tf.__version__.startswith('2.')# 设置相关底层

0评论2023-02-10907

TensorFlow基础笔记(7) 图像风格化效果与性能优化进展
参考 http://hacker.duanshishi.com/?p=1693http://blog.csdn.net/hungryof/article/details/53981959http://blog.csdn.net/hungryof/article/details/61195783http://blog.csdn.net/wyl1987527/article/details/70245214https://www.ctolib.com/AdaIN-style.

0评论2023-02-09559

Tensorflow报错总结 TensorFlow文档
输入不对应报错内容:WARNING:tensorflow:Model was constructed with shape (None, 79) for input Tensor("genres:0", shape=(None, 79), dtype=float32), but it was called on an input with incompatible shape (128, 5).定义模型的输入和训练时候传入的in

0评论2023-02-09636

深度学习框架之TensorFlow的概念及安装(ubuntu下基于pip的安装,IDE为Pycharm)
2015年11月9日,Google发布人工智能系统TensorFlow并宣布开源。TensorFlow 是使用数据流图进行数值计算的开源软件库。也就是说,TensorFlow 使用图(graph)来表示计算任务。图中的节点表示数学运算,边表示运算之间用来交流的多维数组(也就是tensor,张量)

0评论2023-02-09857

tensorflow scope的作用
  我们在使用tensorflow的时候,当你想复用一个函数的模块,调试时候回提示你变量已经出现,提示你是否重用。那我们当然是不重用的,因为每一个变量都是我们需要的。  要体现不同,就在不同的变量中使用name scope限定,那么其中的重复名字就不会出现问题

0评论2023-02-09697

TensorFlow——LinearRegression简单模型代码
代码函数详解tf.random.truncated_normal()函数tf.truncated_normal函数随机生成正态分布的数据,生成的数据是截断的正态分布,截断的标准是2倍的stddev。zip()函数zip() 函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些

0评论2023-02-09381

tensorFlow2.1下的tf.data.Dataset.from_tensor_slices()的用法
一、总结一句话总结:将输入的张量的第一个维度看做样本的个数,沿其第一个维度将tensor切片,得到的每个切片是一个样本数据。实现了输入张量的自动切片。# from_tensor_slices 为输入张量的每一行创建一个带有单独元素的数据集ts = tf.constant([[1, 2], [3,

0评论2023-02-09789

TensorFlow基础笔记(14) 网络模型的保存与恢复_mnist数据实例
http://blog.csdn.net/huachao1001/article/details/78502910http://blog.csdn.net/u014432647/article/details/75276718https://zhuanlan.zhihu.com/p/32887066#coding:utf-8#http://blog.csdn.net/zhuiqiuk/article/details/53376283#http://blog.csdn.net/

0评论2023-02-091030

更多推荐