机器学习之评估机器学习模型

文章代码来源:《deep learning on keras》,非常好的一本书,大家如果英语好,推荐直接阅读该书,如果时间不够,可以看看此系列文章。

我们将我们的数据分为训练集、验证集和测试集,我们不通过相同的数据来评估我们用来训练的模型,原因很明显:经过一些很少批次的训练以后,全部的模型都开始过拟合,也就是说,他们在未见过的数据上的表现跟见过的数据比,不光停滞,还有可能下降。
机器学习的目标就是要让我们的模型在它没见过的模型里面也表现得好,过拟合是主要的障碍,然而我们只能控制我们能观测到的,接下来我们将会介绍一些减缓过拟合和最大化泛化(generalization),如何评估机器学习模型。

训练、验证、测试集

评估模型归纳起来说就是将数据分为训练、验证和测试三个部分。你在训练集上训练模型,在验证集上评估模型,当你将模型训练准备好了以后,在测试集上最后测一次。
你或许会问为什么不直接来两个集合:一个训练集,一个测试集?在训练集上训练,测试集上评估,这会简单的多。
其实呢,除了我们的权重称为参数,还有层数和层数大小称为模型的超参数。你需要通过验证集的反馈来调整超参数,在验证集上训练会导致尽管你没有直接在其上训练,但是结果还是很快会过拟合。
这种现象的核心被称为“信息泄露”。每次你根据模型在验证集上面的表现来调超参数的时候,一些验证集中的数据就会泄露到你的模型中,如果你只这么做一次,对于一个参数来做,那么就只会有很少的信息泄露到你的模型中,验证集仍然是用来评估你的模型的可靠的方法。但若你多次重复同一个验证集,就会漏进来很多。
所以呢,如果你只选择一个训练集,一个测试集,就会导致最后我们在测试集虽然表现得可以,但是泛化性不好。

简单的坚持验证集

选一部分数据作为测试集,在剩余的数据上训练,最后在测试集上评估。

验证集选取

在这里插入图片描述

验证集选取大致如上图所示。
接下来用一个简单的例子来说明

num_validation_samples = 10000
# Shuffling the data is usually appropriate
np.random.shuffle(data)
# Define the validation set
validation_data = data[:num_validation_samples]
data = [num_validation_samples:]
# Define the training set
training_data = data[:]
# Train a model on the training data
# and evaluate it on the validation data
model = get_model()
model.train(training_data)
validation_score = model.evaluate(validation_data)
# At this point you can tune your model,
# retrain it, evaluate it, tune it again...
# Once you have tuned your hyperparameters,
# is it common to train your final model from scratch
# on all non-test data available.
model = get_model()
model.train(np.concatenate([training_data,
 validation_data]))
test_score = model.evaluate(test_data)

np.random.shuffle用来随机打乱数据,以防原来存储数据的顺序对于训练产生影响,接下来两句分别表示从所有的数据中取前面的数量的作为验证集,然后总的数据量变为原来的剩下一部分,再赋给训练集。
然而上述的只是一个最简单的版本,对于稍微比较复杂的还有小样本的情况,我们随机的划分对于结果的影响就比较大,就需要用到k-fold来做。

k-fold验证

首先将你的手头的数据分成k等分,分别对第i份验证,剩余的训练。最后的score使用平均得到,这种方法能够有效的解决你的训练结果很受数据划分的情况。
k-fold方法如下

在这里插入图片描述

k-fold

这里有一个简单的实例:

k = 4
num_validation_samples = len(data) // k
np.random.shuffle(data)
validation_scores = []
for fold in range(k):
 # Select the validation data partition
 validation_data = data[num_validation_samples * fold: num_validation_samples * (fold + 1)]
 # The remainder of the data is used as training data.
 # Note that the "+" operator below is list concatenation, not summation
 training_data = data[:num_validation_samples * fold] + data[num_validation_samples * (fold + 1):]
 # Create a brand new instance of our model (untrained)
 model = get_model()
 model.train(training_data)
 validation_score = model.evaluate(validation_data)
 validation_scores.append(validation_score)
# This is our validation score:
# the average of the validation scores of our k folds
validation_score = np.average(validation_scores)
# We train our final model on all non-test data available
model = get_model()
model.train(data)
test_score = model.evaluate(test_data)

首先k为所需要分的份数,又由于我们实际中不可能分的份数刚好都是总的数据量的约数,所以第二行采用//得到的就是结果的整数部分。
之后的划分就很简单了。比较需要注意的是,将训练的评估结果存下来最后k个循环结束以后再作平均。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值