神经网络之反向传播算法(自适应梯度算法Adagrad)

news2024/9/22 17:22:04

文章目录

  • 自适应梯度算法(Adagrad)
  • 1、算法原理
  • 2、算法实现
    • 2.1 训练过程
    • 2.2 测试过程及结果
  • 3、参考源码及数据集

自适应梯度算法(Adagrad)

自适应梯度算法(Adaptive gradient algorithm,Adagrad)与传统的误差反向传播算法不同的地方在于在该算法中使用累计平方梯度代替迭代过程中每一次计算的梯度值。
反向传播算法及梯度原理参考:
神经网络之反向传播算法(梯度、误差反向传播算法BP)

1、算法原理

假设对某个参数计算的梯度值为g,则自适应梯度算法需要通过下述公式计算出其梯度值的累积平方:
在这里插入图片描述

其中r的初始值为0。
之后通过累积平方对每次更新中的学习率进行调整,并使用更新后的学习率计算出参数的更新值。更新值的计算公式如下:
在这里插入图片描述

在上述公式中,μ为全局学习率,δ为避免分母为0而设置的极小值。
由前面的梯度值计算的相关原理可以得知,参数每次迭代更新的梯度与数据特征的稀疏性关联较大,当数据特征较为稀疏时,参数每次更新的梯度相对较小,此时累计梯度将长时间处于一个较小值,使得学习率的下降速度也会较慢,因此对参数的更新值会随之变大;当数据特征较为稠密时,参数每次更新的梯度相对较大,那么累计梯度将会较大,使得学习率加快下降速度,因此更新值会随之降低。由此带来的最直接的效果就是使得参数的调整速度随之加快进而使得神经网络的训练速度随之加快。
将自适应梯度算法应用于神经网络反向传播过程时的算法步骤如下:

  1. 随机初始化神经网络中所有的参数;
  2. 设置全局学习率μ及参数δ,初始化梯度的累积平方;
  3. 输入数据,按照前向传播过程计算网络的输出;
  4. 使用损失函数计算误差值;
  5. 根据误差值计算出隐含层、输出层每个参数的梯度项;
  6. 计算梯度累积平方;
  7. 利用梯度累积平方、全局学习率更新参数;
  8. 重复步骤3到步骤7,当满足停止迭代条件时输出训练后的参数。

参数初始化方法参考:
神经网络基础知识之参数初始化

2、算法实现

以数据预测为例,下面介绍自适应梯度算法的实现过程,将自适应梯度算法应用于普通的三层神经网络(输入层、隐含层、输出层)的反向传播过程。
选用某省市的表层土壤重金属元素数据集作为实验数据,该数据集总共96组,随机选择其中的24组作为测试数据集,72组作为训练数据集。选取重金属Ti的含量作为待预测的输出特征,选取重金属Co、Cr、Mg、Pb作为模型的输入特征。

2.1 训练过程

#库的导入
import numpy as np
import pandas as pd

#激活函数tanh
def tanh(x):
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
#激活函数偏导数
def de_tanh(x):
    return (1-x**2)

#梯度累积平方计算函数,输入参数r为累积梯度平方,delta为当前梯度
def accumulation(r,delta):
    r =r + (delta**2)
    return  r
#参数更新函数,w为待更新参数,r为累积梯度平方,delta为当前梯度,另外0.01为学习率
def adjust(w,r,delta):
    change1 =0.000001+(r ** (0.5))
    change2 =delta/change1
    change = (-0.01)*change2
    w = w + change
    return w

maxepochs = 1000  #迭代训练次数
errorfinal = 0.65*10**(-3)  #停止训练误差阈值
samnum = 72  #输入数据数量
indim = 4  #输入层节点数
outdim = 1  #输出层节点数
hiddenunitnum = 8  #隐含层节点数

#输入数据的导入
df = pd.read_csv("train.csv")
df.columns = ["Co", "Cr", "Mg", "Pb", "Ti"]
Co = df["Co"]
Co = np.array(Co)
Cr = df["Cr"]
Cr = np.array(Cr)
Mg=df["Mg"]
Mg=np.array(Mg)
Pb = df["Pb"]
Pb =np.array(Pb)
Ti = df["Ti"]
Ti = np.array(Ti)
samplein = np.mat([Co,Cr,Mg,Pb])
sampleout = np.mat([Ti])
#数据归一化,将输入数据压缩至0到1之间,便于计算,后续通过反归一化恢复原始值
sampleinminmax = np.array([samplein.min(axis=1).T.tolist()[0],samplein.max(axis=1).T.tolist()[0]]).transpose()
sampleoutminmax = np.array([sampleout.min(axis=1).T.tolist()[0],sampleout.max(axis=1).T.tolist()[0]]).transpose()
sampleinnorm = (2*(np.array(samplein.T)-sampleinminmax.transpose()[0])/(sampleinminmax.transpose()[1]-sampleinminmax.transpose()[0])-1).transpose()
sampleoutnorm = (2*(np.array(sampleout.T)-sampleoutminmax.transpose()[0])/(sampleoutminmax.transpose()[1]-sampleoutminmax.transpose()[0])-1).transpose()

