神经网络与机器学习 笔记—LMS(最小均方算法)和学习率退火

LMS算法和Rosenblatt感知器算法非常想,唯独就是去掉了神经元的压制函数,Rosenblatt用的Sgn压制函数,LMS不需要压制函数,两者一样是只有单个神经元。

LMS算法信号流图

算法小结:



然后在说下退火:

#pragma once

#include "stdafx.h"

#include <string>

#include <iostream>

using namespace std;

int gnM = 0;      //训练集空间维度

int gnN = 0;      //突触权值个数

double gdU0 = 0.1;  //初始学习率参数,用于退火,前期可以较大

double gdT = 1;  //控制退火用的开始降温的时间点

double gdN = 0;  //当前工作时间(神经网络学习次数)

//退火

//U=U0/(1+(N/T))

double GetNowU() {

gdN++;

//cout<< gdU0 / (1.0 + (gdN / gdT))<<endl;

return gdU0 / (1.0 + (gdN / gdT));

}

void LMSInit(double *dX, const int &nM, double *dW, const int &nN, const double &dB, const double &dU0 ,const double &dT) {

//dX 本次训练数据集

//nM 训练集空间维度

//dW 权值矩阵

//nN 突触权值个数 LMS只有一个神经元,所以nM==nM

//dB 偏置,正常这个是应该 走退火动态调整的,以后再说,现在固定得了。

//dU0 初始学习率参数,用于退火,前期可以较大

//dT控制退火用的开始降温的时间点

if (nM > 0) {

dX[0] = 1;//把偏置永远当成一个固定的突触

}

for (int i = 0; i <= nN; i++) {

if (i == 0) {

dW[i] = dB;//固定偏置

}

else {

dW[i] = 0.0;

}

}

gnM = nM, gnN = nN, gdU0 = dU0, gdT = dT;

}

double Sgn(double dNumber) {

return dNumber > 0 ? +1.0 : -1.0;

}

//感知器收敛算法-学习

void LMSStudy(const double *dX, const double dD, double *dW) {

//dX 本次训练数据集

//dD 本次训练数据集的期望值

//dW 动态参数,突触权值

double dY = 0;

for (int i = 0; i <= gnM && i <= gnN; i++) {

dY = dY + dX[i] * dW[i];

}

//dY = Sgn(dY); LMS这个地方不用了,Rosenblatt是需要的

if (dD == dY) {

return;//不需要进行学习调整突触权值

}

for (int i = 1; i <= gnM && i <= gnN; i++) {

dW[i] = dW[i] + GetNowU() * (dD - dY) * dX[i];

}

}

//感知器收敛算法-泛化

double LMSGeneralization(const double *dX, const double *dW) {

//dX 本次需要泛化的数据集

//dW 已经学习好的突触权值

//返回的是当前需要泛化的数据集的泛化结果(属于那个域的)

double dY = 0;

for (int i = 0; i <= gnM && i <= gnN; i++) {

dY = dY + dX[i] * dW[i];

}

return Sgn(dY);

}

//双月分类模型,随机获取一组值

/*  自己稍微改了下

域1:上半个圆,假设圆心位坐标原点(0,0)

(x - 0) * (x - 0) + (y - 0) * (y - 0) = 10 * 10

x >= -10 && x <= 10

y >= 0 && y <= 10

域2:下半个圆,圆心坐标(10 ,-1)

(x - 10) * (x - 10) + (y + 1) * (y + 1) = 10 * 10;

x >= 0 && x <= 20

y >= -11 && y <= -1

*/

const double gRegionA = 1.0; //双月上

const double gRegionB = -1.0;//双月下

void Bimonthly(double *dX, double *dY, double *dResult) {

//dX      坐标x

//dY      坐标y

//dResult 属于哪个分类

*dResult = rand() % 2 == 0 ? gRegionA : gRegionB;

if (*dResult == gRegionA) {

*dX = rand() % 20 - 10;//在区间内随机一个X

*dY = sqrt(10 * 10 - (*dX) * (*dX));//求出Y

}

else {

*dX = rand() % 20;

*dY = sqrt(10 * 10 - (*dX - 10) * (*dX - 10)) - 1;

*dY = *dY * -1;

}

}

