神经网络2:卷积神经网络学习 1

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

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

sess = tf.Session()
# 定义 tensorflow 特有的占位符
# xs 定义为 【行数未定,但784列】;
# 原理在于图片是28*28=784 即把二维形式的图片,用一维向量表示,None 表示图片的个数,即一行代表一个图片
xs = tf.placeholder(dtype=tf.float32, shape=[None, 784])
# xs 定义为 【行数未定,但10列】
# 10 列表示0到9 这几个数,None 表示图片的个数,即每行代表一个图片对应的label
ys = tf.placeholder(dtype=tf.float32, shape=[None, 10])
keep_prob = tf.placeholder(dtype=tf.float32)


# 定义计算预测准确度的函数
def compute_accuracy(v_xs, v_ys):
    global prediction
    '''本函数由两个sess.run()构成'''
    """该部分计算预测值"""
    y_re = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
    """该部分计算预测的准确度"""
    # tf.argmax() 返回最大值的索引,axis =1 表示行方向的
    # 因为 y_pre 是预测值,v_ys 是实际值 所以通过argmax 返回行方向上的最大值,
    # 使用tf.equal 比较同一位置的值是否相等 返回的是[True,True,False,True ...]
    correct_prediction = tf.equal(tf.argmax(input=y_re, axis=1), tf.argmax(input=v_ys, axis=1))
    # 使用tf.cast将tf.equal的返回值转为float [1.0,1.0,0.0,1.0 ...]
    # 再使用tf.reduce_mean 计算平均值
    accuracy = tf.reduce_mean(tf.cast(x=correct_prediction, dtype=tf.float32))

    result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
    return result


# 定义一个初始化权值的函数
def weight_variable(shape):
    # 截尾正太分布 的随机数  stddev 标准差
    initial = tf.truncated_normal(shape=shape, stddev=0.1)
    return tf.Variable(initial)


# 定义一个初始化偏置量的函数
def bias_variable(shape):
    # 值为0.1 的常量
    initial = tf.constant(value=0.1, shape=shape)
    return tf.Variable(initial)


# 定义卷积层函数
def conv2d(input, Weight):
    # input 为输入的数据
    # Weight 为权值, filter
    # strides 为步长,四个值的意思分别是:样本的步长,1 表示每个样本都作为输入
    #                                   高度的步长,1 表示每次在高度上移动一个单位
    #                                   宽度的步长,1 表示每次在宽度上移动一个单位
    #                                   通道的步长,或者说是厚度上的步长,1,表示每次移动一个
    # padding 有两种取值 SAME VALID,使用SAME会对输入的数据进行0补,也就是移动的步数不会丢失
    #          取VALID,则不进行补0,可能会导致移动步数丢失
    #          如 长度为10的,用一个长度为3的在上面每次移动一个
    #             使用SAME,因为需要补0,所以最后需要移动10次
    #             使用VALID,则移动8次就无法再移动【出界了】
    return tf.nn.conv2d(input=input, filter=Weight, strides=[1, 1, 1, 1], padding='SAME')


# 定义池化层函数
def max_pool_2x2(input):
    # 池化层的目的是在降低数据量,就是用一颗数据来表示一整块数据
    # 这里使用最大值池化
    # ksize 表示池化范围的大小;四个参数的意义与上述相同
    # strides 步长
    return tf.nn.max_pool(value=input, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


''''''
# 将数据xs  reshape 成个数未定,长宽28*28,厚度 为1 的数据类型
x_input = tf.reshape(tensor=xs, shape=[-1, 28, 28, 1])

"""第一层卷积计算  start"""
'''先初始化权值和偏置参数'''
# shape = [5,5,1,32]  的意思是 filter 的大小是5*5的,用于输入厚度为1,输出厚度为32
W_conv1 = weight_variable(shape=[5, 5, 1, 32])
b_conv1 = bias_variable([32])
'''真正的计算'''
# 输入 x_input 28*28*1
# 输出的 h_conv1 28*28*32
# 使用了relu 激活函数;激活函数有很多种,其作用是为了去线性化
h_conv1 = tf.nn.relu(conv2d(x_input, W_conv1) + b_conv1)
# 池化层
# 使用最大值池化 输入为28*28*32
#               输出为14*14*32   池化层的目的就是为了缩小特征的(个人理解)
h_pool1 = max_pool_2x2(h_conv1)
"""第一层卷积计算  end"""

"""第二层卷积计算 start"""
# 因为第二层卷积的输入为第一层的输出,14*14*32
# 因此 权值为5*5 输入为32厚度,输出为64 厚度
W_conv2 = weight_variable(shape=[5, 5, 32, 64])
b_conv2 = bias_variable(shape=[64])
# 输入为14*14*32
# 输出为 14*14*64
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
# 输出为 7*7*64
h_pool2 = max_pool_2x2(h_conv2)
"""第二层卷积计算  end"""

"""全连接层1 start"""
# 7*7*64 是要输入的数数据
# 1024 是神经元的个数
# 也就是经过上次池化层最后的结果为7*7*64 的图片,与1024个神经元的全连接 需要的权值矩阵,其权值个数为矩阵中元素的个数
W_fc1 = weight_variable([7 * 7 * 64, 1024])
# 每个神经元需要一个偏置
b_fc1 = bias_variable([1024])
# reshape 未知行数,每行代表一个图片全部的特征,7*7*64
h_pool2_flat = tf.reshape(tensor=h_pool2, shape=[-1, 7 * 7 * 64])
# 输入 n*(7*7*64) (7*7*64)*1024
# 输出 n*1024
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
# 防止过拟合的dropout方法
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
"""全连接层2 start"""
W_fc2 = weight_variable(shape=[1024, 10])
b_fc2 = bias_variable([10])
# matmul 输入:n*1024 2014*10
#        输出:n*10
# softmax 的输入为:n*10
#           输出为:
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
"""全连接层2 end"""
'''
   上述已将网络搭建完成
    但是尚不能进行持续性的学习
    原因:学习需要有一个学习的目标,在机器学习中也需要刻画一个目标
          常用的刻画方式就是:找到一个损失函数,学习的目标就是不断的最小化损失函数值
                            或者找到一个效用函数,不断的最大化效用函数值
'''

cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), reduction_indices=[1]))  # loss
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
sess.run(tf.global_variables_initializer())

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5})
    if i % 50 == 0:
        print(compute_accuracy(
            mnist.test.images, mnist.test.labels))

 

posted @ 2018-08-08 23:01  Lucky、Dog  阅读(265)  评论(0编辑  收藏  举报