sampleinmax = np.array([sampleinnorm.max(axis=1).T.tolist()]).transpose()
sampleinmin = np.array([sampleinnorm.min(axis=1).T.tolist()]).transpose()
#为归一化后的数据添加噪声
noise = 0.03*np.random.rand(sampleoutnorm.shape[0],sampleoutnorm.shape[1])
sampleoutnorm += noise
sampleinnorm = np.mat(sampleinnorm)

#利用归一化后的输入数据初始化参数w1、b1、w2、b2
dvalue = sampleinmax-sampleinmin
valuemid=(sampleinmin+sampleinmax)/2
wmag=0.7*(hiddenunitnum**(1/indim))
rand1=np.random.rand(hiddenunitnum,outdim)
rand2=np.random.randn(hiddenunitnum,indim)
rand1=rand1*wmag
rand2=rand2*wmag
b1=rand1-np.dot(rand2,valuemid)
for i in range(hiddenunitnum):
    for j in range(indim):
        rand2[i][j]=(2*rand2[i][j])/dvalue[j]
w1=rand2
w2 = np.random.uniform(low=-1, high=1, size=[outdim,hiddenunitnum])
b2 = np.random.uniform(low=-1, high=1, size=[outdim,1])

#参数w1、b1、w2、b2均为矩阵形式参与计算,其形状依次为8*4,8*1,1*8,1*1
w1 = np.mat(w1)
b1 = np.mat(b1)
w2 = np.mat(w2)
b2 = np.mat(b2)

#errhistory存储每次训练后的预测值与真实值的误差
errhistory = []

#rw1、rb1,rw2,rb2分别保存参数w1、b1、w2、b2的累积梯度,其形状与w1、b1、w2、b2一一对应
rw1 = np.zeros((8,4))
rb1 = np.zeros((8,1))
rw2 = np.zeros((1,8))
rb2 = np.zeros((1,1))

#开始训练
for i in range(maxepochs):
    #前向传播
    #计算隐含层输出hiddenout,输出层输出networkout
    hiddenout = tanh((np.dot(w1,sampleinnorm).transpose()+b1.transpose())).transpose()
    networkout = np.dot(w2,hiddenout).transpose()+b2.transpose()
    for j in range(samnum):
        networkout[j,:] = tanh(networkout[j,:])
    networkout = networkout.transpose()
    #计算损失函数
    err = sampleoutnorm - networkout
    loss = np.sum(np.abs(err))/samnum
    sse = np.sum(np.square(err))
    #判断是否满足停止训练条件
    errhistory.append(sse)
    if sse < errorfinal:
        break
    #反向传播
    #利用损失函数计算结果和激活函数偏导数,来计算参数w1、b1、w2、b2的梯度值
    delta2 = np.zeros((outdim,samnum))
    for n in range(samnum):
        delta2[:,n] = (-1) * err[:,n] * de_tanh(networkout[:,n])
    delta1 = np.zeros((hiddenunitnum,samnum))
    for e in range(samnum):
        for f in range(hiddenunitnum):
            delta1[f,e] = w2[:,f] * delta2[:,e] * de_tanh(hiddenout[f,e])
    dw2now = np.dot(delta2,hiddenout.transpose()) #1*8
    db2now = np.dot(delta2,np.ones((samnum,1))) #1*1
    dw1now = np.dot(delta1,sampleinnorm.transpose()) #8*4
    db1now = np.dot(delta1,np.ones((samnum,1))) #8*1
    #先更新输出层参数
    #w2更新,依次更新w2的梯度累积平方、w2
    for m in range(hiddenunitnum):
        rw2[:,m] = accumulation(rw2[:,m],dw2now[:,m])
        w2[:,m]= adjust(w2[:,m],rw2[:,m],dw2now[:,m])
    #b2更新,依次更新b2的梯度累积平方、b2
    rb2 = accumulation(rb2,db2now)
    b2 = adjust(b2,rb2,db2now)

    #更新隐含层参数
    #w1更新,依次更新w1的梯度累积平方、w1
    for a in range(hiddenunitnum):
        for b in range(indim):
            rw1[a,b] = accumulation(rw1[a,b],dw1now[a,b])
            w1[a,b] = adjust(w1[a,b],rw1[a,b],dw1now[a,b])
    #b1更新,依次更新b1的梯度累积平方、b1
    for n in range(hiddenunitnum):
        rb1[n,:] = accumulation(rb1[n,:],db1now[n,:])
        b1[n,:] = adjust(b1[n,:],rb1[n,:],db1now[n,:])
    print("the generation is:",i,",the loss is:",loss)

