浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
【题目】keras中的Merge层(实现层的相加、相减、相乘)
详情请参考:
Merge层
一、层相加
keras.layers.Add()
添加输入列表的图层。
该层接收一个相同shape列表张量,并返回它们的和,shape不变。
Example
importkeras input1=keras.layers.Input(shape=(16,)) x1=keras.layers.Dense(8,activation='relu')(input1) input2=keras.layers.Input(shape=(32,)) x2=keras.layers.Dense(8,activation='relu')(input2) added=keras.layers.Add()([x1,x2])#equivalenttoadded=keras.layers.add([x1,x2]) out=keras.layers.Dense(4)(added) model=keras.models.Model(inputs=[input1,input2],outputs=out)
二、层相减
SubStract
keras.layers.Subtract()
两个输入的层相减。
它将大小至少为2,相同Shape的列表张量作为输入,并返回一个张量(输入[0]-输入[1]),也是相同的Shape。
Example
importkeras input1=keras.layers.Input(shape=(16,)) x1=keras.layers.Dense(8,activation='relu')(input1) input2=keras.layers.Input(shape=(32,)) x2=keras.layers.Dense(8,activation='relu')(input2) #Equivalenttosubtracted=keras.layers.subtract([x1,x2]) subtracted=keras.layers.Subtract()([x1,x2]) out=keras.layers.Dense(4)(subtracted) model=keras.models.Model(inputs=[input1,input2],outputs=out)
三、层相乘
Multiply
keras.layers.Multiply()
该层接收一个列表的同shape张量,并返回它们的逐元素积的张量,shape不变。
注意:keras.layers.add(inputs)、keras.layers.subtract(inputs)、keras.layers.multiply(inputs)分别是对应的层包装,一般只用层包装。
补充知识:Keras天坑:想当然的对层的直接运算带来的问题
天坑
keras如何操作某一层的值(如让某一层的值取反加1等)?keras如何将某一层的神经元拆分以便进一步操作(如取输入的向量的第一个元素乘别的层)?keras如何重用某一层的值(如输入层和输出层乘积作为最终输出)?
这些问题都指向同一个答案,即使用Lambda层。
另外,如果想要更加灵活地操作层的话,推荐使用函数式模型写法,而不是序列式。
Keras当中,任何的操作都是以网络层为单位,操作的实现都是新添一层,不管是加减一个常数还是做乘法,或者是对两层的简单拼接。
所以,将一层单独劈一半出来,是一件难事。强调,Keras的最小操作单位是Layer,每次操作的是整个batch。
自然,在keras中,每个层都是对象,可以通过dir(Layer对象)来查看具有哪些属性。
然而,Backend中Tensorflow的最小操作单位是Tensor,而你搞不清楚到底是Layer和Tensor时,盲目而想当然地进行层的操作,就会出问题。到底是什么?通过type和shape是看不出来的。
如果你只是想对流经该层的数据做个变换,而这个变换本身没有什么需要学习的参数,那么直接用LambdaLayer是最合适的了。
也就是说,对每一层的加减乘除都得用keras的函数,你不能简单使用形如‘new_layer'=1−=1-=1−'layer'这样的表达方式来对层进行操作。
当遇到如下报错信息:
AttributeError:'NoneType'objecthasnoattribute'_inbound_nodes'
或
TypeError:'Tensor'objectisnotcallable
等等
这是就要考虑一下将程序中层的操作改成Lambda的方式表达。
使用Lambda编写自己的层
Lamda层怎么用?官方文档给了这样一个例子。
#addax->x^2layer model.add(Lambda(lambdax:x**2)) #addalayerthatreturnstheconcatenation #ofthepositivepartoftheinputand #theoppositeofthenegativepart defantirectifier(x): x-=K.mean(x,axis=1,keepdims=True) x=K.l2_normalize(x,axis=1) pos=K.relu(x) neg=K.relu(-x) returnK.concatenate([pos,neg],axis=1) defantirectifier_output_shape(input_shape): shape=list(input_shape) assertlen(shape)==2#onlyvalidfor2Dtensors shape[-1]*=2 returntuple(shape) model.add(Lambda(antirectifier, output_shape=antirectifier_output_shape))
乍一看,有点懵逼,什么乱七八糟的。事实上,很简单,假设L0和L1是两层,你只要将你形如下面这样的表达:
L1=F(L0);
改成
L1=Lambda(lambdaL0:F(L0))(L0)
即可。为了看得清楚,多加了几个空格。
事实上,无非就是将原来的变换,通过Lambda(lambda输入:表达式)这样的方式,改成了Lambda型函数,再把输入传进去,放在尾巴上即可。
参考
https://keras-cn.readthedocs.io/en/latest/layers/core_layer/#lambda
(个人觉得这份文档某些地方比官方中文要完整许多)
keras许多简单操作,都需要新建一个层,使用Lambda可以很好完成需求。当你不知道有这个东西存在的时候,就会走不少弯路。
以上这篇浅谈keras中的Merge层(实现层的相加、相减、相乘实例)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。