import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import h5py
#plt.rcParams["font.family"]="SimHei"
#加载keras内部mnist数据集
mnist=tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y)=mnist.load_data()
train_x,test_x=train_x/255,test_x/255
#网络模型结构参数
width_input=784 #输入层神经网络节点数=28*28
width_net1=100 #第一层神经网络节点数
width_net2=100 #第二层神经网络节点数
width_net3=10 #输出层神经网络节点数
#模型训练参数
epoch=50
way_dec_lr=1 #input:1 or 2
"""
学习率更新方式,选1,表示每lr_dec_epoch轮固定按lr_dec_rate比例减少学习率
选择2,表示记录5次学习率大小,当当前轮次loss值大于前nub次(包括本次)loss平均值
时,学习率自动降为当前学习率0.1倍,当学习率降为last_lr时,训练终止,保存模型
"""
nub=3 #设置记录nub次loss值
last_lr=0.0001 #方式2时,最终截止学习率值
learn_rate=0.01 #默认学习率
init_learn_rate=0.01 #初始学习率
lr_dec_epoch=10 #设置每10轮更新一次学习率
lr_dec_rate=0.5 #跟新学习率倍数
savepath='data/weight4.h5' #保存模型地址
loadmodel='data/weight3.h5' #当为迁移学习时,载入模型地址(请确保本次训练模型结构与加载的模型一致)
isretrain=False #是否为迁移学习True or False
#隐含层的激活函数
def sigmoid(x):
return 1/(1+np.exp(-x))
#输出层的激活函数
def softmax(y):
c=np.max(y)
y=y-c
sum=np.sum(np.exp(y))
return np.exp(y)/sum
#定义均方误差损失函数定义
def loss(y_pre,y_grtru):
return np.sum(np.square(y_pre-y_grtru))
#定义交叉熵损失函数
def cross_entropy_loss(y_pre,y_grtru):
return -np.sum(y_grtru*np.log(y_pre)+(1-y_grtru)*np.log(1-y_pre))
#定义网络输入层
x=np.zeros((width_input,))
#定义网络第一层
a1=np.zeros((width_net1,))
#定义网络隐藏层
a2=np.zeros((width_net2,))
#定义网络输出层
y=np.zeros((width_net3,))
#模型权重导入
def get_model(weight_path):
h5f=h5py.File(weight_path,'r')
w1=h5f['w1'][:]
b1=h5f['b1'][:]
w2=h5f['w2'][:]
b2=h5f['b2'][:]
w3=h5f['w3'][:]
b3=h5f['b3'][:]
return w1,w2,w3,b1,b2,b3
#初始化模型
def genarate_model():
w1=np.random.normal(0,2/width_input,(width_input,width_net1))
b1=np.random.normal(0,2/width_net1,(width_net1,))
w2=np.random.normal(0,2/width_net1,(width_net1,width_net2))
b2=np.random.normal(0,2/width_net2,(width_net2,))
w3=np.random.normal(0,2/width_net2,(width_net2,width_net3))
b3=np.random.normal(0,2/width_net3,(width_net3,))
return w1,w2,w3,b1,b2,b3
#初始化nub个临时保存模型的参数,以便在早停前选取最优模型
w11=np.zeros((nub,width_input,width_net1))
b11=np.zeros((nub,width_net1))
w21=np.zeros((nub,width_net1,width_net2))
b21=np.zeros((nub,width_net2))
w31=np.zeros((nub,width_net2,width_net3))
b31=np.zeros((nub,width_net3))
#模型参数生成
if isretrain:
w1,w2,w3,b1,b2,b3=get_model(loadmodel)
else:
w1,w2,w3,b1,b2,b3=genarate_model()
#初始化参数z(其中a=sigmoid(z))
z1=np.dot(x,w1)+b1
z2=np.dot(a1,w2)+b2
z3=np.dot(a2,w3)+b3
#定义前向传播
def feedforward(a,w,b):
return sigmoid(np.dot(a,w)+b)
#保存模型
def save_model(savepath,w_1,w_2,w_3,b_1,b_2,b_3):
filename=savepath
h5f=h5py.File(filename,'w')
h5f.create_dataset('w1',data=w_1)
h5f.create_dataset('w2',data=w_2)
h5f.create_dataset('w3',data=w_3)
h5f.create_dataset('b1',data=b_1)
h5f.create_dataset('b2',data=b_2)
h5f.create_dataset('b3',data=b_3)
h5f.close
#初始化记录nub次loss值loss2
loss2=np.zeros((nub,))
#训练模型
for n in range(0,epoch+1):
#方式1改变学习率
if way_dec_lr==1:
learn_rate=init_learn_rate*lr_dec_rate**(int(n/lr_dec_epoch))#学习率随着学习轮数指数递减
#打乱训练和测试样本
r=np.random.permutation(60000)
train_x = train_x[r,:,:]
train_y = train_y[r]
#r=np.random.permutation(10000)
#test_x = test_x[r,:,:]
#test_y = test_y[r]
for i in range(0,60000):
x=np.array(train_x[i])
x=x.reshape(width_input,)
z1=np.dot(x,w1)+b1
a1=feedforward(x,w1,b1)
z2=np.dot(a1,w2)+b2
a2=feedforward(a1,w2,b2)
z3=np.dot(a2,w3)+b3
#y=softmax(z3)
y=feedforward(a2,w3,b3)
y_t=np.zeros((width_net3,))
y_t[train_y[i]]=1
eta3=(-y_t/y+(1-y_t)/(1-y))*sigmoid(z3)*(1-sigmoid(z3))#此为反向传播过程中中间参数,下同
#eta3=2*(y-y_t)*sigmoid(z3)*(1-sigmoid(z3))#此为反向传播过程中中间参数,下同
eta2=np.dot(eta3,np.transpose(w3))*sigmoid(z2)*(1-sigmoid(z2))
eta1=np.dot(eta2,np.transpose(w2))*sigmoid(z1)*(1-sigmoid(z1))
b3=b3-learn_rate*eta3
b2=b2-learn_rate*eta2
b1=b1-learn_rate*eta1
w3=w3-learn_rate*np.dot(a2.reshape(width_net2,1),eta3.reshape(1,width_net3))
w2=w2-learn_rate*np.dot(a1.reshape(width_net1,1),eta2.reshape(1,width_net2))
w1=w1-learn_rate*np.dot(x.reshape(width_input,1),eta1.reshape(1,width_net1))
loss1=0
True_num=0
#加载测试集,计算loss和precition
for i in range(0,10000):
x=np.array(test_x[i])
x=x.reshape(1,width_input)
y_t=np.zeros((width_net3,))
y_t[test_y[i]]=1
a1=feedforward(x,w1,b1)
a2=feedforward(a1,w2,b2)
#z3=np.dot(a2,w3)+b3
#y=softmax(z3)
y=feedforward(a2,w3,b3)
if test_y[i]==np.argmax(y,axis=1):
True_num=True_num+1
loss1=loss1+cross_entropy_loss(y,y_t)
#loss1=loss1+loss(y,y_t)
precision=True_num/10000*100
#方式2改变学习率,利用队列方式记录连续nub次loss值
if way_dec_lr==2:
#临时存储模型
j=range(1,nub)
k=range(0,nub-1)
w11[j]=w11[k]
b11[j]=b11[k]
w21[j]=w21[k]
b21[j]=b21[k]
w31[j]=w31[k]
w11[0]=w1
b11[0]=b1
w21[0]=w2
b21[0]=b2
w31[0]=w3
b31[0]=b3
loss2[j]=loss2[k]
loss2[0]=loss1
#判断是否改变学习率
if loss2[0]>np.mean(loss2) and loss2[nub-1]>0:
learn_rate=learn_rate*0.1
if learn_rate<last_lr:
save_model(savepath,w11[np.argmin(loss2)],w21[np.argmin(loss2)],w31[np.argmin(loss2)],
b11[np.argmin(loss2)],b21[np.argmin(loss2)],b31[np.argmin(loss2)])
print("epoch:",n+1,"lr:%.6f"%(learn_rate),"loss:",loss1,'precision:%.2f'%(precision),'%')
break
if n%10==0:#每10轮保存一次模型结果
save_model(savepath,w1,w2,w3,b1,b2,b3)
print("epoch:",n+1,"lr:%.6f"%(learn_rate),"loss:",loss1,'precision:%.2f'%(precision),'%')
纯python实现mnist手写体识别.zip
需积分: 45 43 浏览量
2020-04-02
22:27:25
上传
评论 13
收藏 4KB ZIP 举报
恩泽君
- 粉丝: 179
- 资源: 9
最新资源
- 基于Vue+Echarts实现风力发电机中传感器的数据展示监控可视化系统+源代码+文档说明(高分课程设计)
- 基于单片机的风力发电机转速控制源码
- 基于C++实现的风力发电气动平衡监测系统+源代码+测量数据(高分课程设计)
- 毕业设计- 基于STM32F103C8T6 单片机,物联网技术的太阳能发电装置+源代码+文档说明+架构图+界面截图
- 基于 LSTM(长短期记忆)(即改进的循环神经网络)预测风力发电厂中风力涡轮机产生的功率+源代码+文档说明
- 基于stm32f103+空心杯电机+oled按键+运动算法
- 《CKA/CKAD应试指南/从docker到kubernetes 完全攻略》学习笔记 第1章docker基础(1.1-1.4)
- 基于python实现的水下压缩空气储能互补系统建模仿真与经济效益分析+源代码+论文
- 华中科技大学-自然语言处理实验,Bi-LSTM+CRF的中文分词框架,并且利用基于深度学习的方法进行中文命名实体识别++源码报告
- 基于动态罚函数的铁路车流分配与径路优化模型python源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