#达到最大训练次数,保存此时的参数w1、b1、w2、b2
np.save("w1.npy",w1)
np.save("b1.npy",b1)
np.save("w2.npy",w2)
np.save("b2.npy",b2)

2.2 测试过程及结果

测试过程只需要利用训练过程生成的相关参数,对测试数据执行一次前向传播过程来获得预测值,之后可使用相关的误差指标对预测值进行评价,详细的测试过程源码见参考源码及数据集。
在这里插入图片描述

注:由于每次初始化生成的参数不同,因此对参数设置相同的神经网络进行多次训练和预测,测试结果不会完全一致,此外测试结果的好坏也会受到隐含层节点数、学习率、训练次数等参数的影响。

3、参考源码及数据集

参考源码及数据集

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/392835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

惊!初中生也来卷了……

大家好&#xff0c;我是良许。 前两天在抖音直播的时候&#xff0c;突然来了一位不速之客…… 他自称是初中生&#xff0c;一开始我还有点不太相信&#xff0c;直到跟他连麦&#xff0c;听到他还略带一些稚嫩的声音&#xff0c;我才知道&#xff0c;他没有骗我…… 他说他想学…

Dynamic Movement Primitives (DMP) 学习

Dynamic Movement Primitives (DMP) 学习 【知乎】Dynamic Movement Primitives介绍及Python实现与UR5机械臂仿真 1. DMP的建模过程 链接&#xff1a;Dynamic Movement Primitives介绍及Python实现与UR5机械臂仿真 - 知乎 (zhihu.com) 沙漏大佬&#xff01;&#xff01;&am…

转行软件测试需要学习哪些知识点?来来来,都给你汇总在这里啦!

都说IT互联网行业吃香&#xff0c;那么如何才能高效转行&#xff0c;习得一技之长换取心仪offer&#xff1f; 一般来说&#xff0c;0基础小白想转行到软件测试行业&#xff0c;按照如下学习逻辑肯定是错不了的&#xff1a; 1.零基础小白入门篇&#xff08;学前扫盲&#xff09…

ThinkBook15电脑开机后马上蓝屏不能使用怎么办?

ThinkBook15电脑开机后马上蓝屏不能使用怎么办&#xff1f;最近有用户使用的ThinkBook15电脑出现了开机之后屏幕蓝屏的情况。出现这个问题&#xff0c;是系统底层的故障&#xff0c;一般用户很难找出问题进行彻底解决。但是我们可以通过以下重做系统的方法来恢复电脑系统的使用…

阶段二11_面向对象高级_学生管理系统案例3

主要功能&#xff1a; 完成学生信息添加&#xff0c;修改和删除功能。 一.查看学生 思路&#xff1a; 图片&#xff1a;5_查看学生思路图.png 代码&#xff1a; StudentController[客服类中] //查找学生 private void findAllStudent() {//1.方法内部创建StudentService业…

Nacos 使用Postgresql数据库制作镜像

构建前提在 Nacos 2.2.0支持postgresql数据库基础上进行构建github地址&#xff1a;个人仓库编译打包源码mvn -Prelease-nacos clean package install -Dmaven.test.skiptrue若想跳过pmd和checkstyle检查请使用mvn -Prelease-nacos clean package install -Dmaven.test.skiptru…

Vue 3.0 组合式API 介绍 【Vue3 从零开始】

提示 在阅读文档之前&#xff0c;你应该已经熟悉了这两个 Vue 基础和创建组件。 在 Vue Mastery 上观看关于组合式 API 的免费视频。 通过创建 Vue 组件&#xff0c;我们可以将接口的可重复部分及其功能提取到可重用的代码段中。仅此一项就可以使我们的应用程序在可维护性和…

SAP ERP系统PP模块计划策略2050详解

SAP/ERP系统中面向订单生产的计划策略主要有20和50两个策略&#xff0c;这两个策略都是面向订单生产的计划策略&#xff0c;也是离散制造行业应用比较广泛的策略。它们之间最大差异就是在于20策略完全是由订单驱动&#xff0c;而50策略是预测加订单驱动&#xff0c;本文主要介绍…

【Leetcode 剑指Offer】第 14 天 搜索与回溯算法(中等)

