标签: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