BP分类-反向传播神经网络(Backpropagation Neural Network)
源代码 (托管在Github)
BP分类的用途介绍
什么是BP神经网络?
BP神经网络,即反向传播神经网络(Backpropagation Neural Network),是一种前馈神经网络,通过反向传播算法训练网络权重。其基本结构包括输入层、一个或多个隐藏层以及输出层。BP算法通过计算输出误差并将误差反向传播到网络中,逐步调整权重,以最小化误差。
BP神经网络的主要用途和应用场景
-
模式识别
- 应用示例:手写数字识别、人脸识别、指纹识别。
- 解释:通过学习输入特征与类别标签之间的关系,BP神经网络能够准确识别和分类不同的模式和图像。
-
图像分类
- 应用示例:将图像分类为不同类别,如动物、车辆、场景等。
- 解释:BP神经网络可以处理高维图像数据,通过特征提取和分类,实现对图像的自动分类。
-
文本分类
- 应用示例:垃圾邮件检测、情感分析、新闻分类。
- 解释:通过将文本数据转换为数值特征(如词频、TF-IDF等),BP神经网络可以学习不同类别之间的区别,实现文本的自动分类。
-
医疗诊断
- 应用示例:基于病人的症状和检测结果,预测疾病类型,如癌症诊断、糖尿病预测。
- 解释:BP神经网络可以辅助医生进行诊断,通过分析大量医疗数据,提高诊断的准确性和效率。
-
金融风险评估
- 应用示例:信用评分、贷款违约预测、股票价格预测。
- 解释:通过分析客户的财务数据和交易行为,BP神经网络可以预测客户的信用风险或潜在的金融风险。
-
语音识别
- 应用示例:将语音信号转换为文本、语音命令识别。
- 解释:BP神经网络能够处理和分类复杂的语音数据,实现准确的语音识别和理解。
-
预测分析
- 应用示例:销售预测、需求预测、天气预报。
- 解释:通过学习历史数据的模式,BP神经网络可以预测未来趋势,辅助企业和组织做出决策。
-
控制系统
- 应用示例:机器人控制、自动驾驶系统、工业过程控制。
- 解释:BP神经网络可以实时处理传感器数据,进行动态控制和调整,提升系统的智能化水平。
BP神经网络的优势
- 自适应性强:能够根据输入数据自动调整权重,适应不同的数据模式。
- 容错性好:对部分输入或权重的误差具有较强的鲁棒性,不容易受到噪声干扰。
- 通用性高:适用于多种不同类型的任务,包括分类、回归、预测等。
BP神经网络的局限性
- 训练时间长:对于大规模数据集,训练时间较长,计算资源消耗大。
- 容易陷入局部最优:反向传播算法可能会陷入局部最优解,影响最终的模型性能。
- 对参数敏感:网络结构、学习率、隐藏层神经元数量等参数的选择对模型效果影响较大,需要仔细调参。
总结
BP神经网络作为一种经典的前馈神经网络,因其强大的学习和泛化能力,在各个领域得到了广泛应用。通过适当的数据预处理、网络结构设计和训练参数调整,BP神经网络能够在模式识别、分类、预测等任务中表现出色。然而,随着深度学习的发展,许多更为复杂和高效的神经网络架构(如卷积神经网络、循环神经网络等)在某些应用场景中已逐渐取代了传统的BP神经网络。但在许多实际问题中,BP神经网络依然是一个重要且有效的工具。
带有详细中文注释的Matlab代码
matlab
%% 初始化
clear % 清除工作区中的所有变量
close all % 关闭所有打开的图形窗口
clc % 清除命令窗口的内容
warning off % 关闭警告信息
%% 导入数据
res = xlsread('数据集.xlsx'); % 从Excel文件中读取数据,存储在变量res中
%% 分析数据
num_class = length(unique(res(:, end))); % 计算类别数,假设最后一列为类别标签
num_res = size(res, 1); % 计算样本总数,每一行代表一个样本
num_size = 0.7; % 设置训练集占数据集的比例为70%
res = res(randperm(num_res), :); % 随机打乱数据集顺序(提高模型泛化能力)
% 如果不需要打乱数据,可以注释掉上行代码
flag_conusion = 1; % 标志位为1,启用混淆矩阵绘制(要求Matlab 2018及以上版本)
%% 设置变量存储数据
P_train = []; % 初始化训练集输入特征
P_test = []; % 初始化测试集输入特征
T_train = []; % 初始化训练集目标输出
T_test = []; % 初始化测试集目标输出
%% 划分数据集
for i = 1 : num_class
mid_res = res((res(:, end) == i), :); % 提取当前类别的所有样本
mid_size = size(mid_res, 1); % 当前类别的样本数量
mid_tiran = round(num_size * mid_size); % 计算当前类别的训练样本数量(四舍五入)
% 将当前类别的训练样本添加到训练集
P_train = [P_train; mid_res(1: mid_tiran, 1: end - 1)]; % 训练集输入特征(除最后一列)
T_train = [T_train; mid_res(1: mid_tiran, end)]; % 训练集目标输出(最后一列)
% 将当前类别的测试样本添加到测试集
P_test = [P_test; mid_res(mid_tiran + 1: end, 1: end - 1)]; % 测试集输入特征
T_test = [T_test; mid_res(mid_tiran + 1: end, end)]; % 测试集目标输出
end
%% 数据转置
P_train = P_train'; % 转置训练集输入特征,使每列代表一个样本
P_test = P_test'; % 转置测试集输入特征
T_train = T_train'; % 转置训练集目标输出
T_test = T_test'; % 转置测试集目标输出
%% 得到训练集和测试样本个数
M = size(P_train, 2); % 训练集样本数量
N = size(P_test , 2); % 测试集样本数量
%% 数据归一化
[p_train, ps_input] = mapminmax(P_train, 0, 1); % 将训练集输入特征归一化到[0,1]范围
p_test = mapminmax('apply', P_test, ps_input); % 使用相同的归一化参数处理测试集输入特征
t_train = ind2vec(T_train); % 将训练集目标输出转换为向量(独热编码)
t_test = ind2vec(T_test ); % 将测试集目标输出转换为向量(独热编码)
%% 建立模型
net = newff(p_train, t_train, 6); % 创建一个前馈神经网络,隐藏层包含6个神经元
%% 设置训练参数
net.trainParam.epochs = 1000; % 设置最大训练迭代次数为1000次
net.trainParam.goal = 1e-6; % 设置训练目标误差为1e-6
net.trainParam.lr = 0.01; % 设置学习率为0.01
%% 训练网络
net = train(net, p_train, t_train); % 使用训练集数据训练神经网络,优化网络权重
%% 仿真测试
t_sim1 = sim(net, p_train); % 使用训练好的网络对训练集进行仿真测试,得到预测输出
t_sim2 = sim(net, p_test ); % 使用训练好的网络对测试集进行仿真测试,得到预测输出
%% 数据反归一化
T_sim1 = vec2ind(t_sim1); % 将训练集预测输出的向量转换回类别索引
T_sim2 = vec2ind(t_sim2); % 将测试集预测输出的向量转换回类别索引
%% 数据排序
[T_train_sorted, index_1] = sort(T_train); % 对训练集真实标签进行排序,并获取排序索引
[T_test_sorted , index_2] = sort(T_test ); % 对测试集真实标签进行排序,并获取排序索引
T_sim1_sorted = T_sim1(index_1); % 根据排序索引重新排列训练集预测结果
T_sim2_sorted = T_sim2(index_2); % 根据排序索引重新排列测试集预测结果
%% 性能评价
error1 = sum((T_sim1_sorted == T_train_sorted)) / M * 100 ; % 计算训练集准确率
error2 = sum((T_sim2_sorted == T_test_sorted )) / N * 100 ; % 计算测试集准确率
%% 绘图
figure
plot(1: M, T_train_sorted, 'r-*', 1: M, T_sim1_sorted, 'b-o', 'LineWidth', 1) % 绘制训练集真实值与预测值对比图
legend('真实值', '预测值') % 添加图例
xlabel('预测样本') % 设置X轴标签
ylabel('预测结果') % 设置Y轴标签
title(['训练集预测结果对比:准确率=' num2str(error1) '%']) % 设置图形标题,显示准确率
grid on % 显示网格
figure
plot(1: N, T_test_sorted, 'r-*', 1: N, T_sim2_sorted, 'b-o', 'LineWidth', 1) % 绘制测试集真实值与预测值对比图
legend('真实值', '预测值') % 添加图例
xlabel('预测样本') % 设置X轴标签
ylabel('预测结果') % 设置Y轴标签
title(['测试集预测结果对比:准确率=' num2str(error2) '%']) % 设置图形标题,显示准确率
grid on % 显示网格
%% 混淆矩阵
if flag_conusion == 1
figure
cm_train = confusionchart(T_train_sorted, T_sim1_sorted); % 绘制训练集混淆矩阵
cm_train.Title = '训练集混淆矩阵';
cm_train.ColumnSummary = 'column-normalized'; % 列归一化显示
cm_train.RowSummary = 'row-normalized'; % 行归一化显示
figure
cm_test = confusionchart(T_test_sorted, T_sim2_sorted); % 绘制测试集混淆矩阵
cm_test.Title = '测试集混淆矩阵';
cm_test.ColumnSummary = 'column-normalized'; % 列归一化显示
cm_test.RowSummary = 'row-normalized'; % 行归一化显示
end
代码详细说明与注释
1. 初始化部分
matlab
clear
close all
clc
warning off
- 功能 :清理工作环境,确保代码在干净的环境中运行。
clear
:清除所有变量,释放内存。close all
:关闭所有打开的图形窗口。clc
:清空命令窗口内容。warning off
:关闭所有警告信息,避免干扰输出。
2. 导入数据
matlab
res = xlsread('数据集.xlsx');
- 功能 :从Excel文件中读取数据。
- 假设数据集位于"数据集.xlsx"文件中,每一行代表一个样本,最后一列为类别标签。
3. 分析数据
matlab
num_class = length(unique(res(:, end)));
num_res = size(res, 1);
num_size = 0.7;
res = res(randperm(num_res), :);
flag_conusion = 1;
- 功能 :
- 计算类别数(
num_class
),即数据集中不同类别的数量。 - 计算样本总数(
num_res
)。 - 设置训练集比例为70%(
num_size
)。 - 随机打乱数据集顺序,增加模型的泛化能力。
- 设置标志位
flag_conusion
为1,表示启用混淆矩阵绘制。
- 计算类别数(
4. 设置变量存储数据
matlab
P_train = []; P_test = [];
T_train = []; T_test = [];
- 功能 :初始化训练集和测试集的输入特征(
P_train
、P_test
)及目标输出(T_train
、T_test
)。
5. 划分数据集
matlab
for i = 1 : num_class
mid_res = res((res(:, end) == i), :);
mid_size = size(mid_res, 1);
mid_tiran = round(num_size * mid_size);
P_train = [P_train; mid_res(1: mid_tiran, 1: end - 1)];
T_train = [T_train; mid_res(1: mid_tiran, end)];
P_test = [P_test; mid_res(mid_tiran + 1: end, 1: end - 1)];
T_test = [T_test; mid_res(mid_tiran + 1: end, end)];
end
- 功能 :
- 按类别循环,将每个类别的数据按比例划分为训练集和测试集。
- 训练集输入特征和目标输出分别存储在
P_train
和T_train
中。 - 测试集输入特征和目标输出分别存储在
P_test
和T_test
中。
6. 数据转置
matlab
P_train = P_train';
P_test = P_test';
T_train = T_train';
T_test = T_test';
- 功能:将数据转置,使每列代表一个样本,符合Matlab神经网络工具箱的输入要求。
7. 得到训练集和测试样本个数
matlab
M = size(P_train, 2);
N = size(P_test , 2);
- 功能 :获取训练集(
M
)和测试集(N
)的样本数量。
8. 数据归一化
matlab
[p_train, ps_input] = mapminmax(P_train, 0, 1);
p_test = mapminmax('apply', P_test, ps_input);
t_train = ind2vec(T_train);
t_test = ind2vec(T_test );
- 功能 :
- 使用
mapminmax
函数将输入特征归一化到[0,1]范围,提升训练效果。 - 使用相同的归一化参数处理测试集输入特征。
- 将类别标签转换为独热编码(One-Hot Encoding),适用于分类任务。
- 使用
9. 建立模型
matlab
net = newff(p_train, t_train, 6);
- 功能 :创建一个前馈神经网络(Feedforward Neural Network)。
- 输入参数:
p_train
:训练集输入特征。t_train
:训练集目标输出。6
:隐藏层神经元数量,此处设置为6个神经元。
- 输入参数:
10. 设置训练参数
matlab
net.trainParam.epochs = 1000;
net.trainParam.goal = 1e-6;
net.trainParam.lr = 0.01;
- 功能 :
- 设置最大训练迭代次数为1000次(
epochs
)。 - 设置目标训练误差为1e-6(
goal
)。 - 设置学习率为0.01(
lr
)。
- 设置最大训练迭代次数为1000次(
11. 训练网络
matlab
net = train(net, p_train, t_train);
- 功能:使用训练集数据训练神经网络,优化网络权重。
12. 仿真测试
matlab
t_sim1 = sim(net, p_train);
t_sim2 = sim(net, p_test );
- 功能 :
- 使用训练好的网络对训练集进行仿真测试,得到预测输出
T_sim1
。 - 使用训练好的网络对测试集进行仿真测试,得到预测输出
T_sim2
。
- 使用训练好的网络对训练集进行仿真测试,得到预测输出
13. 数据反归一化
matlab
T_sim1 = vec2ind(t_sim1);
T_sim2 = vec2ind(t_sim2);
- 功能:将预测输出的独热编码转换回类别索引。
14. 数据排序
matlab
[T_train_sorted, index_1] = sort(T_train);
[T_test_sorted , index_2] = sort(T_test );
T_sim1_sorted = T_sim1(index_1);
T_sim2_sorted = T_sim2(index_2);
- 功能 :
- 对真实标签进行排序,并根据排序索引重新排列预测结果,便于后续比较和绘图。
15. 性能评价
matlab
error1 = sum((T_sim1_sorted == T_train_sorted)) / M * 100 ;
error2 = sum((T_sim2_sorted == T_test_sorted )) / N * 100 ;
- 功能 :
- 计算训练集和测试集的分类准确率(百分比)。
error1
:训练集准确率。error2
:测试集准确率。
16. 绘图
matlab
figure
plot(1: M, T_train_sorted, 'r-*', 1: M, T_sim1_sorted, 'b-o', 'LineWidth', 1)
legend('真实值', '预测值')
xlabel('预测样本')
ylabel('预测结果')
title(['训练集预测结果对比:准确率=' num2str(error1) '%'])
grid on
figure
plot(1: N, T_test_sorted, 'r-*', 1: N, T_sim2_sorted, 'b-o', 'LineWidth', 1)
legend('真实值', '预测值')
xlabel('预测样本')
ylabel('预测结果')
title(['测试集预测结果对比:准确率=' num2str(error2) '%'])
grid on
- 功能 :
- 绘制训练集和测试集的真实值与预测值对比图,直观展示分类效果。
- 在图形标题中显示分类准确率。
legend
:添加图例,区分真实值和预测值。xlabel
、ylabel
:设置X轴和Y轴标签。title
:设置图形标题,显示准确率。grid on
:显示网格,便于观察数据趋势。
17. 混淆矩阵
matlab
figure
cm = confusionchart(T_train, T_sim1);
cm.Title = 'Confusion Matrix for Train Data';
cm.ColumnSummary = 'column-normalized';
cm.RowSummary = 'row-normalized';
figure
cm = confusionchart(T_test, T_sim2);
cm.Title = 'Confusion Matrix for Test Data';
cm.ColumnSummary = 'column-normalized';
cm.RowSummary = 'row-normalized';
- 功能 :
- 绘制训练集和测试集的混淆矩阵。
- 混淆矩阵有助于评估分类器在不同类别上的表现,特别是对不平衡数据集的分类效果。
confusionchart
:创建混淆矩阵图表,显示真实类别与预测类别之间的关系。ColumnSummary
、RowSummary
:设置混淆矩阵的列和行的归一化显示,便于比较分类器在不同类别上的表现。
总结
通过上述代码,您可以使用Matlab实现一个BP神经网络模型,用于分类任务。详细的中文注释帮助您理解每一步的具体操作和实现逻辑。同时,BP神经网络在多个领域有广泛的应用,包括模式识别、图像和文本分类、医疗诊断、金融风险评估以及语音识别等。根据具体需求,您可以调整网络结构、训练参数和数据预处理方法,以适应不同的应用场景。