int main()

{

//system("color 0b");

double dX[2 + 1], dD, dW[2 + 1]; //输入空间维度为3 平面坐标系+一个偏置

double dB = 0;

double dU0 = 0.1;

double dT = 128; //128之后开始降温

LMSInit(dX, 2, dW, 2, dB, dU0, dT);//初始化 感知器

double dBimonthlyX, dBimonthlyY, dBimonthlyResult;

int nLearningTimes =  1024 * 10;//进行10K次学习

for (int nLearning = 0; nLearning <= nLearningTimes; nLearning++) {

Bimonthly(&dBimonthlyX, &dBimonthlyY, &dBimonthlyResult);//随机生成双月数据

dX[1] = dBimonthlyX;

dX[2] = dBimonthlyY;

dD = dBimonthlyResult;

LMSStudy(dX, dD, dW);

//cout <<"Study:" << nLearning << " :X= " << dBimonthlyX << "Y= " << dBimonthlyY << " D=" << dBimonthlyResult<< "----W1= " << dW[1] << "  W2= " << dW[2] << endl;

}

//进行LMS泛化能力测试 测试数据量1K

int nGeneralizationTimes = 1 * 1024;

int nGeneralizationYes = 0, nGeneralizationNo = 0;

double dBlattGeneralizationSuccessRate = 0;

for (int nLearning = 1; nLearning <= nGeneralizationTimes; nLearning++) {

Bimonthly(&dBimonthlyX, &dBimonthlyY, &dBimonthlyResult);//随机生成双月数据

dX[1] = dBimonthlyX;

dX[2] = dBimonthlyY;

//cout << "Generalization: " << dBimonthlyX << "," << dBimonthlyY;

if (dBimonthlyResult == LMSGeneralization(dX, dW)) {

nGeneralizationYes++;

//cout << " Yes" << endl;

}

else {

nGeneralizationNo++;

//cout << " No" << endl;

}

}

dBlattGeneralizationSuccessRate = nGeneralizationYes * 1.0 / (nGeneralizationNo + nGeneralizationYes) * 100;

cout << "Study : " << nLearningTimes << "     Generalization : " << nGeneralizationTimes << "     SuccessRate:" << dBlattGeneralizationSuccessRate << "%" << endl;

getchar();

return 0;

}

执行结果:

Study : 10240     Generalization : 1024     SuccessRate:96.6797%

注意:

相对于Rosenblatt算法,LMS如果直接把sgn去掉了可能出现泛化能力急剧下降的问题,我就是,直接变成50%了(和没学习一样),因为此时的学习率参数恒等于0.1有点大(为什么说0.1大,因为没有sgn了,算出的XW是比较大的,而这个时候我们训练数据集的期望结果,还是+1和-1)。同时,退火的那个地方,去动态调整那几个参数,会得到你意想不到的效果,挺微妙的。

