本文章为学习MATLAB机器学习时所整理的内容,本篇文章是该系列第一篇,介绍了BP神经网络的基本原理及其MATLAB实现所需的代码,并且增加了一些个人理解的内容。
目录






什么是归一化?
将数据映射到[0, 1]或[-1, 1]区间或其他的区间
为什么要归一化?
归一化算法
1. y = (x-min)/(max-min)
2. y = 2*(x-min)/(max-min)-1
• mapminmax
– Process matrices by mapping row minimum and maximum values to [-1 1]
– [Y, PS] = mapminmax(X, YMIN, YMAX)
– Y = mapminmax('apply', X, PS)
– X = mapminmax('reverse', Y, PS)
• newff
– Create feed-forward backpropagation network
– net = newff(P, T, [S1 S2...S(N-l)], {TF1 TF2...TFNl}, BTF, BLF, PF, IPF, OPF, DDF)
• train
– Train neural network
– [net, tr, Y, E, Pf, Af] = train(net, P, T, Pi, Ai)
• sim
– Simulate neural network
– [Y, Pf, Af, E, perf] = sim(net, P, Pi, Ai, T)
clear all
clc
load spectra_data.mat
执行该程序,可以得到两个工作区变量

NIR是近红外光谱图原始数据,60代表着60个样品,使用plot(NIR')可以得到近红外光谱图
octane是结果,也就是目标值

训练集和测试集可以自行选择,也可以从原始数据中随机生成。本次实验中选择的是随机生成。
temp = randperm(size(NIR,1));
% 训练集--50个样本
P_train = NIR(temp(1:50),:)'; % '表示转置,使得 列 为样本的个数
T_train = octane(temp(1:50),:)'; % '特征与目标一定要保证列即样本个数相等
% 测试集--10个样本
P_test = NIR(temp(50:end),:)'; % '表示转置,使得 列 为样本的个数
T_test = octane(temp(50:end),:)'; % '特征与目标一定要保证列即样本个数相等
N = size(P_test,2); % 取出测试集样本的个数
对原始数据进行归一化处理,使其数据范围在0-1之间
[p_train, ps_input] = mapminmax(P_train,0,1); %调用归一化函数
p_test = mapminmax('apply',P_test,ps_input);
[t_train, ps_output] = mapminmax(T_train,0,1);
使用newff函数便可以创建BP神经网络,其中参数9代表着神经元的个数
net = newff(p_train,t_train,9) % 9代表神经元的个数
%view(net); % 使用view(net)可以看到BP神经网络的结构图
使用view(net)可以看到所创建的BP神经网络结构图

net.trainParam.epochs = 1000 % 设置迭代次数
net.trainParam.goal = 1e-3; % 设置训练目标,即误差精度
net.trainParam.lr = 0.01; % 设置学习速率
通过调用train函数便可以对神经网络进行训练
net = train(net,p_train,t_train);
运行代码,便可以看到训练指标和效果等等




将测试集输入sim预测函数,得到预测结果
t_sim = sim(net,p_test);
此时的t_sim是归一化后的结果,为了与原数据进行对比,对t_sim进行反归一化。
T_sim = mapminmax('reverse',t_sim,ps_output); % T_sim为预测值
5. 性能评价
预测结果效果如何,需要与真实结果对比,进行评估
5.1 相对误差error
error = abs(T_sim-T_test)./T_test;
5.2 决定系数R^2
R2 = (N * sum(T_sim .* T_test) - sum(T_sim) * sum(T_test))^2 / ((N * sum((T_sim).^2) - (sum(T_sim))^2) * (N * sum((T_test).^2) - (sum(T_test))^2));
5.3 结果对比
result = [T_test' T_sim' error'];

可以看到预测值与真实值基本一致,误差很小。
figure
plot(1:N,T_test,'b:*',1:N,T_sim,'r-o')
legend('真实值','预测值')
xlabel('预测样本')
ylabel('辛烷值')
string = {'测试集辛烷值含量预测结果对比';['R^2=' num2str(R2)]};
title(string)

%% 1.清空环境变量
clear all
clc
%% 2.训练集/测试集产生
%% 2.1 导入数据
load spectra_data.mat
% plot(NIR');
% title('60个样品的近红外光谱');
% xlabel('波长(nm)');
% ylabel('吸光度');
%% 2.2 随机产生训练集和测试集
temp = randperm(size(NIR,1));
% 训练集--50个样本
P_train = NIR(temp(1:50),:)'; % '表示转置,使得 列 为样本的个数
T_train = octane(temp(1:50),:)'; % '特征与目标一定要保证列即样本个数相等
% 测试集--10个样本
P_test = NIR(temp(50:end),:)'; % '表示转置,使得 列 为样本的个数
T_test = octane(temp(50:end),:)'; % '特征与目标一定要保证列即样本个数相等
N = size(P_test,2); % 取出测试集样本的个数
%% 3 数据归一化
[p_train, ps_input] = mapminmax(P_train,0,1); %调用归一化函数
p_test = mapminmax('apply',P_test,ps_input);
[t_train, ps_output] = mapminmax(T_train,0,1);
%% 4. BP神经网络创建、训练及仿真测试
%% 4.1 创建网络
net = newff(p_train,t_train,9) % 9代表神经元的个数
% view(net); % 使用view(net)可以看到BP神经网络的结构图
%% 4.2 设置训练参数
net.trainParam.epochs = 1000 % 设置迭代次数
net.trainParam.goal = 1e-3; % 设置训练目标,即误差精度
net.trainParam.lr = 0.01; % 设置学习速率
%% 4.3 训练网路
net = train(net,p_train,t_train);
%% 4.4 仿真测试
t_sim = sim(net,p_test);
%% 4.5 数据反归一化
T_sim = mapminmax('reverse',t_sim,ps_output); % T_sim为预测值
%% 5. 性能评价
%% 5.1 相对误差error
error = abs(T_sim-T_test)./T_test;
%% 5.2 决定系数R^2
R2 = (N * sum(T_sim .* T_test) - sum(T_sim) * sum(T_test))^2 / ((N * sum((T_sim).^2) - (sum(T_sim))^2) * (N * sum((T_test).^2) - (sum(T_test))^2));
%% 5.3 结果对比
result = [T_test' T_sim' error'];
%% 6. 绘图
figure
plot(1:N,T_test,'b:*',1:N,T_sim,'r-o')
legend('真实值','预测值')
xlabel('预测样本')
ylabel('辛烷值')
string = {'测试集辛烷值含量预测结果对比';['R^2=' num2str(R2)]};
title(string)
%%
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO