网易首页 > 网易号 > 正文 申请入驻

如何诊断长短期记忆网络模型的过拟合和欠拟合?

0
分享至

图:pixabay


原文来源:machinelearningmastery

作者:Jason Brownlee

「机器人圈」编译:嗯~阿童木呀、多啦A亮

不知道在训练模型的过程中,你有没有遇到这样一个问题,很难确定你的长短期记忆网络模型是否在序列问题上表现良好。

也许在模型技能上你会获得一个不错的分数,但是更为重要的是,要知道你的模型是否与你的数据拟合良好,或者欠拟合,或者过度拟合,以及是否能够在不同的配置中做得更好。

在本教程中,你将知晓如何诊断LSTM模型在序列预测问题上的拟合问题。

完成本教程后,你将学会:

如何收集和绘制LSTM模型的训练历史。
如何诊断一个欠拟合、拟合和过度拟合模型。
如何通过平均多模型运行来开发更具鲁棒性的诊断。
那接下来就开启我们的探索之旅吧。

教程概述

本教程共分为6部分,它们分别是:

用Keras进行的训练史
诊断图
欠拟合范例
拟合良好范例
过度拟合范例
多次运行范例

1.用Keras进行的训练史

你可以通过回顾它在过去时间里的性能情况来了解模型行为。

通过调用fit()函数训练LSTM模型。此函数返回一个名为history的变量,其中包含损失追踪以及在编译模型时指定的任何其他指标。这些分数都记录在每个训练轮数的末尾。

...

history = model.fit(...)

例如,如果你的模型被编译为优化日志丢失(binary_crossentropy)并且测量每个训练轮数的精确度,那么会将损失和精确度记录在每个训练轮数的历史轨迹中。

通过调用fit()函数返回的历史对象中的一个键即可访问每个评分。默认情况下,在拟合模型过程中优化的损耗称为“loss”,精确度称为“acc”。

...

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

history = model.fit(X, Y, epochs=100)

print(history.history['loss'])

print(history.history['acc'])

在拟合模型的过程中,Keras允许你指定一个单独的验证数据集,同时也可以使用相同的损失和指标进行评估。

这可以通过在fit()上设置validation_split参数,从而将训练数据的一部分用作验证数据集来实现。

...

history = model.fit(X, Y, epochs=100, validation_split=0.33)

这也可以通过设置validation_data参数并传递一个X和y数据集的元组来完成。

...

history = model.fit(X, Y, epochs=100, validation_data=(valX, valY))

在验证数据集上评估的指标可以通过使用相同的名称键入,即“val_”前缀。

...

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

history = model.fit(X, Y, epochs=100, validation_split=0.33)

print(history.history['loss'])

print(history.history['acc'])

print(history.history['val_loss'])

print(history.history['val_acc'])

2.诊断图

关于LSTM模型的训练史可用于诊断模型的行为。

你可以使用Matplotlib库绘制模型的性能图。 例如,你可以绘制如下训练损失VS测试损失图:

from matplotlib import pyplot

...

history = model.fit(X, Y, epochs=100, validation_data=(valX, valY))

pyplot.plot(history.history['loss'])

pyplot.plot(history.history['val_loss'])

pyplot.title('model train vs validation loss')

pyplot.ylabel('loss')

pyplot.xlabel('epoch')

pyplot.legend(['train', 'validation'], loc='upper right')

pyplot.show()

创建并回顾这些图可以帮助你知晓那些可能的新配置,以便从模型中获得更好的性能。

接下来,我们将查看一些范例。 我们将根据损失最小化来考虑训练和验证集上的模型技能。当然,你可以使用对你的问题有意义的任何指标。

3.欠拟合范例

什么是欠拟合?所谓欠拟合就是说,一个在训练数据集上表现良好,但在测试数据集上表现不佳的模型。

这可以从一个训练损失低于验证损失的绘制图中得以诊断,且验证损失具有表明进一步改进有可能实现的趋势。

下面提供了一个小巧的欠拟合LSTM模型的例子。

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

from matplotlib import pyplot

from numpy import array

# return training data

def get_train():

seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((len(X), 1, 1))

return X, y

# return validation data

def get_val():

