#库的导入
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)
#梯度累积平方计算函数,0.9为衰减系数,0.1为1-衰减系数的计算结果,输入参数r为累积梯度平方,delta为当前梯度
def accumulation(r,delta):
r = 0.9 * r + 0.1 * (delta**2)
return r
#参数更新计算函数,输入参数w为原参数值,r为累积梯度值,delta为梯度值,c为移动步长项
def adjust(w,r,delta,c):
#0.000001是为了避免出现分子、分母为0的情况
change1 =(0.000001+c)/(0.000001+r)
#change为参数更新量
change =(change1**0.5)*delta
w = w - change
#0.9为衰减系数,0.1为1-衰减系数的计算结果
c = 0.9 * c + 0.1 * (change**2)
return w,c
maxepochs = 100 #迭代训练次数
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一一对应
rw2 = np.zeros((1,8))
rb2 = np.zeros((1,1))
rw1 = np.zeros((8,4))
rb1 = np.zeros((8,1))
#cw1、cb1,cw2,cb2分别保存参数w1、b1、w2、b2的移动步长项,其形状与w1、b1、w2、b2一一对应
cw2 = np.zeros((1,8))
cb2 = np.zeros((1,1))
cw1 = np.zeros((8,4))
cb1 = np.zeros((8,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
dw2now = dw2now/samnum
db2now = db2now/samnum
dw1now = dw1now/samnum
db1now = db1now/samnum
# 先更新输出层参数
# w2更新,依次更新w2的梯度累积平方、w2、w2的当前移动步长项
for m in range(hiddenunitnum):
rw2[:,m] = accumulation(rw2[:,m],dw2now[:,m])
w2[:,m],cw2[:,m]= adjust(w2[:,m],rw2[:,m],dw2now[:,m],cw2[:,m])
#b2更新,依次更新b2的梯度累积平方、b2、b2的当前移动步长项
rb2 = accumulation(rb2,db2now)
b2,cb2 = adjust(b2,rb2,db2now,cb2)
#更新隐含层参数
#w1更新,依次更新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],cw1[a,b] = adjust(w1[a,b],rw1[a,b],dw1now[a,b],cw1[a,b] )
#b1更新,依次更新b1的梯度累积平方、b1、b1的当前移动步长项
for n in range(hiddenunitnum):
rb1[n,:] = accumulation(rb1[n,:],db1now[n,:])
b1[n,:],cb1[n,:] = adjust(b1[n,:],rb1[n,:],db1now[n,:],cb1[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)
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
将自适应学习率调整算法(Adadelta)作为反向传播算法应用于普通的三层神经网络(输入层、隐含层、输出层)的反向传播过程,之后建立数据预测模型进行数据预测,压缩包中adadelta.py为训练过程源码,test.py为测试过程源码,train.csv文件为训练数据集,test.csv文件为测试数据集,.npy文件为模型训练后保存的参数。
资源推荐
资源详情
资源评论
收起资源包目录
Adadelta.zip (8个子文件)
Adadelta
b1.npy 192B
b2.npy 136B
w1.npy 384B
adadelta.py 6KB
w2.npy 192B
train.csv 2KB
test.py 2KB
test.csv 649B
共 8 条
- 1
资源评论
七层楼的疯子
- 粉丝: 1w+
- 资源: 45
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功