当前位置: 首页 > 编程日记 > 正文

Tensorflow源码解析5 -- 图的边 - Tensor

1 概述

前文两篇文章分别讲解了TensorFlow核心对象Graph,和Graph的节点Operation。Graph另外一大成员,即为其边Tensor。边用来表示计算的数据,它经过上游节点计算后得到,然后传递给下游节点进行运算。本文讲解Graph的边Tensor,以及TensorFlow中的变量。

2 前端边Tensor数据结构

Tensor作为Graph的边,使得节点Operation之间建立了连接。上游源节点Operation经过计算得到数据Tensor,然后传递给下游目标节点,是一个典型的生产者-消费者关系。下面来看Tensor的数据结构

@tf_export("Tensor")
class Tensor(_TensorLike):def __init__(self, op, value_index, dtype):# 源节点,tensor的生产者,会计算得到tensorself._op = op# tensor在源节点的输出边集合中的索引。源节点可能会有多条输出边# 利用op和value_index即可唯一确定tensor。self._value_index = value_index# tensor中保存的数据的数据类型self._dtype = dtypes.as_dtype(dtype)# tensor的shape,可以得到张量的rank,维度等信息self._shape_val = tensor_shape.unknown_shape()# 目标节点列表,tensor的消费者,会使用该tensor来进行计算self._consumers = []#self._handle_data = Noneself._id = uid()

Tensor中主要包含两类信息,一个是Graph结构信息,如边的源节点和目标节点。另一个则是它所保存的数据信息,例如数据类型,shape等。

3 后端边Edge数据结构

后端中的Graph主要成员也是节点node和边edge。节点node为计算算子Operation,边Edge为算子所需要的数据,或者代表节点间的依赖关系。这一点和Python中的定义相似。边Edge的持有它的源节点和目标节点的指针,从而将两个节点连接起来。下面看Edge类的定义。

class Edge {private:Edge() {}friend class EdgeSetTest;friend class Graph;// 源节点, 边的数据就来源于源节点的计算。源节点是边的生产者Node* src_;// 目标节点,边的数据提供给目标节点进行计算。目标节点是边的消费者Node* dst_;// 边id,也就是边的标识符int id_;// 表示当前边为源节点的第src_output_条边。源节点可能会有多条输出边int src_output_;// 表示当前边为目标节点的第dst_input_条边。目标节点可能会有多条输入边。int dst_input_;
};

Edge既可以承载tensor数据,提供给节点Operation进行运算,也可以用来表示节点之间有依赖关系。对于表示节点依赖的边,其src_output_, dst_input_均为-1,此时边不承载任何数据。

4 常量constant

TensorFlow的常量constant,最终包装成了一个Tensor。通过tf.constant(10),返回一个Tensor对象。

@tf_export("constant")
def constant(value, dtype=None, shape=None, name="Const", verify_shape=False):# 算子注册到默认Graph中g = ops.get_default_graph()# 对常量值value的处理tensor_value = attr_value_pb2.AttrValue()tensor_value.tensor.CopyFrom(tensor_util.make_tensor_proto(value, dtype=dtype, shape=shape, verify_shape=verify_shape))# 对常量值的类型dtype进行处理dtype_value = attr_value_pb2.AttrValue(type=tensor_value.tensor.dtype)# 构造并注册类型为“Const”的算子到Graph中,从算子的outputs中取出输出的tensor。const_tensor = g.create_op("Const", [], [dtype_value.type],attrs={"value": tensor_value,"dtype": dtype_value},name=name).outputs[0]return const_tensor

tf.constant的过程为

  1. 获取默认graph
  2. 对常量值value和常量值的类型dtype进行处理
  3. 构造并注册类型为“Const”的算子到默认graph中,从算子的outputs中取出输出的tensor。

此时只是图的构造过程,tensor并未承载数据,仅表示Operation输出的一个符号句柄。经过tensor.eval()或session.run()后,才会启动graph的执行,并得到数据。

5 变量Variable

Variable构造器

通过tf.Variable()构造一个变量,代码如下,我们仅分析入参。

@tf_export("Variable")
class Variable(object):def __init__(self,initial_value=None,trainable=True,collections=None,validate_shape=True,caching_device=None,name=None,variable_def=None,dtype=None,expected_shape=None,import_scope=None,constraint=None):
# initial_value: 初始值,为一个tensor,或者可以被包装为tensor的值
# trainable:是否可以训练,如果为false,则训练时不会改变
# collections:变量要加入哪个集合中,有全局变量集合、本地变量集合、可训练变量集合等。默认加入全局变量集合中
# dtype:变量的类型

