使用神经网络能执行几种典型的任务:聚类、拟合、分类(模式识别)以及时间序列预测。
其中分类任务可以说是最常应用的场景之一,在之前的文章里也使用了分类任务作为案例对神经网络进行了入门讲解。
时常遇到想要使用神经网络快速地实现分类的同学。
今天就讲一讲怎么用MATLAB快速地完成吧。
这里使用MNIST数据集作为案例。
MNIST是一个很有名的手写数字识别数据集。对于每张照片,都是以一个28*28的矩阵存储的,数据“展平”之后是一个长度为784的一维数据。
MNIST数据集数字0~9示例
数据分为四组:
TRAIN_images:训练集输入数据,维度为60000*784。其中60000代表训练集共有60000组数据(批次数bench)。
TRAIN_labels:训练集的标签数据,维度为60000*10,其中的10代表的数字0~9共有10种类型。比如数字0使用[1 0 0 0 0 0 0 0 0 0]代表,数字1使用[0 1 0 0 0 0 0 0 0 0]代表,以此类推。
TEST_images:测试集输入数据,维度为10000*784
TEST_labels:训练集的标签数据,维度为10000*10
其中训练集是用于训练神经网络,测试集用于验证神经网络分类的优劣度(正确率)。
需要注意的是,有的时候标签值不是以矩阵的形式表示的,而是以0~9这样的类别数字表示的。这时候需要对标签类型进行转换,博主写了这样一个函数:
function label = class2label(class)
% 将class转为label
% 例如将[3,2,1,1]转换为[0,0,1;0,1,0;1,0,0;1,0,0]
% 输入:
% class 为类别数据,一维数据
% 输出:
% label 为多维矩阵,一行为一个标签,共n行,即n个标签
% 示例:label = class2label([3,2,1,1])
同样从矩阵形式转变为数字类别形式也有,这两个函数时常会用到:
function class = label2class(label)
% 将label转为class
% 例如将[0,0,1;0,1,0;1,0,0;1,0,0]转换为[3,2,1,1]
% 输入:
% label 为多维矩阵,一行为一个标签,共n行,即n个标签(一定要注意输入的label的维度正确)
% 输出:
% class 为分类结果,行向量,一维数据
% 示例:class = label2class([0,0,1;0,1,0;1,0,0;1,0,0])
patternnet是MATLAB内置的用于对目标类别进行分类的神经网络。使用patternnet时的标签值必须是矩阵形式的。该函数的使用方法比较简单,如下图所示:
% 2.初始化神经网络
hiddenSizes = 120; %隐藏层数
net = patternnet(hiddenSizes); %初始化模式识别神经网络
view(net) %查看神经网络结构
此时神经网络的结构如下图,可以看出隐藏层的激活函数默认的是tansig,该激活函数是可以更换的。
模式识别神经网络结构
MATLAB使用train函数训练浅层神经网络。训练神经网络的指令也可以说是很简单了,不过需要注意的是训练数据的行列方向。
训练集输入数据是R*Q的矩阵,R为特征维度,Q为批次数,训练集标签数据是U*Q的矩阵,U为标签种类数,Q为批次数。如果不是这样的方向则需要对数据进行转置。
如下述语句对数据就进行了转置。
% 3.训练神经网络
net = train(net,TRAIN_images',TRAIN_labels'); %训练网络
这步中使用了测试集进行了分类测试,并与真实的分类值进行对比,得到分类的正确率,代码如下:
% 4.使用测试集进行分类
testLen = 10000; %测试集长度
val = sim(net,TEST_images'); %计算测试集分类结果
classes = vec2ind(val); %将分类结果转换为class
r = sum(classes == label2class(TEST_labels'))/(testLen); %计算正确率
disp(['模式识别的正确率为',num2str(r)]) %打印结果
分类的结果为:
96.69%算是差强人意的正确率,通过优化还可以将正确率进一步提升。例如在第二部分的代码后加入这样两行代码:
net.layers{1}.transferFcn = 'logsig'; %将激活函数改为sigmod
net.trainFcn = 'traincgf'; %将训练函数换为traincgf
关于激活函数和训练函数更多的说明可以看这里:神经网络“分类”工具使用手册
此时分类结果为:
正确率有所提升,同学们可以再优化隐藏层数、激活函数、训练函数以及net的更多属性获取更好的分类效果。
上述流程可以封装为一个函数文件,通过该函数文件可以快速实现分类任务的神经网络训练以及分类性能测试。
而你需要做的只是把数据准备好即可。
封装好的函数的说明如下:
function [net,r] = fastPatternnet(dTrain,dTrainLabel,dTest,dTestLabel,hiddenSizes,auto,set)
% 快速模式识别(分类)神经网络,可以自主设定训练集比例,并得到测试集分类正确率
% 输入:
% dTrain:神经网络输入的训练集,R*Q的矩阵,R为特征维度,Q为批次数,输入该变量时一定要注意行列方向是否正确
% dTrainLabel:神经网络的标签值,U*Q的矩阵,U为标签种类数,Q为批次数,输入该变量时一定要注意行列方向是否正确
% dTest:神经网络输入的测试集,R*Q的矩阵,R为特征维度,Q为批次数,输入该变量时一定要注意行列方向是否正确
% dTestLabel:神经网络输入的测试集,R*Q的矩阵,R为特征维度,Q为批次数,输入该变量时一定要注意行列方向是否正确
% hiddenSizes:神经网络隐藏层数
% auto:是否进行自动纠错,'on'为是,否则为否。开启自动纠错后会智能调整训练、测试集的行列方向。
% set:网络的额外设置,具体设置见:神经网络“分类”工具使用手册 | 工具箱文档
% 输出:
% net:训练完成的神经网络
% r:使用测试集得到的模式识别正确率,1对应100%正确
获取数据集和代码请看这里:神经网络“分类”工具文档(公开版)
获取封装好的函数及其说明文档请看这里:神经网络“分类”工具手册(完整版)
欢迎关注我的公众号“看海的城堡”,公众号里可能还会有更多有趣的东西分享。
后续可能还会补充聚类、拟合和时间序列预测的MATLAB快速实现方法~
分类无处不在