微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Keras 在 MLP 的末尾添加几个二元分类器?

如何解决如何使用 Keras 在 MLP 的末尾添加几个二元分类器?

假设我有一个如下所示的 MLP:

model = models.Sequential()

model.add(layers.Dense(200,activation = "relu",input_dim=250))
model.add(layers.Dense(100,activation="relu"))
model.add(layers.Dense(75,activation="relu"))
model.add(layers.Dense(50,activation="relu"))
model.add(layers.Dense(17,activation = "softmax"))


model.compile(optimizer = optimizers.Adam(lr=0.001),loss = "categorical_crossentropy",metrics = ['MeanSquaredError','AUC','accuracy',tf.keras.metrics.Precision()])

history = model.fit(X_train,y_train,epochs = 100,validation_data = (X_val,y_val))

现在我想在最后一层为 17 个类中的每一个添加一个二元分类器,而不是将 17 个类与 softmax 一起输出;这意味着二元分类器都应该从最后一层开始。这可以在 Keras 中做到吗?我猜它应该是一种不同类型的模型,而不是 Sequential()

编辑:

我知道我不能使用 Sequential,并更改了模型,以便:

from tensorflow.keras import Input
from tensorflow.keras import Model
from tensorflow.keras.layers import Dense,Dropout

def test_model(layer_in):

    dense1 = Dense(200,activation = "relu") (layer_in)
    drop1 = Dropout(rate=0.02)(dense1)
    dense2 = Dense(100,activation="relu")(drop1)
    drop2 = Dropout(rate=0.02)(dense2)
    dense3 = Dense(75,activation="relu")(drop2)
    drop3 = Dropout(rate=0.02)(dense3)
    dense4 = Dense(50,activation="relu")(drop3)
    drop4 = Dropout(rate=0.01)(dense4)
    out = Dense(17,activation= "softmax")(drop4)
    return out


layer_in = Input(shape=(250,))
layer_out = test_model(layer_in)

model = Model(inputs=layer_in,outputs=layer_out)

plot_model(model,show_shapes=True)

enter image description here

所以我想最终目标是在最后有 17 个二元层,每个层都有一个 sigmoid 函数,它们都连接到 drop4...

解决方法

在您的问题中,您尝试使用 Sequential API 来创建模型。 Sequential API 有一些限制,您只能创建一个逐层模型。它无法处理多个输入/输出。它也不能用于分支。

以下为Keras官网原文:https://keras.io/guides/functional_api/

函数式 API 可以轻松操作多个输入和输出。这无法通过 Sequential API 处理。

此堆栈链接对您也很有用:Keras' Sequential vs Functional API for Multi-Task Learning Neural Network

现在您可以使用功能 API 或模型子类创建模型。

如果是功能性 API,您的模型将是

假设 Output_1 是有 17 个类别的分类,Output_2 是有 2 个类别的分类,而 Output_3 是回归

input_layer=Input(shape=(250))
x=Dense(200,activation = "relu")(input_layer)
x=Dense(100,activation = "relu")(x)
x=Dense(75,activation = "relu")(x)
x=Dense(50,activation = "relu")(x)
output_1=Dense(17,activation = "softmax",name='output_1')(x)
output_2=Dense(3,name='output_2')(x)
output_3=Dense(1,name='output_3')(x)
model=Model(inputs=input_layer,outputs=[output_1,output_2,output_3])
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),loss = {'output_1' : tf.keras.losses.CategoricalCrossentropy(),'output_2' : tf.keras.losses.CategoricalCrossentropy(),'output_3' : "mse"
                     },metrics = {'output_1' :'accuracy','output_2': 'accuracy','output_3' : tf.keras.metrics.RootMeanSquaredError()
                       }
             )

更新 下面是假设你有 6 个类的代码你可以为 17 个类扩展相同的

input_layer=Input(shape=(250))
x=Dense(200,activation = "relu")(x)
output_1=Dense(1,activation='softmax',name='output_1')(x)
output_2=Dense(1,name='output_2' )(x)
output_3=Dense(1,name='output_3')(x)
output_4=Dense(1,name='output_4')(x)
output_5=Dense(1,name='output_5' )(x)
output_6=Dense(1,name='output_6')(x)
model=Model(inputs=input_layer,loss = {'output_1' : tf.keras.losses.SparseCategoricalCrossentropy(),'output_2':  tf.keras.losses.SparseCategoricalCrossentropy(),'output_3' : tf.keras.losses.SparseCategoricalCrossentropy(),'output_4' :tf.keras.losses.SparseCategoricalCrossentropy(),'output_5' :tf.keras.losses.SparseCategoricalCrossentropy(),'output_6' :tf.keras.losses.SparseCategoricalCrossentropy()
                     },metrics = {'output_1' : 'accuracy','output_2':  'accuracy','output_3' : 'accuracy','output_4' :'accuracy','output_5' :'accuracy','output_6' :'accuracy'
                       }
             )

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。