Theano 符号图结构

使用 Theano,首先要定义符号变量,然后是利用这写符号变量进行计算,这些符号被称为 variables,而操作 +, -, , sum(), tanh() 被称为 ops**,一个 op 操作接受某些类型的输入,并返回某些类型的输出。

Theano 利用这些来构建一个图结构,一个图结构包括:

  • variable 节点
  • op 节点
  • apply 节点 其中,apply 节点用来表示一个特定的 op 作用在一些特定的 variables 上,例如:

In [1]:

  1. import theano
  2. import theano.tensor as T
  3.  
  4. x = T.dmatrix('x')
  5. y = T.dmatrix('y')
  6. z = x + y
  1. Using gpu device 0: GeForce GTX 850M

要显示这个图结构可以用 pydotprint,先安装 graphviz

Windows 下:

在环境变量 path 后加上:

  • path
    • C:\Program Files (x86)\Graphviz2.38\bin 然后要先安装 pydot 包:

如果你的 pyparsing >= 2.0 ,则将其降为 1.5.7,下载并安装 pydot-1.0.28

安装完之后,找到 pydot.py 将其中:

  1. graph.append( '%s %s {\n' % (self.obj_dict['type'], self.obj_dict['name']) )

修改为:

  1. graph.append( '%s %s {\n' % (self.obj_dict['type'], quote_if_necessary(self.obj_dict['name'])) )

In [2]:

  1. theano.printing.pydotprint(z, outfile='apply1.png', var_with_name_simple=True)
  1. The output file is available at apply1.png

它的图结构如下:

图结构1

zowner 是一个 apply 结构,其 op 为:

In [3]:

  1. z.owner.op.name

Out[3]:

  1. 'Elemwise{add,no_inplace}'

这个 apply 结构的输入值有两个,输出值有一个:

In [4]:

  1. print z.owner.nin
  2. print z.owner.nout
  1. 2
  2. 1

查看它的输入:

In [5]:

  1. z.owner.inputs

Out[5]:

  1. [x, y]

我们可以用 pprint 来显示它:

In [6]:

  1. print theano.printing.pprint(z)
  1. (x + y)

debugprint 显示图结构:

In [7]:

  1. theano.printing.debugprint(z)
  1. Elemwise{add,no_inplace} [@A] ''
  2. |x [@B]
  3. |y [@C]

再看另一个稍微复杂的例子:

In [8]:

  1. y = x * 2

查看 y 的图谱:

In [9]:

  1. theano.printing.debugprint(y)
  1. Elemwise{mul,no_inplace} [@A] ''
  2. |x [@B]
  3. |DimShuffle{x,x} [@C] ''
  4. |TensorConstant{2} [@D]

这里我们看到,y 对应的第二个 input 并不是 2,而是一个 DimShuffle 的操作:

In [10]:

  1. y.owner.inputs[1].owner.op

Out[10]:

  1. <theano.tensor.elemwise.DimShuffle at 0x1b816390>

它的输入才是常数 2:

In [11]:

  1. y.owner.inputs[1].owner.inputs

Out[11]:

  1. [TensorConstant{2}]

In [12]:

  1. theano.printing.pydotprint(y, outfile='apply2.png', var_with_name_simple=True)
  1. The output file is available at apply2.png

其图结构为结构2

function 对图的优化

In [13]:

  1. a = T.dscalar('a')
  2. b = a + a ** 10
  3.  
  4. f = theano.function([a], b)

In [14]:

  1. theano.printing.pydotprint(b, outfile='apply_no_opti.png', var_with_name_simple=True)
  2. theano.printing.pydotprint(f, outfile='apply_opti.png', var_with_name_simple=True)
  1. The output file is available at apply_no_opti.png
  2. The output file is available at apply_opti.png

比较一下 function 函数对图结构进行的优化:

未优化前:

没有优化

优化后:

优化

图结构的作用

  • 计算按照图结构来计算
  • 优化,求导

原文: https://nbviewer.jupyter.org/github/lijin-THU/notes-python/blob/master/09-theano/09.04-graph-structures.ipynb