神经网络与机器学习 笔记—LMS(最小均方算法)和学习率退火的更多相关文章

  1. 机器学习:Python实现最小均方算法(lms)

    lms算法跟Rosenblatt感知器相比,主要区别就是权值修正方法不一样.lms采用的是批量修正算法,Rosenblatt感知器使用的 是单样本修正算法.两种算法都是单层感知器,也只适用于线性可分的 ...

  2. Python机器学习笔记:异常点检测算法——LOF(Local Outiler Factor)

    完整代码及其数据,请移步小编的GitHub 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/MachineLearningNote 在数据挖掘方面,经常需 ...

  3. 【机器学习笔记之四】Adaboost 算法

    本文结构: 什么是集成学习? 为什么集成的效果就会好于单个学习器? 如何生成个体学习器? 什么是 Boosting? Adaboost 算法? 什么是集成学习 集成学习就是将多个弱的学习器结合起来组成 ...

  4. 最小均方算法(LMS Algorithm)理论及DSP实现

    LMS算法可认为是机器学习里面最基本也比较有用的算法,神经网络中对参数的学习使用的就是LMS的思想,在通信信号处理领域LMS也非常常见,比如自适应滤波器. 本文主要对LMS(Least Mean Sq ...

  5. 神经网络与机器学习 笔记—Rosenblatt感知器收敛算法C++实现

    Rosenblatt感知器收敛算法C++实现 算法概述 自己用C++实现了下,测试的例子和模式用的都是双月分类模型,关于双月分类相关看之前的那个笔记: https://blog.csdn.net/u0 ...

  6. 神经网络与机器学习 笔记—反向传播算法(BP)

    先看下面信号流图,L=2和M0=M1=M2=M3=3的情况,上面是前向通过,下面部分是反向通过. 1.初始化.假设没有先验知识可用,可以以一个一致分布来随机的挑选突触权值和阈值,这个分布选择为均值等于 ...

  7. Stanford机器学习笔记-9. 聚类(K-means算法)

    9. Clustering Content 9. Clustering 9.1 Supervised Learning and Unsupervised Learning 9.2 K-means al ...

  8. 神经网络与机器学习 笔记—多层感知器(MLP)

    多层感知器(MLP) Rosenblatt感知器和LMS算法,都是单层的并且是单个神经元构造的神经网络,他们的局限性是只能解决线性可分问题,例如Rosenblatt感知器一直没办法处理简单异或问题.然 ...

  9. 神经网络与机器学习 笔记—卷积神经网络(CNN)

    卷积神经网络 之前的一些都是考虑多层感知器算法设计相关的问题,这次是说一个多层感知器结构布局相关的问题.来总结卷积神经网络.对于模式分类非常合适.网络的提出所隐含的思想收到了神经生物学的启发. 第一个 ...

随机推荐

  1. Percona XtraDB Cluster之流量控制

    什么是流量控制? Percona XtraDB Cluster具有一种称为流控制的自调节机制.该机制有助于避免集群中最弱/最慢的成员明显落后于集群中其他成员的情况. 当集群成员在写数据很慢(同时又继续 ...

  2. root 登录 lightdm freebsd下

    root 登录 lightdm freebsd下方法 pkg install lightdm-gtk-greeter lightdm 写入lightdm_enable="YES"到 ...

  3. FreeBSD 家图谱

    https://cgit.freebsd.org/src/tree/share/misc/bsd-family-tree

  4. Solon 框架详解(十)- Solon 的常用配置

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  5. Python内置函数作用及解析

    Python内置的函数及其用法.为了方便记忆,已经有很多开发者将这些内置函数进行了如下分类: 数学运算(7个)    类型转换(24个)    序列操作(8个)    对象操作(7个)    反射操作 ...

  6. “/”应用程序中的服务器错误。||分析器错误消息: 未能加载类型“WebApplication1._Default”

    环境VS2008 无法运行WEB项目,Winfrom程序OK. 新创建的WEB项目直接运行报下图错误. 尝试多种方法: 1,重新生成项目,运行.(失败) 2,重装VS2008(默认.完全.自定义)安装 ...

  7. C#控制鼠标自动连续点(DEMO)

    ---------------------------界面---------------------------------------------------- ------------------ ...

  8. SpringBoot Shiro 权限注解不起作用

    最近在学习springboot结合shiro做权限管理时碰到一个问题. 问题如下: 我在userRealm中的doGetAuthorizationInfo方法中给用户添加了权限,然后在Controll ...

  9. Tomcat详解系列(2) - 理解Tomcat架构设计

    Tomcat - 理解Tomcat架构设计 前文我们已经介绍了一个简单的Servlet容器是如何设计出来,我们就可以开始正式学习Tomcat了,在学习开始,我们有必要站在高点去看看Tomcat的架构设 ...

  10. Ubuntu20.04linux内核(5.4.0版本)编译准备与实现过程-编译前准备(1)

    最近项目也和linux kernel技术有关,调试内核和内核模块.修改内核源码,是学习内核的重要技术手段之一.应用这些技术时,都有一本基本的要求,那就是编译内核.因此,在分析内核调试技术之前,本随笔给 ...