基于TensorBoard中graph模块图结构分析


Posted in Python onFebruary 15, 2020

在上一篇文章中,我们介绍了如何使用源码对TensorBoard进行编译教程,没有定制需求的可以直接使用pip进行安装。

TensorBoard中的graph是一种计算图,里面的点用于表示Tensor本身或者运算符,图中的边则代表Tensor的流动或者控制关系。

基于TensorBoard中graph模块图结构分析

本文主要从代码的层面,分析graph的数据来源与结构。

一般来说,我们在启动TensorBoard的时候会使用--logdir参数配置文件路径(或者设置数据库位置),这些日志文件为TensorBoard提供了数据。于是我们打开一个日志文件,查看里面的内容

基于TensorBoard中graph模块图结构分析

我们看到,文件是通过二进制展示的,因此无法直接读取文件的内容。

回到浏览器中,进入graph页面,通过开发者工具发现,构造图的时候调用了一个接口

http://localhost:6006/data/plugin/graphs/graph?large_attrs_key=_too_large_attrs&limit_attr_size=1024&run=task1

用浏览器打开这个地址,看到以下内容

node {
 name: "Input/X"
 op: "Placeholder"
 attr {
 key: "_output_shapes"
 value {
  list {
  shape {
   unknown_rank: true
  }
  }
 }
 }
 attr {
 key: "dtype"
 value {
  type: DT_FLOAT
 }
 }
 attr {
 key: "shape"
 value {
  shape {
  unknown_rank: true
  }
 }
 }
}
...

每个node都能够与图中的一个节点相对应,因此我们可以确定,这个接口里返回的node,就是构成图所需要的数据结构。

那么,TensorBoard是如何将日志文件转化为图的呢?

TesnorBoard中的每个模块都是以plugin存在的,我们进入tensorboard/plugin/graph/graphs_plungin.py,在这个文件中定义了graph相关的接口

def get_plugin_apps(self):
 return {
  '/graph': self.graph_route,
  '/runs': self.runs_route,
  '/run_metadata': self.run_metadata_route,
  '/run_metadata_tags': self.run_metadata_tags_route,
 }

我们可以看到,‘/graph'这个接口返回值为self.graph_route,在这个文件中搜索graph_route方法

@wrappers.Request.application
 def graph_route(self, request):
 """Given a single run, return the graph definition in protobuf format."""
 run = request.args.get('run')
 if run is None:
  return http_util.Respond(
   request, 'query parameter "run" is required', 'text/plain', 400)
 
 limit_attr_size = request.args.get('limit_attr_size', None)
 if limit_attr_size is not None:
  try:
  limit_attr_size = int(limit_attr_size)
  except ValueError:
  return http_util.Respond(
   request, 'query parameter `limit_attr_size` must be an integer',
   'text/plain', 400)
 
 large_attrs_key = request.args.get('large_attrs_key', None)
 
 try:
  result = self.graph_impl(run, limit_attr_size, large_attrs_key)
 except ValueError as e:
  return http_util.Respond(request, e.message, 'text/plain', code=400)
 else:
  if result is not None:
  (body, mime_type) = result # pylint: disable=unpacking-non-sequence
  return http_util.Respond(request, body, mime_type)
  else:
  return http_util.Respond(request, '404 Not Found', 'text/plain',
         code=404)

在这个方法中,分别取了“run”,”limit_attr_size“和“large_attrs_key”三个参数,和前面url所调用的参数一致,说明这个是我们要找的方法。在方法的最后,调用了self.graph_impl生成了图,我们继续查看这个方法

def graph_impl(self, run, limit_attr_size=None, large_attrs_key=None):
 """Result of the form `(body, mime_type)`, or `None` if no graph exists."""
 try:
  graph = self._multiplexer.Graph(run)
 except ValueError:
  return None
 # This next line might raise a ValueError if the limit parameters
 # are invalid (size is negative, size present but key absent, etc.).
 process_graph.prepare_graph_for_ui(graph, limit_attr_size, large_attrs_key)
 return (str(graph), 'text/x-protobuf') # pbtxt

这个方法调用了self._multiplexer.Graph(run)生成图。_multiplexer是一个event_multiplexer实例,在graph_plugln初始化时通过base_plaugin.TBContext获得。

def __init__(self, context):
 """Instantiates GraphsPlugin via TensorBoard core.
 Args:
  context: A base_plugin.TBContext instance.
 """
 self._multiplexer = context.multiplexer

进入tensorboard/backend/event_processing/event_multiplexer,找到Graph方法

def Graph(self, run):
 """Retrieve the graph associated with the provided run.
 Args:
  run: A string name of a run to load the graph for.
 Raises:
  KeyError: If the run is not found.
  ValueError: If the run does not have an associated graph.
 Returns:
  The `GraphDef` protobuf data structure.
 """
 accumulator = self.GetAccumulator(run)
 return accumulator.Graph()
 
 def GetAccumulator(self, run):
 """Returns EventAccumulator for a given run.
 Args:
  run: String name of run.
 Returns:
  An EventAccumulator object.
 Raises:
  KeyError: If run does not exist.
 """
 with self._accumulators_mutex:
  return self._accumulators[run]

