Keras: 基于 Python 的深度学习库(这份学习资料是学习的老师上课的ppt,感谢张老师)

一、Keras关键词

中文官网:https://keras.io/zh/

  • 纯Python
  • 符号式编程
  • Tensorflow或Theano为后端(backend)——站在巨人的肩膀上
  • 快速原型
  • 轻量级,高度模块化
  • 不断完善的预训练模型库

1、Keras由纯Python编写,这意味着它的源代码简单易懂,你可以随时进去看看它都做了什么,怎么做的。并且,当你需要修改源代码的时候,大胆修改就可以了,它会立刻生效。  尽管Python的运行效率要低于C++,但Keras只是Tensorflow和Theano的包装而已,这层包装的运行代价是很小的。

2、“先确定符号以及符号之间的计算关系,然后才放数据进去计算”的办法,就是符号式编程。当声明a和b时,它们里面是空的。当确立z=a+b的计算关系时,a,b和z仍然是空的,只有当真的把数据放入a和b了,程序才开始做计算。

3、Keras事实上是一个基于Theano和Tensorflow上的一个包装,所谓站在巨人的肩膀上也不外如是了。 因为Theano和Tensorflow都是符号主义的东西(下面讲再说这是啥),因此Keras自然也是符号主义的。

4、Keras是一款高度模块化的框架,使用它搭建网络和训练网络将会非常容易,如果你需要深入模型中控制细节,通常使用Keras提供的一些函数就可以了,很少需要深入到Tensorflow或Theano那一层。因此,Keras适合于快速原型生成,如果你经常需要很快的实现一下自己的idea,Keras会是一个不错的选择。

5、另外,Keras的预训练模型库也在逐步建设,目前有VGG-16,VGG-19,resnet50,Inceptionv3四种预训练好的模型供大家使用。

  • 张量 Tensor

参与符号运算的那些变量统一称作张量。张量是矩阵的进一步推广。

  • 规模最小的张量是0阶张量,即标量scalar,也就是一个数。
  • 当我们把一些数有序的排列起来,就形成了1阶张量,也就是一个向量vector
  • 如果我们继续把一组向量有序的排列起来,就形成了2阶张量,也就是一个矩阵matrix
  • 把矩阵摞起来,就是3阶张量,我们可以称为一个立方体,具有3个颜色通道的彩色图片就是一个这样的立方体
  • 把矩阵摞起来,就叫4阶张量了,不要去试图想像4阶张量是什么样子,它就是个数学上的概念。
  • Keras的计算过程

建立一个从张量到张量的映射函数,再放入真实数据进行计算。

对深度学习而言,这个“映射函数”就是一个神经网络,而神经网络中的每个层自然也都是从张量到张量的映射。

  • Keras框架
  • backend:后端,对Tensorflow、Theano和CNTK进行封装,完成低层的张量运算、计算图编译等。
  • models:模型,模型是层的有序组合,也是层的“容器”,是“神经网络”的整体表示。
  • layers:层,神经网络的层本质上规定了一种从输入张量到输出张量的计算规则,显然,整个神经网络的模型也是这样一种张量到张量的计算规则,因此keras的model是layer的子类。
  • 设计一个深度神经网络模型,首先定义一个model,其实利用各种layers定义网络结构。

上面的三个模块是Keras最为要紧和核心的三块内容,搭建一个神经网络,就只用上面的内容即可。注意的是,backend虽然很重要,但其内容多而杂,大部分内容都是被其他keras模块调用,而不是被用户直接使用。所以它不是新手马上就应该学的,初学Keras不妨先将backend放一旁,从model和layers学起。

  • models/layers:Keras的核心主题
  • 网络就是张量到张量的映射,所以Keras的网络就是一个由多个子计算图构成的大计算图。当这些子计算图是顺序连接时,称为顺序模型Sequential,否则就是一般的model,称为泛型模型。
  • 模型不但是张量的计算方式,还是层对象的容器,模型用来将它所含有的层整合起来。
  • layers:构筑模型的基石

