Files
ailearning/docs/da/118.md
2020-10-19 21:08:55 +08:00

256 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Theano 符号图结构
使用 `Theano`,首先要定义符号变量,然后是利用这写符号变量进行计算,这些符号被称为 **`variables`**,而操作 `+, -, **, sum(), tanh()` 被称为 **`ops`**,一个 `op` 操作接受某些类型的输入,并返回某些类型的输出。
`Theano` 利用这些来构建一个图结构,一个图结构包括:
* **`variable`** 节点
* **`op`** 节点
* **`apply`** 节点
其中,`apply` 节点用来表示一个特定的 `op` 作用在一些特定的 `variables` 上,例如:
In [1]:
```py
import theano
import theano.tensor as T
x = T.dmatrix('x')
y = T.dmatrix('y')
z = x + y
```
```py
Using gpu device 0: GeForce GTX 850M
```
要显示这个图结构可以用 `pydotprint`,先安装 [graphviz](http://www.graphviz.org)。
`Windows` 下:
在环境变量 path 后加上:
* path
* C:\Program Files (x86)\Graphviz2.38\bin
然后要先安装 `pydot` 包:
如果你的 `pyparsing >= 2.0` ,则将其降为 `1.5.7`,下载并安装 `pydot-1.0.28`
安装完之后,找到 `pydot.py` 将其中:
```py
graph.append( '%s %s {\n' % (self.obj_dict['type'], self.obj_dict['name']) )
```
修改为:
```py
graph.append( '%s %s {\n' % (self.obj_dict['type'], quote_if_necessary(self.obj_dict['name'])) )
```
In [2]:
```py
theano.printing.pydotprint(z, outfile='apply1.png', var_with_name_simple=True)
```
```py
The output file is available at apply1.png
```
它的图结构如下:
![图结构1](apply1.png)
`z``owner` 是一个 `apply` 结构,其 `op` 为:
In [3]:
```py
z.owner.op.name
```
Out[3]:
```py
'Elemwise{add,no_inplace}'
```
这个 `apply` 结构的输入值有两个,输出值有一个:
In [4]:
```py
print z.owner.nin
print z.owner.nout
```
```py
2
1
```
查看它的输入:
In [5]:
```py
z.owner.inputs
```
Out[5]:
```py
[x, y]
```
我们可以用 pprint 来显示它:
In [6]:
```py
print theano.printing.pprint(z)
```
```py
(x + y)
```
`debugprint` 显示图结构:
In [7]:
```py
theano.printing.debugprint(z)
```
```py
Elemwise{add,no_inplace} [@A] ''
|x [@B]
|y [@C]
```
再看另一个稍微复杂的例子:
In [8]:
```py
y = x * 2
```
查看 `y` 的图谱:
In [9]:
```py
theano.printing.debugprint(y)
```
```py
Elemwise{mul,no_inplace} [@A] ''
|x [@B]
|DimShuffle{x,x} [@C] ''
|TensorConstant{2} [@D]
```
这里我们看到,`y` 对应的第二个 `input` 并不是 `2`,而是一个 `DimShuffle` 的操作:
In [10]:
```py
y.owner.inputs[1].owner.op
```
Out[10]:
```py
<theano.tensor.elemwise.DimShuffle at 0x1b816390>
```
它的输入才是常数 2
In [11]:
```py
y.owner.inputs[1].owner.inputs
```
Out[11]:
```py
[TensorConstant{2}]
```
In [12]:
```py
theano.printing.pydotprint(y, outfile='apply2.png', var_with_name_simple=True)
```
```py
The output file is available at apply2.png
```
其图结构为 ![结构2](apply2.png)
## function 对图的优化
In [13]:
```py
a = T.dscalar('a')
b = a + a ** 10
f = theano.function([a], b)
```
In [14]:
```py
theano.printing.pydotprint(b, outfile='apply_no_opti.png', var_with_name_simple=True)
theano.printing.pydotprint(f, outfile='apply_opti.png', var_with_name_simple=True)
```
```py
The output file is available at apply_no_opti.png
The output file is available at apply_opti.png
```
比较一下 `function` 函数对图结构进行的优化:
未优化前:
![没有优化](apply_no_opti.png)
优化后:
![优化](apply_opti.png)
## 图结构的作用
* 计算按照图结构来计算
* 优化,求导