printing —— 打印图和符号的语句

指南

执行期间打印

计算的中间值不能使用print语句以普通的Python方式打印,因为Theano没有语句取而代之的是Print Op。

>>> from theano import tensor as T, function, printing
>>> x = T.dvector()
>>> hello_world_op = printing.Print('hello world')
>>> printed_x = hello_world_op(x)
>>> f = function([x], printed_x)
>>> r = f([1, 2, 3])
hello world __str__ = [ 1.  2.  3.]

If you print more than one thing in a function like f, they will not necessarily be printed in the order that you think. The order might even depend on which graph optimizations are applied. 严格地说,打印的顺序不是由接口完全定义的 —— 唯一的硬规则是,如果一些打印输出a的输入最终用作某个其他打印输入b的输入(b取决于a),则a将在b之前打印。

打印图

Theano提供两个函数(theano.pp()theano.printing.debugprint())在编译之前或之后将图打印到终端。这两个函数以不同的方式打印表达式图:pp()更紧凑并类似数学,debugprint()更冗长。Theano also provides theano.printing.pydotprint() that creates a png image of the function.

  1. The first is theano.pp().
>>> from theano import pp, tensor as T
>>> x = T.dscalar('x')
>>> y = x ** 2
>>> gy = T.grad(y, x)
>>> pp(gy)  # print out the gradient prior to optimization
'((fill((x ** TensorConstant{2}), TensorConstant{1.0}) * TensorConstant{2}) * (x ** (TensorConstant{2} - TensorConstant{1})))'
>>> f = function([x], gy)
>>> pp(f.maker.fgraph.outputs[0])
'(TensorConstant{2.0} * x)'

第一行中T.dscalar(‘x’) 中的参数是图中此变量的名称。此名称在打印图时使用,以使其更易读。If no name is provided the variable x is printed as its type as returned by x.type(). 在这个例子中,为<TensorType(float64, scalar)>。

The name parameter can be any string. There are no naming restrictions: in particular, you can have many variables with the same name. As a convention, we generally give variables a string name that is similar to the name of the variable in local scope, but you might want to break this convention to include an object instance, or an iteration number or other kinds of information in the name.

Note

为了使图清晰可见,pp()隐藏了图中实际存在的一些Ops。For example, automatic DimShuffles are not shown.

  1. 打印图的第二个函数是theano.printing.debugprint()
>>> theano.printing.debugprint(f.maker.fgraph.outputs[0])  
Elemwise{mul,no_inplace} [id A] ''
 |TensorConstant{2.0} [id B]
 |x [id C]

打印的每一行代表图中的一个变量。|x [id C]表示名为x的变量是Elemwise的输入,并带有debugprint的标志[id C]。如果你在你的图中意外地有两个变量叫做x,它们不同的调试标识符将是你的线索。

|TensorConstant{2.0} [id B]行表示有一个常量2.0,并带有这个debugprint标识符。

Elemwise{mul,no_inplace} [id A] ''的缩进小于其他行,因为它表示有一个变量是通过其他变量(更多缩进)相乘计算得到的。

|符号只是为了帮助阅读很大的图。它们将输入分组在一起到一个节点。

有时,你会看到一个变量,而不是下面的输入。That can happen when that Variable has already been printed. 已经在哪里打印过?使用你的文本编辑器的查找功能查找debugprint标识符。

>>> theano.printing.debugprint(gy)  
Elemwise{mul} [id A] ''
 |Elemwise{mul} [id B] ''
 | |Elemwise{second,no_inplace} [id C] ''
 | | |Elemwise{pow,no_inplace} [id D] ''
 | | | |x [id E]
 | | | |TensorConstant{2} [id F]
 | | |TensorConstant{1.0} [id G]
 | |TensorConstant{2} [id F]
 |Elemwise{pow} [id H] ''
   |x [id E]
   |Elemwise{sub} [id I] ''
     |TensorConstant{2} [id F]
     |InplaceDimShuffle{} [id J] ''
       |TensorConstant{1} [id K]
>>> theano.printing.debugprint(gy, depth=2)  
Elemwise{mul} [id A] ''
 |Elemwise{mul} [id B] ''
 |Elemwise{pow} [id C] ''

如果提供depth参数,它将限制显示的级别数。

  1. 函数theano.printing.pydotprint()会将编译后的theano函数打印到png文件。

在图片中,Apply节点(op的应用)显示为椭圆,变量显示为矩形。每个标签末尾的数字表示图的位置。矩形和椭圆有自己的位置集合,所以你可以有apply #1和variable #1。The numbers in the boxes (Apply nodes) are actually their position in the run-time execution order of the graph. 绿色椭圆形是图的输入,蓝色椭圆形是输出。

If your graph uses shared variables, those shared variables will appear as inputs. Future versions of the pydotprint() may distinguish these inplicit inputs from explicit inputs.

如果你在创建你的函数时给出更新参数,这些将作为额外的输入和输出添加到图中。Future versions of pydotprint() may distinguish these implicit inputs and outputs from explicit inputs and outputs.

参考

class theano.printing.Print(Op)[source]

