参考链接: Python中的单个神经元神经网络

本文实例讲述了Python利用全连接神经网络求解MNIST问题。分享给大家供大家参考,具体如下:

1、单隐藏层神经网络

人类的神经元在树突接受刺激信息后,经过细胞体处理,判断如果达到阈值,则将信息传递给下一个神经元或输出。类似地,神经元模型在输入层输入特征值x之后,与权重w相乘求和再加上b,经过激活函数判断后传递给下一层隐藏层或输出层。

单神经元的模型只有一个求和节点(如左下图所示)。全连接神经网络(Full Connected Networks)如右下图所示,中间层有多个神经元,并且每层的每个神经元都是与上一层和下一层的节点都对应连接。中间隐藏层只有一层的神经元网络称为单隐藏层神经网络。如果有多个中间隐藏层则称为多隐藏层神经网络。

常见的激活函数如下所示:

下面是在单个神经元逻辑回归求解MNIST手写数字识别问题的基础上,采用单隐藏层神经网络进行求解的过程。

首先载入数据,从Tensor FLow提供的数据库中导入MNIST数据

import tensorflow as tf

import tensorflow.examples.tutorials.mnist.input_data as input_data

mnist=input_data.read_data_sets('MNIST_data/',one_hot=True)

构建输入层,其中x是图像的特征值,由于是28×28=784个像素点,所有输入为未知行数、每行784的二维数组。y是图像的标签值,共有0~9十种可能,所有为[None,10]的二维数组

x=tf.placeholder(tf.float32,[None,784],name='x')

y=tf.placeholder(tf.float32,[None,10],name='y')

构建隐藏层,设置隐藏层神经元个数为256,由于输入层输入为784,而隐藏层神经元为h1_num,所以W1为[784,h1_num]形式的二维数组,b为[h1_num]的一维向量。此外采用ReLU作为激活函数处理输出。

h1_num=256 #设置隐藏层神经元数量

W1=tf.Variable(tf.random_normal([784,h1_num]),name='W1')

b1=tf.Variable(tf.zeros([h1_num]),name='b1')

Y1=tf.nn.relu(tf.matmul(x,W1)+b1) #激活函数

构建输出层,由于隐藏层有h1_num个神经元输出,输出层输出10种输出结果,所以W2为[h1_num,10]的二维数组,b2为[10]的一维向量。最后结果通过softmax将线性输出Y2转化为独热编码方式。

W2=tf.Variable(tf.random_normal([h1_num,10]),name='W2')

b2=tf.Variable(tf.zeros([10]),name='b2')

Y2=tf.matmul(Y1,W2)+b2

pred=tf.nn.softmax(Y2)

设置训练的超参数、损失函数、优化器,这里采用Adam Optimizer进行优化。准确率是通过比较预测值和标签值是否一致来定义。在定义损失函数时,如果直接使用交叉熵的方式定义,会出现log0值为NaN的情况,导致数据不稳定,无法得出结果。Tensor Flow提供了结合softmax定义交叉熵的方式softmax_cross_entropy_with_logits(),第一个参数为不经softmax处理的前向计算结果Y2,第二个参数为标签值y

train_epochs=20 #训练轮数

batch_size=50 #每个批次的样本数

batch_num=int(mnist.train.num_examples/batch_size) #一轮需要训练多少批

learning_rate=0.01

#定义损失函数、优化器

loss_function=tf.reduce_mean( #softmax交叉熵损失函数

tf.nn.softmax_cross_entropy_with_logits(logits=Y2,labels=y))

optimizer=tf.train.AdamOptimizer(learning_rate).minimize(loss_function)

#定义准确率

correct_prediction=tf.equal(tf.argmax(pred,1),tf.argmax(y,1))

accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

进行训练并输出损失值与准确率,训练进行多轮,每轮一开始分批次读入数据进行训练,每结束一轮输出一次损失和准确率。

ss=tf.Session()

ss.run(tf.global_variables_initializer()) #进行全部变量的初始化

