定义问题
脚本 prprob 定义了一个包含 26 列的矩阵 X,每列对应一个字母。每列有 35 个值,值可能是 1,也可能是 0。每列(包含 35 个值)定义一个字母的 5×7 位图。
矩阵 T 是一个 26×26 的单位矩阵,它将 26 个输入向量映射到 26 个类。
[X,T] = prprob;
以下命令将第一个字母 A 绘制为一个位图。
plotchar(X(:,1))
创建第一个神经网络
为求解此问题,我们将使用针对模式识别建立的具有 25 个隐藏神经元的前馈神经网络。
由于神经网络以随机初始权重进行初始化,因此每次运行该示例进行训练后的结果都略有不同。为了避免这种随机性,请设置随机种子以便每次都重现相同的结果。这对于您自己的应用情形不是必需的。
setdemorandstream(pi);
net1 = feedforwardnet(25);
view(net1)
训练第一个神经网络
函数 train 将数据划分为训练集、验证集和测试集。训练集用于更新网络,验证集用于在网络过拟合训练数据之前停止网络,从而保持良好的泛化。测试集用作完全独立的测量手段,用于衡量网络针对新样本的预期表现。
当网络针对训练集或验证集不再可能有改善时,训练停止。
net1.divideFcn = '';
net1 = train(net1,X,T,nnMATLAB);
Computing Resources:
MATLAB on GLNXA64
训练第二个神经网络
我们希望网络不仅可以识别形状标准的字母,还可以识别含噪的字母。因此,我们将尝试针对含噪数据训练第二个网络,并将其泛化能力与第一个网络进行比较。
以下命令为每个字母 Xn 创建 30 个含噪副本。值由 min 和 max 限制在 0 和 1 之间。还定义了相应的目标 Tn。
numNoise = 30;
Xn = min(max(repmat(X,1,numNoise)+randn(35,26*numNoise)*0.2,0),1);
Tn = repmat(T,1,numNoise);
以下是 A 的含噪版本。
figure
plotchar(Xn(:,1))
以下命令将创建并训练第二个网络。
net2 = feedforwardnet(25);
net2 = train(net2,Xn,Tn,nnMATLAB);
Computing Resources:
MATLAB on GLNXA64
测试两个神经网络
noiseLevels = 0:.05:1;
numLevels = length(noiseLevels);
percError1 = zeros(1,numLevels);
percError2 = zeros(1,numLevels);
for i = 1:numLevels
Xtest = min(max(repmat(X,1,numNoise)+randn(35,26*numNoise)*noiseLevels(i),0),1);
Y1 = net1(Xtest);
percError1(i) = sum(sum(abs(Tn-compet(Y1))))/(26*numNoise*2);
Y2 = net2(Xtest);
percError2(i) = sum(sum(abs(Tn-compet(Y2))))/(26*numNoise*2);
end
figure
plot(noiseLevels,percError1*100,'--',noiseLevels,percError2*100);
title('Percentage of Recognition Errors');
xlabel('Noise Level');
ylabel('Errors');
legend('Network 1','Network 2','Location','NorthWest')
由于存在噪声,在无噪声情况下训练的网络 1 的错误数多于在有噪声情况下训练的网络 2。