深度学习简单介绍

首先要简单区别几个概念:人工智能,机器学习,深度学习,神经网络。这几个词应该是出现的最为频繁的,但是他们有什么区别呢?

人工智能:人类通过直觉可以解决的问题,如:自然语言理解,图像识别,语音识别等,计算机很难解决,而人工智能就是要解决这类问题。

机器学习:如果一个任务可以在任务T上,随着经验E的增加,效果P也随之增加,那么就认为这个程序可以从经验中学习。

深度学习:其核心就是自动将简单的特征组合成更加复杂的特征,并用这些特征解决问题。

神经网络:最初是一个生物学的概念,一般是指大脑神经元,触点,细胞等组成的网络,用于产生意识,帮助生物思考和行动,后来人工智能受神经网络的启发,发展出了人工神经网络。

来一张图就比较清楚了,如下图:

MNIST解析

MNIST是深度学习的经典入门demo,他是由6万张训练图片和1万张测试图片构成的,每张图片都是28*28大小(如下图),而且都是黑白色构成(这里的黑色是一个0-1的浮点数,黑色越深表示数值越靠近1),这些图片是采集的不同的人手写从0到9的数字。TensorFlow将这个数据集和相关操作封装到了库中,下面我们来一步步解读深度学习MNIST的过程。

上图就是4张MNIST图片。这些图片并不是传统意义上的png或者jpg格式的图片,因为png或者jpg的图片格式,会带有很多干扰信息(如:数据块,图片头,图片尾,长度等等),这些图片会被处理成很简易的二维数组,如图:

可以看到,矩阵中有值的地方构成的图形,跟左边的图形很相似。之所以这样做,是为了让模型更简单清晰。特征更明显。

我们先看模型的代码以及如何训练模型:

#coding=utf-8
import tensorflow as tf
import numpy as np
import cv2 as cv
import os
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

def nn_auto_bp():
    num_hiddens = 30
    """
    输入训练或者测试数据(28*28)
    这里shape中的None,意味着行数不定,由输入的时候来确定
    """
    x = tf.placeholder(shape=[None, 784], dtype=tf.float32)
    """
    输入数据对应的标签,代表着(0-9)的数字,用于和训练结果进行比较
    这里shape中的None,意味着行数不定,由输入的时候来确定
    """
    y = tf.placeholder(shape=[None, 10], dtype=tf.float32)
    #隐藏层的权重,训练过程中会不断更新
    w1 = tf.Variable(tf.truncated_normal(shape=[784, num_hiddens]))
    #隐藏层的偏置,训练过程中会不断更新
    b1 = tf.Variable(tf.truncated_normal(shape=[1, num_hiddens]))

    #输出层的权重,训练过程中会不断更新
    w2 = tf.Variable(tf.truncated_normal(shape=[num_hiddens, 10]))
    #输出层的偏置,训练过程中会不断更新
    b2 = tf.Variable(tf.truncated_normal(shape=[1, 10]))

    #nn1是计算的隐藏层的输入数据
    nn1 = tf.add(tf.matmul(x, w1), b1)
    #nn1是计算的隐藏层的输出数据
    h1 = tf.sigmoid(nn1)

    #nn2是计算的输出层的输入数据
    nn2 = tf.add(tf.matmul(h1, w2), b2)
    #out是计算的输出层的输出数据
    out = tf.sigmoid(nn2)

    #diff是训练后真实结果和预测结果的差值
    diff = tf.subtract(y, out)
    #差值有可能是负数因此求个平方
    loss = tf.square(diff)
    #学习力的设置
    step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)
    """
    1.
    从训练结果(一个包含10个元素的一维矩阵)中取出最大的一个元素所在的序号
    2.
    和真实数字代表的一维矩阵进行比较
    3.
    输出维度和元素个数相同的矩阵
    4.
    例如: [True]代表本次识别成功,
          [False]则代表本次识别失败
          acc_mat:行数由输入来决定,列数为1
          demo:
          [False]
          [False]
          [False]
          [True]
          [True]
           ...
    """
    acc_mat = tf.equal(tf.argmax(out, 1), tf.argmax(y, 1))
    """
    tf.cast(acc_mat, dtype=tf.float32)
    上面是将acc_mat中的True转换为1,False转换为0
    tf.reduce_sum
    用于将二维矩阵中每个元素求和
    -------------------------
    那么经过上面操作后,acc_ret代表的就是识别成功的次数
    """
    acc_ret = tf.reduce_sum(tf.cast(acc_mat, dtype=tf.float32))

    with tf.Session() as sess:
        #初始化tf的变量
        sess.run(tf.global_variables_initializer())
        #训练次数
        for i in range(10000):
            #每次训练给到的训练图片有多少张
            batch_xs, batch_ys = mnist.train.next_batch(100)
            #开始训练
            sess.run(step, feed_dict={x: batch_xs, y: batch_ys})
            #每间隔多少次,测试下训练成功率,测试的时候输入测试图片1000张
            if (i+1) % 1000 == 0:
                curr_acc = sess.run(acc_ret, feed_dict={x: mnist.test.images[:1000], y: mnist.test.labels[:1000]})
                print curr_acc
	nn_auto_bp()