for epoch in range(train_epochs):

for batch in range(batch_num): #分批次读取数据进行训练

xs,ys=mnist.train.next_batch(batch_size)

ss.run(optimizer,feed_dict={x:xs,y:ys})

loss,acc=ss.run([loss_function,accuracy],\

feed_dict={x:mnist.validation.images,y:mnist.validation.labels})

print('第%2d轮训练:损失为:%9f,准确率:%.4f'%(epoch+1,loss,acc))

ss.close()

运行结果如下图,与单个神经元相比,可以较快得到较高的准确率

评估模型,将测试集数据填充入占位符x,y去求准确率,

test_res=ss.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})

print('测试集的准确率为:%.4f'%(test_res))

2、多层神经网络

多层是指中间的隐藏层有多个,例如使用两层隐藏层,第一个隐藏层在计算后将结果输出到第二个隐藏层,再由第二个隐藏层计算后交给输出层,而第二个隐藏层的设置与第一个基本相同,例如:

#构建输入层

x=tf.placeholder(tf.float32,[None,784],name='x')

y=tf.placeholder(tf.float32,[None,10],name='y')

#构建第一个隐藏层

h1_num=256 #第一隐藏层神经元数量256

W1=tf.Variable(tf.truncated_normal([784,h1_num],stddev=0.1),name='W1')

b1=tf.Variable(tf.zeros([h1_num]),name='b1')

Y1=tf.nn.relu(tf.matmul(x,W1)+b1)

#构建第二个隐藏层

h2_num=64 #第二隐藏层神经元数量64

W2=tf.Variable(tf.random_normal([h1_num,h2_num],stddev=0.1),name='W2')

b2=tf.Variable(tf.zeros([h2_num]),name='b2')

Y2=tf.nn.relu(tf.matmul(Y1,W2)+b2)

#构建输出层

W3=tf.Variable(tf.random_normal([h2_num,10],stddev=0.1),name='W3')

b3=tf.Variable(tf.zeros([10]),name='b3')

Y3=tf.matmul(Y2,W3)+b3

pred=tf.nn.softmax(Y3)

在第一隐藏层产生参数W1时采用的是截断正态分布的随机函数tf.truncated_normal(),与普通正太分布相比,截断正态分布生成的值之间的差距不会太大。

设置的第一隐藏层的神经元256个,第二层64个,因此第二层的每个输入有256个特征值,并产生64个输出,相应的W2的shape为[h1_num,h2_num],b2的shape为[h2_num]。输出层W3的shape为[h2_num,10]。函数的其他部分与单层神经网络相同。

经过运算多层的神经网络训练的准确率不一定比单层的高,因为还涉及到训练的超参数的设置等多种因素。但是多层神经网络的运行速度比单层慢,越多层的神经网络意味着更加复杂的计算量。

全连接层函数

通过以上多层神经网络的定义可以看出两个隐藏层与输出层的构建方法基本类似,都是定义对应的变量W、b,在定义W时其shape为[输出维度,输出维度],因此可以将隐藏层与输出层统一定义为一个全连接层函数:

#定义一个通用的全连接层函数模型

def fcn_layer(inputs,in_dim,out_dim,activation=None):

W=tf.Variable(tf.truncated_normal([in_dim,out_dim],stddev=0.1))

b=tf.Variable(tf.zeros([out_dim]))

Y=tf.matmul(inputs,W)+b

if activation==None:

output=Y

else:

output=activation(Y)

return output

#构建第一个隐藏层

Y1=fcn_layer(x,784,256,tf.nn.relu)

#构建第二个隐藏层

Y2=fcn_layer(Y1,256,64,tf.nn.relu)

#构建输出层

Y3=fcn_layer(Y2,64,10)

pred=tf.nn.softmax(Y3)

