zoukankan      html  css  js  c++  java
  • 神经网络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))
  • 相关阅读:
    如何学习编程语言?
    spring AOP(1)
    一个老工程师给年轻工程师的十大忠告!!!
    跳楼时看到的[转]
    Python distribution打包&安装流程
    php rsa类的一个写法
    yii数据表关联操作
    JIRA是个好工具
    Yii CModel.rules() 方法 validate预定义完整列表
    Python Challenge挑战一下
  • 原文地址:https://www.cnblogs.com/infoo/p/9446304.html
Copyright © 2011-2022 走看看