Keras中ReLU与LeakyReLU的实现差异及带alpha参数的ReLU导入方法
首先来解决你的核心疑问,再帮你搞定代码里的问题:
一、二者的本质差异
其实在Keras的实现里,带alpha参数的ReLU和LeakyReLU在计算逻辑上是完全一致的——当alpha>0时,relu(x, alpha=alpha)的输出规则就是LeakyReLU的定义:x>0输出x,x<0输出alpha*x。它们的区别主要在于封装形式:
keras.activations.relu是一个激活函数,可以通过调整alpha参数切换普通ReLU和LeakyReLU的行为,适合作为参数直接传给Dense等层的activation参数。keras.layers.LeakyReLU是一个独立的层类,专门封装了LeakyReLU的逻辑,作为一个层添加到模型中,使用起来更直观,不需要手动处理函数调用。- 另外Keras还有
keras.layers.ReLU(注意是大写的层类),它支持传入alpha参数,本质上是把带参数的relu函数封装成了层,当你设置alpha>0时,它的效果和LeakyReLU层完全一样。
简单说:LeakyReLU是专门针对负区间有斜率的场景做的层封装,而带alpha的ReLU(不管是函数还是ReLU层)是一个更通用的实现,覆盖了普通ReLU和LeakyReLU的所有情况。
二、如何导入并使用带alpha参数的ReLU
你遇到的报错和无法传参的问题,都是因为使用方式不对,下面给你两种正确的方案:
方案1:使用ReLU层类(和LeakyReLU的使用方式完全一致)
直接导入大写的ReLU层类,它支持传入alpha参数,替换你原来的LeakyReLU层即可:
from keras.layers import Dense, ReLU # ... 其他模型定义代码 model.add(Dense(512, activation='linear')) model.add(ReLU(alpha=0.001)) # 这里直接替换成ReLU层,传入alpha参数
方案2:在Dense层中直接调用带参数的relu函数
如果你不想单独加一层,可以用lambda表达式把带alpha的relu函数传给activation参数:
from keras.layers import Dense from keras.activations import relu # ... model.add(Dense(512, activation=lambda x: relu(x, alpha=0.001)))
为什么你之前的代码会报错?
你之前的错误AttributeError: 'LeakyReLU' object has no attribute '__name__',大概率是你尝试把relu函数(小写的激活函数)当成层来add了——只有层类(比如ReLU、LeakyReLU)才能用model.add()添加,而小写的relu是函数,不能直接作为层添加。
另外,model.add(Activation('relu'))没法传alpha是因为用字符串指定激活函数时,Keras会使用默认参数初始化,没法传递自定义参数,所以需要用lambda或者直接用ReLU层类来解决。
内容的提问来源于stack exchange,提问作者Rodrigo Laguna

