本文的主要内容来自Mathworks官网的相关示例,body-fat-estimation。此示例说明神经网络如何基于多个身体测量值来估计体脂率,实现函数逼近和非线性回归。
问题:估计体脂率
在此示例中,尝试构建一个神经网络,该网络可以通过下面的 13 个身体属性来估计一个人的体脂率:
这是输入数据与相关输出目标进行匹配的拟合问题,我们希望所创建的神经网络不仅可以根据已知输入估计已知目标,还能泛化成针对未知输入数据的网络。
为什么使用神经网络?
神经网络非常擅长处理函数拟合问题,隐含层具有足够神经元的神经网络可以以任意准确度拟合任何数据,而且特别适合处理非线性问题。由于真实问题(如体脂增加)的非线性特性,神经网络是处理此问题的优选方案。
十三个身体属性将作为神经网络的输入,体脂率作为神经网络的输出。该网络将使用体脂率已知的人体解剖学数据进行训练以生成目标估值。
MATLAB代码
代码的含义在注释中
%% 导入数据
% X是13*252的矩阵,T是1*252的矩阵,对应输入和目标
[X,T] = bodyfat_dataset;
%% 构建神经网络
% 建立一个隐含层的神经网络,神经元数为15
% 前馈神经网络可以拟合任何输入-输出关系,前提是隐含层中有足够的神经元。
% 一般情况下,问题越困难,需要的隐含层和每层的神经元就越多。问题越简单,需要的层和神经元就越少。
net = fitnet(15);
% 展示网络,可以看到输入和输出的大小为 0,因为网络尚未经过训练,没有与输入数据和目标数据相匹配
view(net)
神经网络结构示意图,隐含层有15个神经元
%% 训练网络
% 开始训练,样本自动分为训练集、验证集和测试集。训练集用于对网络进行训练。
% 只要网络针对验证集持续改进,训练就会继续。测试集用于完全独立的网络性能测试
[net,tr] = train(net,X,T);
% 神经网络训练工具显示正在接受训练的网络和用于训练的算法。
% 它还显示训练过程中的训练状态以及停止训练的条件(以绿色突出显示)。
% 底部的按钮用于打开有用的绘图,这些图可以在训练期间和训练后打开。
% 算法名称和绘图按钮旁边的链接可打开这些主题的相关文档。
nntraintool
神经网络训练工具
% 要查看在训练过程中网络性能的改善情况,请点击训练工具中的 Performance 按钮,或调用 PLOTPERFORM。
% 性能以均方误差衡量,并以对数刻度显示。随着网络训练的加深,均方误差迅速降低。
% 绘图会显示训练集、验证集和测试集的性能。最终得到的网络是针对验证集性能最好的网络,图中圆圈处
plotperform(tr)
网络性能变化图,圆圈处为针对测试集性能最好的点
%% 三种方法检验网络性能
% 第一种方法是均方误差,将测试样本用于网络性能的测试,计算出均方误差,能够了解网络在应用于真实数据时的表现
testX = X(:,tr.testInd);
testT = T(:,tr.testInd);
testY = net(testX);
figure;
perf = mse(net,testT,testY)
% 衡量神经网络数据拟合程度的另一个方法是回归图。下面绘制了所有样本的回归图。
% 如果网络能够很好地拟合数据,则此输出-目标线性拟合线(蓝色实线)与图中虚线应该十分接近甚至重合。
% 如果不是这样,则建议进一步进行训练,或训练具有更多隐含层和神经元的网络。
Y = net(X);
figure;
plotregression(T,Y)
% 衡量神经网络数据拟合程度的第三个方法是误差直方图。该图可显示误差大小的分布方式。通常,大多数误差接近于零,很少有误差大幅偏离。
e = T - Y;
figure;
ploterrhist(e)
三种方法的结果如下:
测试集的均方误差
perf =
24.3793
回归图,可以看到蓝线和虚线的拟合程度还算不错
误差直方图,可以看到多数误差分布在0附近