美文网首页
# tensorflow实战笔记(二)

# tensorflow实战笔记(二)

作者: Kean_L_C | 来源:发表于2017-11-14 14:42 被阅读1012次

    实现卷积神经网络

    卷积图示:LE-Net5

    捕获.PNG

    这个图可以利用来学习单通道卷积,例如下面mnist训练的数据仅仅用到黑白图片的灰度,因此是单通道。彩色的图片由3色RGB构成的三通道。

    mnist训练简单的cnn

    • tensorflow实现简单cnn的网络结构:
    1. input层
    2. 卷积层
    3. pool
    4. 卷积层
    5. pool
    6. 全连接层
    7. 输出层
    • code释义
    1. 读取数据
      数据是由28x28展开到784的数据,因此后面需要还原成28x28
    import tensorflow as tf
    import numpy as np
    from sklearn import preprocessing
    from tensorflow.examples.tutorials.mnist import input_data
    
    mnist = input_data.read_data_sets(r'D:\PycharmProjects\HandWritingRecognition\TF\data',
                                      one_hot=True)  # getdata
    sess = tf.InteractiveSession()
    # 样本定义
    x = tf.placeholder(dtype=tf.float32, shape=[None, 784])
    # 真实值
    y_ = tf.placeholder(dtype=tf.float32, shape=[None, 10])
    
    1. 权重和偏执的初始化
    # 定义初始权重函数
    def init_weights(shape):
        # 服从截断的正态分布, 方差为0.1
        initial = tf.truncated_normal(shape=shape, stddev=0.1)
        return tf.Variable(initial_value=initial)
    
    # 定义偏置的初始值
    def init_bias(shape):
        initial = tf.constant(value=0.1, shape=shape)
        return tf.Variable(initial)
    
    1. 卷积
      tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)除去name参数用以指定该操作的name,与方法有关的一共五个参数:
    • input:指需要做卷积的输入图像,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]这样shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一

    • filter:相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels, out_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维

    • strides:卷积在图像每一维的步长,这是一个一维的向量,长度4,[batch, in_height, in_width, in_channels]

    • padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式
      same:相同卷积,在kernel提取进行卷积时候边缘会有损失,same保证输出维度和输入维度的一致,那么就会在边缘填充0,然后再计算卷积以保证维度的一致。
      valid:有效卷积,与上面相反,不做填充。strides=1行/列关系:output_row = input_row - kernel_row + 1

    • use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true

    • 结果返回一个Tensor,这个输出,就是我们常说的feature map

    # 定义一个2D的单通道卷积层
    def conv2d(x, W):
        # stage=1,卷积仅仅导致边缘损失padding=“same”代表用0来填充保证输入和输出的图片像素一致
        # 2d to 4d
        return tf.nn.conv2d(input=x, filter=W, strides=[1, 1, 1, 1], padding="SAME")
    
    1. 池化
    • value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch, height, width, channels]这样的shape

    • ksize:池化窗口的大小,取一个四维向量,一般是[1, height, width, 1],因为我们不想在batch和channels上做池化,所以这两个维度设为了1

    • strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride,stride, 1]

    • padding:和卷积类似,可以取'VALID' 或者'SAME'

    • 返回一个Tensor,类型不变,shape仍然是[batch, height, width, channels]这种形式

    # 定义pool函数,maxpool用来降为提取显著的特征
    def max_pool_2x2(x):
        # 两个维度采取边缘填充0,stride=2:那么图像维度行列都变为原来的1/2
        return tf.nn.max_pool(value=x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
    
    1. input转化
    # 要把数据转化为28x28的图片
    x_image = tf.reshape(x, [-1, 28, 28, 1])  # -1:类似于numpy,后面的1:代表通道
    
    1. 构建卷积和池化层
    # 定义第一个卷积层, 定义32个单通道5x5的核,提取32个特征
    W_conv1 = init_weights(shape=[5, 5, 1, 32])
    b_conv1 = init_bias(shape=[32])
    # 第一层卷积层的输出
    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    h_pool1 = max_pool_2x2(h_conv1)  # 图像变成14x14 x 32
    
    # 定义第二层卷积层
    W_conv2 = init_weights(shape=[5, 5, 32, 64])  # 单通道变成32,提起64个特征,定义5x5核
    b_conv2 = init_bias(shape=[64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)   # 7x7 x 64
    
    # h_pool2转化为1维度的数据
    num = 7 * 7 * 64 
    h_pool2_flat = tf.reshape(h_pool2, [-1, num])
    

    一个卷积层输出每个特征是14 x 14,一共有32个kernel滤波提取32个特征。
    7 全连接层

    # 隐藏节点设定为1024:全连接层
    W_fc1 = init_weights([num, 1024])
    b_fc1 = init_weights([1024])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    
    # dropout
    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(x=h_fc1, keep_prob=keep_prob)
    
    1. 输出层
    # 全连接输出层
    W_fc2 = init_weights([1024, 10])
    b_fc2 = init_weights([10])
    h_fc2 = tf.nn.relu(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
    y = tf.nn.softmax(h_fc2)
    
    1. 训练模型
    # loss function
    loss = tf.reduce_mean(
        - tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])  # 先计算求和每行的交叉熵,然后去每个样本的交叉熵均值
    )
    
    # train
    train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    tf.global_variables_initializer().run()  # 图的所有变量初始化
    
    # 训练模型
    for i in range(3000):
        batchX, batchY = mnist.train.next_batch(100)
        train_step.run(feed_dict={x: batchX, y_: batchY, keep_prob: 0.75})
        # print(h_pool2_flat.shape)
        if i % 100 == 0:
            print(sess.run(loss, feed_dict={x: batchX, y_: batchY, keep_prob: 0.75}))
    
    # test
    print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
    
    • output
    iteration 300: 0.1200
    iteration 600: 0.9200
    iteration 900: 0.9200
    iteration 1200: 1.0000
    iteration 1500: 0.9800
    iteration 1800: 0.9600
    iteration 2100: 1.0000
    iteration 2400: 0.9600
    iteration 2700: 1.0000
    2017-11-14 16:24:17.311788: W C:\tf_jenkins\home\workspace\rel-win\M\windows-gpu\PY\36\tensorflow\core\common_runtime\bfc_allocator.cc:217] Allocator (GPU_0_bfc) ran out of memory trying to allocate 2.59GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory is available.
    2017-11-14 16:24:17.312383: W C:\tf_jenkins\home\workspace\rel-win\M\windows-gpu\PY\36\tensorflow\core\common_runtime\bfc_allocator.cc:217] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.34GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory is available.
    2017-11-14 16:24:17.820643: W C:\tf_jenkins\home\workspace\rel-win\M\windows-gpu\PY\36\tensorflow\core\common_runtime\bfc_allocator.cc:217] Allocator (GPU_0_bfc) ran out of memory trying to allocate 3.90GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory is available.
    test data accuracy: 0.985
    

    代码

    CNN进阶

    再次之前需要补一补一些正则化的知识(后面会采用正则化的方法避免过度拟合):http://blog.csdn.net/zouxy09/article/details/24971995。这个绝对是深度好文,讲解L0,L1,L2正则化方法以及对比区别。

    • 网络结构
    1. 卷积层
    2. 最大池化
    3. LRN
    4. 卷积层
    5. 最大池化层
    6. 全连接层
    7. 全连接层
    8. logits

    相关文章

      网友评论

          本文标题:# tensorflow实战笔记(二)

          本文链接:https://www.haomeiwen.com/subject/nbzamxtx.html