TensorFlow_CNN内tf.nn.conv2d和tf.layers.conv2d参数

 1 tf.nn.conv2d(
 2     input,
 3     filter,
 4     strides,
 5     padding,
 6     use_cudnn_on_gpu=True,
 7     data_format='NHWC',
 8     dilations=[1, 1, 1, 1],
 9     name=None
10 )

input:输入数据

filter:过滤器

strides:卷积滑动步长,实际上可以解释为过滤器的大小

padding:图像边填充方式

--------------------------------------------------------------------------------------------->

在这里详细地对各个参数做出解释:

input:就是卷积的输入数据,该输入数据要求是一个Tensor,所以张量的shape为[batch, in_height, in_width, in_channels],batch为训练 [ 一个 ] batch图片数量,这是一个四维向量,所以类型为halfbfloat16float32, float64.

filter:为一个张量,必须和input是一样的4D shape。[filter_height, filter_width, in_channels, out_channels],参数的第三维就是input内的第四维

padding:整数型的列表,只有“SAME”和“VALID”两个值,在这里SAME和VALID的计算需要说明一下

1 #“SAME” 计算方式
2 out_height = ceil(float(in_height)) / float(strides[1]) 
3 out_width = ceil(float(in_width)) / float(strides[2]) 
4 
5 #“VALID”计算方式
6 out_height = ceil(float(in_height - filter_height + 1)) / float(strides[1]) 
7 out_width = ceil(float(in_width - filter_width + 1)) / float(strides[2]) 

strides:在这里直接参考官方API吧。很详细!  

 1 tf.layers.conv2d(
 2     inputs,
 3     filters,
 4     kernel_size,
 5     strides=(1, 1),
 6     padding='valid',
 7     data_format='channels_last',
 8     dilation_rate=(1, 1),
 9     activation=None,
10     use_bias=True,
11     kernel_initializer=None,
12     bias_initializer=tf.zeros_initializer(),
13     kernel_regularizer=None,
14     bias_regularizer=None,
15     activity_regularizer=None,
16     kernel_constraint=None,
17     bias_constraint=None,
18     trainable=True,
19     name=None,
20     reuse=None
21 )

根据官方API文档说明,tf.layer.con2d的input和padding与tf.nn.conv2d一样。

但也有其它差别:

在这里filter为一个整数,该整数的数量为卷积数量 >>>整数,表示输出空间的维数(即卷积过滤器的数量)。

kernel_size,可以是一个整数,或list或tuple类型的两个整数。

strides:一个整数,或者包含了两个整数的元组/队列,表示卷积的纵向和横向的步长。如果是一个整数,则横纵步长相等。另外, strides不等于1 和 dilation_rate 不等于1 这两种情况不能同时存在。

转载于:https://www.cnblogs.com/AlexHaiY/p/9342384.html

