Tensorflow实战 CNN实现minst分析 总结及难点记录

本文详细介绍了深度学习中的卷积神经网络(CNN)应用,包括数据加载、网络初始化、误差函数定义、反向传播参数更新及训练过程。深入探讨了权重和偏置的初始化方法,卷积和池化层的padding参数区别,以及如何利用TensorFlow进行高效模型训练和准确率评估。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结

1.算法过程
加载数据→初始化网络→定义误差函数→反向传播更新参数→重复该过程
2.经过各层后图片大小的变化。
在这里插入图片描述

难点记录

1.去掉输出中的警告信息。

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

2.tf.InteractiveSession()是一种交互式的session方式,它让自己成为了默认的session,也就是说用户在不需要指明用哪个session运行的情况下,就可以运行起来,这就是默认的好处。这样的话就是run()和eval()函数可以不指明session啦。
这句获得作用和下面的两句话具有相同的意思。

# 定义交互式会话框
sess = tf.InteractiveSession()

sess=tf.Session()
with sess.as_default():

3.权重和偏执必须使variable类型的,这种类型可以在神经网络的反向传播过程中求导,如果不指明variable类型,在反向传播时就会出错。

# 定义权重函数,截断正态分布
def weight_variable(shape):
    return tf.Variable(tf.truncated_normal(shape, stddev=0.1))

# 定义偏置函数
def bias_variable(shape):
    return tf.Variable(tf.constant(0.1, shape=shape))

4.tf.nn.conv2d()和tf.nn.max_pool()两个函数的padding参数有细微的差别。
卷积函数的padding='same’是为了让输入和输出的尺寸完全一致,如果输入图片尺寸为[28,28,1],那么通过适当的填充使得输出也是[28,28,1]。
池化函数的padding='same’并不是为了保证输入和输出完全一致,而是在到达边界时才进行一次填充,让最后一次取值的时候不会因为剩余的图片小于池化大小而不完成最后一次取值。例如图片大小为[5,5],池化大小为[2,2],步长为[2,2],那么当padding='vaild’时,输出为[2,2],当padding='same’时,输出为[3,3]。

# 定义二维卷积
def conv2d(x, w):
    return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')
# 定义2x2池化
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

5.在tensorflow实战数中的tf版本中,需要先将目前不确定值的参数进行占位操作,就是先为其分配内存,但不进行赋值。比如你有1000个数据,但你一次只想处理100个数据,那么就可以placeholder一个100维的位置,在实际操作时循环10次进行。相当于函数的输入参数,在后续op进行run()的时候,如果该op或者该op的前序op需要用到该参数时,要用feed_dict对其进行赋值。

# 定义输入,标签、dropout保留率占位符
x = tf.placeholder(tf.float32, [None, 784])
y_ = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)

6.误差计算:
tf.argmax(y,1)函数是取y中axis=1的那一维的数据中最大值的数据的下标。
tf.equal(a, b)函数是判断a,b中的对应元素是否相等,返回boolean类型。
tf.cast()函数用作类型转换。
tf.reduce_mean()函数用于求均值。

# 定义预测正误判断模型,(模型最大值index,标签最大值index)是否相等
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
# 计算预测准确率,将预测正误判断模型的bool型转化为float32,对其求平均为准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

7.tf.global_variables_initializer()是对variable和get_varialbe得到的参数进行初始化。返回一个op,因为已经指定了默认session,所以可以直接在op上调用run()方法。如果没有variable类型的变量可以不执行该条语句。

# 为variable和get_varialbe得到的参数进行初始化。
tf.global_variables_initializer().run()

8.这点代码中比较困惑我的是第四行和最后一行,不明白为什么一个调用eval()方法,一个调用run()方法。如果不指定默认session,那么都可以通过se.run(x)的方式运行,但是指定了默认se,那么x是tensor类型的就需要用eval()方法来计算x的值,如果x是op类型的话,就需要调用run()方法来运行op以及所有相关op。

for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i % 100 == 0:
        train_accuracy = accuracy.eval({x: batch[0], y_: batch[1], keep_prob: 1})
        print('step{:5d}:train_accuracy={:g}'.format(i, train_accuracy))
    train.run({x: batch[0], y_: batch[1], keep_prob: 0.75})

完整代码

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
# 设置TensorFlowCPU运算优先级
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 导入手写数字输入集
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)

# 定义交互式会话框
sess = tf.InteractiveSession()


# 定义权重函数,截断正态分布
def weight_variable(shape):
    return tf.Variable(tf.truncated_normal(shape, stddev=0.1))


# 定义偏置函数
def bias_variable(shape):
    return tf.Variable(tf.constant(0.1, shape=shape))


# 定义二维卷积
def conv2d(x, w):
    return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')


# 定义2x2池化
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


# 定义输入,标签、dropout保留率占位符
x = tf.placeholder(tf.float32, [None, 784])
y_ = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
# 就输入转化为图像形式
x_image = tf.reshape(x, [-1, 28, 28, 1])
# 第一卷积层,卷积、激活、池化
w_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
# 第二卷积层,卷积、激活、池化
w_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
# 第一全连接层,一维化、线性、激活、dropout
w_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
# 第二全连接层,线性、激活
w_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2)
# 定义损失函数为交叉熵
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
# 使用亚当优化器,最小化交叉熵
train = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# 定义预测正误判断模型,(模型最大值index,标签最大值index)是否相等
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
# 计算预测准确率,将预测正误判断模型的bool型转化为float32,对其求平均为准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# 含有tf.Variable的环境下,因为tf中建立的变量是没有初始化的,也就是在debug时还不是一个tensor量,而是一个Variable变量类型
# 为variable和get_varialbe得到的参数进行初始化。
tf.global_variables_initializer().run()


# 定义训练循环,minibatch size=50,训练keep_prob=0.75,预测keep_prob=1
for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i % 100 == 0:
        train_accuracy = accuracy.eval({x: batch[0], y_: batch[1], keep_prob: 1})
        print('step{:5d}:train_accuracy={:g}'.format(i, train_accuracy))
    train.run({x: batch[0], y_: batch[1], keep_prob: 0.75})


# 使用eval获取test_accuracy
print('test_accuracy=%g' % accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1}))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值