seq = [[0.5, 0.6], [0.6, 0.7], [0.7, 0.8], [0.8, 0.9], [0.9, 1.0]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((len(X), 1, 1))

return X, y

# define model

model = Sequential()

model.add(LSTM(10, input_shape=(1,1)))

model.add(Dense(1, activation='linear'))

# compile model

model.compile(loss='mse', optimizer='adam')

# fit model

X,y = get_train()

valX, valY = get_val()

history = model.fit(X, y, epochs=100, validation_data=(valX, valY), shuffle=False)

# plot train and validation loss

pyplot.plot(history.history['loss'])

pyplot.plot(history.history['val_loss'])

pyplot.title('model train vs validation loss')

pyplot.ylabel('loss')

pyplot.xlabel('epoch')

pyplot.legend(['train', 'validation'], loc='upper right')

pyplot.show()

运行这个例子将产生一个训练和验证损失的绘制图,显示了一个欠拟合模型的特征。在这种情况下,通过增加训练轮数的数量可以提高性能。

在这种情况下,通过增加训练时期的数量可以提高性能。

诊断线图显示了一个欠拟合模型

或者,如果训练集上的性能优于验证集并且性能已经下降,那么该模型也有可能是一个欠拟合模型。下面是一个没有足够记忆单元的欠拟合示例。

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

from matplotlib import pyplot

from numpy import array

# return training data

def get_train():

seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((5, 1, 1))

return X, y

# return validation data

def get_val():

seq = [[0.5, 0.6], [0.6, 0.7], [0.7, 0.8], [0.8, 0.9], [0.9, 1.0]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((len(X), 1, 1))

return X, y

# define model

model = Sequential()

model.add(LSTM(1, input_shape=(1,1)))

model.add(Dense(1, activation='linear'))

# compile model

model.compile(loss='mae', optimizer='sgd')

# fit model

X,y = get_train()

valX, valY = get_val()

history = model.fit(X, y, epochs=300, validation_data=(valX, valY), shuffle=False)

# plot train and validation loss

pyplot.plot(history.history['loss'])

pyplot.plot(history.history['val_loss'])

pyplot.title('model train vs validation loss')

pyplot.ylabel('loss')

pyplot.xlabel('epoch')

pyplot.legend(['train', 'validation'], loc='upper right')

pyplot.show()

运行此示例显示出一个未能充分配置的模型的特征。

在这种情况下,可以通过增加模型的容量来提高性能,例如隐藏层中的记忆单元的数量或隐藏层的数量。

诊断线图通过状态显示了一个欠拟合模型

4.拟合示例

一个很好的拟合是指在训练和验证集上模型的性能都表现得很好。

这可以从训练和验证损失减少并在同一点稳定的情况下诊断。

下面的小例子演示了LSTM模型具有良好的拟合。

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

from matplotlib import pyplot

from numpy import array

# return training data

def get_train():

seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((5, 1, 1))

return X, y

# return validation data

def get_val():

seq = [[0.5, 0.6], [0.6, 0.7], [0.7, 0.8], [0.8, 0.9], [0.9, 1.0]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((len(X), 1, 1))

return X, y

# define model

model = Sequential()

model.add(LSTM(10, input_shape=(1,1)))

model.add(Dense(1, activation='linear'))

# compile model

model.compile(loss='mse', optimizer='adam')

# fit model

X,y = get_train()

valX, valY = get_val()

history = model.fit(X, y, epochs=800, validation_data=(valX, valY), shuffle=False)

# plot train and validation loss

pyplot.plot(history.history['loss'])

pyplot.plot(history.history['val_loss'])

pyplot.title('model train vs validation loss')

pyplot.ylabel('loss')

pyplot.xlabel('epoch')

pyplot.legend(['train', 'validation'], loc='upper right')

pyplot.show()

运行示例创建一个显示训练和验证损失相遇的线条图。

理想情况下,如果可能的话,我们希望看到这样的模型性能,尽管这可能不适用于具有大量数据的有挑战性的问题。

诊断线图显示一个很好的拟合模型

5.过度拟合示例

过度拟合模型是一个在训练上的性能良好并持续改进的模型,而验证集上的性能提升到一个点,然后开始降级。

这可以从训练损耗向下倾斜和验证损失向下倾斜的曲线中诊断出来,碰到拐点,并再次开始向上倾斜。

下面的例子演示了一个LSTM过度拟合模型。

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

from matplotlib import pyplot

from numpy import array

# return training data

def get_train():

seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((5, 1, 1))

return X, y

# return validation data

def get_val():

seq = [[0.5, 0.6], [0.6, 0.7], [0.7, 0.8], [0.8, 0.9], [0.9, 1.0]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((len(X), 1, 1))

return X, y

# define model

model = Sequential()

model.add(LSTM(10, input_shape=(1,1)))

model.add(Dense(1, activation='linear'))

# compile model

model.compile(loss='mse', optimizer='adam')

# fit model

X,y = get_train()

valX, valY = get_val()

history = model.fit(X, y, epochs=1200, validation_data=(valX, valY), shuffle=False)

# plot train and validation loss

pyplot.plot(history.history['loss'][500:])

pyplot.plot(history.history['val_loss'][500:])

pyplot.title('model train vs validation loss')

pyplot.ylabel('loss')

pyplot.xlabel('epoch')

pyplot.legend(['train', 'validation'], loc='upper right')

pyplot.show()

运行此示例创建一个绘图,显示过度模型验证损失中的特征拐点。

这可能是训练次数太多的特征。

在这种情况下,模型训练可以在拐点处停止。或者,可以增加训练示例的数量。

诊断线图显示过度拟合模型

6.多次运行示例

LSTM是随机的,这意味着每次运行你会得到一个不同的诊断图。

重复诊断运行多次(例如5次,10次或30次)可能是有用的。然后,可以绘制每个运行的训练和验证轨迹,以便随着时间的推移对模型的行为提供更具有鲁棒性的想法。

以下示例运行多次相同的实验,然后绘制每次运行的训练轨迹和验证损失。

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

from matplotlib import pyplot

from numpy import array

from pandas import DataFrame

# return training data

def get_train():

seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((5, 1, 1))

return X, y

# return validation data

def get_val():

seq = [[0.5, 0.6], [0.6, 0.7], [0.7, 0.8], [0.8, 0.9], [0.9, 1.0]]

seq = array(seq)

X, y = seq[:, 0], seq[:, 1]

X = X.reshape((len(X), 1, 1))

return X, y

# collect data across multiple repeats

train = DataFrame()

val = DataFrame()

for i in range(5):

# define model

model = Sequential()

model.add(LSTM(10, input_shape=(1,1)))

model.add(Dense(1, activation='linear'))

# compile model

model.compile(loss='mse', optimizer='adam')

X,y = get_train()

valX, valY = get_val()

# fit model

history = model.fit(X, y, epochs=300, validation_data=(valX, valY), shuffle=False)

# story history

train[str(i)] = history.history['loss']

val[str(i)] = history.history['val_loss']

# plot train and validation loss across multiple runs

pyplot.plot(train, color='blue', label='train')

pyplot.plot(val, color='orange', label='validation')

pyplot.title('model train vs validation loss')

pyplot.ylabel('loss')

pyplot.xlabel('epoch')

pyplot.show()

在生成的结果图中,我们可以看到,五次运行的总体趋势是持续不断的,也许增加了训练轮数的数量。

诊断线图显示模型的多个运行

进一步阅读

如果你进一步了解,本部分将提供有关该主题的更多资源。

Keras API回调函数的历史(https://keras.io/callbacks/#history)

维基百科上机器学习中的学习曲线(https://en.wikipedia.org/wiki/Learning_curve#In_machine_learning)

在维基百科上的过度拟合(https://en.wikipedia.org/wiki/Overfitting)

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
“戏混子”没走,比资本家丑孩子更可怕的是“星二代”开始世袭了

“戏混子”没走,比资本家丑孩子更可怕的是“星二代”开始世袭了

流史岁月
2026-01-26 10:58:30
小伙买烟后,突然告知店主,“我17岁未成年,准备举报”,老板给了300元后报警,小伙被罚500元

小伙买烟后,突然告知店主,“我17岁未成年,准备举报”,老板给了300元后报警,小伙被罚500元

观威海
2026-05-03 08:52:22
消化科主任:胃癌最危险信号,不是胃疼,而是频繁出现这4种异常

消化科主任:胃癌最危险信号,不是胃疼,而是频繁出现这4种异常

路医生健康科普
2026-05-04 16:45:03
采访了100个娶了小三的男人,他们几乎都说了同一句话,让人恍然

采访了100个娶了小三的男人,他们几乎都说了同一句话,让人恍然

千秋文化
2026-04-15 20:18:32
日本高层抵华,中国的安排绝了!高市早苗决定:找中国的友国帮忙

日本高层抵华,中国的安排绝了!高市早苗决定:找中国的友国帮忙

小影的娱乐
2026-05-04 15:01:30
广东单亲父亲苦熬19年,送儿子进美国名校,孩子却永远离开了

广东单亲父亲苦熬19年,送儿子进美国名校,孩子却永远离开了

糖逗在娱乐
2026-05-02 18:11:47
迪丽热巴上学时无人追求,看到她早期照片,网友:这谁敢追啊

迪丽热巴上学时无人追求,看到她早期照片,网友:这谁敢追啊

乔话
2026-04-22 20:36:30
54岁高虎现状:种地创业折戟,送外卖讨生活,发福到160斤认不出

54岁高虎现状:种地创业折戟,送外卖讨生活,发福到160斤认不出

小徐讲八卦
2026-04-08 15:05:02
1940年的天安门见过吗?古城墙长满杂草很清冷,还挂着蒋介石照片

1940年的天安门见过吗?古城墙长满杂草很清冷,还挂着蒋介石照片

微野谈写作
2026-05-02 09:30:18
耐人寻味!川大、武大两位校领导提前离任,均未到退休年龄

耐人寻味!川大、武大两位校领导提前离任,均未到退休年龄

百家论大学
2026-05-04 07:10:06
叶帅问许世友:南京军区还指挥得动不?许世友:军区司令是我保镖

叶帅问许世友:南京军区还指挥得动不?许世友:军区司令是我保镖

掠影后有感
2026-05-03 16:16:20
朝鲜姑娘怀孕,查明是志愿军营长所为,彭总得知后批示8个字

朝鲜姑娘怀孕,查明是志愿军营长所为,彭总得知后批示8个字

元哥说历史
2026-04-26 11:40:03
22分大胜,拒绝22分逆转!活塞VS骑士赛程出炉,持球大核对决来了

22分大胜,拒绝22分逆转!活塞VS骑士赛程出炉,持球大核对决来了

世界体育圈
2026-05-04 14:19:23
设计院正在集体死去:不是没项目,是被6座大山压垮了!

设计院正在集体死去:不是没项目,是被6座大山压垮了!

悟话八门
2026-05-03 12:57:09
找吴彦祖来演年轻版蔡元祺,是《寒战1994》导演最正确的决定!

找吴彦祖来演年轻版蔡元祺,是《寒战1994》导演最正确的决定!

陈意小可爱
2026-05-02 01:19:10
柳州4死1伤命案最新:疑似案发原因曝出!“凶手被反杀”不属实

柳州4死1伤命案最新:疑似案发原因曝出!“凶手被反杀”不属实

胡侃社会百态
2026-05-03 12:20:04
“说好给2000,他给10元”:2011年75岁男子睡33岁女人拒付钱被杀

“说好给2000,他给10元”:2011年75岁男子睡33岁女人拒付钱被杀

汉史趣闻
2026-04-18 15:19:07
北青:邵佳一将参加亚洲杯抽签仪式;国足6月热身对手基本敲定

北青:邵佳一将参加亚洲杯抽签仪式;国足6月热身对手基本敲定

懂球帝
2026-05-04 16:07:05
深蹲,被严重低估了!研究提示:每天坚持5分钟,能预防6种疾病

深蹲,被严重低估了!研究提示:每天坚持5分钟,能预防6种疾病

增肌减脂
2026-04-30 19:15:09
震惊!旧金山移民法庭将永久关闭,曾创下超90%通过率

震惊!旧金山移民法庭将永久关闭,曾创下超90%通过率

大洛杉矶LA
2026-05-04 05:15:33
2026-05-04 17:19:00
雷克智能 incentive-icons
雷克智能
智能才是机器之道
1124文章数 5883关注度
往期回顾 全部

科技要闻

OpenAI“复活”了QQ宠物,网友直接玩疯

头条要闻

宇树机器人在美坐飞机电池超标被拆卸暂扣 致航班延误

头条要闻

宇树机器人在美坐飞机电池超标被拆卸暂扣 致航班延误

体育要闻

骑士破猛龙:加雷特·阿伦的活力

娱乐要闻

张敬轩还是站上了英皇25周年舞台

财经要闻

魔幻的韩国股市,父母给婴儿开户买股票

汽车要闻

同比大涨190% 方程豹4月销量29138台

态度原创

家居
艺术
数码
时尚
教育

家居要闻

灵动实用 生活艺术场

艺术要闻

300米!重庆解放碑区在建第一高楼,冲刺竣工!

数码要闻

联想来酷“W3259PS”31.5英寸显示器发售:4K 240Hz,5499元

这几条裙子太适合度假了,减龄又时髦!

教育要闻

小升初附加题,求四边形面积,难倒了不少人

无障碍浏览 进入关怀版