先对tensorflow的几个函数做下说明,以方便以后查询
函数1:tf.argmax(out, 1)
说明:取出out矩阵中每行最大的元素对应的索引,结果 也会是一个矩阵(会降维)
例子:

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
x = tf.constant([[1, 2, 3], [0, 4, 1]])
y = tf.arg_max(x,1)
sess = tf.Session()
result = sess.run(y)
print result

结果如下:

[2 1]

函数2:tf.equal(x,y)
说明:比较矩阵x和y,如果矩阵中x和y对应的位置上元素相同,则为True,否则为False,输出是一个BOOL型的矩阵
例子:

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
x = tf.constant([1, 2, 3])
y = tf.constant([4, 2, 5])

diff = tf.equal(x,y)
sess = tf.Session()
result = sess.run(diff)
print result

输出结果:

[False  True False]

函数3:tf.cast
说明:强制类型转换
例子:

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
x = tf.constant([1, 2, 3])
y = tf.constant([4, 2, 5])

diff = tf.equal(x,y)
cast = tf.cast(diff,dtype=tf.float32)
sess = tf.Session()
result = sess.run(cast)
print result

结果:

[0. 1. 0.]

很显然,本例中将bool型转换为了float类型
函数4:tf.reduce_sum(array)
说明:将矩阵array中每个元素求和
例子:

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
x = tf.constant([[1, 2, 3],[4,5,6]])
y = tf.reduce_sum(x)
sess = tf.Session()
result = sess.run(y)
print result

结果:

21

最后说明下这里的mnist集训练的输出结果,例如本例中输出层out,其数据样式如下:
[9.54777002e-04 4.01586294e-04 6.47783279e-04 1.02393925e-02 4.86612320e-04 9.39667225e-05 7.74860382e-05 9.95363533e-01 1.99070573e-03 2.37381458e-03]

这个一维矩阵中最大的元素是第7个(下标从0开始),值越大,说明本次训练结果预测为7的概率越大。

再看看输入的训练集或者测试集对应的标签样式如下:
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]

这意味着本次输入的图片(28*28)对应的数字是7

如果第一个矩阵能够在训练的模型中得出第7个元素值最大,那么本次识别就是成功的,否则说明这张图片在模型中未能被成功识别。

另外在代码头部的如下声明:
mnist = input_data.read_data_sets(“MNIST_data/”, one_hot=True)
这意味着mnist数据集采用的是one hot编码,这个编码规范是采用的包含10个元素的一维矩阵,每个元素只能为0或者1(只有一个1,其余全部为0),其中1所在的下标对应的就是图片代表的数字。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