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

您所在的位置:网站首页 梯度gradu公式 神经网络之反向传播算法(自适应梯度算法Adagrad)

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

2023-03-13 17:42| 来源: 网络整理| 查看: 265

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

自适应梯度算法(Adagrad)

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

1、算法原理

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

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

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

随机初始化神经网络中所有的参数;设置全局学习率μ及参数δ,初始化梯度的累积平方;输入数据,按照前向传播过程计算网络的输出;使用损失函数计算误差值;根据误差值计算出隐含层、输出层每个参数的梯度项;计算梯度累积平方;利用梯度累积平方、全局学习率更新参数;重复步骤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


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3