美文网首页
# 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