普通train/test set
直接将训练数据划分为两部分,一部分用来做训练train set
,一部分用来固定作为测试集test set
。然后反复更换超参在训练集上进行训练,使用测试集依次测试,进行m次,可以得到每一组超参在测试集上的结果,我们叫做评价指标,记为
p
m
p_m
pm,然后根据这m个结果,选一个最好的,得到最优超参数。最后,使用那个最优超参数,用所有数据进行训练,得到模型的权重参数,毕竟这才是我们需要的。
注意:
- 上面的test set在训练的过程中大多的时候叫做validation set或者叫做dev set(development开发集)。
- 上面的评价指标p不一定需要只看测试集上的正确率,可以取测试集和训练集上正确率的平均。
实践:
import numpy as np
from sklearn.model_selection import train_test_split
#生成训练数据
x=np.linspace(1,8,8).reshape(4,2)
#生成标签
label=list([1,0,1,1])
#打印看看
print(x)
print(label)
#对半(0.5)划分训练数据。
trainx,testx,lable1,label2=train_test_split(x,y,test_size=0.5,shuffle=False)
#打印看看
print(trainx)
print(testx)
结果如下:
1.原始训练数据x,原始训练数据x对应的的标签label。
2.划分数据之后的trainx,testx。
交叉验证(cross validation)
举个例子可能会比较好理解。
考虑三层神经网络FNN,比如F(d,h,c),其中d,h,c是超参数,d是样本每一个样本点的维度,h是隐藏层节点个数,c是样本类别总数。
做法:
- 将训练数据划分成k份
- 确定超参数,比如F(3,3,3),10000个epochs,设置好batch,并初始化权重参数。
- 第一次使用训练数据中的第1,2,…k-1份做训练
- 用第k份的训练数据用来做测试,比如你用了一个指标正确率,那么记录下来,p1。
- 保持超参数不变,重新初始化F(3,3,3)的权重参数。
- 第二次使用训练数据中的第2,…k-1,k份做训练
- 用第1份的训练数据用来做测试,记录指标p2。
- 重复5-7步直到一共训练了k次,并得到了p1,p2,…pk。求平均作为这一组超参数好不好的评价指标。记为M1
- 重复2-8步,得到M1,M2,…Mm,(假设你调超参了m次,炼丹大师)
- 比较指标M1,M2,…Mm,选择最好的那一个,显然这个模型是你想要的,但是我们获得了模型的超参数,还没有获得模型的权重参数,因为这个超参数对应得权重参数有k个。这个时候,我们可以用整个训练数据(不再进行划分),进行训练得到最终的权重参数。
选上面哪一个划分验证集的方法?
我感觉:
如果训练数据量中等的话,或许选交叉验证好,但也没有事实依据。
如果训练数据量大的话,应该没得区别,交叉验证反而麻烦。
如果训练数据量小的话,就别验证了吧,训练数据:我全都要!