我尝试在CNN层上应用ReLU和PReLU以比较结果,并尝试了以下代码:
with ReLU:
model.add(Conv1D(filters, kernel_size, activation='relu'))
使用PReLU:
model.add(Conv1D(filters, kernel_size))
model.add(PReLU())
Conv1D层是否使用PReLU作为激活功能?
我怀疑,因为我打印了模型摘要,它显示了CNN和PReLU之间具有不同数量参数的单独层,同时具有ReLU功能的CNN层位于同一层。
如果我使用了错误的代码,如何纠正它?
是的,Conv1D层将使用PReLu激活功能。当您定义Conv2D
层时,
x = tf.keras.layers.Conv2D( 13 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' )( inputs )
以上陈述等同于,
x = tf.keras.layers.Conv2D( 13 , kernel_size=( 3 , 3 ) , strides=1 )( inputs )
x = tf.keras.layers.Activation( 'relu' )( x )
将激活功能提供为单独的层的原因是,有时我们需要在将特征图传递给激活功能之前将逻辑添加到特征图。
例如,在将要素映射传递到激活功能之前,添加了BatchNormalization
层,
x = tf.keras.layers.Conv2D( 13 , kernel_size=( 3 , 3 ) , strides=1 )( inputs )
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Activation( 'relu' )( x )
回到您的问题,
[一些特殊的激活函数,例如elu
,LeakyReLU
和PReLU
被添加为单独的层,我们无法使用Conv1D
参数将它们包括在activation=
层中。
关于可训练参数,conv1d_18
层具有15050个参数,这些参数形成一维卷积的内核。这些参数与激活功能无关。
PReLU
的4900参数是通过反向传播优化的斜率参数。这些参数以及内核权重将随每批更新,因此包含在可训练的参数中。
因此,
Conv1D
层的输出(未激活)将通过PReLU
激活,它实际上使用斜率参数来计算激活的输出。
这将等效
model.add(Dense(64))
model.add(Activation('tanh'))
至此
model.add(Dense(64, activation='tanh'))
我不知道为什么必须将高级激活功能用作层,而PReLu可以与CNN一起使用,并且完全没有问题。