Aly*_*ono 3 python machine-learning neural-network keras
当精度已经达到1.0时,如何停止Keras Training?我尝试监视损失值,但是在精度已经达到1的情况下,我没有尝试停止训练。
我没有运气尝试下面的代码:
stopping_criterions =[
EarlyStopping(monitor='loss', min_delta=0, patience = 1000),
EarlyStopping(monitor='acc', base_line=1.0, patience =0)
]
model.summary()
model.compile(Adam(), loss='binary_crossentropy', metrics=['accuracy'])
model.fit(scaled_train_samples, train_labels, batch_size=1000, epochs=1000000, callbacks=[stopping_criterions], shuffle = True, verbose=2)
Run Code Online (Sandbox Code Playgroud)
更新:
即使精度仍然不是1.0,训练也会立即从第一个纪元停止。
请帮忙。
小智 9
据我所知,使用带有基线回调的 EarlyStopping 在这里不起作用。“基线”是您应该继续训练的监控变量的最小值(此处为准确度)。这里的基线是 1.0,在第一个纪元结束时基线小于“准确度”(显然你不能指望第一个纪元本身的“准确度”为 1.0)并且由于耐心设置为零,训练停止在第一个纪元本身,因为基线大于准确度。使用自定义回调在这里完成工作。
class MyThresholdCallback(tf.keras.callbacks.Callback):
def __init__(self, threshold):
super(MyThresholdCallback, self).__init__()
self.threshold = threshold
def on_epoch_end(self, epoch, logs=None):
accuracy = logs["acc"]
if accuracy >= self.threshold:
self.model.stop_training = True
Run Code Online (Sandbox Code Playgroud)
并在 model.fit 中调用回调
callback=MyThresholdCallback(threshold=1.0)
model.fit(scaled_train_samples, train_labels, batch_size=1000, epochs=1000000, callbacks=[callback], shuffle = True, verbose=2)
Run Code Online (Sandbox Code Playgroud)
更新:我不知道为什么EarlyStopping在这种情况下不起作用。相反,我定义了一个自定义回调,该回调在acc(或val_acc)达到指定的基线时停止训练:
from keras.callbacks import Callback
class TerminateOnBaseline(Callback):
"""Callback that terminates training when either acc or val_acc reaches a specified baseline
"""
def __init__(self, monitor='acc', baseline=0.9):
super(TerminateOnBaseline, self).__init__()
self.monitor = monitor
self.baseline = baseline
def on_epoch_end(self, epoch, logs=None):
logs = logs or {}
acc = logs.get(self.monitor)
if acc is not None:
if acc >= self.baseline:
print('Epoch %d: Reached baseline, terminating training' % (epoch))
self.model.stop_training = True
Run Code Online (Sandbox Code Playgroud)
您可以像这样使用它:
callbacks = [TerminateOnBaseline(monitor='acc', baseline=0.8)]
callbacks = [TerminateOnBaseline(monitor='val_acc', baseline=0.95)]
Run Code Online (Sandbox Code Playgroud)
注意:此解决方案不起作用。
如果要在训练(或验证)准确性完全达到100%时停止训练,请使用EarlyStoppingcallback并将baseline参数设置为1.0并patience设置为零:
EarlyStopping(monitor='acc', baseline=1.0, patience=0) # use 'val_acc' instead to monitor validation accuarcy
Run Code Online (Sandbox Code Playgroud)
这个名字baseline有误导性。虽然从下面的源码中不太容易解读,但baseline应该理解为:
当监测值比基线差1patience时,请保持最大epoch 的训练时间更长。如果效果更好,请提高基线并重复。
1即精度较低,损耗较高。
相关(修剪过的)源代码EarlyStopping:
self.best = baseline # in initialization
...
def on_epoch_end(self, epoch, logs=None):
current = self.get_monitor_value(logs)
if self.monitor_op(current - self.min_delta, self.best): # read as `current > self.best` (for accuracy)
self.best = current
self.wait = 0
else:
self.wait += 1
if self.wait >= self.patience:
self.model.stop_training = True
Run Code Online (Sandbox Code Playgroud)
那么你的例子
EarlyStopping(monitor='acc', base_line=1.0, patience=0)意味着:虽然监测值比 1.0 更差(它总是如此),但继续训练 0 epoch(即立即终止)。
如果您想要这些语义:
当监控值比基线差时,请继续训练。patience如果更好的话,继续训练,直到连续 epoch没有任何进展,并且还保留 的所有特征EarlyStopping,我可以这样建议:
class MyEarlyStopping(EarlyStopping):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
self.baseline_attained = False
def on_epoch_end(self, epoch, logs=None):
if not self.baseline_attained:
current = self.get_monitor_value(logs)
if current is None:
return
if self.monitor_op(current, self.baseline):
if self.verbose > 0:
print('Baseline attained.')
self.baseline_attained = True
else:
return
super(MyEarlyStopping, self).on_epoch_end(epoch, logs)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2005 次 |
| 最近记录: |