如何在模型内部更改Keras模型输出的阈值?
How to change the threshold of output of Keras model inside the model?
我正在构建这样一个 Keras 模型:
Y = 1 for X >= 0.5
Y = 0 for X < 0.5
我的模特:
def define_model():
model = Sequential()
model.build(input_shape = (None, 1))
model.add(Dense(1, activation = 'sigmoid'))
opt = SGD(learning_rate = 0.01, momentum = 0.99)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
return model
创建模型后,我将权重设置为 [1] 并将偏差设置为 [-0.5]
现在,我获得了很高的准确性,但以下输入的输出错误:
[[0.50000006]
[0.5 ]
[0.50000001]
[0.50000002]
[0.50000007]
[0.50000004]
[0.50000001]
[0.50000004]
[0.50000004]
[0.50000001]
[0.50000003]
[0.50000007]
[0.50000008]
[0.50000008]
[0.50000004]
[0.50000002]
[0.50000006]
[0.50000006]
[0.5000001 ]
[0.50000008]
[0.50000002]
[0.50000004]
[0.50000006]
[0.50000004]
[0.5 ]
[0.50000005]
[0.50000003]
[0.50000007]
[0.50000004]
etc.
所以,模型已经知道 Y = 1 for only X > 0.5
但我需要 Y = 1 for X >= 0.5
。
我知道这可以通过 pred = model.predict(X)
获取输出然后手动比较来完成。但我希望这在模型内部完成。 model.predict_classes
应该有个门槛。我想改变这个门槛。我该怎么做?
predict_classes
不允许我们更改阈值。 keras是这样实现的
def predict_classes(self, x, batch_size=32, verbose=0):
proba = self.predict(x, batch_size=batch_size, verbose=verbose)
if proba.shape[-1] > 1:
return proba.argmax(axis=-1)
else:
return (proba > 0.5).astype('int32')
如果你想有自己的阈值,那么你将不得不重载该方法。
代码
class MySequential(keras.models.Sequential):
def __init__(self, **kwargs):
super(MySequential, self).__init__(**kwargs)
def predict_classes(self, x, batch_size=32, verbose=0):
proba = self.predict(x, batch_size=batch_size, verbose=verbose)
return (proba >= 0.6).astype('int32')
def define_model():
model = MySequential()
model.add(keras.layers.Dense(1, activation = 'sigmoid', input_shape=(None, 1)))
opt = keras.optimizers.SGD(learning_rate = 0.01, momentum = 0.99)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
return model
# Test
model = define_model()
x = np.random.randn(5)
print (model.predict(x))
print (model.predict_classes(x))
我正在构建这样一个 Keras 模型:
Y = 1 for X >= 0.5
Y = 0 for X < 0.5
我的模特:
def define_model():
model = Sequential()
model.build(input_shape = (None, 1))
model.add(Dense(1, activation = 'sigmoid'))
opt = SGD(learning_rate = 0.01, momentum = 0.99)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
return model
创建模型后,我将权重设置为 [1] 并将偏差设置为 [-0.5] 现在,我获得了很高的准确性,但以下输入的输出错误:
[[0.50000006]
[0.5 ]
[0.50000001]
[0.50000002]
[0.50000007]
[0.50000004]
[0.50000001]
[0.50000004]
[0.50000004]
[0.50000001]
[0.50000003]
[0.50000007]
[0.50000008]
[0.50000008]
[0.50000004]
[0.50000002]
[0.50000006]
[0.50000006]
[0.5000001 ]
[0.50000008]
[0.50000002]
[0.50000004]
[0.50000006]
[0.50000004]
[0.5 ]
[0.50000005]
[0.50000003]
[0.50000007]
[0.50000004]
etc.
所以,模型已经知道 Y = 1 for only X > 0.5
但我需要 Y = 1 for X >= 0.5
。
我知道这可以通过 pred = model.predict(X)
获取输出然后手动比较来完成。但我希望这在模型内部完成。 model.predict_classes
应该有个门槛。我想改变这个门槛。我该怎么做?
predict_classes
不允许我们更改阈值。 keras是这样实现的
def predict_classes(self, x, batch_size=32, verbose=0):
proba = self.predict(x, batch_size=batch_size, verbose=verbose)
if proba.shape[-1] > 1:
return proba.argmax(axis=-1)
else:
return (proba > 0.5).astype('int32')
如果你想有自己的阈值,那么你将不得不重载该方法。
代码
class MySequential(keras.models.Sequential):
def __init__(self, **kwargs):
super(MySequential, self).__init__(**kwargs)
def predict_classes(self, x, batch_size=32, verbose=0):
proba = self.predict(x, batch_size=batch_size, verbose=verbose)
return (proba >= 0.6).astype('int32')
def define_model():
model = MySequential()
model.add(keras.layers.Dense(1, activation = 'sigmoid', input_shape=(None, 1)))
opt = keras.optimizers.SGD(learning_rate = 0.01, momentum = 0.99)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
return model
# Test
model = define_model()
x = np.random.randn(5)
print (model.predict(x))
print (model.predict_classes(x))