% 批量方式训练BP网络,实现病症识别
%% 清理
clear all
clc
%% 读入数据
xlsfile='train_dataset_washed.xls';
[~,label] = xlsread(xlsfile,'DataSet','J1:J541');
[data,~] = xlsread(xlsfile,'DataSet','A1:I541');
l = zeros(size(label));
for i = 1:length(l)
if label{i} == 'C'
l(i,:) = 1;
end
if label{i} == 'D'
l(i,:) = 1;
end
end
label = l;
%% 划分数据
%正常与不正常各取81个,352个进行训练
TRAIN_NUM_N = 81;
TRAIN_NUM_U = 352;
%正常与不正常分开
n_data = data(label == 1,:);
u_data = data(label == 0,:);
NUM_N = length(n_data);%正常的个数
%正常
r = randperm(NUM_N);
traind(1:TRAIN_NUM_N,:) = n_data(r(1:TRAIN_NUM_N),:);
testd(1:NUM_N - TRAIN_NUM_N,:) = n_data(r(TRAIN_NUM_N + 1:NUM_N),:);
NUM_U = length(u_data);%不正常的个数
%不正常
r = randperm(NUM_U);
traind(TRAIN_NUM_N + 1:TRAIN_NUM_U + TRAIN_NUM_N,:) = u_data(r(1:TRAIN_NUM_U),:);
testd(NUM_N - TRAIN_NUM_N + 1:NUM_N - TRAIN_NUM_N + NUM_U - TRAIN_NUM_U,:) = u_data(r(TRAIN_NUM_U + 1:NUM_U),:);
% 赋值
trainl=zeros(1,TRAIN_NUM_N+TRAIN_NUM_U);
trainl(1:TRAIN_NUM_N)=1;
testl=zeros(1,NUM_N+NUM_U-TRAIN_NUM_N-TRAIN_NUM_U);
testl(1:NUM_N-TRAIN_NUM_N)=1;
%% 设置参数
rng('default')
rng(0)
nTrainNum = TRAIN_NUM_N + TRAIN_NUM_U; % 433个训练样本
%% 构造网络
net.nIn = 9;
net.nHidden1 = 12; % 第一个隐藏层有?个神经元
net.nHidden2 = 4; % 第二个隐藏层有?个神经元
net.nOut = 1; % 1x个输出层节点
w1 = rand(net.nHidden1,net.nIn);
b1 = rand(net.nHidden1,1);
net.w1 = [w1,b1];
w2 = rand(net.nHidden2,net.nHidden1);
b2 = rand(net.nHidden2,1);
net.w2 = [w2,b2];
W = rand(net.nOut,net.nHidden2);
B = rand(net.nOut,1);
net.w3 = [W,B];
%% 训练数据归一化
[traind_s,ps] = mapminmax(traind',0,1);
%% 训练
SampInEx = [traind_s;ones(1,nTrainNum)];
expectedOut = trainl;
eb = 0.01; % 误差容限
eta = 0.01; % 学习率
mc = 0.01; % 动量因子
maxiter = 1000; % 最大迭代次数
iteration = 0; % 第一代
errRec = zeros(1,maxiter);
outRec = zeros(nTrainNum, maxiter);
NET=[]; % 记录
% 开始迭代
for i = 1 : maxiter
hid1_input = net.w1 * SampInEx; % 第一层隐含层的输入
hid1_out = logsig(hid1_input); % 第一层隐含层的输出
hid2_input = [hid1_out;ones(1,nTrainNum)];
hid2_input2 = net.w2 * hid2_input; % 第二层隐含层的输入
hid2_out = logsig(hid2_input2); % 第二层隐含层的输出
ou_input1 = [hid2_out;ones(1,nTrainNum)]; % 输出层的输入
ou_input2 = net.w3 * ou_input1;
out_out = logsig(ou_input2); % 输出层的输出
outRec(:,i) = out_out'; % 记录每次迭代的输出
err = expectedOut - out_out; % 误差
sse = sumsqr(err);
errRec(i) = sse; % 保存误差值
fprintf('第 %d 次迭代 误差: %f\n', i, sse);
iteration = iteration + 1;
% 判断是否收敛
if sse <= eb
break;
end
% 误差反向传播
% 第二层隐含层与输出层之间的局部梯度
% DELTA = err;
DELTA = err.*dlogsig(ou_input2,out_out);
% 第一层隐含层与第二层隐含层之间的局部梯度
delta1 = net.w3(:,1:end-1)'*DELTA.*dlogsig(hid2_input2,hid2_out);
% 输入层与第一层隐含层之间的局部梯度
delta2 = net.w2(:,1:end-1)'* delta1.*dlogsig(hid1_input,hid1_out);
% 权值修改量
dWEX = DELTA * ou_input1';
dwex2 = delta1 * hid2_input';
dwex1 = delta2 * SampInEx';
% 修改权值,如果不是第一次修改,则使用动量因子
if i == 1
net.w3 = net.w3 + eta * dWEX;
net.w2 = net.w2 + eta * dwex2;
net.w1 = net.w1 + eta * dwex1;
else
net.w3 = net.w3 + (1 - mc) * eta * dWEX + mc * dWEXOld;
net.w2 = net.w2 + (1 - mc) * eta * dwex2 + mc * dwex2Old;
net.w1 = net.w1 + (1 - mc) * eta * dwex1 + mc * dwex1Old;
end
% 记录上一次的权值修改量
dWEXOld = dWEX;
dwex1Old = dwex1;
dwex2Old = dwex2;
end
MATLAB BP神经网络两层全连接 找了好多遍不知道哪有问题 求DS解答
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
2条回答 默认 最新
- 三个太阳啊啊啊 2021-12-27 19:16关注
训练得到的误差很大,改变隐藏层神经元数量,会导致把另1类完全判断成0类。数据集没有问题,已经通过matlab自带的工具箱达到90%以上的正确率。
解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
- ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
- ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
- ¥20 腾讯企业邮箱邮件可以恢复么
- ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
- ¥15 错误 LNK2001 无法解析的外部符号
- ¥50 安装pyaudiokits失败
- ¥15 计组这些题应该咋做呀
- ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
- ¥15 让node服务器有自动加载文件的功能