其中inputs为本层的输入,in_dim为本层的输入维度,也就是上一层的输出维度,out_dim为本层的输出维度,activation为激活函数,默认为None。将输入与权重W叉乘再加上偏置值b得到Y,如果定义了激活函数,用激活函数处理Y,否则直接将Y赋给output输出。

3、模型的保存与读取

在模型训练结束后,如果希望下次继续使用或训练模型则需要将储存起来。

模型的储存

首先需要定义模型数据的保存路径:

import os

save_dir='D:/Temp/MachineLearning/ModelSaving/' #定义模型的保存路径

if not os.path.exists(save_dir): #如果不存在该路径则创建

os.makedirs(save_dir)

定义储存粒度与saver,所谓储存粒度即每个几轮数据进行一次储存

save_step=5 #定义存储粒度

saver=tf.train.Saver() #定义saver

在每轮训练结束后进行判断,每隔5轮储存一次,储存路径中拼接轮数信息,

if epoch%save_step==0:

saver.save(ss,os.path.join(save_dir,'mnist_fcn_{:02d}.ckpt'.format(epoch+1)))

在所有迭代训练执行结束后,再整体储存一次

saver.save(ss,os.path.join(save_dir,'mnist_fcn.ckpt'))

这样就会在指定目录下生成模型的保存文件:

模型的读取

从定义的模型目录中读取存盘点数据,并将其中的参数赋值给当前的session,然后便可以直接利用session进行测试,其准确率与保存时一致。

save_dir='D:/Temp/MachineLearning/ModelSaving/' #定义模型的保存路径

saver=tf.train.Saver() #定义saver

ss=tf.Session()

ss.run(tf.global_variables_initializer())

ckpt=tf.train.get_checkpoint_state(save_dir) #读取存盘点

if ckpt and ckpt.model_checkpoint_path:

saver.restore(ss,ckpt.model_checkpoint_path) #从存盘中恢复参数到当前的session

print('数据恢复从',ckpt.model_checkpoint_path)

test_res=accuracy.eval(session=ss,feed_dict={x:mnist.test.images,y:mnist.test.labels})

print('测试集的准确率为:%.4f'%(test_res))

在读取模型时有时候会遇到报错:

NotFoundError (see above for traceback): Restoring from checkpoint failed. This is most likely due to a Variable name or other graph key that is missing from the checkpoint. Please ensure that you have not altered the graph expected based on the checkpoint.

这时只需重启kernel即可。

通过图来保存模型

也可以将训练好的模型以图的形式保存为.pb文件,下次直接可以使用,但不可以继续训练。

通过tf.train.write_graph函数来保存模型如下:

import tensorflow as tf

v=tf.Variable(1.0,'new_var')

with tf.Session() as ss:

tf.train.write_graph(ss.graph_def,'D:\Temp\MachineLearning\ModelSaving\Graph',

'test_graph.pb',as_text=False)

读取图文件并还原:

with tf.Session() as ss:

with tf.gfile.GFile('D:/Temp\MachineLearning/ModelSaving/Graph/test_graph.pb','rb') as pb_file:

graph_def=tf.GraphDef()

graph_def.ParseFromString(pb_file.read())

ss.graph.as_default()

tf.import_graph_def(graph_def)

print(graph_def)

希望本文所述对大家Python程序设计有所帮助。

