LVQ神经网络
1.结构
由3层神经元组成,即输入层、竞争层和线性输出层,输入层与竞争层之间采用全连接方式,竞争层与线性输出层之间采用部分连接的方式。
2.学习算法
LVQ1算法、LVQ2算法
概述
数据库包含细胞核图像的10个量化特征(细胞核半径、质地、周长、面积、光滑度等),这些特征与肿瘤的性质密切相关。因此需要建立一个确定的模型来描述数据库中各个量化特征与肿瘤性质的关系,从而可以根据细胞核显微图像的量化特征诊断乳腺肿瘤是良性还是恶性。
设计思路
将乳腺肿瘤病灶组织的细胞核显微图像的10个量化特征作为网络的输入,良性乳腺肿瘤和恶性乳腺肿瘤作为网络的输出。用训练集数据对设计的LVQ神经网络进行训练,然后对测试集数据进行测试并对测试结果进行分析。
设计步骤
1.数据采集
500组数据作为训练集,剩余69组作为测试集。数据文件中每组数据共32个字段,第一个字段为病例编号,第2个字段为确诊结果,B为良性,M为恶性;其余字段为该病例肿瘤病灶组织的各细胞核显微图像的量化特征。
2.网络创建
利用MATLAB自带的神经网络工具箱函数newlvq()构建LVQ神经网络。
3.网络训练
设置神经网络参数,将训练集500个病例数据输入网络进行训练。
4.网络仿真
将测试集69个病例数据输入网络,得出相应的输出。
5.结果分析
对网络仿真结果进行分析,可以得到误诊率。
具体实现
1.导入数据
随机选取500组数据作为训练集,其余69组数据作为测试集。输入神经元个数为30,分别代表30个细胞核的形态特征;输出神经元个数为2,分别表示良性和恶性乳腺肿瘤。‘1’对应良性,‘2’对应恶性。
%清除环境变量
clear;
clc;
%导入数据
%数据文件共32个字段,第一个为病例编号,第二个为确诊结果,后30个为细胞核的形态特征
load data.mat;
%随机取500组数据作为训练集,剩余69组数组为测试集
a = randperm(569); %随机打乱1-569间的数字序列
Train = data(a(1:500),:);
Test = data(a(501:end),:);
%训练数据
P_train = Train(:,3:end)'; %取后30个字段
Tc_train = Train(:,2)'; %取第二个字段,确诊结果1良性,2恶性
T_train = ind2vec(Tc_train); %确诊结果类别转为对应目标向量[1,0]'、[0,1]'
%测试数据
P_test = Test(:,3:end)';
Tc_test = Test(:,2)';
2.创建LVQ网络
利用newlvq()函数创建LVQ神经网络
net = newlvq(PR,S1,PC,LR,LF)
% PR为输入向量的范围,S1为竞争层神经元个数,PC为线性输出层期望类别各自所占的比重,
% LR为学习速率,默认为0.01,LF为学习函数,默认为"learnlv1"
%创建LVQ网络
count_B = length(find(Tc_train == 1)); %训练集中确诊结果为1的长度,即确诊良性病例数
count_M = length(find(Tc_train == 2)); %确诊恶性病例数
rate_B = count_B/500; %1类占比
rate_M = count_M/500; %2类占比
net = newlvq(minmax(P_train),10,[rate_B rate_M]);
%训练集,隐含层神经元个数,所属类别百分比
%设置网络参数
net.trainParam.epochs = 1000; %训练次数
net.trainParam.show = 10; %显示频率,每训练10次显示一次
net.trainParam.lr = 0.1; %学习速率
net.trainParam.goal = 0.1; %训练目标最小误差
3.训练LVQ网络
利用MATLAB自带的网络训练函数train()对网络进行训练学习
%网络训练
net = train(net,P_train,T_train); %训练集、目标向量,返回训练后的网络net
4.仿真测试
sim()函数将测试集输入数据送入训练好的神经网络便可得到对应的测试集输出仿真数据
%仿真测试
T_sim = sim(net,P_test); %sim()函数将测试集输入数据送入训练好的神经网络便可得到对应测试集输出的仿真数据
Tc_sim = vec2ind(T_sim); %将目标向量转换为对应的代表类别的下标矩阵
result = [Tc_sim;Tc_test]; %第1行:测试集的仿真结果,第2行:测试集的真实结果
5.结果分析
disp()函数将结果显示在命令窗口中
%结果显示
total_B = length(find(data(:,2)==1)); %全部数据集中确诊结果为1的长度,即确诊良性病例数
total_M = length(find(data(:,2)==2)); %全部数据集中确诊恶性病例数
number_B = length(find(Tc_test == 1)); %测试集真实确诊良性病例数
number_M = length(find(Tc_test == 2)); %测试集真实确诊恶性病例数
number_B_sim = length(find(Tc_sim == 1 & Tc_test == 1)); %测试集仿真测试得出的确诊良性病例数
number_M_sim = length(find(Tc_sim == 2 & Tc_test == 2)); %测试集仿真测试得出的确诊恶性病例数
disp(['病例总数:' num2str(569)...
' 良性:' num2str(total_B)...
' 恶性:' num2str(total_M)]);
disp(['训练集病例总数:' num2str(500)...
' 良性:' num2str(count_B)...
' 恶性:' num2str(count_M)]);
disp(['测试集病例总数:' num2str(69)...
' 良性:' num2str(number_B)...
' 恶性:' num2str(number_M)]);
disp(['良性乳腺肿瘤确诊:' num2str(number_B_sim)...
' 误诊:' num2str(number_B-number_B_sim)...
' 确诊率p1=' num2str(number_B_sim/number_B*100) '%']);
disp(['恶性乳腺肿瘤确诊:' num2str(number_M_sim)...
' 误诊:' num2str(number_M-number_M_sim)...
' 确诊率p2=' num2str(number_M_sim/number_M*100) '%']);
对比基于BP神经网络实现
%清除环境变量
clear;
clc;
%导入数据
%数据文件共32个字段,第一个为病例编号,第二个为确诊结果,后30个为细胞核的形态特征
load data.mat;
%随机取500组数据作为训练集,剩余69组数组为测试集
a = randperm(569); %随机打乱1-569间的数字序列
Train = data(a(1:500),:);
Test = data(a(501:end),:);
%训练数据
P_train = Train(:,3:end)'; %取后30个字段
Tc_train = Train(:,2)'; %取第二个字段,确诊结果1良性,2恶性
%测试数据
P_test = Test(:,3:end)';
Tc_test = Test(:,2)';
%创建BP神经网络
count_B = length(find(Tc_train == 1)); %训练集中确诊结果为1的长度,即确诊良性病例数
count_M = length(find(Tc_train == 2)); %确诊恶性病例数
net = newff(minmax(P_train),[50 1],{'tansig','purelin'},'trainlm');
%训练集,第1层50个神经元、第2层1个神经元,第1、2层传递函数,训练函数
% [补充]:net = newff(PR,[S1 S2 ...SN],{TF1 TF2...TFN},BTF,BLF,PF)
%函数newff建立一个可训练的前馈网络。输入参数说明:
%PR:Rx2的矩阵以定义R个输入向量的最小值和最大值为输入向量的范围;
%Si:第i层神经元个数;
%TFi:第i层的传递函数,默认函数为tansig函数;
%BTF:训练函数,默认函数为trainlm函数;
%BLF:权值/阈值学习函数,默认函数为learngdm函数;
%PF:性能函数,默认函数为mse函数。
%设置网络参数
net.trainParam.epochs = 1000; %训练次数
net.trainParam.show = 10; %显示频率,每训练10次显示一次
net.trainParam.lr = 0.1; %学习速率
net.trainParam.goal = 0.1; %训练目标最小误差
%网络训练
net = train(net,P_train,Tc_train); %训练集、目标输出,返回训练后的网络net
%仿真测试
T_sim = sim(net,P_test); %sim()函数将测试集输入数据送入训练好的神经网络便可得到对应测试集输出的仿真数据
%BP网络输出非二值结果,因此进行四舍五入处理,即若输出小于1.5则认为属于良性肿瘤
for i = 1:length(T_sim)
if T_sim(i)<=1.5
T_sim(i) = 1;
else
T_sim(i) = 2;
end
end
result = [T_sim;Tc_test]; %第1行:测试集的仿真结果,第2行:测试集的真实结果
%结果显示
total_B = length(find(data(:,2)==1)); %全部数据集中确诊结果为1的长度,即确诊良性病例数
total_M = length(find(data(:,2)==2)); %全部数据集中确诊恶性病例数
number_B = length(find(Tc_test == 1)); %测试集真实确诊良性病例数
number_M = length(find(Tc_test == 2)); %测试集真实确诊恶性病例数
number_B_sim = length(find(T_sim(1:number_B) == 1)); %测试集仿真测试得出的确诊良性病例数
number_M_sim = length(find(T_sim(number_B+1:end) == 2)); %测试集仿真测试得出的确诊恶性病例数
disp(['病例总数:' num2str(569)...
' 良性:' num2str(total_B)...
' 恶性:' num2str(total_M)]);
disp(['训练集病例总数:' num2str(500)...
' 良性:' num2str(count_B)...
' 恶性:' num2str(count_M)]);
disp(['测试集病例总数:' num2str(69)...
' 良性:' num2str(number_B)...
' 恶性:' num2str(number_M)]);
disp(['良性乳腺肿瘤确诊:' num2str(number_B_sim)...
' 误诊:' num2str(number_B-number_B_sim)...
' 确诊率p1=' num2str(number_B_sim/number_B*100) '%']);
disp(['恶性乳腺肿瘤确诊:' num2str(number_M_sim)...
' 误诊:' num2str(number_M-number_M_sim)...
' 确诊率p2=' num2str(number_M_sim/number_M*100) '%']);
基于LVQ与BP神经网络乳腺肿瘤分类结果对比
从结果可看出,LVQ神经网络的效果比BP神经网络要好很多,这也表明LVQ神经网络用于模式识别是有效的。
LVQ神经网络
BP神经网络