改进浅神经网络泛化,避免过拟合gydF4y2Ba
提示gydF4y2Ba
要了解如何为深度学习网络设置参数,请参见gydF4y2Ba参数设置与卷积神经网络训练gydF4y2Ba.gydF4y2Ba
在神经网络训练中出现的一个问题叫做gydF4y2Ba过度拟合。训练集上的误差被驱动到一个非常小的值,但是当新的数据呈现给网络时,误差就很大了。网络已经记住了训练的例子,但它还没有学会gydF4y2Ba对新情况进行概括。gydF4y2Ba
下图显示了1-20-1神经网络的响应,该神经网络经过训练,可以近似一个有噪声的正弦函数。下面的正弦函数由虚线表示,噪声测量由+符号给出,神经网络响应由实线给出。显然,这个网络已经过度拟合了数据,不能很好地泛化。gydF4y2Ba
提高网络泛化的一种方法是使用刚好足够大的网络来提供足够的拟合。使用的网络越大,网络可以创建的功能就越复杂。如果您使用一个足够小的网络,它将没有足够的能力来过度拟合数据。运行gydF4y2Ba神经网络设计gydF4y2Ba例子gydF4y2Bannd11gngydF4y2Ba
[gydF4y2BaHDB96gydF4y2Ba]来研究如何减少网络的大小可以防止过拟合。gydF4y2Ba
不幸的是,对于特定的应用程序,很难事先知道网络应该有多大。在Deep Learning Toolbox™软件中还实现了另外两种提高泛化的方法:正则化和早期停止。接下来的部分将描述这两种技术以及实现它们的例程。gydF4y2Ba
请注意,如果网络中的参数数量远远小于训练集中的点总数,那么过拟合的可能性很小或根本没有。如果你可以轻松地收集更多的数据并增加训练集的大小,那么就没有必要担心以下防止过拟合的技术。本节的其余部分仅适用于希望充分利用有限数据供应的情况。gydF4y2Ba
再训练神经网络gydF4y2Ba
通常,每个反向传播训练会话都以不同的初始权重和偏差开始,并将数据划分为训练集、验证集和测试集。对于同一个问题,这些不同的条件会导致截然不同的解决方案。金宝搏官方网站gydF4y2Ba
训练多个网络以确保找到具有良好泛化的网络是一个好主意。gydF4y2Ba
这里加载一个数据集,并将其分为两部分:90%用于设计网络,10%用于测试所有网络。gydF4y2Ba
[x, t] = bodyfat_dataset;Q = size(x, 2);Q1 =地板(Q * 0.90);Q2 = q - q1;ind = randperm(Q);ind1 = ind(1:Q1);ind2 = ind(Q1 + (1:Q2));X1 = x(:, ind1);T1 = t(:, ind1);X2 = x(:, ind2); t2 = t(:, ind2);
接下来,在数据集的第一部分上选择网络架构并训练10次,在数据集的第二部分上使用每个网络的均方误差。gydF4y2Ba
Net = feedforwardnet(10);numNN = 10;NN = cell(1, numNN);pers = 0 (1, numNN);for i = 1:numNN fprintf('训练%d/%d\n', i, numNN);NN{i} = train(net, x1, t1);y2 = NN{i}(x2);Perfs (i) = mse(net, t2, y2);结束gydF4y2Ba
每个网络将从不同的初始权重和偏差开始训练,并将第一个数据集分为训练集、验证集和测试集。请注意,测试集是每个网络泛化的一个很好的度量,但不是所有网络,因为一个网络的测试集数据可能会被其他神经网络用于训练或验证。这就是为什么原始数据集被分为两部分,以确保保留一个完全独立的测试集。gydF4y2Ba
性能最低的神经网络是对数据集的第二部分推广最好的神经网络。gydF4y2Ba
多神经网络gydF4y2Ba
另一种提高泛化的简单方法,特别是当由噪声数据或小数据集引起时,是训练多个神经网络并平均它们的输出。gydF4y2Ba
例如,这里有10个神经网络在一个小问题上接受训练,它们的均方误差与它们平均值的均方误差进行了比较。gydF4y2Ba
首先,加载数据集并将其划分为设计集和测试集。gydF4y2Ba
[x, t] = bodyfat_dataset;Q = size(x, 2);Q1 =地板(Q * 0.90);Q2 = q - q1;ind = randperm(Q);ind1 = ind(1:Q1);ind2 = ind(Q1 + (1:Q2));X1 = x(:, ind1);T1 = t(:, ind1);X2 = x(:, ind2); t2 = t(:, ind2);
然后,训练10个神经网络。gydF4y2Ba
Net = feedforwardnet(10);numNN = 10;net = cell(1, numNN);for i = 1:numNN fprintf('Training %d/%d\n', i, numNN) nets{i} = train(net, x1, t1);结束gydF4y2Ba
接下来,每个网络在第二个数据集上进行测试,包括单个性能和计算平均输出的性能。gydF4y2Ba
pers = 0 (1, numNN);y2Total = 0;for i = 1:numNN neti = net {i};Y2 = neti(x2);Perfs (i) = mse(neti, t2, y2);y2Total = y2Total + y2;end perfs y2AverageOutput = y2Total / numNN;perfaverageoutput = mse(net {1}, t2, y2AverageOutput)gydF4y2Ba
平均输出的均方误差可能低于大多数个别表现,也许不是全部。它很可能更好地泛化到额外的新数据。gydF4y2Ba
对于一些非常困难的问题,可以训练一百个网络,并对任何输入取其输出的平均值。结合贝叶斯正则化训练函数,这对于小型、有噪声的数据集特别有用gydF4y2BatrainbrgydF4y2Ba
,如下所述。gydF4y2Ba
早期停止gydF4y2Ba
用于改进泛化的默认方法被调用gydF4y2Ba早期停止gydF4y2Ba.该技术自动提供给所有监督网络创建函数,包括反向传播网络创建函数,例如gydF4y2BafeedforwardnetgydF4y2Ba
.gydF4y2Ba
在这种技术中,可用的数据被分为三个子集。第一个子集是训练集,用于计算梯度和更新网络权重和偏差。第二个子集是验证集。在训练过程中监测验证集上的误差。验证误差通常在训练的初始阶段减小,训练集误差也是如此。然而,当网络开始过度拟合数据时,验证集上的误差通常开始上升。当验证错误在指定次数的迭代中增加时(gydF4y2Banet.trainParam.max_failgydF4y2Ba
),停止训练,并返回验证误差最小的权重和偏差。gydF4y2Ba
测试集误差在训练过程中不使用,但用于比较不同的模型。在训练过程中绘制测试集误差图也是有用的。如果测试集中的错误在与验证集错误显著不同的迭代次数中达到最小值,这可能表明数据集的划分很差。gydF4y2Ba
提供了四个函数将数据划分为训练集、验证集和测试集。他们是gydF4y2BadividerandgydF4y2Ba
(默认),gydF4y2BadivideblockgydF4y2Ba
,gydF4y2BadivideintgydF4y2Ba
,gydF4y2BadivideindgydF4y2Ba
.你可以使用这个属性访问或更改网络的除法函数:gydF4y2Ba
net.divideFcngydF4y2Ba
每个函数都接受自定义其行为的参数。这些值被存储,并可以通过以下网络属性进行更改:gydF4y2Ba
net.divideParamgydF4y2Ba
索引数据部(diind)gydF4y2Ba
创建一个简单的测试问题。对于完整的数据集,生成201个输入点的噪声正弦波,取值范围为−1到1,步长为0.01:gydF4y2Ba
P = [-1:0.01];T = sin(2*pi*p)+0.1*randn(size(p));gydF4y2Ba
将数据按指标进行划分,使连续的样本依次分配到训练集、验证集和测试集:gydF4y2Ba
trainInd = 1:3:201 valInd = 2:3:201;testInd = 3:3:20 0;[trainP,valP,testP] = diinind (p,trainInd,valInd,testInd);[trainT,valT,testT] = divide (t,trainInd,valInd,testInd);gydF4y2Ba
随机数据除法(dividerand)gydF4y2Ba
您可以对输入数据进行随机划分,使60%的样本分配给训练集,20%分配给验证集,20%分配给测试集,如下所示:gydF4y2Ba
[trainP,valP,testP,trainInd,valInd,testInd] =分隔符(p);gydF4y2Ba
此函数不仅对输入数据进行分割,而且还返回索引,以便您可以使用gydF4y2BadivideindgydF4y2Ba
:gydF4y2Ba
[trainT,valT,testT] = divide (t,trainInd,valInd,testInd);gydF4y2Ba
块数据划分(diviblock)gydF4y2Ba
您还可以随机划分输入数据,将前60%的样本分配给训练集,接下来的20%分配给验证集,最后的20%分配给测试集,如下所示:gydF4y2Ba
[trainP,valP,testP,trainInd,valInd,testInd] = diviblock (p);gydF4y2Ba
对目标数据进行相应的划分gydF4y2BadivideindgydF4y2Ba
:gydF4y2Ba
[trainT,valT,testT] = divide (t,trainInd,valInd,testInd);gydF4y2Ba
交错数据部(股息)gydF4y2Ba
另一种划分输入数据的方法是根据百分比在训练集、验证集和测试集之间循环样本。你可以将60%的样本交织到训练集,20%的样本交织到验证集,20%的样本交织到测试集,如下所示:gydF4y2Ba
[trainP,valP,testP,trainInd,valInd,testInd] =红利(p);gydF4y2Ba
对目标数据进行相应的划分gydF4y2BadivideindgydF4y2Ba
.gydF4y2Ba
[trainT,valT,testT] = divide (t,trainInd,valInd,testInd);gydF4y2Ba
正则化gydF4y2Ba
另一种改进泛化的方法被称为gydF4y2Ba正则化。这涉及到修改性能函数,它通常被选择为训练集中网络误差的平方和。下一节解释如何修改性能函数,下一节描述自动设置最佳性能函数以实现最佳泛化的例程。gydF4y2Ba
修改性能功能gydF4y2Ba
典型的gydF4y2Ba用于训练前馈神经网络的性能函数是网络误差平方和的平均值。gydF4y2Ba
如果您通过添加由网络权重和偏差平方和的平均值组成的项来修改性能函数,则有可能改善泛化gydF4y2Ba ,在那里gydF4y2Ba 是性能比,和gydF4y2Ba
使用这个性能函数可以使网络具有更小的权重和偏差,这迫使网络响应更平滑,不太可能过拟合。gydF4y2Ba
下面的代码重新初始化之前的网络,并使用带有正则化性能函数的BFGS算法对其进行重新训练。这里的性能比设置为0.5,这给予均方误差和均方权重相等的权重。gydF4y2Ba
[x,t] = simplefit_dataset;Net = feedforwardnet(10,'trainbfg');net.divideFcn=''; net.trainParam.epochs = 300; net.trainParam.goal = 1e-5; net.performParam.regularization = 0.5; net = train(net,x,t);
正则化的问题是很难确定性能比参数的最佳值。如果你把这个参数设得太大,你可能会过度拟合。如果比例太小,则网络不能充分拟合训练数据。下一节描述自动设置正则化参数的例程。gydF4y2Ba
自动正则化(trainbr)gydF4y2Ba
确定最优值是可取的gydF4y2Ba以自动的方式正则化参数。这个过程的一种方法是gydF4y2BaDavid MacKay的贝叶斯框架[gydF4y2BaMacK92gydF4y2Ba].在该框架中,网络的权重和偏差假设为具有指定分布的随机变量。正则化参数与与这些分布相关的未知方差有关。然后可以使用统计技术估计这些参数。gydF4y2Ba
关于贝叶斯正则化的详细讨论超出了本用户指南的范围。结合Levenberg-Marquardt训练,使用贝叶斯正则化的详细讨论可以在[gydF4y2BaFoHa97gydF4y2Ba].gydF4y2Ba
函数中实现了贝叶斯正则化gydF4y2BatrainbrgydF4y2Ba
.下面的代码展示了如何使用此函数训练1-20-1网络来近似图中所示的噪声正弦波gydF4y2Ba改进浅神经网络泛化,避免过拟合gydF4y2Ba.(通过设置取消数据划分gydF4y2Banet.divideFcngydF4y2Ba
这样的效果gydF4y2BatrainbrgydF4y2Ba
与早期停止隔离。)gydF4y2Ba
X = -1:0.05:1;T = sin(2*pi*x) + 0.1*randn(size(x));Net = feedforwardnet(20,'trainbr');Net = train(Net,x,t);gydF4y2Ba
该算法的一个特点是,它提供了一个度量网络有效使用了多少网络参数(权重和偏差)的方法。在这种情况下,最终训练的网络使用大约12个参数(由gydF4y2Ba#一样gydF4y2Ba
在打印输出中)从1-20-1网络中的61个总权重和偏差中取出。无论网络中的参数数量有多大,有效的参数数量应该保持大致相同。(这假设网络已经训练了足够数量的迭代,以确保收敛。)gydF4y2Ba
的gydF4y2BatrainbrgydF4y2Ba
当网络输入和目标进行缩放,使其大致落在[- 1,1]范围内时,算法通常工作得最好。这就是测试问题的情况。如果您的输入和目标不在此范围内,则可以使用该函数gydF4y2BamapminmaxgydF4y2Ba
或gydF4y2BamapstdgydF4y2Ba
若要执行伸缩,请参见gydF4y2Ba选择神经网络输入输出处理函数gydF4y2Ba.使用gydF4y2BafeedforwardnetgydF4y2Ba
包括gydF4y2BamapminmaxgydF4y2Ba
默认为输入输出处理函数。gydF4y2Ba
下图为训练后网络的响应。与上图中1-20-1网络对数据过拟合形成对比的是,在这里您可以看到网络响应非常接近底层正弦函数(虚线),因此,网络将很好地泛化到新的输入。您可以尝试更大的网络,但网络响应永远不会过度拟合数据。这消除了确定最佳网络大小所需的猜测。gydF4y2Ba
当使用gydF4y2BatrainbrgydF4y2Ba
时,让算法运行到有效参数数收敛为止是很重要的。训练可能会在提示“达到最大MU”时停止。这是典型的,并且很好地表明算法已经真正收敛了。如果平方和误差(SSE)和加权平方和(SSW)在几次迭代中相对恒定,则可以判断算法已经收敛。出现这种情况时,您可能希望单击gydF4y2Ba停止训练gydF4y2Ba按钮。gydF4y2Ba
早期停止与正规化的总结与探讨gydF4y2Ba
当你正确地应用它们时,早期停止和正则化可以确保网络泛化。gydF4y2Ba
对于早期停止,必须注意不要使用收敛速度过快的算法。如果你使用的是快速算法(比如gydF4y2BatrainlmgydF4y2Ba
),设置训练参数,使收敛速度相对较慢。例如,setgydF4y2BaμgydF4y2Ba
到一个比较大的值,如1,并设置gydF4y2Bamu_decgydF4y2Ba
而且gydF4y2Bamu_incgydF4y2Ba
到接近1的值,例如分别为0.8和1.5。培训功能gydF4y2BatrainscggydF4y2Ba
而且gydF4y2BatrainbrgydF4y2Ba
通常早停效果很好。gydF4y2Ba
对于早期停止,验证集的选择也很重要。验证集应该代表训练集中的所有点。gydF4y2Ba
当你使用贝叶斯正则化时,训练网络直到达到收敛是很重要的。当网络收敛时,和平方和误差、和平方和权值和有效参数数应达到恒定值。gydF4y2Ba
对于早期停止和正则化,从几个不同的初始条件开始训练网络是一个好主意。在某些情况下,任何一种方法都有可能失败。通过测试几个不同的初始条件,您可以验证健壮的网络性能。gydF4y2Ba
当数据集很小并且你正在训练函数逼近网络时,贝叶斯正则化比早期停止提供更好的泛化性能。这是因为贝叶斯正则化不要求验证数据集与训练数据集分离;它使用所有的数据。gydF4y2Ba
为了深入了解算法的性能,在几个算法上测试了早期停止和贝叶斯正则化gydF4y2Ba基准测试数据集,下表中列出。gydF4y2Ba
数据集gydF4y2Ba |
点数gydF4y2Ba | 网络gydF4y2Ba | 描述gydF4y2Ba |
---|---|---|---|
球gydF4y2Ba |
67gydF4y2Ba | 2-10-1gydF4y2Ba | 用于测量球位置的双传感器校准gydF4y2Ba |
sin (5% n)gydF4y2Ba |
41gydF4y2Ba | 1-15-1gydF4y2Ba | 5%高斯噪声的单周期正弦波gydF4y2Ba |
sin (2% n)gydF4y2Ba |
41gydF4y2Ba | 1-15-1gydF4y2Ba | 带2%高斯噪声的单周期正弦波gydF4y2Ba |
引擎(全部)gydF4y2Ba |
1199gydF4y2Ba | 2-30-2gydF4y2Ba | 发动机传感器-完整的数据集gydF4y2Ba |
引擎(1/4)gydF4y2Ba |
300gydF4y2Ba | 2-30-2gydF4y2Ba | 发动机传感器- 1/4的数据集gydF4y2Ba |
克洛伊(所有)gydF4y2Ba |
264gydF4y2Ba | 5-15-3gydF4y2Ba | 胆固醇测量-完整的数据集gydF4y2Ba |
克洛伊(1/2)gydF4y2Ba |
132gydF4y2Ba | 5-15-3gydF4y2Ba | 胆固醇测量- 1/2数据集gydF4y2Ba |
这些数据集的大小不同,输入和目标的数量也不同。对于其中的两个数据集,网络使用所有数据进行了一次训练,然后只使用其中的一部分数据进行重新训练。这说明了当数据集较小时,贝叶斯正则化的优势如何变得更加明显。除sin数据集外,所有数据集都来自物理系统。这两个信号是人为地在一个正弦波周期中加入不同级别的噪声而产生的。算法在这两个数据集上的性能说明了噪声的影响。gydF4y2Ba
下表总结了早期停止(ES)和贝叶斯正则化(BR)在七个测试集上的性能。(gydF4y2BatrainscggydF4y2Ba
采用算法进行早停试验。其他算法也提供了类似的性能。)gydF4y2Ba
均方测试集误差gydF4y2Ba
方法gydF4y2Ba | 球gydF4y2Ba | 引擎(全部)gydF4y2Ba | 引擎(1/4)gydF4y2Ba | 克洛伊(所有)gydF4y2Ba | 克洛伊(1/2)gydF4y2Ba | 正弦(5% N)gydF4y2Ba | sin (2% N)gydF4y2Ba |
---|---|---|---|---|---|---|---|
西文gydF4y2Ba | 1.2 e 1gydF4y2Ba | 1.3依照gydF4y2Ba | 1.9依照gydF4y2Ba | 1.2 e 1gydF4y2Ba | 1.4 e 1gydF4y2Ba | 1.7 e 1gydF4y2Ba | 1.3 e 1gydF4y2Ba |
BRgydF4y2Ba | 1.3 e - 3gydF4y2Ba | 2.6 e - 3gydF4y2Ba | 4.7 e - 3gydF4y2Ba | 1.2 e 1gydF4y2Ba | 9.3依照gydF4y2Ba | 3.0依照gydF4y2Ba | 6.3 e - 3gydF4y2Ba |
ES / BRgydF4y2Ba | 92gydF4y2Ba | 5gydF4y2Ba | 4gydF4y2Ba | 1gydF4y2Ba | 1.5gydF4y2Ba | 5.7gydF4y2Ba | 21gydF4y2Ba |
你可以看到贝叶斯正则化在大多数情况下比早期停止表现得更好。当数据集很小,或者数据集中几乎没有噪声时,性能的改善是最明显的。例如,BALL数据集是从噪音很小的传感器中获得的。gydF4y2Ba
尽管贝叶斯正则化的泛化性能通常优于早期停止,但情况并非总是如此。此外,工具箱中实现的贝叶斯正则化形式在模式识别问题上的表现不如在函数逼近问题上的表现好。这是因为当网络输出饱和时,Levenberg-Marquardt算法中使用的Hessian的近似值就不那么准确了,就像模式识别问题中的情况一样。贝叶斯正则化方法的另一个缺点是,它通常需要比早期停止更长的时间来收敛。gydF4y2Ba
培训后分析(回归)gydF4y2Ba
的表演gydF4y2Ba经过训练的网络在某种程度上可以通过训练集、验证集和测试集上的误差来测量,但更详细地研究网络响应通常是有用的。一种选择是在网络响应和相应目标之间进行回归分析。例程gydF4y2Ba回归gydF4y2Ba
用于执行此分析。gydF4y2Ba
下面的命令说明如何在训练好的网络上执行回归分析。gydF4y2Ba
X = [-1:.05:1];T = sin(2*pi*x)+0.1*randn(size(x));Net = feedforwardnet(10);Net = train(Net,x,t);Y = net(x);[r,m,b] =回归(t,y)gydF4y2Ba
R = 0.9935 m = 0.9874 b = -0.0067gydF4y2Ba
网络输出和相应的目标被传递给gydF4y2Ba回归gydF4y2Ba
.它返回三个参数。前两个,gydF4y2Ba米gydF4y2Ba
而且gydF4y2BabgydF4y2Ba
,对应于斜率和gydF4y2BaygydF4y2Ba-将目标与网络输出相关的最佳线性回归的截距。如果存在完美拟合(输出完全等于目标),则斜率为1,而gydF4y2BaygydF4y2Ba-intercept为0。在这个例子中,你可以看到这些数字非常接近。返回的第三个变量gydF4y2Ba回归gydF4y2Ba
为输出与目标之间的相关系数(r值)。它衡量的是目标对产出变化的解释程度。如果这个数字等于1,那么目标和输出之间是完全相关的。在这个例子中,这个数字非常接近1,这表明很适合。gydF4y2Ba
提供的图形输出如下图所示gydF4y2Ba回归gydF4y2Ba
.网络输出相对于目标绘制为开圈。最佳线性拟合用虚线表示。完美拟合(输出等于目标)由实线表示。在这个例子中,很难区分最佳线性拟合线和完美拟合线,因为拟合非常好。gydF4y2Ba