This identity-like Op has the side effect of printing a message followed by its inputs when it runs. Default behaviour is to print the __str__ representation. Optionally, one can pass a list of the input member functions to execute, or attributes to print.

__init__(message="", attrs=("__str__")[source]
Parameters:
  • message (string) – prepend this to the output
  • attrs (list of strings) – list of input node attributes or member functions to print. Functions are identified through callable(), executed and their return value printed.
__call__(x)[source]
Parameters:x (a Variable) – any symbolic variable
Returns:symbolic identity(x)

When you use the return-value from this function in a theano function, running the function will print the value that x takes in the graph.

theano.printing.debugprint(obj, depth=-1, print_type=False, file=None, ids='CHAR', stop_on_name=False, done=None, print_storage=False)[source]

Print a computation graph as text to stdout or a file.

Parameters:
  • obj (Variable, Apply, or Function instance) – symbolic thing to print
  • depth (integer) – print graph to this depth (-1 for unlimited)
  • print_type (boolean) – whether to print the type of printed objects
  • file (None, 'str', or file-like object) – print to this file (‘str’ means to return a string)
  • ids (str) – How do we print the identifier of the variable id - print the python id value int - print integer character CHAR - print capital character “” - don’t print an identifier
  • stop_on_name – When True, if a node in the graph has a name, we don’t print anything below it.
  • done (None or dict) – A dict where we store the ids of printed node. Useful to have multiple call to debugprint share the same ids.
  • print_storage (bool) – If True, this will print the storage map for Theano functions. Combined with allow_gc=False, after the execution of a Theano function, we see the intermediate result.
Returns:

string if file == ‘str’, else file arg

Each line printed represents a Variable in the graph. The indentation of lines corresponds to its depth in the symbolic graph. The first part of the text identifies whether it is an input (if a name or type is printed) or the output of some Apply (in which case the Op is printed). The second part of the text is an identifier of the Variable. If print_type is True, we add a part containing the type of the Variable

If a Variable is encountered multiple times in the depth-first search, it is only printed recursively the first time. Later, just the Variable identifier is printed.

If an Apply has multiple outputs, then a ‘.N’ suffix will be appended to the Apply’s identifier, to indicate which output a line corresponds to.

theano.pp(*args)[source]

Just a shortcut to theano.printing.pp()

theano.printing.pp(*args)[source]
theano.printing.pydotprint(fct, outfile=None, compact=True, format='png', with_ids=False, high_contrast=True, cond_highlight=None, colorCodes=None, max_label_size=70, scan_graphs=False, var_with_name_simple=False, print_output_file=True, return_image=False)[source]

Print to a file the graph of a compiled theano function’s ops. Supports all pydot output formats, including png and svg.

Parameters:
  • fct – a compiled Theano function, a Variable, an Apply or a list of Variable.
  • outfile – the output file where to put the graph.
  • compact – if True, will remove intermediate var that don’t have name.
  • format – the file format of the output.
  • with_ids – Print the toposort index of the node in the node name. and an index number in the variable ellipse.
  • high_contrast – if true, the color that describes the respective node is filled with its corresponding color, instead of coloring the border
  • colorCodes – dictionary with names of ops as keys and colors as values
  • cond_highlight – Highlights a lazy if by sorrounding each of the 3 possible categories of ops with a border. The categories are: ops that are on the left branch, ops that are on the right branch, ops that are on both branches As an alternative you can provide the node that represents the lazy if
  • scan_graphs – if true it will plot the inner graph of each scan op in files with the same name as the name given for the main file to which the name of the scan op is concatenated and the index in the toposort of the scan. This index can be printed with the option with_ids.
  • var_with_name_simple – If true and a variable have a name, we will print only the variable name. Otherwise, we concatenate the type to the var name.
  • return_image

    If True, it will create the image and return it. Useful to display the image in ipython notebook.

    import theano
    v = theano.tensor.vector()
    from IPython.display import SVG
    SVG(theano.printing.pydotprint(v*2, return_image=True,
                                   format='svg'))
    

In the graph, ellipses are Apply Nodes (the execution of an op) and boxes are variables. If variables have names they are used as text (if multiple vars have the same name, they will be merged in the graph). Otherwise, if the variable is constant, we print its value and finally we print the type + a unique number to prevent multiple vars from being merged. We print the op of the apply in the Apply box with a number that represents the toposort order of application of those Apply. If an Apply has more than 1 input, we label each edge between an input and the Apply node with the input’s index.

Variable color code::
  • Cyan boxes are SharedVariable, inputs and/or outputs) of the graph,
  • Green boxes are inputs variables to the graph,
  • Blue boxes are outputs variables of the graph,
  • Grey boxes are variables that are not outputs and are not used,
Default apply node code::
  • Red ellipses are transfers from/to the gpu
  • Yellow are scan node
  • Brown are shape node
  • Magenta are IfElse node
  • Dark pink are elemwise node
  • Purple are subtensor
  • Orange are alloc node

For edges, they are black by default. If a node returns a view of an input, we put the corresponding input edge in blue. If it returns a destroyed input, we put the corresponding edge in red.

Note

Since October 20th, 2014, this print the inner function of all scan separately after the top level debugprint output.