前言
接着之前的训练模型,实际使用的时候发现,如果训练20000次基本可以保证理想的结果, 可是如果我为了节约时间调整为5000次,有的时候结果非常不理想,那该如何优化这个训练次数呢,tensorflow 提供了EarlyStopping 来解决这个问题 。
使用model.fit 进行训练,就不需要写循环了,为监测训练的进展,fit提供了callbacks参数,用于在每次训练的过程中进行控制操作。EarlyStopping 需要在 callback 里面执行。
提示:以下是本篇文章正文内容,下面案例可供参考
一、EarlyStopping是什么?
EarlyStopping 用于告诉模型 什么时候可以提早结束训练,代码如下:
# patience 值用来检查改进 训练的数量
# 大约意思是 如果 每次训练 loss的变动 小于 0.0001 ,则为学习没有进展
# 如果连续100次没有进展,结束训练
early_stop = tf.keras.callbacks.EarlyStopping(monitor='loss', min_delta=0.0001, patience=100)
# 在callbacks 里面调用 early_stop
history = model.fit(X, y, epochs=num_epoch,
# validation_split=0.2,
callbacks=[early_stop, PrintDot()],
use_multiprocessing=True,
verbose=0)
二、使用步骤
1.期望目的
在上篇代码的基础上,我们希望增加3个功能:
- 打印训练过程评估效果的变动情况
- 执行EarlyStopping
- 使用图表展示整个训练过程
新的代码如下:
# -*- coding: utf-8 -*-
"""
Created on Tue Feb 23 17:40:51 2021
@author: huwp001
Dependencies:
tensorflow: 2.0
matplotlib
numpy
EarlyStopping 测试
"""
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
"""
原始数据 X_raw, y_raw
"""
X_raw = np.array([2013, 2014, 2015, 2016, 2017, 2018], dtype=np.float32)
y_raw = np.array([12000, 14000, 15000, 16500, 17500, 18400], dtype=np.float32)
"""
进行归一化,转换为了 0,1 之间的值
"""
X = (X_raw - X_raw.min()) / (X_raw.max() - X_raw.min())
y = (y_raw - y_raw.min()) / (y_raw.max() - y_raw.min())
X = X.reshape(-1,1)
y = y.reshape(-1,1)
X = tf.constant(X, dtype=tf.float32)
y = tf.constant(y, dtype=tf.float32)
num_epoch = 20000
# 在训练的时候输出进度图
class PrintDot(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs):
if (epoch+1) % 10 == 0 or epoch==num_epoch-1:
print(epoch, logs['loss'])
# patience 值用来检查改进 epochs 的数量
# 大约意思是 如果 每次训练 loss的变动 小于 0.0001 ,则为学习没有进展
# 如果连续100次没有进展,结束训练
early_stop = tf.keras.callbacks.EarlyStopping(monitor='loss', min_delta=0.0001, patience=100)
#构建模型
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(1)
])
# 编译模型,设置了损失函数,优化器,评估工具
model.compile(
optimizer=tf.keras.optimizers.SGD(learning_rate=5e-2),
loss=tf.losses.MeanSquaredError(),
metrics=['mae', 'mse']
)
# 训练模型
# validation_split 表示边训练,边验证的比例。 Fraction of the training data to be used as validation data
history = model.fit(X, y, epochs=num_epoch,
# validation_split=0.2,
callbacks=[early_stop, PrintDot()],
use_multiprocessing=True,
verbose=0)
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
hist.tail()
def plot_history(history):
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
plt.figure()
plt.xlabel('Epoch')
plt.ylabel('Mean Abs Error [MPG]')
plt.plot(hist['epoch'], hist['mae'],
label='mae Train Error')
if 'val_mae' in hist.columns:
plt.plot(hist['epoch'], hist['val_mae'],
label = 'mae Val Error')
plt.legend()
plt.xlabel('Epoch')
plt.ylabel('Mean Square Error [$MPG^2$]')
plt.plot(hist['epoch'], hist['mse'],
label='mse Train Error')
if 'val_mse' in hist.columns:
plt.plot(hist['epoch'], hist['val_mse'],
label = 'mse Val Error')
#plt.ylim([0,20])
plt.legend()
plt.show()
plot_history(history)
# 评估模型
y_pred = model.predict(X)
plt.figure()
plt.scatter(X, y)
plt.plot(X, y_pred, 'r-', lw=5)
#plt.ylim([0,2])
plt.legend()
plt.show()
model.evaluate(X, y, verbose=2)
2.运行源码
代码中,我设置了总训练次数两万次,执行后得到如下结果:
训练效果图,可以看到 损失越来越小,训练200次以后,变动就很小了。
打印输出的训练次数和 loss值,可见实际只运行不到500次,就结束了训练。
结果图还是跟之前差不多。
3.其他
tensorflow 开发环境安装 前往
总结
本章内容完善了日志的打印,训练过程的图表以及 提早结束功能。为后续训练复杂数据做好准备。