tensorflow源码解析之framework-shape_inference
目录
- 什么是形状推断
- InferenceContext
- 关系图
- 涉及的文件
- 迭代记录
1. 什么是形状推断
前面我们讲到op的时候,提到了操作的注册器OpRegistry,并且提到,其中注册的数据是一个结构OpRegistrationData,这个结构中除了OpDef之外,还包含了一个OpShapeInferenceFn,这个数据是做什么用的呢?
我们知道,op只是定义了操作的输入输出和参数,但并没有定义操作具体的输入形状,举个例子,MatMul操作,代表矩阵乘法,这只是一个抽象的表示,没有具体说,这个矩阵乘法代表的是[2,3]x[3,4]=[2,4],还是[100,200]x[200,300]=[100,300]。所以在实际应用中,在得到输入之前,输出的真实形状是无法预知的,但在得到输入之后,我们必须能够根据输入的形状,以及当前op的作用,判断输出的具体形状,才能给它申请对应大小的内存空间。所以,我们需要为每一个操作,配备一个形状推断的函数,这就是形状推断的由来。
2. InferenceContext
前面提到了OpShapeInferenceFn,我们来看一下它的详细定义:
typedef std::function<Status(shape_inference::InferenceContext* c)> OpShapeInferenceFn;
可见,OpShapeInferenceFn是一个接收InferenceContext参数的函数,TF为所有op的形状推断函数,准备了这样一个统一的接口。所有跟形状推断相关的数据和功能函数,都放在InferenceContext这个类的内部。回想一下前面讲过的OpKernelContext,其实它们的功能很像。OpKernelContext是作为OpKernel的核心API Compute函数的参数,所有计算相关的参数都会包含在这个对象中。InferenceContext也是一样,我们把所有跟形状推断相关的数据和功能函数封装在一个InferenceContext对象中,然后把这个对象传递给OpShapeInferenceFn,就可以实现形状推断。这种设计实现了数据部分和实现逻辑的解耦。
在具体看ShapeInference类之前,我们先要看一些辅助类:
class Dimension {
private:
//...
const int64 value_;
};
class DimensionHandle {
private:
//...
const Dimension* ptr_ = nullptr;
};
class Shape {
//...
private:
const int32 rank_;
const std::vector<DimensionHandle> dims_;
};
class ShapeHandle {
//...
private:
const Shape* ptr = nullptr;
};
class DimensionOrConstant {
public:
//...
DimensionHandle dim;
int64 val;
};
class ShapeAndType {
ShapeHandle shape;
DataType dtype = DT_INVALID;
};
这几个类都比较简单。在下面用到时能够认得就好了。
下面我们看下InferenceContext这个类:
class InferenceContext {
public:
InferenceContext(int graph_def_version, const NodeDef* node_def, const OpDef& op_def, const std::vector<ShapeHandle>& input_shapes, const std::vector<const Tensor*>& input_tensors, const std::vector<ShapeHandle>& input_tensors_as_shapes, std::vector<std::unique_ptr<std::vector<ShapeAndType>>> input_handle_shapes_and_types);//构造函数
Status Run(const std::function<Status(shape_inference::InferenceContext* c)>& fn);//运行一个以this为参数的函数,没错,这里运行的就是OpShapeInferenceFn
bool MergeInput(int idx, ShapeHandle shape);
bool RelaxInput(int idx, ShapeHandle shape);
private:
ShapeManager shape_manager_;
std::vector<ShapeHandle> inputs_;
std::vector<const Tensor*> input_tensors_;
std::vector<bool> requested_input_tensor_;
std::vector<ShapeHandle> outputs_;
std::vector<ShapeHandle> input_tensors_as_shapes_;
std::vector<bool> requested_input_tensor_as_partial_shape_;
std::vector<std::unique_ptr<std::vector<ShapeAndType>>> input_handle_shapes_and_types_;
std::vector<std::unique_ptr<std::vector<ShapeAndType>>> output_handle_shapes_and_types_;
const int graph_def_version_;
const NodeDef& node_def_;
NameRangeMap input_name_map_;
NameRangeMap output_name_map_;
Status construction_status_;
};
前面已经介绍过了这个类的作用,是作为真正的形状推断函数的参数,为形状推断提供足够的数据和功能函数支持,那么这个类的成员就比较清晰了,私有数据成员为形状推断提供数据支持,而公有API,为形状推断提供公用的功能函数,比如上面提到的MergeInput和RelaxOutput,下面我们重点介绍下这两个函数的功能:
MergeInput函数是将输入索引idx处的输入与shape合并,具体的合并规则是:
- 如果ShapeHandles是一样的,或者shape是未知的,那么输入维度不变。否则,如果输入维度是未知的,那么输出是shape;
- 如果两个形状都是已知的,它们必须拥有相同的rank;
- 对于任意一个维度,如果在两个形状中这个维度都已知,那么它们必须相等;
- 如果一个形状在任意维度上的信息都多于另一个形状,那么拥有更多信息的形状将被返回。否则,一个新的形状将被构建并返回,这个新的形状综合了输入的两个形状的信息;
- 比如,合并[2,?]和[?,2]将得到[2,2];
- 比如,[2,2]不能被合并到[1,2]
如果说MergeInput函数对输入形状是“收缩”的,那么“RelaxInput”函数对输入形状就是“扩张”的,它倾向于让形状变的更模糊,具体的规则是:
- 如果ShapeHandles是一样的,那么对应的shape将会被返回;
- 如果任一个ShapeHandle是未知的,那么一个未知的ShapeHandle将会被返回;
- 如果两个形状的rank已知,但不同,那么一个未知ShapeHandle将会被返回;
- 对于任一维度,如果任一shape是未知的,那么对应的输出维度也是未知的;
- 对于任一维度,如果两个shape对应的维度位置都是已知的,但并不相同,那么对应的输出维度也是未知的;
- 如果两个shape的rank和对应维度大小都一样,那么这个形状将会被返回;
- 例如,[2,?]和[?,2]会得到[?,?];
- 例如,[2,2]和[3,2]会得到[?,2];
- 例如,[2,2]和[1,2,3]会得到?
3. 关系图
OpShapeInferenceFn-.使用参数.->InferenceContext
OpKernel::Compute-.使用参数.->OpKernelContext
4. 涉及的文件
- shape_inference
5. 迭代记录
- v1.0 2018-08-29 文档创建
- v2.0 2018-09-10 文档重构
tensorflow源码解析之framework-shape_inference的更多相关文章
- tensorflow源码解析之framework拾遗
把framework中剩余的内容,按照文件名进行了简单解析.时间原因写的很仓促,算是占个坑,后面有了新的理解再来补充. allocation_description.proto 一个对单次内存分配结果 ...
- tensorflow源码解析系列文章索引
文章索引 framework解析 resource allocator tensor op node kernel graph device function shape_inference 拾遗 c ...
- Tensorflow源码解析1 -- 内核架构和源码结构
1 主流深度学习框架对比 当今的软件开发基本都是分层化和模块化的,应用层开发会基于框架层.比如开发Linux Driver会基于Linux kernel,开发Android app会基于Android ...
- tensorflow源码解析之common_runtime-executor-上
目录 核心概念 executor.h Executor NewLocalExecutor ExecutorBarrier executor.cc structs GraphView ExecutorI ...
- tensorflow源码解析之framework-allocator
目录 什么是allocator 内存分配器的管理 内存分配追踪 其它结构 关系图 涉及的文件 迭代记录 1. 什么是allocator Allocator是所有内存分配器的基类,它定义了内存分配器需要 ...
- tensorflow源码解析之common_runtime-executor-下
目录 核心概念 executor.h Executor NewLocalExecutor ExecutorBarrier executor.cc structs GraphView ExecutorI ...
- tensorflow源码解析之framework-op
目录 什么是op op_def定义 op注册 op构建与注册辅助结构 op重写 关系图 涉及的文件 迭代记录 1. 什么是op op和kernel是TF框架中最重要的两个概念,如果一定要做一个类比的话 ...
- tensorflow源码解析之distributed_runtime
本篇主要介绍TF的分布式运行时的基本概念.为了对TF的分布式运行机制有一个大致的了解,我们先结合/tensorflow/core/protobuf中的文件给出对TF分布式集群的初步理解,然后介绍/te ...
- tensorflow源码解析之common_runtime拾遗
把common_runtime中剩余的内容,按照文件名排序进行了简单的解析,时间原因写的很仓促,算是占个坑,后续有了新的理解再来补充. allocator_retry 有时候内存分配不可能一次完成,为 ...
- Tensorflow源码解析2 -- 前后端连接的桥梁 - Session
Session概述 1. Session是TensorFlow前后端连接的桥梁.用户利用session使得client能够与master的执行引擎建立连接,并通过session.run()来触发一次计 ...
随机推荐
- 【linux命令】wget
感谢作者:八雲苗 链接:https://www.jianshu.com/p/1c3847fa7e45 wget官方文档:wget wget是一个使用HTTP,HTTPS,FTP和FTPS协议来下载文件 ...
- Xcode 插件推荐
1. Alcatraz(建议安装,以下插件都可以在Alcatraz下载安装) 使用Alcatraz来下载管理Xcode插件, 2.下载安装注释插件VVDocumenter-Xcode. 3.使用代码对 ...
- Ext原码学习之Ext.js
1 // JavaScript Document 2 //定义全局Ext变量 3 var Ext = Ext ||{}; 4 Ext._startTime = new Date().getTime() ...
- 稳住,传输层里的TCP与UDP协议
传输层协议 1.TCP协议介绍及报文格式 2.TCP三次握手三次挥手 3.UDP协议介绍 1.传输层有两个协议:TCP(传输控制协议) UDP(用户数据协议) . TCP是面向连接的,可靠的进程到进 ...
- 4G无线全网通太阳能水文设备电源监测系统BMS110
钡铼技术BMS110模块可实现4路电池电压.2路模拟量.2路数字量和1路温度测量,支持Modbus RTU over TCP和MQTT通讯协议,DC9-36V电源供电.BMS110可应用于各种有使用蓄 ...
- PHP程序员可以这样准备找工作
你好,是我琉忆.PHP程序员面试笔试图书系列作者. 今天就跟大家聊聊作为一个PHP程序员,每年的跳槽季都应该怎么准备一番. 其实普遍的跳槽季总的就有2个. 分别是新年后的3-4月,还有9-10月份. ...
- PHP实习生面试准备的建议
你好,是我琉忆.PHP程序员面试笔试图书系列作者. 今天就跟大家聊聊作为一个PHP程序员,每年的跳槽季都应该怎么准备一番. 其实普遍的跳槽季总的就有2个. 分别是新年后的3-4月,还有9-10月份. ...
- windows设备相关位图与设备无关位图
windows支持两种位图格式,DDB(device-dependent bitmap),DIB(device-independent bitmap).设备相关位图用于windows显示系统中,其图像 ...
- suse 12 二进制部署 Kubernetets 1.19.7 - 第10章 - 部署kube-proxy组件
文章目录 1.10.部署kube-proxy 1.10.0.创建kube-proxy证书 1.10.1.生成kube-proxy证书和秘钥 1.10.2.创建kube-proxy的kubeconfig ...
- 阿里云人脸1:N搜索开源版-Java版(文末附开源地址)
一.人脸检测相关概念 人脸检测(Face Detection)是检测出图像中人脸所在位置的一项技术,是人脸智能分析应用的核心组成部分,也是最基础的部分.人脸检测方法现在多种多样,常用的技术或工具大 ...