import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets("MNIST_data/", one_hot=True)def weight_variable(shape): initial = tf.truncated_normal(shape, stddev=0.1) return tf.Variable(initial)def bias_variable(shape): initial = tf.constant(0.1, shape=shape) return tf.Variable(initial)def conv2d(x, W): return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')def max_pool_2x2(x): return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')W_conv1 = weight_variable([5, 5, 1, 32])b_conv1 = bias_variable([32])x_image = tf.reshape(x, [-1,28,28,1])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)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)keep_prob = tf.placeholder("float")h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)W_fc2 = weight_variable([1024, 10])b_fc2 = bias_variable([10])y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv)) #交叉熵损失#定义优化策略:采用Adam优化算法,以0.0001的学习率进行最小化损失操作train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) #判断预测值与标签是否相等,返回一个布尔值correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) #将布尔值转化为数值,计算平均准确率sess.run(tf.initialize_all_variables()) #变量初始化for i in range(20000): #在循环中实现参数更新 batch = mnist.train.next_batch(50) #batch size为50,每次获取50张数据 if i%100 == 0: #每100次在屏幕打印一次信息 train_accuracy = accuracy.eval(feed_dict={ x:batch[0], y_: batch[1], keep_prob: 1.0}) #将数据填入占位符,喂给网络 print "step %d, training accuracy %g"%(i, train_accuracy) #输出迭代次数测试训练的准确率 train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})print "test accuracy %g"%accuracy.eval(feed_dict={ x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}) 改进他,让他能运行
最新发布
05-14
<think>嗯,用户的问题是关于如何修复优化TensorFlow实现的MNIST手写数字识别的CNN代码,使其能正确运行。首先,我需要回顾用户提供的引用内容,看看里面有哪些有用的信息。 用户引用了几个资料,其中提到了TensorFlow的卷积层、池化层的实现,以及LeNet模型的结构,还有MNIST数据集的加载方式。比如引用[2][3]中提到了导入MNIST数据使用卷积层、池化层的代码示例。而引用[4]提到了使用tf.layers模块的高层API,这可能对简化代码有帮助。引用[5]则是一些修改建议,可能涉及图像处理的调整,但用户的问题是关于MNIST,所以可能这部分参考价值不大。 首先,用户的问题可能是代码无法运行,需要修复错误。常见的MNIST代码问题可能包括数据加载不正确、TensorFlow版本不兼容、层定义错误、输入形状不匹配等。比如在引用[3]中,用户使用了tf.Variable来手动创建权重,而高版本的TensorFlow可能推荐使用Keras层或者tf.layers,这样更容易出错,尤其是在输入形状的处理上。例如,输入数据是否需要reshape成四维张量(batch, height, width, channels)? 然后,用户提到优化代码。可能的优化点包括使用更现代的API如tf.keras,添加正则化、dropout,数据增强,学习率调整等。比如引用[4]中的tf.layers模块提供的高级API,可以简化卷积层池化层的创建。另外,数据预处理是否正确,比如归一化,MNIST像素值范围是0-255,通常需要归一化到0-1。 接下来,我需要考虑用户可能的代码结构。比如,用户是否使用了旧版的tf.Sessionplaceholder,而新版的TensorFlow推荐使用Eager Execution或者tf.function。例如,在引用[2]中,使用了input_data.read_data_sets,这可能在新版本中已经被弃用,应该改用tf.keras.datasets.mnist.load_data()。 此外,引用[3]中的代码可能存在问题,比如使用tf.Variable来手动定义卷积核,而更高效的方式是使用tf.keras.layers.Conv2D。手动定义容易出错,比如strides的格式是否正确,padding是否合适,以及激活函数是否正确应用。 另一个可能的问题是输入数据的形状。MNIST原始数据是28x28的灰度图,通道数为1,所以在输入卷积层时需要reshape成(batch_size, 28, 28, 1)。例如,在引用[3]中,用户使用了x_data = tf.reshape(x, shape=[-1,28,28,1]),但如果输入层没有正确处理这个reshape,可能会导致错误。 此外,池化层的参数是否正确,比如ksizestrides的维度是否正确。例如,在引用[3]中,ksize=[1,2,2,1],这可能是正确的,因为max_pool的ksize通常是四维的[batch, height, width, channels],而通常batchchannels设为1,不进行池化。 优化方面,可能要考虑添加BatchNormalization层,使用更好的优化器如Adam,添加Dropout层防止过拟合。例如,在引用[4]中提到tf.layers.densedropout层,这些都是常用的优化手段。 另外,模型的编译步骤是否正确,比如损失函数是否使用交叉熵,优化器的学习率是否合适,以及是否正确处理了one-hot编码的标签。例如,在分类问题中,输出层的激活函数应为softmax,损失函数为sparse_categorical_crossentropy(如果标签是整数)或者categorical_crossentropy(如果是one-hot编码)。 还需要检查训练循环是否正确,比如是否进行了正确的批次训练,是否在会话中正确初始化变量(如果使用旧版TF),或者是否使用了model.fit(如果使用Keras)。 综上所述,修复优化的步骤可能包括: 1. 更新数据加载方式,使用tf.keras.datasets.mnist。 2. 数据预处理,归一化并reshape。 3. 使用Keras API构建模型,简化层定义。 4. 添加正则化、BatchNorm、Dropout等优化。 5. 确保输入形状正确。 6. 使用合适的优化器学习率调度。 7. 检查模型编译训练循环是否正确。 同时,用户可能需要处理版本兼容性问题,例如,旧代码中使用tf.placeholdertf.Session,而新版本中推荐使用Eager Execution。如果用户使用的是TensorFlow 2.x,则需要使用tf.compat.v1来兼容旧代码,或者迁移到新的Keras接口。 例如,在引用[3]中的代码可能使用了tf.Variable_scopetf.nn.conv2d,这属于低级API,容易出错。改用tf.keras.layers.Conv2D会更简洁,减少错误。 另外,检查是否有错误提示,比如输入形状不匹配,或者未初始化变量等。例如,如果在构建卷积层时,输入通道数与权重定义的通道数不一致,会导致错误。比如,MNIST的输入是单通道,所以卷积核的第三个维度应该是1,如[5,5,1,32]是否正确? 在优化方面,可以建议使用数据增强,如图像旋转、缩放,虽然MNIST比较简单,但可能提升泛化能力。或者调整网络结构,增加卷积层深度,使用更深的网络如类似LeNet-5的结构。 最后,确保代码的各个部分正确衔接,比如模型输出与损失函数的匹配,评估指标的正确性等。</think>以下是根据TensorFlow 2.x最佳实践修复优化MNIST卷积神经网络代码的步骤: ### 一、数据预处理优化 ```python import tensorflow as tf # 加载数据集并标准化 (train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data() train_images = train_images.reshape(-1,28,28,1).astype('float32') / 255.0 test_images = test_images.reshape(-1,28,28,1).astype('float32') / 255.0 # 转换标签格式 train_labels = tf.keras.utils.to_categorical(train_labels, 10) test_labels = tf.keras.utils.to_categorical(test_labels, 10) ``` ### 二、模型架构改进(使用Keras API) ```python model = tf.keras.Sequential([ # 卷积层+批归一化 tf.keras.layers.Conv2D(32, (5,5), activation='relu', input_shape=(28,28,1), padding='same', kernel_regularizer=tf.keras.regularizers.l2(0.001)), tf.keras.layers.BatchNormalization(), # 池化层 tf.keras.layers.MaxPooling2D((2,2)), # 添加Dropout防止过拟合 tf.keras.layers.Dropout(0.25), # 第二卷积层 tf.keras.layers.Conv2D(64, (3,3), activation='relu', padding='same', kernel_regularizer=tf.keras.regularizers.l2(0.001)), tf.keras.layers.BatchNormalization(), # 全局平均池化替代全连接层 tf.keras.layers.GlobalAveragePooling2D(), # 输出层 tf.keras.layers.Dense(10, activation='softmax') ]) ``` ### 三、训练配置优化 ```python # 自定义学习率调度 lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate=0.001, decay_steps=10000, decay_rate=0.96) # 编译模型 model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=lr_schedule), loss='categorical_crossentropy', metrics=['accuracy']) # 添加早停机制 early_stop = tf.keras.callbacks.EarlyStopping( monitor='val_accuracy', patience=5, restore_best_weights=True) # 训练模型 history = model.fit( train_images, train_labels, epochs=30, batch_size=128, validation_split=0.2, callbacks=[early_stop]) ``` ### 四、模型评估 ```python test_loss, test_acc = model.evaluate(test_images, test_labels) print(f'测试集准确率:{test_acc:.4f}') ``` ### 改进要点说明: 1. **数据预处理**:使用官方API加载数据,自动处理one-hot编码[^2],添加reshape操作适配卷积层输入要求[^3] 2. **模型架构**: - 使用Keras顺序API简化层定义 - 添加批归一化层加速训练收敛[^4] - 采用全局平均池化代替全连接层减少参数量 - 添加L2正则化防止过拟合 3. **训练优化**: - 指数衰减学习率平衡训练稳定性与收敛速度 - 早停机制避免无效训练 - 使用Adam优化器自适应调整学习率 4. **版本兼容性**:完全基于TensorFlow 2.x实现,确保代码可维护性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值