“边运行边定义”的方法使构建深度学习网络变的灵活简单
Chainer是一个专门为高效研究和开发深度学习算法而设计的开源框架。 这篇博文会通过一些例子简要地介绍一下Chainer,同时把它与其他一些框架做比较,比如Caffe、Theano、Torch和Tensorflow。
大多数现有的深度学习框架是在模型训练之前构建计算图。 这种方法是相当简单明了的,特别是对于结构固定且分层的神经网络(比如卷积神经网络)的实现。
然而,现在的复杂神经网络(比如循环神经网络或随机神经网络)带来了新的性能改进和新的应用。虽然现有的框架可以用于实现这些复杂神经网络,但是它们有时需要一些(不优雅的)编程技巧,这可能会降低代码的开发效率和可维护性。
而Chainer的方法是独一无二的:即在训练时“实时”构建计算图。
这种方法可以让用户在每次迭代时或者对每个样本根据条件更改计算图。同时也很容易使用标准调试器和分析器来调试和重构基于Chainer的代码,因为Chainer使用纯Python和NumPy提供了一个命令式的API。 这为复杂神经网络的实现提供了更大的灵活性,同时又加快了迭代速度,提高了快速实现最新深度学习算法的能力。
以下我会介绍Chainer是如何工作的,以及用户可以从中获得什么样的好处。
Chainer 基础
Chainer 是一个基于Python的独立的深度学习框架。
不同于其它基于Python接口的框架(比如Theano和TensorFlow),Chainer通过支持兼容Numpy的数组间运算的方式,提供了声明神经网络的命令式方法。Chainer 还包括一个名为CuPy的基于GPU的数值计算库。
>>> from chainer import Variable
>>> import numpy as np
Variable 类是把numpy.ndarray数组包装在内的计算模块(numpy.ndarray存放在.data中)。
>>> x = Variable(np.asarray([[0, 2],[1, -3]]).astype(np.float32))
>>> print(x.data)
[[ 0. 2.]
[ 1. -3.]]
用户可以直接在Variables上定义各种运算和函数(Function的实例)。
>>> y = x ** 2 – x + 1
>>> print(y.data)
[[ 1. 3.]
[ 1. 13.]]
因为这些新定义的Varriable类知道他们是由什么类生成的,所以Variable y跟它的父类有一样的加法运算(.creator)。
>>> print(y.creator)
<chainer.functions.math.basic_math.AddConstant at 0x7f939XXXXX>
利用这种机制,可以通过反向追踪从最终损失函数到输入的完整路径来实现反向计算。完整路径在执行正向计算的过程中存储,而不预先定义计算图。
在chainer.functions类中给出了许多数值运算和激活函数。 标准神经网络的运算在Chainer类中是通过Link类实现的,比如线性全连接层和卷积层。Link可以看做是与其相应层的学习参数的一个函数(例如权重和偏差参数)。你也可以创建一个包含许多其他Link的Link。这样的一个link容器被命名为Chain。这允许Chainer可以将神经网络建模成一个包含多个link和多个chain的层次结构。Chainer还支持最新的优化方法、序列化方法以及使用CuPy的由CUDA驱动的更快速计算。
>>> import chainer.functions as F
>>> import chainer.links as L
>>> from chainer import Chain, optimizers, serializers, cuda
>>> import cupy as cp