如何在Keras中使用高级激活层?

34
这是我的代码,如果我使用其他激活层(如tanh),它就可以正常工作:
model = Sequential()
act = keras.layers.advanced_activations.PReLU(init='zero', weights=None)
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(Activation(act))
model.add(Dropout(0.15))
model.add(Dense(64, init='uniform'))
model.add(Activation('softplus'))
model.add(Dropout(0.15))
model.add(Dense(2, init='uniform'))
model.add(Activation('softmax'))

sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose = 2)
在这种情况下,它无法正常工作并显示“TypeError: 'PReLU' object is not callable”,错误出现在model.compile行。为什么会这样?所有非高级激活函数都可以正常工作。然而,包括这个的所有高级激活函数都不能正常工作。
3个回答

33

使用高级激活函数(如PReLU)的正确方法是使用add()方法,而不是使用Activation类进行包装。例如:

model = Sequential()
act = keras.layers.advanced_activations.PReLU(init='zero', weights=None)
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(act)

1
如果我们有两个密集的全连接层,我们应该在它们的每个之后添加吗?如果我们还有dropout,该怎么办? - fermat4214
在ReLU的情况下,无论你是在激活函数之前还是之后添加Dropout都无关紧要(也许只有性能上的差异,但结果将是相同的)。 - Tarantula

21
如果在Keras中使用Model API,您可以直接调用Keras Layer中的函数。这是一个例子:
from keras.models import Model
from keras.layers import Dense, Input
# using prelu?
from keras.layers.advanced_activations import PReLU

# Model definition
# encoder
inp = Input(shape=(16,))
lay = Dense(64, kernel_initializer='uniform',activation=PReLU(),
            name='encoder')(inp)
#decoder
out = Dense(2,kernel_initializer='uniform',activation=PReLU(), 
            name='decoder')(lay)

# build the model
model = Model(inputs=inp,outputs=out,name='cae')

5

对于Keras函数式API,我认为正确地结合Dense和PRelu(或任何其他高级激活函数)的方法是这样使用:

focus_tns =focus_lr(enc_bidi_tns)

enc_dense_lr = k.layers.Dense(units=int(hidden_size))
enc_dense_tns = k.layers.PReLU()(enc_dense_lr(focus_tns))

dropout_lr = k.layers.Dropout(0.2)
dropout_tns = dropout_lr(enc_dense_tns)

enc_dense_lr2 = k.layers.Dense(units=int(hidden_size/4))
enc_dense_tns2 = k.layers.PReLU()(enc_dense_lr2(dropout_tns)) 

当然,我们应该根据问题的需求来对层进行参数化。

1
在使用函数式API进行高级激活的示例非常少。如果您要使用多个输入或输出,这是正确的方法。这给了我很大的启示。谢谢。 - Julian C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接