如何使用 Keras 在 MLP 的末尾添加多个二元分类器?
How to add several binary classifiers at the end of a MLP with Keras?
假设我有一个如下所示的 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)
所以我猜最终目标是在最后有 17 个二进制层,每个层都有一个 sigmoid 函数,它们都连接到 drop4...
在您的问题中,您正在尝试使用顺序 API 来创建模型。 Sequential API 有局限性,您可以逐层创建模型。它无法处理多个 inputs/outputs。它也不能用于分支。
以下为Keras官网原文:https://keras.io/guides/functional_api/
函数式 API 可以轻松操作多个输入和输出。这不能用顺序 API.
处理
此外,此堆栈 link 对您也很有用: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, activation = "softmax",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")(input_layer)
x=Dense(100, activation = "relu")(x)
x=Dense(75, activation = "relu")(x)
x=Dense(50, activation = "relu")(x)
output_1=Dense(1,activation='softmax', name='output_1')(x)
output_2=Dense(1,activation='softmax',name='output_2' )(x)
output_3=Dense(1,activation='softmax',name='output_3')(x)
output_4=Dense(1,activation='softmax', name='output_4')(x)
output_5=Dense(1,activation='softmax',name='output_5' )(x)
output_6=Dense(1,activation='softmax',name='output_6')(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.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'
}
)
假设我有一个如下所示的 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)
所以我猜最终目标是在最后有 17 个二进制层,每个层都有一个 sigmoid 函数,它们都连接到 drop4...
在您的问题中,您正在尝试使用顺序 API 来创建模型。 Sequential API 有局限性,您可以逐层创建模型。它无法处理多个 inputs/outputs。它也不能用于分支。
以下为Keras官网原文:https://keras.io/guides/functional_api/
函数式 API 可以轻松操作多个输入和输出。这不能用顺序 API.
处理此外,此堆栈 link 对您也很有用: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, activation = "softmax",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")(input_layer)
x=Dense(100, activation = "relu")(x)
x=Dense(75, activation = "relu")(x)
x=Dense(50, activation = "relu")(x)
output_1=Dense(1,activation='softmax', name='output_1')(x)
output_2=Dense(1,activation='softmax',name='output_2' )(x)
output_3=Dense(1,activation='softmax',name='output_3')(x)
output_4=Dense(1,activation='softmax', name='output_4')(x)
output_5=Dense(1,activation='softmax',name='output_5' )(x)
output_6=Dense(1,activation='softmax',name='output_6')(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.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'
}
)