卷积层、递归神经网络层、全连接层、激活层……等等

  • Advanced Activation:高级激活层,主要收录了包括leakyReLU,pReLU,ELU,SReLU等一系列高级激活函数,这些激活函数不是简单的element-wise计算,所以单独拿出来实现一下
  • Merge层:这个层用于将多个层对象的输出组合起来,支持级联、乘法、余弦等多种计算方式,它还有个小兄弟叫merge,这个函数完成与Merge相同的作用,但输入的对象是张量而不是层对象。
  • Lambda层:这是一个神奇的层,看名字就知道它用来把一个函数作用在输入张量上。这个层可以大大减少你的工作量,当你需要定义的新层的计算不是那么复杂的时候,可以通过lambda层来实现,而不用自己完全重写。
  • Highway/Maxout/AtrousConvolution2D层:这个就不多说了,懂的人自然懂,keras还是在一直跟着潮流走的
  • Wrapper层:Wrapper层用于将一个普通的层对象进行包装升级,赋予其更多功能。目前,Wrapper层里有一个TimeDistributed层,用于将普通的层包装为对时间序列输入处理的层,而Bidirectional可以将输入的递归神经网络层包装为双向的(如把LSTM做成BLSTM)
  • Input:补一个特殊的层,Input,这个东西实际上是一个Keras tensor的占位符,主要用于在搭建Model模型时作为输入tensor使用,这个Input可以通过keras.layers来import。
  • stateful与unroll:Keras的递归神经网络层,如SimpleRNN,LSTM等,支持两种特殊的操作。一种是stateful,设置stateful为True意味着训练时每个batch的状态都会被重用于初始化下一个batch的初始状态。另一种是unroll,unroll可以将递归神经网络展开,以空间换取运行时间。
  • model training
  • 两套训练和测试的函数:
  • 一套是fit,evaluate等,适用于普通情况
  • 另一套是fit_generator,evaluate_generator适用于数据是以迭代器动态生成的情况。迭代器可以在内存/显存不足,实时动态数据提升进行网络训练。
  • 最核心的函数有两个:
  • compile():编译,模型在训练前必须编译,这个函数用于完成添加正则项,确定目标函数,确定优化器等等一系列模型配置功能。这个函数必须指定的参数是优化器和目标函数,还需要指定一个metrics来进行模型评估。
  • fit()/fit_generator():用来训练模型,参数较多,是需要重点掌握的函数。
  • 编写自己的layer
  • 计算比较简单,那可以尝试通过Lambda层来解决
  • 从Layer(或其他层)继承的类,除了__init__以外还需要重写三个函数:
  • build,这个函数用来确立这个层都有哪些参数,哪些参数是可训练的哪些参数是不可训练的。
  • call,这个函数在调用层对象时自动使用,里面就是该层的计算逻辑,或计算图了。显然,这个层的核心应该是一段符号式的输入张量到输出张量的计算过程。
  • get_output_shape_for:如果你的层计算后,输入张量和输出张量的shape不一致,那么你需要把这个函数也重新写一下,返回输出张量的shape,以保证Keras可以进行shape的自动推断。
  • 网络训练
  • objectives:目标函数,规定了神经网络的优化方向。本质上是一个从张量到数值的函数。
  • MSE、交叉熵
  • optimizers:优化器,规定了神经网络的参数如何更新。
  • activation是激活函数,这部分的内容一般不直接使用,而是通过激活层Activation来调用。
  • callback是回调函数,这其实是一个比较重要的模块,回调函数不是一个函数而是一个类,用于在训练过程中收集信息或进行某种动作。

预定义的回调函数中CheckModelpoint,History和EarlyStopping都是比较重要和常用的。其中CheckPoint用于保存模型,History记录了训练和测试的信息,EarlyStopping用于在已经收敛时提前结束训练。回调函数LearningRateScheduler支持按照用户的策略调整学习率。值得注意的是,History是模型训练函数fit的返回值,也就是说即使你没有使用任何回调函数,找一个变量接住model.fit(),还是能得到不少训练过程中的有用信息。

  • Keras提供了一组模块用来对神经网络进行配置
  • initialization:初始化策略,规定了网络参数的初始化方法
  • regularizers:正则项,提供了一些用于参数正则的方法,以对抗过拟合
  • constraints:约束项,提供了对网络参数进行约束的方法

十一、调试分析和使用网络,处理数据的模块

  • callbacks:回调函数,在网络训练的过程中返回一些预定义/自定义的信息
  • visualization:可视化,用于将网络结构绘制出来,以直观观察
  • preprocessing:提供了一组用于对文本、图像、序列信号进行预处理的函数
  • utils:常用函数库
  • utils.np_utils中的to_categorical,用于将1D标签转为one-hot的2D标签
  • convert_kernel函数,用于将卷积核在theano模式和Tensorflow模式之间转换。

十二、常用数据集的模块

  • datasets:提供了一些常用数据库的接口,用户将通过这些接口下载和载入数据集

十三、与scikit-learn联动机制

  • wrappers.scikit-learn
  • 两个类:KerasClassifier和KerasRegressor,搭建好Sequential模型(只能是Sequential)将被它们包装为sklearn的分类器和迭代器加入的sklearn的工作流中。

十四、构建一个深度模型的四大要素:

  • 网络拓扑结构
  • 层,激活函数
  • 成本(损失)函数
  • 梯度下降
  • 方法,mini-batch
  • 网络性能度量

 

十五、举例:

from keras.models import Sequential  # Sequential 模型

from keras.layers import Dense, Activation

from keras.optimizers import SGD



model = Sequential()  

# 简单用.add()堆积模型

model.add(Dense(output_dim=64, input_dim=100))

model.add(Activation("relu"))

model.add(Dense(output_dim=10))

model.add(Activation("softmax"))



# 完成模型构建后使用.compile配置学习过程

model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])

# 批量在训练数据上迭代

model.fit(X_train, Y_train, nb_epoch=5, batch_size=32)

# 评估模型

loss = model.evaluate(X_test, Y_test, batch_size=32)

# 或者对新数据进行预测

Classes = model.predict(x_test,batch_size_size=128)

应用:案例一:线性回归 案例二:手写数字识别

十六、目前流行的梯度下降方法

  1. Momentum法
  2. Nesterov加速梯度法
  3. Adagrad法
  4. Adadelta法
  5. RMSprop法
  6. 适应性动量估计法(Adam)

在罚函数的等高线图中,优化器的位置随时间的变化情况。注意到,Adagrad、 Adadelta 及 RMSprop 法几乎立刻就找到了正确前进方向并以相似的速度很快收敛。而动量法和 NAG 法,则找错了方向,如图所示,让小球沿着梯度下降的方向前进。但 NAG 法能够很快改正它的方向向最小指出前进,因为他能够往前看并对前面的情况做出响应。

展现了各算法在鞍点附近的表现。如上面所说,这对对于 SGD 法、动量法及 NAG 法制造了一个难题。他们很难打破」对称性「带来的壁垒,尽管最后两者设法逃脱了鞍点。而 Adagrad 法、RMSprop 法及 Adadelta 法都能快速的沿着负斜率的方向前进。