标签:sam data 网络 for 学生 file bp神经网络 src 过程
本文主要介绍BP神经网络的基本原理,涉及单隐层神经网络的原理图、BP算法的推导以及附带单隐层BP神经网络的MATLAB源码,适用对象:掌握一定程度的MATLAB基础同时对BP神经网络感兴趣的小白
3 MATLAB源码详解
3.1 数据读取及预处理
首先准备数据,本文中描述的任务是根据学生的年龄、性别等特征来预测最后的数学成绩,并将其简化为一个二分类问题,学生特征数据如下
https://files.cnblogs.com/files/yong1/dataset.zip
接下来使用MATLAB读取数据
% 读取训练集数据 X_raw = xlsread(‘mat_part1_train.xlsx‘, ‘A2:O317‘); Y_raw = xlsread(‘mat_part1_train.xlsx‘, ‘P2:P317‘);
本文涉及的神经网络所使用的激活函数为Sigmoid函数,结合该函数的特性,当网络的输入值比较大时,会使得Sigmoid函数陷入饱和区,即神经元的输出值一直为1,因此需要对训练集数据的属性特征值进行归一化处理。本文选择线性归一化处理函数,即

另外对于二分类任务,需要对网络的输出值进行调整,即输出值为0或者1,因此对原始样本的教师信号进行二值处理,最终的数据预处理过程如下
function [ X, Y ] = data_preprocessing( X_raw, Y_raw )
%DATA_PREPROCESSING 输入数据归一化处理
% 通过线性函数归一化对原始数据进行预处理
% X_norm = (X - X_min)/(X_max - X_min)
X0 = X_raw; Y0 = Y_raw; % 原始数据
column1 = size(X0,2); % 获取样本的属性个数
array = []; % 存放某一属性值的最大值、最小值
% max0 = max(X0(:,1))
for i=1:column1
extreme(1) = max(X0(:,i)); % 获取第i个属性的最大值
extreme(2) = min(X0(:,i)); % 获取第i个属性的最小值
array = [array; extreme];
end
% disp(array)
% 线性函数归一化
% X(:,1) = (X0(:,1)-array(1,2)) / (array(1,1)-array(1,2));
for i=1:column1
X(:,i) = (X0(:,i)-array(i,2)) / (array(i,1)-array(i,2));
end
% 对样本输出进行二分类处理
for i=1:size(Y0,2)
for j=1:size(Y0,1)
if Y0(j,i)>10
Y(j,i) = 1; % 当样本值>10时,记为第一类,即 y=1
else
Y(j,i) = 0; % 当样本值<10时,记为第二类,即 y=0
end
end
end
end
3.2 网络结构初始化
由于是单隐层神经网络,即网络结构只包括输入层、隐层和输出层,其中输入层神经元的个数由训练集数据的属性个数(即X_raw的列数)确定,输出层神经元的个数由输出值的个数(即Y_raw的列数)确定,至于隐层神经元的个数便可以视情况而定,一般情况下隐层神经元的个数比输入层神经元多,本文中隐层神经元的个数比输入层多5个,网络结构初始化代码如下
function [ v_init, w_init, gamma_init, theta_init ] = net_initial( d, q, l ) %NET_INITIAL 单隐层BP网络结构初始化 % d:输入神经元的个数 % q:隐层神经元的个数 % l:输出层神经元的个数 global v w gamma theta v = rand(d+1, q); % 输入层--隐层的连接权的随机初始化 w = rand(q+1, l); % 隐层--输出层的连接权的随机初始化 gamma = rand(1, q); % 隐层神经元的阈值 theta = rand(1, l); % 输出层神经元的阈值 v_init = v; w_init = w; gamma_init = gamma; theta_init = theta; % disp(v_init),disp(w_init),disp(gamma_init),disp(theta_init) end
上述代码中在随机初始化输入层--隐层以及隐层--输出层的连接权时,矩阵的维度分别设置为 (d+1)*q 和 (q+1)*l,这是因为输入层和隐层各有一个偏置信号,可分别将其看做输入值为1、连接权分别为ω(d+1)q和ω(q+1)l的神经元,于是便完成网络结构的初始化。
3.3 参数更新
由于训练样本个数较少,因此可以使每个样本都对网络模型进行一次更新,样本的循环更新次数可以通过times变量设置,学习率通过eta变量设置,模型训练部分的代码如下
function [ v_train, w_train, gamma_train, theta_train ] = net_train( X, Y, times, eta )
%NET_TRAIN 训练网络参数
% X:输入样本的属性值,即输入层神经元的输入
% Y:样本的期望输出,即输出层神经元的期望输出
% times:网络的训练次数
% eta:网络的学习率
global v w gamma theta
k = size(X,1); % k:样本个数
for time=1:times % 网络的训练轮次
for i=1:k % 遍历所有样本对网络进行训练
x0 = X(i,:); % 获取单个样本的所有属性值
x = [x0 1]; % 为输入层神经元加入偏置
y = Y(i,:); % y:样本的期望输出值
% 前向计算
alpha = x*v; % alpha:隐层神经元的输入
b0 = f_active(alpha, gamma); % b0:隐层神经元的输出/点运算
b = [b0 1]; % 为隐层神经元加入偏置
beta = b*w; % beta:输出层神经元的输入
y_samp = f_active(beta, theta); % y_samp:输出层神经元的输出
% 后向计算/每个样本都对网络参数更新一次
g = y_samp.*(1-y_samp).*(y-y_samp); % 输出层神经元的梯度项
q = size(w,1)-1; % 获取隐层神经元的个数
e = b0.*(1-b0).*(g*w(1:q,:)‘); % 隐层神经元的梯度项
delta_w = eta*b‘*g; % 隐层-输出层的连接权的变化量
delta_thet = -eta*g; % 输出层阈值的变化量
delta_v = eta*x‘*e; % 输入层-隐层的连接权的变化量
delta_gamma = -eta*e; % 隐层阈值的变化量
w = w+delta_w; % 更新隐层-输出层的连接权
theta = theta+delta_thet; % 更新输出层阈值
v = v+delta_v; % 更新输入层-隐层的连接权
gamma = gamma+delta_gamma; % 更新隐层的阈值
v_train = v;
w_train = w;
gamma_train = gamma;
theta_train = theta;
% disp(v_train),disp(w_train),disp(gamma_train),disp(theta_train)
end
end
% disp(v_train),disp(w_train),disp(gamma_train),disp(theta_train)
end
上述代码中的“x = [x0 1]; % 为输入层神经元加入偏置”、“b = [b0 1]; % 为隐层神经元加入偏置”是网络中加入的偏置信号,另外激活函数采用Sigmoid函数,输出值为(0,1)
function [ output ] = f_active( input, threshold ) %F_ACTIVE 激活函数 % sigmoid:非线性激活函数 output = 1./(1+exp(-(input-threshold))); end
3.4 模型准确率测试
function [ y_pre ] = net_validation( X )
%NET_VALIDATION 使用验证集来验证模型
% 输出单隐层BP网络模型预测结果
global v w gamma theta
k = size(X,1); % 获取验证集的大小
y_pre = []; % 预测结果
for i=1:k
x0 = X(i,:); % 读取样本
x = [x0 1]; % 加入偏置
alpha = x*v; % 隐层神经元的输入
b = f_active(alpha, gamma); % 隐层输出
beta = [b 1]*w; % 输出层神经元的输入
y_pre = [y_pre; f_active(beta, theta)]; % 样本预测输出
end
end
3.5 主函数
%% 单隐层BP网络测试函数
% 读取训练集数据
X_raw = xlsread(‘mat_part1_train.xlsx‘, ‘A2:O317‘);
Y_raw = xlsread(‘mat_part1_train.xlsx‘, ‘P2:P317‘);
[X,Y] = data_preprocessing(X_raw,Y_raw); % 输入数据归一化(线性函数归一化)
% 获取网络结构参数
d = size(X,2); % 输入层神经元的个数
l = size(Y,2); % 输出层神经元的个数
% 单隐层BP网络结构初始化net_initial(d,q,l)
net_initial(d,d+5,l);
% 网络训练net_train(X,Y,times,eta)
net_train(X,Y,10000,0.1); % 迭代次数越多,预测精度越高(10000次起步)
% 模型验证
X1 = xlsread(‘mat_part1_validation.xlsx‘, ‘A2:O80‘);
Y1 = xlsread(‘mat_part1_validation.xlsx‘, ‘P2:P80‘);
[Xv,Yv] = data_preprocessing(X1,Y1); % 测试集数据归一化处理
y = net_validation(Xv); % 将测试集数据输入网络得到预测结果
Y_pre = []; % 存储样本最终预测分类结果
str1 = ‘样本真实输出值:‘;
str2 = ‘样本预测输出值:‘;
str3 = ‘预测正确率为:‘;
err_count = 0; % 初始化预测错误率
for i=1:size(y,1)
if y(i,1) > 0.5
Y_pre(i,1) = 1;
else
Y_pre(i,1) = 0; % 利用网络输出结果为样本分类
end
sprintf(‘%s%d %s%d‘,str1,Yv(i,1),str2,Y_pre(i,1))
if Yv(i,1) ~= Y_pre(i,1)
err_count = err_count+1; % 对错误预测结果进行计数
end
end
disp(err_count)
accuracy = double(1.0 - err_count / size(y,1)); % 最终预测正确率
sprintf(‘%s%d‘,str3,accuracy)
3.6 预测结果展示

标签:sam data 网络 for 学生 file bp神经网络 src 过程
原文地址:https://www.cnblogs.com/yong1/p/12179428.html