文章目录剑指 Offer 12. 矩阵中的路径DFS剪枝面试题13. 机器人的运动范围剑指 Offer 12. 矩阵中的路径 典型矩阵搜索题 DFS剪枝 深度优先搜索&#xff1a; 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归&#xff0c;先朝一个方向搜到底&#xff0c;再回溯至上…

实现迭代回声服务器端/客户端

文章目录1.迭代服务器端/客户端2.迭代回声服务器端/客户端2.1 echo_server.c2.2 echo_client.c3.回声客户端存在的问题4.回声客户端问题解决方法1.迭代服务器端/客户端 之前讨论的 HelloWorld 服务器端处理完 111 个客户端连接请求即退出&#xff0c;连接请求等待队列实际没有…

唯品会盈利十年:韧性有余,冲劲不足

配图来自Canva可画唯品会在电商市场是一个特殊的存在&#xff0c;从2012年第四季度首次盈利至今&#xff0c;唯品会已经连续十年保持盈利。这十年&#xff0c;电商产业逐渐走向成熟&#xff0c;电商玩家新老接替成层出不穷&#xff0c;曾经家喻户晓的蘑菇街、聚美优品、苏宁易购…

Vue2.0开发之——购物车案例-Goods组件封装-商品数量的加减及总数量(53)

一 概述 Goods点击加减实现修改数量的原理Goods点击增加实现实例Goods点击-减少实现实例Footer计算商品总数量 二 Goods点击加减实现修改数量的原理 点击Counter组件里面的加减&#xff0c;修改Counter组件里面的数量Counter组件的数量变化时&#xff0c;Goods商品的数量相应…

leetcode-每日一题-807(中等,数组)

正常情况第一眼看这道题&#xff0c;看懂意思的话很简单就可以解出来。给你一座由 n x n 个街区组成的城市&#xff0c;每个街区都包含一座立方体建筑。给你一个下标从 0 开始的 n x n 整数矩阵 grid &#xff0c;其中 grid[r][c] 表示坐落于 r 行 c 列的建筑物的 高度 。城市的…

C++各类设计模式及实现详解

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

Jetpack Compose 中的重组作用域和性能优化

只有读取可变状态的作用域才会被重组 这句话的意思是只有读取 mutableStateOf() 函数生成的状态值的那些 Composable 函数才会被重新执行。注意&#xff0c;这与 mutableStateOf() 函数在什么位置被定义没有关系。读取操作指的是对状态值的 get 操作。也就是取值的操作。 从一…

Rasa 3.x 学习系列-Rasa [3.4.4] - 2023-02-17新版本发布

Rasa 3.x 学习系列-Rasa [3.4.4] - 2023-02-17新版本发布 任何人都可以学习Rasa之优秀Rasa学习资源推荐 欢迎同学们报名Gavin老师的Rasa系列课程,任何人都可以学习Rasa之优秀Rasa学习资源推荐: 1.NLP on Transformers高手之路137课 2 .Rasa 3.X 智能对话机器人案例开发硬核…

Linux如何性能优化,怎么理解平均负载?如何利用系统缓存优化程序的运行效率?内存泄漏如何定位和处理?如何“快准狠”找到系统内存存在的问题?

Linux如何性能优化&#xff0c;怎么理解平均负载&#xff1f;如何利用系统缓存优化程序的运行效率&#xff1f;内存泄漏如何定位和处理&#xff1f;如何“快准狠”找到系统内存存在的问题&#xff1f;1. 性能优化1.1 性能指标1.2 到底应该怎么理解"平均负载"1.3 平均…

插件系列 vue2安装tailwindcss

先说结论&#xff0c;tailwindcss在vue2中引入&#xff0c;可以与其它css预处理混用&#xff0c;并不冲突, vue3可以直接参考官网的安装方式即可。 官方网址&#xff1a;https://www.tailwindcss.cn/ 安装步骤&#xff1a; 直接安装 创建文件 tailwindcss.css main.js全局引…

分析了近500位产品经理后,得出这些产品经理的日常

前些天,我从实现网上抓取了497位产品经理的个人信息,这些产品人平均工作时间超过5年,来自200多家公司,其中152人拥有BAT 、京东、美团、网易、小米等一线互联网公司工作经历,当然也有很大一部分来自不知名的创业公司。 以下是正文: 对这里面各产品经理擅长技

HBase单机版安装详细步骤

目录 一、安装HBase前置环境 1.jdk 2.hadoop 3.zookeeper 二、安装HBase步骤 (一)解压 (二)修改文件名 (三)修改配置文件 (四)配置HBase的环境变量 (五)启动HBase 1.启动hadoop 2.启动zookeeper 3.启动hbase 4.jps出现HMaster和HRegionServer 5.HBase的WebUI (…