[转载] python bp神经网络 mnist_Python利用全连接神经网络求解MNIST问题详解相关推荐

  1. 深度学习——神经网络之DNN全连接神经网络、BP算法原理

    深度学习--神经网络之DNN全连接神经网络.BP算法原理 深度学习--神经网络之DNN全连接神经网络.BP算法原理 1.啥是人工神经网络 2.神经网络的应用 3.神经网络的组成 3.1.神经元 3.2 ...

  2. python神经网络案例——FC全连接神经网络实现mnist手写体识别

    全栈工程师开发手册 (作者:栾鹏) python教程全解 FC全连接神经网络的理论教程参考 http://blog.csdn.net/luanpeng825485697/article/details ...

  3. 利用全连接神经网络对车辆进行识别

    import os import zipfile import random import paddle import numpy as np import matplotlib.pyplot as ...

  4. 【DL】基于pytorch搭建BP神经网络/人工神经网络/多层感知机/全连接神经网络的鸢尾花分类

    目录 1.介绍 2.数据 3.模型 4.完整代码 1.介绍 鸢尾(学名:Iris tectorum Maxim. )又名:蓝蝴蝶.紫蝴蝶.扁竹花等,属百合目.鸢尾科.鸢尾属多年生草本,根状茎粗壮,直径 ...

  5. python requests库api_python利用requests库进行接口测试的方法详解

    前言 之前介绍了接口测试中需要关注得测试点,现在我们来看看如何进行接口测试,现在接口测试工具有很多种,例如:postman,soapui,jemter等等,对于简单接口而言,或者我们只想调试一下,使用 ...

  6. [转载] python中set函数是什么数据类型_Python基本数据类型-list-tuple-dict-set详解

    参考链接: Python中的isdisjoint函数 Python基本数据类型-list-tuple-dict-set 数据类型 表示方法 特性 list 列表用方括号表示:[] list是一种有序的 ...

  7. [转载] python里字典的用法_python中字典(Dictionary)用法实例详解

    参考链接: Python字典dictionary copy方法 本文实例讲述了python中字典(Dictionary)用法.分享给大家供大家参考.具体分析如下: 字典(Dictionary)是一种映 ...

  8. [转载] python hasattr函数_Python的hasattr() getattr() setattr() 函数使用方法详解

    参考链接: Python hasattr() hasattr(object, name) 判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回Fa ...

  9. 【神经网络与深度学习】 Numpy 实现全连接神经网络

    1.实验名称 Numpy 实现全连接神经网络实验指南 2.实验要求 用 python 的 numpy 模块实现全连接神经网络. 网络结构为一个输入层.一个隐藏层.一个输出层. 隐藏层的激活函数为 Re ...

最新文章

  1. 提取pfx证书公钥和私钥
  2. 深度学习(十四)——Softmax详解, 目标检测, RCNN
  3. C# 合并BitMap图像,生成超大bitmap
  4. nginx(五)rewrite
  5. oracle基本的操作命令,oracle命令基本操作
  6. 《全数据时代的炼金师》全书语言生动、易懂
  7. bootstrap插件(对话框)bootbox参数和自定义弹出框宽度设置
  8. 无法启动SQL Server 2005中的SQL Server(MSSQLSERVER)服务--zt
  9. pytorch学习笔记(二十一):Channels
  10. CSS3特效----制作3D旋转导航
  11. 洛谷OJ P1003 铺地摊
  12. Python入门基础教程(非常详细)
  13. 爬虫---涨跌停股票池信息----(东方财富)
  14. Bootstrap 4框架
  15. 手机开发APP整体界面设计工具之墨刀---没用过就知道它很牛掰
  16. Oceans (where feet may fail)
  17. Solr评分整理汇总:深入理解Lucene默认打分算法以及常用的三种评分方法
  18. JDBC(Java数据库连接) 学习笔记 第四天
  19. PIPI1003: 最少钱币数c++
  20. 软件工程专业画图工具Jude的安装与Windows找不到javaw文件的解决办法

热门文章

  1. 2021 年百度之星·程序设计大赛 - 复赛 1001 Palindrome(结论,奇偶性)
  2. C++复制粘贴代码去行标
  3. 计算机应用基础2016高起专,2016年秋季《计算机应用基础(高起专)》期末考核
  4. html图片鼠标动态效果代码,纯css3实现鼠标经过图片显示描述的动画效果
  5. SQL Server高级查询之数据查询和操作(DDL和DML)
  6. 去除内联元素之间的间距
  7. 用SQL表达内连接和外链接
  8. bzoj 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐(暴力DFS)
  9. 51nod 1428 bzoj 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚
  10. 2017杭电ACM集训队单人排位赛 - 1(ALL题解)