主要的入参代码中已经给出了注释。Variable可以接受一个tensor或者可以被包装为tensor的值,来作为初始值。事实上,Variable可以看做是Tensor的包装器,它重载了Tensor的几乎所有操作,是对Tensor的进一步封装。

Variable初始化

变量只有初始化后才能使用,初始化时将initial_value初始值赋予Variable内部持有的Tensor。通过运行变量的初始化器可以对变量进行初始化,也可以执行全局初始化器。如下

y = tf.Variable([5.3])with tf.Session() as sess:initialization = tf.global_variables_initializer()print sess.run(y)

Variable集合

Variable被划分到不同的集合中,方便后续操作。常见的集合有

  1. 全局变量:全局变量可以在不同进程中共享,可运用在分布式环境中。变量默认会加入到全局变量集合中。通过tf.global_variables()可以查询全局变量集合。其op标示为GraphKeys.GLOBAL_VARIABLES

    @tf_export("global_variables")
    def global_variables(scope=None):return ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES, scope)
  2. 本地变量:运行在进程内的变量,不能跨进程共享。通常用来保存临时变量,如训练迭代次数epoches。通过tf.local_variables()可以查询本地变量集合。其op标示为GraphKeys.LOCAL_VARIABLES

    @tf_export("local_variables")
    def local_variables(scope=None):return ops.get_collection(ops.GraphKeys.LOCAL_VARIABLES, scope)
  3. 可训练变量:一般模型参数会放到可训练变量集合中,训练时,做这些变量会得到改变。不在这个集合中的变量则不会得到改变。默认会放到此集合中。通过tf.trainable_variables()可以查询。其op标示为GraphKeys.TRAINABLE_VARIABLES

    @tf_export("trainable_variables")
    def trainable_variables(scope=None):return ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES, scope)

其他集合还有model_variables,moving_average_variables。

相关文章:

物联网成网络安全防护新重点!

在昨天的 2019 北京网络安全大会上,工信部负责人表示,我国面向 5G 和车联网将建设网安防护体系,提升监测预警和应急响应能力。其中物联网设备已成为网安防护新重点。为什么工信部会这么重视物联网?物联网开发者的现状又是如何呢&a…

【分享】Java的几个重要词语

Java 是一种解释型语言,由SUN公司开发,基本上属于一个完全面向对象的语言,并且语言的设计仍然以简捷为重点。初学Java肯定会被一些名词给弄晕了,现在集中几个解释一下下。1、JVMJVM是Java Virtual Machine(Java虚拟机)的缩写&…

64位Ubuntu上编译32位程序操作步骤

1. 确认主机为64位架构的内核,应该输出为adm64,执行:$ dpkg --print-architecture2. 确认打开了多架构支持功能,应该输出为i386,执行:$ dpkg --print-foreign-architectures如果没有,…

分布式事务中间件 Fescar—RM 模块源码解读

2019独角兽企业重金招聘Python工程师标准>>> 前言 在SOA、微服务架构流行的年代,许多复杂业务上需要支持多资源占用场景,而在分布式系统中因为某个资源不足而导致其它资源占用回滚的系统设计一直是个难点。我所在的团队也遇到了这个问题&…

二维码检测哪家强?五大开源库测评比较

作者 | 周强来源 | 我爱计算机视觉(ID:aicvml)二维码已经进入人们的日常生活中,尤其是日本Denso Wave公司1994年发明的QR码,由于其易于检测、写入信息量大、提供强大的纠错机制,应用最为广泛,可…

linux 内核 出错-HP 方案

2019独角兽企业重金招聘Python工程师标准>>> SUPPORT COMMUNICATION - CUSTOMER ADVISORY Document ID: c03456595 Version: 1 Advisory: Red Hat Enterprise Linux 6 - "P4-Clockmod: Warning: EST-Capable CPU Detected" Messages Logged in /var/log…

Windows7 64bit VS2013 Caffe test MNIST操作步骤

在http://blog.csdn.net/fengbingchun/article/details/49849225中用Caffe对MNIST数据库进行训练,产生了model。下面介绍下如何将产生的model应用在实际的数字图像识别中。用到的测试图像与http://blog.csdn.net/fengbingchun/article/details/50573841中相同&#…

