深度学习笔记(一)DNN-在mnist数据集上用tensorflow搭建dnn

本文代码运行的环境为:

  • ubuntu 16.04 64
  • cuda=9.0
  • cudnn=7.0.5
  • tensorflow=1.9.0
  • python=3.6.4(anaconda 3.5.1)

本文包含的知识点有:

  • DNN基本概念
  • DNN和多层感知机区别
  • 神经网络层数到底怎么回事
  • Mnist数据集介绍
  • tensorflow定义网络结构
  • tensorflow定义损失函数
  • tensorflow选择优化算法
  • tensorflow定义测试指标
  • tensorflow模型的保存和加载

1.从感知机到DNN

感知机(Perception)就不细讲了,讲清楚需要大量篇幅.可以参见网上感知机的简单理解Using neural nets to recognize handwritten digits等.其中的思想并不简单.

多层感知机MLP(Multi Layer Perception)由感知机推广而来,是一种前馈神经网络,有多个神经元层.DNN(Deep Neural Network)是Hinton大神在2006年提出的概念,也是是一种前馈人工神经网络,DNN与MLP的不同在于,DNN在做有监督学习前要先做非监督学习(一般使用RBM或Autoencoder),然后将非监督学习学到的权值当作有监督学习的初值进行训练.

比如CNN后面的全连接层我们成为MLP比较合适,而一个使用无监督预训练权重的多层前馈神经网络,我们称之为DNN比较合适.

但日常使用中,何必分这么细呢对不对.MLP和DNN所表达的网络结构是相同的,所以MLP就是DNN,DNN就是MLP,DNN名字明显高大上,所以以下统一称为DNN. DNN常见网络结构如下:

dnn网络结构
这是一个三层的神经网络.这里提一下神经网络的层数,类比下感知机就明白了,感知机有输入层和输出层却叫单层感知机.我们说神经网络层数的时候,这里的"层"是带有运算单元和激活函数的层数,所以不把输入层计算在内.所以双隐层+输入层是一个三层神经网络.

首先看下数据集吧.

2.数据集Mnist

Mnist已经用"烂"了,但有些人可能还不是很了解,下面简要介绍下.
Mnist数据可从THE MNIST DATABASE获取.训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据.
Mnist数据
它有7万张黑底白字手写的0-9数字图片,其中60000张为训练集,10000张为测试集.本文调用tensorflow中的read_data_sets函数,会把训练集分为55000的训练集,和5000张的验证集.当然也可以自己分.每张图片大小为 28x28 像素,图片中纯黑色的像素值为0,纯白色像素值为1.

3.实战

第一步,配置基本参数

import tensorflow as tf
import numpy as np
from tensorflow.contrib.layers import fully_connected
from tensorflow.examples.tutorials.mnist import input_data

# load data and configure parameters
mnist = input_data.read_data_sets("MNIST_data/")
lr = 0.1
n_inputs = 28*28
n_hidden1 = 300
n_hidden2 = 100
n_outputs= 10
epochs = 10
batch_size = 50
iterations = mnist.train.num_examples // batch_size

这里使用input_data.read_data_sets会读取目录"MNIST_data"下的数据,如果没有目录则创建目录,把数据集下载到目录"MNIST_data"下面并读取数据.数据集分为三部分,mnist.train,mnist.evaluation和mnist.test,分别有55000,5000,10000张图片.

第二步,定义静态图

x = tf.placeholder(tf.float32, shape=(None, n_inputs), name='x')
y = tf.placeholder(tf.int64, shape=(None), name='y')

with tf.name_scope('dnn'):
    hidden1 = fully_connected(x, n_hidden1, activation_fn=tf.nn.relu, scope='hidden1')
    hidden2 = fully_connected(hidden1, n_hidden2, activation_fn=tf.nn.relu, scope='hidden2')
    logits = fully_connected(hidden2, n_outputs, activation_fn=None, scope='logits') # 输出层不需要激活函数
    
with tf.name_scope('loss'):
    entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)
    loss = tf.reduce_mean(entropy, name='loss')
    
with tf.name_scope('train'):
    optimizer = tf.train.GradientDescentOptimizer(lr)
    train = optimizer.minimize(loss)    # apply_gradients(compute_gradients)
    
with tf.name_scope('metrics'):
    correct = tf.nn.in_top_k(logits, y, 1)
    acc = tf.reduce_mean(tf.cast(correct, tf.float32), name='acc')

第三步,调用静态图
初始化变量:

init = tf.global_variables_initializer()
saver = tf.train.Saver()    # defalt: save all variables 

训练数据,保存tensorflow模型:

with tf.Session() as sess:
    tf.summary.FileWriter('./log', sess.graph)
    init.run()  # sess.run(init)
    for epoch in range(epochs):
        acc_train = 0.0
        for iteration in range(iterations):
            x_batch, y_batch = mnist.train.next_batch(batch_size)
            _, acc_batch = sess.run([train, acc], feed_dict={x:x_batch, y:y_batch})
            acc_train += acc_batch
        acc_eval = sess.run(acc, feed_dict={x:mnist.validation.images, y:mnist.validation.labels})
        print(epoch+1, 'Train_acc:', acc_train/iterations,'Eval_acc', acc_eval)
		
    saver.save(sess, 'model/dnn.ckpt')

加载tensorflow模型,测试数据:

with tf.Session() as sess:
    saver.restore(sess, 'model/dnn.ckpt')
    acc_test = acc.eval(feed_dict={x:mnist.test.images, y: mnist.test.labels})
    print("Acc_test:{0}".format(acc_test))

结果如下图所示:
result

在这份代码中,验证集其实可有可无.
验证集的用法一般是用来选择在训练过程中表现比较好的模型.训练结束后,把选择的模型加载,在测试集上测试,也就是说,测试集只有到最后一步才会用到.为什么这样呢,如果没有验证集,我们选择最优模型在测试集上测试,可能因为效果过拟合而导致精度不高.而加上验证集后,在验证集上表现较好的模型,我们可以认为其泛化性能较强,因此选择这个模型为最终模型,拿到测试集上进行测试.
而在本文中为了简化训练过程,没有这么做.读者可以自行尝试,后续实战也有范例.

参考:

https://www.cnblogs.com/pinard/p/6418668.html
http://neuralnetworksanddeeplearning.com/index.html
https://baike.baidu.com/item/DNN/19974079?fr=aladdin
https://www.cnblogs.com/jiaxin359/p/9011457.html#_label1
https://www.cnblogs.com/LHWorldBlog/p/8660315.html

广告

完整代码:https://github.com/wyl6/Deep-Learning/tree/master/dnn/tensorflow_mnist

欢迎关注微信公众号:推荐算法工程师

公众号分享博主的推荐系统学习经验和心得,欢迎交流

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值