Keras是一个由
Python编写的开源人工神经网络库,可以作为
TensorFlow、
微软CNTK和Theano的高阶应用程序接口,进行深度学习模型的设计、调试、评估、应用和可视化。
基本介绍
Keras在代码结构上由面向对象方法编写,完全模块化并具有可扩展性,其运行机制和说明文档有将用户体验和使用难度纳入考虑,并试图简化复杂算法的实现难度。Keras支持现代
人工智能领域的主流算法,包括前馈结构和递归结构的神经网络,也可以通过封装参与构建统计学习模型。在硬件和
开发环境方面,Keras支持多操作系统下的多GPU
并行计算,可以根据后台设置转化为
TensorFlow、
微软CNTK等系统下的组件。
Keras的主要开发者是
谷歌工程师François Chollet,此外其
GitHub项目页面包含6名主要维护者和超过800名直接贡献者。Keras在其正式版本公开后,除部分预编译模型外,按MIT许可证开放源代码。
Keras:基于Theano和
TensorFlow的深度学习库
Keras是一个高层神经网络API,Keras由纯
Python编写而成并基Tensorflow、Theano以及CNTK后端。Keras 为支持快速实验而生,能够把你的idea迅速转换为结果,如果你有如下需求,请选择Keras:
• 简易和快速的原型设计(keras具有高度模块化,极简,和可扩充特性)
• 支持CNN和RNN,或二者的结合
• 无缝CPU和GPU切换
Keras适用的Python版本是:Python 2.7-3.6
Keras的设计原则是
• 用户友好:Keras是为人类而不是天顶星人设计的API。用户的使用体验始终是我们考虑的首要和中心内容。Keras遵循减少认知困难的最佳实践:Keras提供一致而简洁的API,能够极大减少一般应用下用户的工作量,同时,Keras提供清晰和具有实践意义的bug反馈。
• 模块性:模型可理解为一个层的序列或数据的运算图,完全可配置的模块可以用最少的代价自由组合在一起。具体而言,网络层、损失函数、优化器、初始化策略、激活函数、正则化方法都是独立的模块,你可以使用它们来构建自己的模型。
• 易扩展性:添加新模块超级容易,只需要仿照现有的模块编写新的类或函数即可。创建新模块的便利性使得Keras更适合于先进的研究工作。
• 与
Python协作:Keras没有单独的模型配置文件类型(作为对比,caffe有),模型由python代码描述,使其更紧凑和更易debug,并提供了扩展的便利性。
历史与命名
Keras的前身是François Chollet为ONEIROS(Open-ended Neuro-Electronic Intelligent Robot Operating System)项目所的编写的代码,在2015年分离成为开源的人工神经网络工具。Keras的最初版本以Theano为后台,设计理念参考了Torch但完全由
Python编写 。2015年11月的Keras测试版本0.3.0,
TensorFlow被加入了后台选项。2016年4月,Keras在PIPy上发布了第一个稳定版本1.0.0 。2017年5月,Keras版本2.0.0发布 。同年6月,Keras版本2.0.5测试性地将
微软CNTK加入后台选项 。
自2017年起,Keras得到了Tensorflow团队的支持,其大部分组件被整合至Tensorflow的
Python API中。在2018年Tensorflow 2.0.0公开后,Keras被正式确立为Tensorflow高阶API,即tf.keras 。此外自2017年7月开始,Keras也得到了CNTK 2.0的后台支持 。
在2019年9月17日Keras稳定版本2.3.0的更新文档中,Keras团队宣布了计划调整:在该版本之后,Keras将集中于Tensoflow后台的有关内容,多后台Keras的开发优先度被降低,且更新将仅包含补丁(bug fix),不会有新的功能性内容移植/加入 。
Keras的命名来自古希腊语“κέρας (牛角)”或 “κραίνω(实现)”,意为将梦境化为现实的“牛角之门” 。由荷马史诗《
奥德赛》第19卷佩涅罗佩与
奥德修斯的对话,无法挽留的梦幻拥有两座门,一座门由牛角制成,一座门由象牙制成,象牙之门内光彩夺目,却仅是无法实现的梦境;唯有走进牛角之门,才能由梦境看见真实 。
安装
Keras支持Python 2.7-3.6版本,且安装前要求预装
TensorFlow、Theano、
微软CNTK中的至少一个 。其它可选的预装模块包括:h5py,用于将Keras模型的保存为HDF文件;cuDNN,用于GPU计算;PyDot,用于模型绘图 。Keras可以通过PIPy、Anaconda安装,也可从
GitHub上下载源代码安装 :
神经网络
Keras的神经网络API是在封装后与使用者直接进行交互的API组件,在使用时可以调用Keras的其它组件。除数据预处理外,使用者可以通过神经网络API实现机器学习任务中的常见操作,包括人工神经网络的构建、编译、学习、评估、测试等 。
属性与方法
Keras支持序列化模型和函数化模型,且二者具有一定数量的公有属性(attribute)和方法(method)。其中的公有属性包括layers、inputs、outputs,能够以
Python列表的形式返回模型信息 :
Keras模型的公有方法主要与模型权重和结构有关,这里分别介绍如下:
搭建模型
序列化模型(keras.models.Sequential)
Keras的序列化模型是由其API中层对象(参考“层API”)堆叠得到的神经网络模型 。序列化模型有两种定义方式,一种是运行keras.models.Sequential时由列表指定所有的层对象,另一种是在运行时不指定层API,而是对Sequential类使用model.add添加层对象,这里给出使用的例子:
序列模型不显式定义输入层,因此其第一个层对象要求指定输入数据的大小,例子中使用了参量input_shape,也可等价地使用参量input_dim 。
函数化模型(keras.models.Model)
Keras的函数化模型也被称为functional API,其功能是将一个
张量指定为输入,另一个张量指定为输出,并将与输入、输出张量之间存在连接的节点(层对象)组合成神经网络模型 。这里提供一个函数化模型的使用例子。
相比于序列化模型,函数化模型显示定义了隐含层的张量,因此可以更容易地搭建非序列化的模型,具有更好的可扩展性。此外,Keras的函数化模型支持自定义的子类继承 ,但在定义子类时,模型的拓扑结构由Keras的
Python代码而不是层对象的静态图指定,因此一部分基于模型静态图的方法在子类继承后无法使用 。
使用模型
编译(model.complie)
Keras模型的编译由model.compile实现,运行时可将Keras代码翻译为后台代码以执行学习、评估等后续操作。编译可以指定学习组件(参考“学习与优化API”),其使用格式如下 :
格式中各参量的含义和调用方法如下 :
除上述参量外,根据后台的不同,model.compile也可以将其它参量和关键字传递至keras.backend.
函数或tf.Session.run。
学习(model.fit、model.fit_generator)
模型编译完成后可以使用model.fit或model.fit_generator进行学习,其使用格式如下 :
model.fit和model.fit_generator的使用格式包含一些共有的参量,其含义和调用方法如下 :
除上述共有参量外,对model.fit,其余参量的含义和调用方法如下:
对model.fit_generator,其余参量的含义和调用方法如下:
评估(model.evaluate、model.evaluate_generator)
在模型完成学习后,Keras提供model.evaluate和model.evaluate_generator进行模型评估,二者的使用格式如下 :
测试(model.predict、model.predict_generator、model.predict_on_batch)
Keras模型可以通过model.predict、model.predict_generator和model.predict_on_batch进行测试,其使用格式如下 :
层
这里对Keras的层API(keras.layers)进行介绍。在Keras的神经网络API中,层API创建的层对象被用于搭建模型 。
属性与方法
Keras的层API包含一些共有方法,这些方法与给定层对象的结构和权重更新有关 :
当一个层对象仅有一个节点,即没有层对象的合并时,上述方法按属性的形式使用 :
作为进一步说明,Keras中所有的层(子类),除输入层外都继承自keras.engine.base_layer.Layer类,在该类中,层的“节点”是输入和输出
张量的连结。例如在顺序连结的Keras模型中,每个层对象都只有一个节点,但包含共享输入或输出的层对象,例如keras.layers.concatenate按张量映射的顺序,包含了多个节点 。
核心层
输入层(keras.layers.Input)
Keras的输入层继承自keras.engine.input_layer,是一个后台张量,例如tf.Tensor的实现。由Keras的输入层子类创建层对象的方式为 :
格式中各参量的含义和调用方法如下 :
全连接层(keras.layers.Dense)
Keras内部全连接层对象的创建方式为 :
格式中各参量的含义和调用方法如下 :
激活层(keras.layers.Activation)
Keras支持创建独立的激活层对象,其创建方式为 :
格式中的activation表示一个Keras的激活函数对象、例如keras.activations.sigmoid。将激活层前置于全连接层时可以实现神经网络中的预激活(pre-activation)操作。激活层和全连接层中的activation参量不产生冲突,同时使用时会分别进行激活函数计算 。此外Keras也可以直接从层API创建激活层,参考“特殊激活层”。
随机失活层
参考:随机失活
Keras支持随机连接失活和随机空间失活,可用的子类包括Dropout、SpatialDropout1D、SpatialDropout2D和SpatialDropout3D,其创建方式为 :
格式中rate接收一个0和1之间的
浮点数,表示随机失活的比率。Dropout中noise_shape表示随机失活对
张量各个维度的操作,例如对输入张量(t,x,y),给定noise_shape=(1,x,y)时,输入张量(x,y)维度的随机失活在t维不变。默认值None表示完全的随机连接失活 。
Keras中的随机空间失活,例如SpatialDropout2D会随机归零整个通道,例如对4维张量(t,x,y,c),2维的随机空间失活会随机选择某个c维和t维上所有的(x,y)元素归零 。
输出正则化层(keras.layers.ActivityRegularization)
Keras提供了独立的输出正则化层子类,并支持L1和L2正则化方法,其创建方式为 :
格式中的l1和l2接收对应的正则化系数。输出正则化层和全连接层中的activity_regularizer参量不产生冲突,使用时会分别执行正则化操作 。
Keras在层API中提供了支持特定张量操作的层类。由于张量操作层所进行的操作均可以类比
numpy数组中的对应操作,因此这里仅对张量操作层进行简单介绍 :
卷积层与池化层
参考:卷积神经网络
Keras内置了一系列1维至3维的卷积层和池化层子类用于搭建卷积神经网络,且作为特色地,加入了深度可分卷积、转置卷积、扩张卷积等较为复杂的构筑。另注意到,Keras中卷积层和池化层的“维度”是特征图的维度,即一个keras的2维卷积层对象的输入和输出都是4维
张量,通常为(样本/批次, 特征图第1维, 特征图第2维, 通道)。在指定data_format时也可以为(通道, 特征图第1维, 特征图第2维, 样本/批次) 。
卷积层与深度可分卷积层
Keras包含1维至3维的卷积层,以及2维和3维的深度可分卷积层子类:Conv[1-3]D、SeparableConv[1,2]D。以2维情形为例,其对象的创建方式为 :
格式中共有参量的含义和调用方法如下 :
SeparableConv[1,2]D中参量的含义和调用方法如下 :
极大池化、均值池化与全局池化层
Keras支持1维到3维的极大池化、均值池化和全局池化:MaxPooling[1-3]D、AveragePooling[1-3]D、GlobalMaxPooling[1-3]D、GlobalAveragePooling[1-3]D。以2维极大池化和全局极大池化为例,池化层对象的创建方式为 :
格式中pool_size接收一个
Python元组,表示池化层感受野的大小,其余参量的调用方法与keras.layers.Conv2D相同。
转置卷积与反池化层
Keras包含2维和3维的转置卷积子类:Conv[2,3]DTranspose,以及1维至3维的反池化层子类:UpSampling[2,3]D。以2维情形为例,其创建方式为 :
Conv2DTranspose的参量的含义和调用方法如下 :
UpSampling2D中参量size表示反池化的放大系数,例如一个100x100特征图在经过size=(2, 2)的反池化后会输出200x200的特征图。keras.layers.UpSampling2D中的interpolation仅对Tensorflow后台有效,表示反池化的差值方法,默认值‘nearest’表示最接近原则插值,也可接收'bilinear'表示双线性插值 。
裁剪和0值填充层
Keras支持创建2维和3维特征图的裁剪层对象:Cropping2D、Cropping3D;以及独立的1维至3维0值填充层对象:ZeroPadding1D、ZeroPadding2D、ZeroPadding3D,以2维情形为例,其创建方式分别为 :
参量cropping接收2维或3维元组,表示由特征图边缘向中心裁剪去除的像素个数,对多维元组,其顺序为((第1维左, 第1维右), (第2维左, 第2维右))以此类推。cropping也接收单个整数,表示对特征图的所有维度进行相同像素的裁剪 。参量中的padding表示特征图各维度上0值填充的层数。
循环层与循环单元
参考:循环神经网络
Keras提供循环层和循环单元用于构建循环神经网络,二者是keras.engine.base_layer.Layer类的子类,属于层API的一部分,其中循环层是在功能上与其它层对象相当的构筑,可以直接堆叠得到神经网络模型;循环单元是循环层内对序列数据的每个时间步进行(系统)状态和输出进行处理的模块,一个循环层可以包含一个或多个循环单元 。
循环单元子类
Keras的循环单元子类包括简单循环单元(SimpleRNNCell)、长短期记忆单元(LSTMCell)、门控循环单元(GRUCell),其对应的子类实现方式如下:
简单循环单元的创建方式为 :
格式中3类循环单元共有的参量的含义和调用方法如下 :
格式中LSTMCell和GRUCell共有的参量的含义和调用方法如下 :
对LSTMCell,unit_forget_bias是其控制遗忘门偏差量初始化的参量,默认值为True,表示将遗忘门偏差量的初始值设定为1.0。对GRUCell,reset_after=False表示在时序输入与权重矩阵相乘后使用复位门 。此外LSTM单元有对应的循环卷积单元子类 。
循环层子类
Keras的循环层子类包括一个可接收任意循环单元的子类:keras.layers.RNN,和预设了特定循环单元的子类:SimpleRNN、GRU、LSTM、LSTM2D 。不是一般性这里只对通用的子类进行介绍:
格式中参量的含义和调用方法如下 :
预设了特定循环单元的循环层子类包含了keras.layers.RNN的所有参量,以及对应循环单元的参量。
层间合并
Keras提供了8个层子类用于隐含层的合并,按对应的
张量操作方式包括:加Add、减Subtract、乘Multiply、取均值Average、取极大值/极小值Maximum/Minimum、拼接Concatenate、点乘Dot。当上述子类的名称为全小写时,即add、multiply等,表示该子类的函数化接口 。
层间合并子类的输入为一个列表,列表内按顺序包含需要合并的张量,这里对张量的拼接给出一个例子:
自定义层
Keras可以使用自定义的层对象搭建模型,具体地,一个自定义层子类必须包含3个特定方法,其含义介绍如下 :
其它子类
除上述子类外,keras的层API还包含一些其它子类,这里将其列出并简要介绍:
学习与优化
优化器
Keras内置了7个可在反向传播算法框架内使用的优化器(keras.optimizers),这些优化器按keras.optimizers.Optimizer的子类进行封装,这里对优化器的名称和实现进行介绍 :
优化器包含共用参数,其中lr表示学习
速率,接收大于0的
浮点数、decay表示学习速率随纪元的递减,默认值为0,表示学习速率无递减、epsilon表示最小
常数,默认值为keras.backend.epsilon。其余参数为各优化器可选的超参数 。
表格中优化器可以按关键字调用,关键字为小写的子类名称,例如keras.optimizers.Adam的关键字为'adam'。按关键字调用优化器时,其超参数取默认值 。
初始化器
Keras的初始化器子类(keras.initializers)提供了在创建层对象(时需要指定的权重初始化方法 。所有的Keras初始化器都继承自keras.initializers.Initializer,通过对Initializer进行子类继承,也可以自定义初始化器。这里列出Keras可用的所有初始化器:
正则化器
正则化器(keras.regularizers)类提供了神经网络学习的正则化操作,即在计算损失函数时考虑该层权重的范数。Keras的正则化器继承自keras.regularizers.Regularizer类,包括L1正则化、L2正则化和两者的线性叠加,共3个子类 :keras.regularizers.l1、l2、l1l2。注意到,正则化器中的正则化系数,是正则化项(而非经验风险项)相乘的系数。
参数限制器
Keras中参数限制器(keras.constraints)类的功能是将神经网络权重的取值限定在一个范围内,防止神经网络在学习过程中出现个别高权重节点控制整体输出的情形出现;在特定问题下可使神经网络仅包含非负权重 。keras.constraints包含4个预设子类:MaxNorm、NonNeg、UnitNorm、MinMaxNorm,功能分别为限制权重极大值、限制负权重、权重(范数)归一化、权重0-1标准化 。
回调函数
Keras的回调函数(keras.callbacks)是一个特殊的类,其功能是在模型的学习过程中按条件触发给定的操作。Keras的回调函数预置了12个子类,也支持用户自定义的子类继承。一般地,回调函数对象在按列表的形式组织后可以在Keras神经网络API中进行调用:
记录与监控工具
Keras的内置回调函数中包含了一系列可用于记录和监控模型行为的子类:BaseLogger、CSVLogger、ProgbarLogger、History、RemoteMonitor、TensorBoard。其中BaseLogger和History在模型学习时会默认加载,其余的回调函数为可选加载。
检查点
ModelCheckpoint可以在模型学习的迭代过程中对模型进行备份,其对象的创建方式如下:
动态调参和早停工具
Keras的内置回调函数包含了动态调整学习参数和进行学习终止判定的子类,包括LearningRateScheduler、ReduceLROnPlateau、TerminateOnNaN、EarlyStopping,其中前2个子类用于调节优化器的学习
速率(参考“优化器”),后2个子类分别为异常值终止和早停法。上述对象的创建方式如下:
自定义回馈器
使用者可以通过在LambdaCallback中指定操作或对Callback进行子类继承创建自定义的回调函数。对第1种选择,LambdaCallback对象的创建方法为:
这里LambdaCallback的使用方法类似于
Python中的匿名函数,格式中的6个参数表示在学习的不同阶段可以进行的操作。
后台API
Keras作为一个高阶应用程序接口,其底层计算不是独立完成的,而是构架于支持
张量计算的符号数学库之上,截至稳定版本2.2.4,Keras支持的底层构架包括Tensorflow、
微软CNTK和Theano。Keras的后台API(keras.backend)包含一系列与后台交互的组件,这些组件中的部分函数对所有后台通用,但也包含一部分限制于特定后台的函数和类 。
通用后台工具
Keras后台API的一些函数和类能够不依赖于特定的后台类型直接操作张量,这些函数在Keras文档中被称为“抽象后台(abstract Keras backend)函数”。后台API的抽象函数超过50个,按功能包括定义
张量,例如keras.backend.placeholder、查看与检索张量,例如keras.backend.print_tensor、对张量进行计算,例如keras.backend.abs、内置函数/子类的计算,例如keras.backend.gradients、查看与修改后台设置,例如keras.backend.backend、keras.backend.set_epsilon以及通用的后台计算交互,例如keras.backend.ckear_session等 。
后台指令交互
Keras后台API的一部分类是面向特定后台设计的,在导入keras后台,例如"import keras.backend as K"后,按后台选项,可通过K.tf和K.th调出
TensorFlow和Theano的后台。在K.tf和K.th可以直接接收对应的后台指令,这里给出一个Tensorflow后台的例子 :
keras.json
Keras在导入后会生成一份json文件,通常位于用户主目录下的.keras/keras.json,该文件定义了Keras的全局选项,并显式指定了后台。这里给出一个后台文件的例子 :
通过后台API可以查看keras.json的内容,例如对上述例子keras.backend.epsilon会返回1e-07。修改keras.json的“backend”可以切换Keras的后台 。
数据预处理
序列
Keras的序列数据预处理API可用于对时间序列和字符嵌入后的文本序列进行预处理。这里简要列出其功能 :
文本
Keras提供了文本数据预处理的类和函数,这里简要列出其功能 :
图像
Keras的图像数据预处理API是1个图像的生成器类:keras.preprocessing.image.ImageDataGenerator。在给定图像样本后,ImageDataGenerator可以进行数据强化(data augmentation)操作,包括旋转、反转、平移、
白化病等并输出图像 。
其它组件
函数
损失函数(keras.losses)
Keras以函数的形式定义了可用于神经网络学习和评价的损失函数,这里按表格的形式给出其内置损失函数的名称,代码和说明 :
Keras的所有损失函数都接收2个输入,按顺序为代表真实值和代表预测值的
张量,以
TensorFlow为后台时,是tf.Tensor类,接收张量的大小必须匹配 。
表格中的损失函数可以按关键字调用,关键字与函数名相同,例如keras.losses.categorical_crossentropy的关键字为‘categorical_crossentropy’。一些损失函数的关键字有别名,例如keras.losses.mean_squared_error的关键字为可以为'mean_squared_error'或'mse' 。
激活函数(keras.activations)
Keras按两类方式提供神经网络模型的激活函数:一部分作为keras.engine.base_layer.Layer的子类被封装至层API中,另一部分则按函数的形式定义 。这里给出按函数形式定义的激活函数 :
激活函数接收一个
张量并返回一个相同大小的张量,keras.activations.softmax的参数axis表示归一化的维度,默认为张量的最后1维,keras.activations.relu和keras.activations.elu的参数为其超参数 。
表格中激活函数可以按关键字调用,关键字与函数名相同。按关键字调用激活函数时,激活函数的超参数取默认值 。
评价函数(keras.metrics)
在应用方面,keras.losses中定义的所有函数均可作为评价函数使用,此外,keras.metrics额外定义了5个评价函数 :
上述评价函数接收2个输入,按顺序为代表真实值和代表预测值的
张量,张量大小必须匹配。评价函数可以按关键字调用,例如keras.metrics.binary_accuracy的关键字为'binary_accuracy'或'acc' 。
通用工具
Keras提供了神经网络学习中可用的其它通用工具(keras.utils),这里将其列出 :
Scikit-Learn封装器
完成编译(和学习)的keras模型可以通过Scikit-Learn封装器输出1个Scikit-Learn对象并加入到其环境下的机器学习和统计学习流程中 。具体地,keras分类器使用keras.wrappers.scikit_learn.KerasClassifier进行封装,keras回归器使用keras.wrappers.scikit_learn.KerasRegressor进行封装,封装时可以使用Scikit-Learn对象的共有属性和方法,包括fit、predict、predict_proba、score等 。该API要求
Python环境预装Scikit-Learn 。
预编译模型
这里按表格的形式给出keras包含的预编译模型 :
自带数据
Keras包含6份自带数据集,这里按表格形式给出其元数据 :
生态系统
Keras在
谷歌 Group和
slack上有用户交流区,细节有在其官方文档的主页列出 。错误报告和新功能请求可以通过Keras在
GitHub的开发者页面进行反馈 。在Keras的Github项目页面上,有列出开发计划,用户可以申请加入并贡献内容 。此外,Keras官方文档有介绍反馈错误和参与开发的准则 。
Keras包含一些与神经网络的微调和结构优化有关的子项目,包括AutoKeras 和Keras-Tuner ,截至Keras主分支版本2.2.4,二者均处于开发阶段,未提供稳定版本。
比较与评价
根据其官方文档,Keras在开发时的关注点包括:用户友好、模块化、可扩展性和完全的
Python支持。Keras同时也提供了由代码-产品间转化的途径,例如支持在iOS的Apple's CoreML 、Android的
TensorFlow运行以及网页的
ECMAScript运行 。
Keras被认为是深度学习开发端受到关注的工具之一,例如在2018年的一份测评中,Keras的普及率仅次于TensorFlow,超过了
PyTorch、
微软CNTK和Theano 。
参考资料
Warning: Invalid argument supplied for foreach() in
/www/wwwroot/newbaike1.com/id.php on line
362