TensorFlow v1实现猫狗分类训练时报TypeError索引无效问题求解
问题原因
- 直接报错诱因:预处理阶段末尾执行
Y = tf.transpose(Y)、X = tf.transpose(X)后,原本为numpy数组的X、Y被转换为TensorFlow v1的静态图张量,该类型张量不支持直接传入numpy数组作为索引做花式切片,因此你用np.random.choice生成的numpy数组索引idx会触发类型错误。 - 隐藏逻辑错误1:转置后的Y维度为
(3000, 1),但代码仍使用Y[0,idx]做索引,相当于取Y第一行的对应位置,完全不符合按样本索引的需求,即使解决索引类型问题也会出现维度不匹配报错。 - 隐藏逻辑错误2:训练函数中定义的特征维度
D=12880为笔误,64×64×3的展开维度实际为12288,后续会触发矩阵乘法维度不匹配报错。 - 附带警告原因:重复创建
tf.InteractiveSession且未主动释放旧会话资源,触发显存泄漏警告。
修复方案
按以下步骤修改代码即可正常运行:
- 预处理阶段放弃使用
tf.transpose,改用numpy原生转置,保持X、Y为numpy数组类型,支持numpy数组索引 - 修正特征维度D的数值为12288
- 修正Y的索引逻辑,匹配转置后的维度
- 创建会话前先关闭可能存在的旧会话,消除警告
预处理代码修改
将原预处理结尾的转置代码替换为:
# 用numpy原生转置,保持变量为numpy数组 X = X.T Y = Y.T print ("after transpose X shape is {}".format(X.shape)) print ("after transpose Y shape is {}".format(Y.shape))
训练函数修改
修复后的训练函数代码如下:
def tf_train(X, Y, batch_size=20): # 修正特征维度为正确值 D = 12288 x = tf.placeholder(tf.float32, [batch_size, D]) y_ = tf.placeholder(tf.float32, [batch_size, 1]) W = tf.Variable(tf.random_normal([D, 1],stddev=0.1)) z = tf.matmul(x,W) cross_entropy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=z, labels=y_)) train_step = tf.train.GradientDescentOptimizer(1e-2).minimize(cross_entropy) # 先关闭已存在的会话消除警告 if tf.get_default_session() is not None: tf.get_default_session().close() sess = tf.InteractiveSession() tf.initialize_all_variables().run() for epoch in range(3000): idx = np.random.choice(len(TRAIN_DATA), batch_size, replace=False) # 修正索引逻辑,X/Y为numpy数组直接用idx索引 _, l = sess.run([train_step, cross_entropy], feed_dict={x: X[idx], y_: Y[idx]}) if epoch%100 == 0: print('loss: '+str(l))
内容的提问来源于stack exchange,提问作者Jewgah
相关产品推荐
相关产品推荐

