Keras

一. Backend:

这个模块的主要作用,是对tensorflow和theano的底层张量运算进行了包装。用户不用关心具体执行张量运算的是theano还是tensorflow,就可以编写出能在两个框架下可以无缝对接的程序。

j介绍几个有用的函数:

1. function:毫无疑问这估计是最有用的一个函数了,function用于将一个计算图(计算关系)编译为具体的函数。典型的使用场景是输出网络的中间层结果。

2. int_shape:用于以整数tuple的形式返回张量的shape。要知道从前网络输出张量的shape是看都看不到的,int_shape可以在debug时起到很大作用。

3. image_ordering和set_image_ordering:这组函数用于返回/设置图片的维度顺序,由于Theano和Tensorflow的图片维度顺序不一样,所以有时候需要获取/指定。典型应用是当希望网络自适应的根据使用的后端调整图片维度顺序时。

4. learning_phase:这个函数的主要作用是返回网络的运行状态,0代表测试,1代表训练。当你需要便携一个在训练和测试是行为不同的层(如Dropout)时,它会很有用。

5. gradients: 求损失函数关于变量的导数,也就是网络的反向计算过程。这个函数在不训练网络而只想用梯度做一点奇怪的事情的时候会很有用,如图像风格转移。

backend的其他大部分函数的函数名是望而知义的,什么max,min,equal,eval,zeros,ones,conv2d等等。函数的命名方式跟numpy差不多,下次想用时不妨先‘.’一下,说不定就有。

二. models/layers:Keras的核心主题

使用Keras最常见的目的,当然还是训练一个网络。之前说了网络就是张量到张量的映射,所以Keras的网络,其实是一个由多个子计算图构成的大计算图。当这些子计算图是顺序连接时,称为Sequential,否则就是一般的model,我们称为泛型模型。

模型有两套训练和测试的函数,一套是fit,evaluate等,另一套是fit_generator,evaluate_generator,前者适用于普通情况,后者适用于数据是以迭代器动态生成的情况。迭代器可以在内存/显存不足,实时动态数据提升进行网络训练,所以使用Keras的话,Python的迭代器这一部分是一定要掌握的内容。对模型而言,最核心的函数有两个:

1. compile():编译,模型在训练前必须编译,这个函数用于完成添加正则项啊,确定目标函数啊,确定优化器啊等等一系列模型配置功能。这个函数必须指定的参数是优化器和目标函数,经常还需要指定一个metrics来评价模型。

2. fit()/fit_generator():用来训练模型,参数较多,是需要重点掌握的函数,对于keras使用者而言,这个函数的每一个参数都需要掌握。

模型还有几个常用的属性和函数:

  • layers:该属性是模型全部层对象的列表,是的就是一个普通的python list
  • get_layer():这个函数通过名字来返回模型中某个层对象
  • pop():这个函数文档里没有,但是可以用。作用是弹出模型的最后一层,从前进行finetune时没有pop,大家一般用model.layers.pop()来完成同样的功能。

因为Model是Layer的子类,Layer的所有属性和方法也自动被Model所有,这些有用的属性稍后介绍。

Keras的层对象是构筑模型的基石,除了卷积层,递归神经网络层,全连接层,激活层这种烂大街的Layer对象外,Keras还有一些不是那么烂大街的东西:

  • Advanced Activation:高级激活层,主要收录了包括leakyReLU,pReLU,ELU,SReLU等一系列高级激活函数,这些激活函数不是简单的element-wise计算,所以单独拿出来实现一下
  • Merge层:这个层用于将多个层对象的输出组合起来,支持级联、乘法、余弦等多种计算方式,它还有个小兄弟叫merge,这个函数完成与Merge相同的作用,但输入的对象是张量而不是层对象。
  • Lambda层:这是一个神奇的层,看名字就知道它用来把一个函数作用在输入张量上。这个层可以大大减少你的工作量,当你需要定义的新层的计算不是那么复杂的时候,可以通过lambda层来实现,而不用自己完全重写。
  • Highway/Maxout/AtrousConvolution2D层
  • 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可以将递归神经网络展开,以空间换取运行时间。

Keras的层对象还有一些有用的属性和方法,比较有用的是:

  • name:别小看这个,从茫茫层海中搜索一个特定的层,如果你对数数没什么信心,最好是name配合get_layer()来用。
  • trainable:这个参数确定了层是可训练的还是不可训练的,在迁移学习中我们经常需要把某些层冻结起来而finetune别的层,冻结这个动作就是通过设置trainable来实现的。
  • input/output:这两个属性是层的输入和输出张量,是Keras tensor的对象,这两个属性在你需要获取中间层输入输出时非常有用
  • get_weights/set_weights:这是两个方法用于手动取出和载入层的参数,set_weights传入的权重必须与get_weights返回的权重具有同样的shape,一般可以用get_weights来看权重shape,用set_weights来载入权重

要在Keras中编写一个自己的层,需要开一个从Layer(或其他层)继承的类,除了__init__ 外你需要覆盖三个函数:

  • build,这个函数用来确立这个层都有哪些参数,哪些参数是可训练的哪些参数是不可训练的。
  • call,这个函数在调用层对象时自动使用,里面就是该层的计算逻辑,或计算图了。显然,这个层的核心应该是一段符号式的输入张量到输出张量的计算过程。
  • get_output_shape_for:如果你的层计算后,输入张量和输出张量的shape不一致,那么你需要把这个函数也重新写一下,返回输出张量的shape,以保证Keras可以进行shape的自动推断

objectives是优化目标, 它本质上是一个从张量到数值的函数,当然,是用符号式编程表达的。具体的优化目标有mse,mae,交叉熵等等等等,根据具体任务取用即可,当然,也支持自己编写。需要特别说明的一点是,如果选用categorical_crossentropy作为目标函数,需要将标签转换为one-hot编码的形式,这个动作通过utils.np_utils.to_categorical来完成。

optimizers是优化器,没什么可说了,如何选用合适的优化器不在本文讨论范畴。注意模型是可以传入优化器对象的,你可以自己配置一个SGD,然后将它传入模型中。 另外,最新版本的Keras为所有优化器额外设置了两个参数clipnorm和clipvalue,用来对梯度进行裁剪。

activation是激活函数,这部分的内容一般不直接使用,而是通过激活层Activation来调用,此处的激活函数是普通的element-wise激活函数,如果想使用高级激活函数,请翻到高级激活函数层。

History是模型训练函数fit的返回值,也就是说即使你没有使用任何回调函数,找一个变量接住model.fit(),还是能得到不少训练过程中的有用信息。

另外,回调函数还支持将信息发送到远程服务器,以及与Tensorflow的tensorboard联动,在网页上动态展示出训练和测试的情况(需要使用tensorflow为后端)

回调函数支持用户自定义,定义方法也非常简单,请参考文档说明编写即可。

utils文档中没有,里面包含的函数也不必怎么了解,除了两个。一个是说了很多遍的to_catgoraical,另一个是convert_kernel。后者的主要作用是把卷积滤波器的卷积核在 theano 和 tensorflow 之间互相转换。

utils出了一个新的layer_utils,里面有一个convert_all_kernels_in_model函数,用来把一个模型的所有卷积核全部进行转换,以后就用这个吧~

 

posted @ 2019-06-27 16:26  爱学英语的程序媛  阅读(611)  评论(0编辑  收藏  举报