Graph方法获取了run对应的accumulator实例,并返回了这个实例的Graph方法的返回值。我们进入tensorboard/backend/event_processing/event_accumulator,找到Graph()方法

def Graph(self):
 """Return the graph definition, if there is one.
 If the graph is stored directly, return that. If no graph is stored
 directly but a metagraph is stored containing a graph, return that.
 Raises:
  ValueError: If there is no graph for this run.
 Returns:
  The `graph_def` proto.
 """
 graph = tf.GraphDef()
 if self._graph is not None:
  graph.ParseFromString(self._graph)
  return graph
 raise ValueError('There is no graph in this EventAccumulator')

事实上,它返回了一个GraphDef图,因此我们也可以通过将日志转换为GraphDef的方式读取日志。

# 导入要用到的基本模块。为了在python2、python3 中可以使用E侣兼容的 print 函数
from __future__ import print_function
import numpy as np
import tensorflow as tf
 
# 创建图和Session
graph = tf.Graph()
sess = tf.InteractiveSession(graph=graph)
 
#日志路径
model_fn = '/log/events.out.tfevents.1535957014.ubuntu'
 
for e in tf.train.summary_iterator(model_fn):
 if e.HasField('graph_def'):
  graph = e.graph_def;
  graph_def = tf.GraphDef()
  graph_def.ParseFromString(graph)
  print(graph_def)

我们新建一个python文件,修改日志路径为自己的日志位置,便可以得到与TensorBoard相同的内容。

以上这篇基于TensorBoard中graph模块图结构分析就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中bisect的用法
Sep 23 Python
Python的自动化部署模块Fabric的安装及使用指南
Jan 19 Python
Django基础知识与基本应用入门教程
Jul 20 Python
Python网页正文转换语音文件的操作方法
Dec 09 Python
Python删除n行后的其他行方法
Jan 28 Python
Pycharm使用远程linux服务器conda/python环境在本地运行的方法(图解))
Dec 09 Python
Python3.x+pyqtgraph实现数据可视化教程
Mar 14 Python
Python函数默认参数常见问题及解决方案
Mar 26 Python
浅谈tensorflow使用张量时的一些注意点tf.concat,tf.reshape,tf.stack
Jun 23 Python
PyTorch的torch.cat用法
Jun 28 Python
Pytorch1.5.1版本安装的方法步骤
Dec 31 Python
pycharm 使用anaconda为默认环境的操作
Feb 05 Python
使用Bazel编译TensorBoard教程
Feb 15 #Python
TensorBoard 计算图的可视化实现
Feb 15 #Python
TensorBoard 计算图的查看方式
Feb 15 #Python
pycharm 更改创建文件默认路径的操作
Feb 15 #Python
PyCharm刷新项目(文件)目录的实现
Feb 14 #Python
浅谈Pycharm最有必要改的几个默认设置项
Feb 14 #Python
python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法
Feb 14 #Python
You might like
php&java(一)
2006/10/09 PHP
VPS中使用LNMP安装WordPress教程
2014/12/28 PHP
ThinkPHP表单数据智能写入create方法实例分析
2015/09/27 PHP
ThinkPHP静态缓存简单配置和使用方法详解
2016/03/23 PHP
Yii实现显示静态页的方法
2016/04/25 PHP
PHP仿tp实现mvc框架基本设计思路与实现方法分析
2018/05/23 PHP
ThinkPHP框架实现的邮箱激活功能示例
2018/06/15 PHP
JavaScript 事件参考手册
2008/12/24 Javascript
PPK 谈 JavaScript 的 this 关键字 [翻译]
2009/09/29 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
2014/03/20 Javascript
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
json中换行符的处理方法示例介绍
2014/06/10 Javascript
使用jQuery判断IE浏览器版本的代码
2014/06/14 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
JS中使用DOM来控制HTML元素
2016/07/31 Javascript
使用ReactJS实现tab页切换、菜单栏切换、手风琴切换和进度条效果
2016/10/17 Javascript
微信小程序 高德地图SDK详解及简单实例(源码下载)
2017/01/11 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
玩转Koa之核心原理分析
2018/12/29 Javascript
vue实现跨域的方法分析
2019/05/21 Javascript
分析在Python中何种情况下需要使用断言
2015/04/01 Python
Python上传package到Pypi(代码简单)
2016/02/06 Python
利用python打开摄像头及颜色检测方法
2018/08/03 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
python实现自动化报表功能(Oracle/plsql/Excel/多线程)
2019/12/02 Python
高清屏中使用Canvas绘图出现模糊的问题及解决方法
2019/06/03 HTML / CSS
TripAdvisor西班牙官方网站:全球领先的旅游网站
2018/01/10 全球购物
进修护士自我鉴定
2013/10/14 职场文书
学校文明单位申报材料
2014/05/06 职场文书
不忘国耻振兴中华演讲稿
2014/05/14 职场文书
2014年社区卫生工作总结
2014/12/18 职场文书
家属答谢词
2015/01/05 职场文书
2015年卫生局工作总结
2015/07/24 职场文书
2016年党员公开承诺书格式范文
2016/03/24 职场文书
Python合并pdf文件的工具
2021/07/01 Python
Django路由层如何获取正确的url
2021/07/15 Python