TensorFlow中MNIST模型输入转置后结果差异求助
解析MNIST模型输入维度修改后结果差异大的问题
嘿,作为TensorFlow新手碰到这种维度坑太正常了,我来帮你捋清楚为啥两个版本结果差这么大~
首先得明确第一个版本的输入格式[None,784]到底是什么意思:
None代表批量大小,也就是每次喂给模型的样本数量,TensorFlow会自动适配不同的批量;784是每个MNIST样本的特征数(28×28像素展开成一维)。
这是TensorFlow处理批量数据的标准格式——样本维度在前,特征维度在后,大部分内置层(比如全连接层)、损失函数都是基于这个逻辑设计的。
那你改成[784,None]后出问题的核心原因,是把维度完全反过来了:现在是特征在前,样本在后,这和后续所有计算逻辑都不匹配,哪怕你调整了部分矩阵格式,只要有一处没对应上,整个模型的计算就全乱了。
举个具体的例子:
在第一个版本里,全连接层的权重W通常是[784,10],输入x是[None,784],两者矩阵相乘后得到[None,10]——正好对应每个样本的10类输出,和标签的维度完美匹配,损失计算、梯度传播都能正常工作。
但如果改成输入[784,None],你只调整输入维度是不够的:
- 权重
W的维度得改成[10,784],才能和输入做矩阵乘法(矩阵乘法要求前一个的列数等于后一个的行数); - 相乘后得到的是
[10,None],这时候需要转置成[None,10],才能和[None]形状的标签匹配; - 偏置
b的维度也得改成[10,1],才能和[10,None]的结果做加法; - 要是这些细节没改全,要么会直接报错,要么损失计算完全错误,模型根本学不到任何有效特征,结果自然和第一个版本天差地别。
如果你非要尝试这种维度布局,这里给你一段修正后的核心代码参考:
import tensorflow as tf import tensorflow.examples.tutorials.mnist.input_data as input_data mnist = input_data.read_data_sets("./MNIST_data/", one_hot=False) # 输入维度改为[784, None],标签保持[None] x = tf.placeholder(tf.float32, shape=[784, None]) y_ = tf.placeholder(tf.int32, shape=[None]) # 调整权重和偏置的维度 W = tf.Variable(tf.truncated_normal([10, 784], stddev=0.1)) b = tf.Variable(tf.constant(0.1, shape=[10, 1])) # 计算logits并转置到样本在前的格式 logits = tf.matmul(W, x) + b # 此时shape是[10, None] logits = tf.transpose(logits) # 转置后shape为[None, 10] # 损失计算与优化 loss = tf.reduce_mean(tf.sparse_categorical_crossentropy(labels=y_, logits=logits)) train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss) # 准确率计算 correct_prediction = tf.equal(tf.argmax(logits, 1), tf.cast(y_, tf.int64)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 训练流程 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for i in range(1000): batch_xs, batch_ys = mnist.train.next_batch(100) # 注意这里要把batch_xs转置成[784, 100]再喂进去 sess.run(train_step, feed_dict={x: batch_xs.T, y_: batch_ys}) if i % 100 == 0: acc = sess.run(accuracy, feed_dict={x: mnist.test.images.T, y_: mnist.test.labels}) print(f"Step {i}, Test Accuracy: {acc:.4f}")
新手阶段建议先老老实实遵循[批量大小, 特征数]的标准格式,等你对张量维度、矩阵运算逻辑熟悉之后,再尝试自定义维度布局会更稳妥~
内容的提问来源于stack exchange,提问作者Junchao Chen
相关产品推荐
相关产品推荐

