使用浅层神经网络进行模式识别
除了函数拟合,神经网络也擅长识别模式。
例如,假设您要根据细胞大小、肿块厚度、有丝分裂等特征的均匀性将肿瘤分为良性或恶性。您有 699 个样本,相关特征有 9 项,并且这些案例已正确分类为良性或恶性。
与函数拟合一样,解决此问题的方法有两种:
使用神经网络模式识别,如使用神经网络模式识别进行模式识别中所述。
使用命令行函数,如使用命令行函数进行模式识别中所述。
一般最好从 App 开始,然后使用该 App 自动生成命令行脚本。在使用任何方法之前,首先通过选择数据集来定义问题。每个神经网络 App 都可以访问许多采样数据集,您可以使用这些数据集来试验工具箱(请参阅浅层神经网络的样本数据集)。如果您有要解决的特定问题,可以将您自己的数据加载到工作区中。下一节介绍数据格式。
提示
要以交互方式构建和可视化深度学习神经网络,请使用深度网络设计器。有关详细信息,请参阅深度网络设计器快速入门。
定义问题
要定义模式识别问题,请将一组输入向量(预测变量)排列为一个矩阵中的列。然后排列另一组响应向量,指示观测值分配到的类。
当只有两个类时,每个响应向量有两个元素,即 0 和 1,指示对应的观测值属于哪个类。例如,您可以定义一个两类分类问题,如下所示:
predictors = [7 10 3 1 6; 5 8 1 1 6; 6 7 1 1 6]; responses = [0 0 1 1 0; 1 1 0 0 1];
当预测变量要分类为 N 个不同的类时,则响应向量具有 N 个元素。对于每个响应变量,有一个元素为 1,其他元素为 0。例如,下文展示了如何定义一个将 5×5×5 立方体的各个角分为三类的分类问题:
原点(第一个输入向量)为一个类
离原点最远的角(最后一个输入向量)为第二个类
所有其他点为第三个类
predictors = [0 0 0 0 5 5 5 5; 0 0 5 5 0 0 5 5; 0 5 0 5 0 5 0 5]; responses = [1 0 0 0 0 0 0 0; 0 1 1 1 1 1 1 0; 0 0 0 0 0 0 0 1];
下一节说明如何使用 Neural Net Pattern Recognition 来训练用于识别模式的网络。此示例使用工具箱附带的示例数据集。
使用神经网络模式识别进行模式识别
此示例说明如何使用神经网络模式识别训练浅层神经网络,以对模式进行分类。
使用 nprtool
打开神经网络模式识别。
nprtool
选择数据
神经网络模式识别提供了示例数据来帮助您开始训练神经网络。
要导入示例玻璃分类数据,请选择导入 > 导入玻璃数据集。您可以使用此数据集训练神经网络,根据玻璃的化学属性将玻璃分为窗用玻璃或非窗用玻璃。如果您从文件或工作区导入自己的数据,则必须指定预测变量和响应变量,以及观测值位于行中还是列中。
有关导入数据的信息显示在模型摘要中。此数据集包含 214 个观测值,每个观测值有 9 个特征。每个观测值分为两个类之一:窗用或非窗用。
将数据分成训练集、验证集和测试集。保留默认设置。数据拆分为:
70% 用于训练。
15% 用于验证网络是否正在泛化,并在过拟合前停止训练。
15% 用于独立测试网络泛化。
有关数据划分的详细信息,请参阅划分数据以实现最优神经网络训练。
创建网络
该网络是一个双层前馈网络,其中在隐藏层有一个 sigmoid 传递函数,在输出层有一个 softmax 传递函数。隐藏层的大小对应于隐藏神经元的数量。默认层大小为 10
。您可以在网络窗格中看到网络架构。输出神经元的数量设置为 2,等于响应数据指定的类的数量。
训练网络
要训练网络,请点击训练。
在训练窗格中,您可以看到训练进度。训练会一直持续,直到满足其中一个停止条件。在此示例中,训练会一直持续,直到六次连续验证迭代的验证误差大于或等于先前最小验证误差(“满足验证条件”)。
分析结果
模型摘要包含关于每个数据集的训练算法和训练结果的信息。
您可以通过生成绘图来进一步分析结果。要对混淆矩阵绘图,请在绘图部分中,点击混淆矩阵。您会看到绿色方块(对角线)中的正确分类数字很高,红色方块(非对角线)中的错误分类数字很低,这表明网络输出非常准确。
查看 ROC 曲线以获得网络性能的额外验证。在绘图部分中,点击 ROC 曲线。
每个轴上的彩色线条表示 ROC 曲线。ROC 曲线是随阈值变化的真正率(敏感度)对假正率(1 - 特异度)的图。完美的测试会在左上角显示点,灵敏度和特异度均为 100%。对于此问题,网络性能非常好。
如果您对网络性能不满意,可以执行以下操作之一:
重新训练网络。
增加隐藏神经元的数量。
使用更大的训练数据集。
如果基于训练集的性能很好,但测试集的性能很差,这可能表明模型出现了过拟合。减少神经元的数量可以减少过拟合。
您还可以评估基于附加测试集的网络性能。要加载附加测试数据来评估网络,请在测试部分中,点击测试。模型摘要显示附加测试结果。您也可以生成图来分析附加测试结果。
生成代码
选择生成代码 > 生成简单的训练脚本以创建 MATLAB 代码,从命令行重现前面的步骤。如果您要了解如何使用工具箱的命令行功能来自定义训练过程,则创建 MATLAB 代码会很有帮助。在使用命令行函数进行模式识别中,您可以更详细地研究生成的脚本。
导出网络
您可以将经过训练的网络导出到工作区或 Simulink®。您也可以使用 MATLAB Compiler™ 和其他 MATLAB 代码生成工具部署网络。要导出您的训练网络和结果,请选择导出模型 > 导出到工作区。
使用命令行函数进行模式识别
了解如何使用工具箱的命令行功能的最简单方法是从 App 生成脚本,然后修改它们以自定义网络训练。例如,看看上一节使用神经网络模式识别创建的简单脚本。
% Solve a Pattern Recognition Problem with a Neural Network % Script generated by Neural Pattern Recognition app % Created 22-Mar-2021 16:50:20 % % This script assumes these variables are defined: % % glassInputs - input data. % glassTargets - target data. x = glassInputs; t = glassTargets; % Choose a Training Function % For a list of all training functions type: help nntrain % 'trainlm' is usually fastest. % 'trainbr' takes longer but may be better for challenging problems. % 'trainscg' uses less memory. Suitable in low memory situations. trainFcn = 'trainscg'; % Scaled conjugate gradient backpropagation. % Create a Pattern Recognition Network hiddenLayerSize = 10; net = patternnet(hiddenLayerSize, trainFcn); % Setup Division of Data for Training, Validation, Testing net.divideParam.trainRatio = 70/100; net.divideParam.valRatio = 15/100; net.divideParam.testRatio = 15/100; % Train the Network [net,tr] = train(net,x,t); % Test the Network y = net(x); e = gsubtract(t,y); performance = perform(net,t,y) tind = vec2ind(t); yind = vec2ind(y); percentErrors = sum(tind ~= yind)/numel(tind); % View the Network view(net) % Plots % Uncomment these lines to enable various plots. %figure, plotperform(tr) %figure, plottrainstate(tr) %figure, ploterrhist(e) %figure, plotconfusion(t,y) %figure, plotroc(t,y)
您可以保存脚本,然后从命令行运行它,以重现上次训练会话的结果。您还可以编辑脚本来自定义训练过程。在此例中,请遵循脚本中的每个步骤。
选择数据
该脚本假设预测变量和响应向量已加载到工作区中。如果未加载数据,您可以按如下方式加载它:
load glass_dataset
glassInputs
和响应变量 glassTargets
加载到工作区中。此数据集是工具箱的示例数据集之一。有关可用数据集的信息,请参阅浅层神经网络的样本数据集。您可以输入命令 help nndatasets
来查看所有可用数据集的列表。您可以使用自己的变量名称从这些数据集中加载变量。例如,命令
[x,t] = glass_dataset;
x
中,并将玻璃响应变量加载到数组 t
中。选择训练算法
定义训练算法。
trainFcn = 'trainscg'; % Scaled conjugate gradient backpropagation.
创建网络
创建网络。模式识别(分类)问题的默认网络 patternnet
是一个前馈网络,其默认 sigmoid 传递函数在隐藏层,softmax 传递函数在输出层。网络有一个包含十个神经元(默认值)的隐藏层。
网络有两个输出神经元,因为有两个响应值(类)与每个输入向量关联。每个输出神经元表示一个类。将相应类的输入向量应用于网络时,对应的神经元应生成 1,其他神经元应输出 0。
hiddenLayerSize = 10; net = patternnet(hiddenLayerSize, trainFcn);
注意
神经元越多,需要的计算也越多;当数量设置得太高时,可能会出现数据过拟合倾向,但这使网络能够求解更复杂的问题。层越多,需要的计算也越多,但使用更多的层可以使网络更高效地求解复杂问题。要使用多个隐藏层,请在 patternnet
命令中输入隐藏层大小作为数组的元素。
划分数据
设置数据划分。
net.divideParam.trainRatio = 70/100; net.divideParam.valRatio = 15/100; net.divideParam.testRatio = 15/100;
使用这些设置,预测变量向量和响应向量将被随机划分,70% 用于训练,15% 用于验证,15% 用于测试。有关数据划分过程的详细信息,请参阅划分数据以实现最优神经网络训练。
训练网络
训练网络。
[net,tr] = train(net,x,t);
在训练期间,将打开训练进度窗口。您随时可以通过点击停止按钮 来中断训练。
当验证误差大于或等于六次连续验证迭代的先前最小验证误差时,训练结束,这发生在第 14 轮。
如果在训练窗口中点击性能,将显示表示训练误差、验证误差和测试误差的图,如下图所示。
在此示例中,结果是合理的,因为最终的交叉熵误差很小。
测试网络
测试网络。您可以使用经过训练的网络来计算网络输出。以下代码将计算网络输出、误差和整体性能。
y = net(x); e = gsubtract(t,y); performance = perform(net,t,y)
performance = 0.0659
您还可以计算误分类的观测值的比例。在此示例中,模型的误分类率非常低。
tind = vec2ind(t); yind = vec2ind(y); percentErrors = sum(tind ~= yind)/numel(tind)
percentErrors = 0.0514
通过使用训练记录中的测试索引,还可以只针对测试集计算网络性能。
tInd = tr.testInd; tstOutputs = net(x(:,tInd)); tstPerform = perform(net,t(tInd),tstOutputs)
tstPerform = 2.0163
查看网络
查看网络图。
view(net)
分析结果
使用 plotconfusion
函数绘制混淆矩阵。您也可以通过点击训练窗口中的混淆来对每个数据集的混淆矩阵绘图。
figure, plotconfusion(t,y)
对角线上的绿色单元格显示正确分类的案例数,非对角线上的红色单元格显示误分类的案例数。结果表明识别效果非常好。如果您需要更准确的结果,可以尝试下列方法之一:
在这种情况下,网络训练结果是令人满意的,您现在可以将网络用于新输入数据集。
后续步骤
要获得更多命令行操作经验,您可以尝试以下任务:
在训练期间,打开绘图窗口(如混淆矩阵图),并观察其动画效果。
从命令行使用
plotroc
和plottrainstate
等函数绘图。
每次训练神经网络时,由于初始权重和偏置值随机,并且将数据划分为训练集、验证集和测试集的方式也不同,可能会产生不同的解。因此,针对同一问题训练的不同神经网络对同一输入可能给出不同输出。为确保找到准确度良好的神经网络,需要多次重新训练。
如果需要更高的准确度,可以采用几种其他方法来改进初始解。有关详细信息,请参阅提高浅层神经网络泛化能力,避免过拟合。
另请参阅
神经网络拟合 | 神经网络时间序列 | 神经网络模式识别 | 神经网络聚类 | 深度网络设计器 | trainscg