记住这35个英文单词,你就可以在RPA界混了!

无论是想玩转RPA(机器人流程自动化),还是有意了解、进入这项行业,只有先了解该领域的专有名词(行业术语),才能为之后的活动提供更多的可能。UiBot现为您编译整理了这份机器人流程自动化术语表&a…

福利 | 送你一张通往「2019 AI开发者大会」的门票

2019 AI开发者大会(AI ProCon 2019)是由中国IT社区CSDN主办的AI技术与产业年度盛会。多年经验淬炼,如今蓄势待发:2019年9月6-7日,大会将有近百位中美顶尖AI专家、知名企业代表以及千余名AI开发者齐聚北京,进行技术解读和产业论证。…

收缩日志文件夹

-- MSSQL2005 USE mastergo DECLARE dbname sysname;SET dbnameBSV100;-- 清空日志EXEC (DUMP TRANSACTION [dbname] WITH NO_LOG); -- 截断事务日志:EXEC (BACKUP LOG [dbname] WITH NO_LOG); -- 收缩数据库文件(如果不压缩,数据库的文件不会减小EXEC (DBCC SHR…

腾讯AI开源框架Angel 3.0重磅发布:超50万行代码,支持3种算法,打造全栈机器学习平台...

出品 | AI科技大本营(ID:rgznai100)【导语】2019年8月22日,腾讯首个AI开源项目Angel正式发布3.0版本。Angel 3.0尝试打造一个全栈的机器学习平台,功能特性涵盖了机器学习的各个阶段:特征工程,模…

路印协议受邀参加澳洲新南威尔士政府孵化器Haymarket HQ分享论坛

2019年2月15日,澳洲新南威尔士政府孵化器Haymarket HQ和Next Genius 社区联合举办了区块链解决方案分享论坛,路印协议CMO周杰受邀介绍当前交易所现状和路印协议的去中心化解决方案。参与此次论坛的还有区块链开发人员、企业家和去中心化技术爱好者&#…

一步一步指引你在Windows7上配置编译使用Caffe(https://github.com/fengbingchun/Caffe_Test)

之前写过几篇关于Caffe源码在Windows764位上配置编译及使用过程,只是没有把整个工程放到网上,最近把整个工程整理清理了下,把它放到了GitHub上。下面对这个工程的使用作几点说明:1. 整个工程Caffe在Windows7 64位VS2013下编译…

演示:思科IPS在线模式下Inline Interface Mode的响应行为(区别各个防御行为)

演示:思科IPS在线模式下Inline Interface Mode的响应行为演示目标:科IPS在线模式下InlineInterface Mode的响应行为。演示环境:仍然使用图5.16所示的网络环境。演示背景:在VLAN3的主机192.168.4.2上发起对主机192.168.4.1的漏洞扫…

【笔记】重学前端-winter

本文为:winter 发布在极客时间 【重学前端】系列课程的的笔记和总结支持正版哦: https://time.geekbang.org/col... 导语 如果深入进去了解,你会发现,表面上看他们可能是一时忘记了,或者之前没注意但实际上是他们对于前端的知识体…

如何用知识图谱挖掘商业数据背后的宝藏?

这是一个商业时代,一个数据为王的时代,也是一个 AI 迎来黄金发展期的时代。据史料记载,商业在商朝已初具规模。斗转星移,时光流转,到 2019 年,商业形式已发生翻天覆地的变化,但是商业的本质——…

通过define _CRTDBG_MAP_ALLOC宏来检测windows上的code是否有内存泄露

VS中自带了内存泄露检测工具&#xff0c;若要启用内存泄露检测&#xff0c;则在程序中包括以下语句&#xff1a; #define _CRTDBG_MAP_ALLOC #include <crtdbg.h> 它们的先后顺序不能改变。通过包括 crtdbg.h&#xff0c;将malloc和free函数映射到其”Debug”版本_malloc…

java.sql.SQLException: Data truncation: Truncated incorrect DOUBLE value

mysql 报这个异常&#xff1a;java.sql.SQLException: Data truncation: Truncated incorrect DOUBLE value update 表名 set col1 ? and col2 ? where id ? 改为&#xff1a; update 表名 set col1 ? , col2 ? where id ? 用逗号隔开

在Ubuntu14.04 64位上编译CMake源码操作步骤

在Ubuntu上通过apt-get install安装CMake并不是最新版的&#xff0c;这里记录下在Ubuntu上通过源码安装CMake的操作步骤&#xff1a;1. 卸载旧版CMake&#xff0c;执行以下命令&#xff1a;apt-get autoremove cmake如果卸载不掉&#xff0c;则通过执行以下命令删除&…

一份贪心算法区间调度问题解法攻略,拿走不谢

作者 | labuladong来源 | labuladong&#xff08;ID:labuladong&#xff09;【导读】什么是贪心算法呢&#xff1f;贪心算法可以认为是动态规划算法的一个特例&#xff0c;相比动态规划&#xff0c;使用贪心算法需要满足更多的条件&#xff08;贪心选择性质&#xff09;&#x…

css:z-index

针对position: absolute;解决position:relative;z-index固定定位层级显示问题转载于:https://blog.51cto.com/13507333/2352775

折半查找函数(from 《The C Programming Language》)

该函数用于判定已排序的数组array中是否存在某个特定的值value。这里假定数组元素以升序排列&#xff0c;如果数组array中包含value&#xff0c;则函数返回value在array中的位置&#xff08;介于0~n-1之间的一个整数&#xff09;&#xff1b;否则&#xff0c;该函数返回-1。 在…

C++中的explicit关键字介绍

C中的关键字explicit主要是用来修饰类的构造函数&#xff0c;被修饰的构造函数的类&#xff0c;不能发生相应的隐式类型转换&#xff0c;只能以显示的方式进行类型转换。类构造函数默认情况下声明为隐式的即implicit。隐式转换即是可以由单个实参来调用的构造函数定义了一个从形…

Redis的集群模式

集群 即使使用哨兵&#xff0c;此时的Redis集群的每个数据库依然存有集群中的所有数据&#xff0c;从而导致集群的总数据存储量受限于可用存储内存最小的数据库节点&#xff0c;形成木桶效应。由于Redis中的所有数据都是基于内存存储&#xff0c;这一问题就尤为突出了尤其是当使…

刚上线就报名2000人!8位大牛免费讲座,再不报名就满额了!

今年是CSDN的第20年&#xff0c;我们已经不再满足解决你的技术问题&#xff0c;还要帮你解决人生大事&#xff01;为了让你飞黄腾达&#xff0c;我们特别邀请到了8位大牛老师进行直播&#xff0c;他们已经实现了成为技术总监、创业、财富自由的梦想&#xff0c;这场直播&#x…

排序算法之插入排序

插入排序一般分为直接插入排序和二分插入排序。一、直接插入排序&#xff1a;直接插入排序又可以分为前插和后插&#xff0c;不过虽然是这样分&#xff0c;只是寻找地点的方向不一样而已。“前插”就是从头开始找合适的位置&#xff0c;“后插”就是从后面开始找合适的位置。直…

C++中#error/assert/static_assert的区别及使用

C 语言支持可帮助您调试应用程序的三个错误处理机制&#xff1a;#error 指令、static_assert 关键字和 assert (CRT) 宏。所有的三种机制都会发出错误消息。#error可看做预编译期断言&#xff0c;甚至都算不上断言&#xff0c;仅仅能在预编译时显示一个错误信息&#xff0c;它能…

读完ACL 2019录取的30篇知识图谱论文,我发现了这5点趋势

作者 | Michael Galkin译者 | Freesia编辑 | 夕颜出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】近年来&#xff0c;自然语言处理领域中广泛应用的知识图谱&#xff08;KGs&#xff09;正在不断地吸引人们的目光&#xff0c;此次 ACL 2019 中的有关于知识图…

力扣(LeetCode)933

题目地址&#xff1a;https://leetcode-cn.com/probl...题目描述&#xff1a;写一个 RecentCounter 类来计算最近的请求。 它只有一个方法&#xff1a;ping(int t)&#xff0c;其中 t 代表以毫秒为单位的某个时间。 返回从 3000 毫秒前到现在的 ping 数。 任何处于 [t - 3000, …

2013年10月1日C#随机数

最近开始接触C跟C#&#xff0c;总是有人说女生本来就不适合做程序&#xff0c;就连今天都听到有人这样跟我讲&#xff0c;不过呢没有关系&#xff0c;我相信男生不一定比女生厉害多少&#xff0c;就好像我身边就有一位男生就总是觉得我的程序比他好一点就是理所当然的&#xff…