@devilogic
2016-08-09T16:32:15.000000Z
字数 2576
阅读 1631
matlab
假设你想分类一个肿瘤是良性还是恶性,基于细胞大小的均匀程度,肿块的厚度,有丝分裂等等。你有699个9种特征的样本数据来让你区别它们。
定义一个模式识别问题,指定一个Q列的输入矩阵(每列是一个样本)。指定另外一个Q列的矩阵作为目标矩阵。它们表明了输入向量要分到哪一类(参见理解神经网络工具箱的数据结构一文来详细了解静态与时序数据的输入格式)。这有两种方式创建目标向量。
一种方式是目标仅有两种类别;你设置每一个标量目标为或者,表明输入向量属于哪个目标类型。使用以下命令定义:
inputs = [0 1 0 1; 0 0 1 1];
targets = [0 1 0 1; 1 0 1 0];
目标向量有个元素,对于目标向量,一个元素或者是或者是。如果要定义一个输入向量被划分为个不同的类型。例如,下面的命令显示了如何定义一个多目标类型:
* 第一个输入向量是第一种类型
* 最后一个输入向量是第二种类型
* 其余的是第三种类型
分类问题只涉及这两种格式。目标能被组成为标量或者元素或者两个元素向量,其中一元素是其余是。
inputs = [0 0 0 0 5 5 5 5; 0 0 5 5 0 0 5 5; 0 5 0 5 0 5 0 5];
targets = [1 0 0 0 0 0 0 0; 0 1 1 1 1 1 1 0; 0 0 0 0 0 0 0 1];
下面是分类代码:
% Solve a Pattern Recognition Problem with a Neural Network
% Script generated by NPRTOOL
%
% This script assumes these variables are defined:
%
% cancerInputs - input data.
% cancerTargets - target data.
inputs = cancerInputs;
targets = cancerTargets;
% 创建一个模式识别网络
hiddenLayerSize = 10; % 隐藏层数量为10
net = patternnet(hiddenLayerSize);
% 设置训练,测试,验证数据集
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
% 训练
[net,tr] = train(net,inputs,targets);
% 测试网络
outputs = net(inputs);
errors = gsubtract(targets,outputs);
performance = perform(net,targets,outputs)
% 浏览网络
view(net)
% 画图
% Uncomment these lines to enable various plots.
% figure, plotperform(tr)
% figure, plottrainstate(tr)
% figure, plotconfusion(targets,outputs)
% figure, ploterrhist(errors)
[inputs, targets] = cancer_dataset;
创建一个网络,默认的网络是为了适应性(回归问题)问题,patternnet,是一个在隐藏层使用tan-sigmoid
激励函数,在输出层使用softmax
传输激励函数的前向网络。这里指定了一个元素的单隐藏层。
* 网络有两个输出神经元,因为有两个目标值(类型)对应每个输入向量。
* 每个输出神经元表明一个类型。
* 当一组输入向量应用到一个网络,那么如果判定是这个输入要表明的类型,则输出,否则则输出。
创建一个网络使用以下命令:
hiddenLayerSize = 10;
net = patternnet(hiddenLayerSize);
对于模式识别的网络架构的选择,类似于拟合问题。越复杂的问题神经元越多,但是当数量太多时将会产生过拟合问题,但是它们将能解决更复杂的问题。更多隐藏层需要更多的技术,但是它们对解决复杂问题是有效果的。如果要使用多隐藏层则传递一个数组到patternnet命令。
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
参加分离数据集一文。
模式识别网络使用默认的Scaled Conjugate Gradient(trainscg)算法来做激励函数。训练这个网络,使用以下的命令:
[net,tr] = train(net,inputs,targets);
在训练成功之后。需要测试网络,以下代码用来计算网络输出,误差。
outputs = net(inputs);
errors = gsubtract(targets,outputs);
performance = perform(net,targets,outputs)
performance =
0.0419
计算网络性能评估仅使用测试数据,通过使用在训练记录中的测试索引。
tInd = tr.testInd;
tstOutputs = net(inputs(:,tInd));
tstPerform = perform(net,targets(:,tInd),tstOutputs)
tstPerform =
0.0263
view(net)
figure, plotperform(tr)
使用plotconfusion命令来绘制在最终训练网络完成时的各种类型的误差。
对角线的小方格显示了种类被正确分类的正确率,非对角线方格显示了错误分类的类型。右下角蓝色的方格显示了正确分类的百分率(绿色)以及错误分类的百分率(红色)。
如果你得到更好的结果,尝试以下的方式:
* 重新设置网络权重与偏置值使用init函数后再次训练网络
* 增加隐藏层的神经元
* 增加训练向量的数量
* 增加输入的有效特征的数量
* 尝试不同的训练算法
每次一个神经网络被训练完毕,结果都有所不同这是因为不同的初始化权值与偏置值与不同的训练,验证,测试的几何。不同的神经网络在同一问题同一输入上训练结果不同。
参见提高神经网络适应性与避免过拟合一文。