You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tensorflow模型加载后预测结果不随输入图像变化问题求助

TensorFlow图像分类器预测概率不随输入图像变化的问题

我是TensorFlow的新手,最近在搭建一个基于Fashion MNIST的图像分类器,但遇到了一个非常棘手的问题——不管我更换哪张输入图像,通过sess.run()得到的预测概率都完全没有变化。

我已经完成了模型的搭建和训练流程,以下是加载预训练模型并执行预测的核心代码:

def predict():
    train = data.train
    tf.reset_default_graph()
    with tf.Session() as sess:
        new_saver = tf.train.import_meta_graph('~/trained-model.ckpt.meta')
        new_saver.restore(sess, '~/trained-model.ckpt')
        print(tf.get_default_graph().get_name_scope()) # 注释:这里应该包含最后一层的softmax输出
        y_pred = tf.get_default_graph().get_tensor_by_name('y_pred:0')
        X = tf.get_default_graph().get_tensor_by_name('X:0')
        final = imageprepare('tshirts.png')
        final = np.asarray(final)
        final = np.reshape(final,[784,1])
        output_label = sess.run(y_pred, feed_dict={X: final})
        print(output_label)

我尝试替换不同的输入图像(比如换成裤子、鞋子类别的图片),但output_label的结果始终保持一致,完全没有变化。

完整实现代码

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
from PIL import Image, ImageFilter

data = input_data.read_data_sets('data/fashion', source_url='http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/')

# 训练参数
learning_rate = 0.001
num_steps = 500
batch_size = 128
display_step = 10

# 网络参数
num_input = 784  # Fashion MNIST输入维度(28*28像素)
num_classes = 10 # 分类类别数(0-9对应不同服饰)
dropout = 0.75   # Dropout保留概率

# TF图输入
X = tf.placeholder(tf.float32, [None, num_input], name='X')
Y = tf.placeholder(tf.float32, [None, num_classes], name='Y')
keep_prob = tf.placeholder(tf.float32, name='keep_prob') # Dropout参数

# 卷积层封装
def conv2d(x, W, b, strides=1):
    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
    x = tf.nn.bias_add(x, b)
    return tf.nn.relu(x)

# 池化层封装
def maxpool2d(x, k=2):
    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding='SAME')

# 构建卷积神经网络
def conv_net(x, weights, biases, dropout):
    # 将输入reshape为4D张量:[批量大小, 高度, 宽度, 通道数]
    x = tf.reshape(x, shape=[-1, 28, 28, 1])
    # 第一层卷积+池化
    conv1 = conv2d(x, weights['wc1'], biases['bc1'])
    conv1 = maxpool2d(conv1, k=2)
    # 第二层卷积+池化
    conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
    conv2 = maxpool2d(conv2, k=2)
    # 全连接层
    fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])
    fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])
    fc1 = tf.nn.relu(fc1)
    # 应用Dropout
    fc1 = tf.nn.dropout(fc1, dropout)
    # 输出层
    out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])
    return out

# 定义网络权重和偏置
weights = {
    'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
    'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
    'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
    'out': tf.Variable(tf.random_normal([1024, num_classes]))
}

biases = {
    'bc1': tf.Variable(tf.random_normal([32])),
    'bc2': tf.Variable(tf.random_normal([64])),
    'bd1': tf.Variable(tf.random_normal([1024])),
    'out': tf.Variable(tf.random_normal([10]))
}

# 构建模型
logits = conv_net(X, weights, biases, keep_prob)
prediction = tf.nn.softmax(logits, name='y_pred')

# 定义损失函数和优化器
loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
train_op = optimizer.minimize(loss_op)

# 模型评估
correct_pred = tf.equal(tf.argmax(prediction, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

# 初始化变量
init = tf.global_variables_initializer()

# 开始训练
with tf.Session() as sess:
    sess.run(init)
    for step in range(1, num_steps+1):
        batch_x, batch_y = data.train.next_batch(batch_size)
        sess.run(train_op, feed_dict={X: batch_x, Y: batch_y, keep_prob: dropout})
        if step % display_step == 0 or step == 1:
            loss, acc = sess.run([loss_op, accuracy], feed_dict={X: batch_x, Y: batch_y, keep_prob: 1.0})
            print(f"Step {step}, Minibatch Loss= {loss:.4f}, Training Accuracy= {acc:.3f}")
    print("Optimization Finished!")
    # 测试集评估
    print("Testing Accuracy:", sess.run(accuracy, feed_dict={X: data.test.images[:256], Y: data.test.labels[:256], keep_prob: 1.0}))
    # 保存模型
    saver = tf.train.Saver()
    saver.save(sess, '~/trained-model.ckpt')

# 图像预处理函数
def imageprepare(argv):
    im = Image.open(argv).convert('L')
    width = float(im.size[0])
    height = float(im.size[1])
    newImage = Image.new('L', (28, 28), (255)) # 创建28x28的白色画布

    if width > height:
        nheight = int(round((20.0/width*height),0))
        if nheight == 0:
            nheight = 1
        img = im.resize((20,nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wtop = int(round(((28 - nheight)/2),0))
        newImage.paste(img, (4, wtop))
    else:
        nwidth = int(round((20.0/height*width),0))
        if nwidth == 0:
            nwidth = 1
        img = im.resize((nwidth,20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wleft = int(round(((28 - nwidth)/2),0))
        newImage.paste(img, (wleft, 4))

    tv = list(newImage.getdata())
    # 归一化像素值到0-1区间
    tva = [ (255-x)*1.0/255.0 for x in tv]
    return tva

# 预测函数
def predict():
    train = data.train
    tf.reset_default_graph()
    with tf.Session() as sess:
        new_saver = tf.train.import_meta_graph('~/trained-model.ckpt.meta')
        new_saver.restore(sess, '~/trained-model.ckpt')
        print(tf.get_default_graph().get_name_scope())
        y_pred = tf.get_default_graph().get_tensor_by_name('y_pred:0')
        X = tf.get_default_graph().get_tensor_by_name('X:0')
        final = imageprepare('tshirts.png')
        final = np.asarray(final)
        final = np.reshape(final,[784,1])
        output_label = sess.run(y_pred, feed_dict={X: final})
        print(output_label)

我自己排查了一些点:

  • 图像预处理函数imageprepare输出的是长度为784的列表,转换成数组后我reshape成了(784,1),但模型输入X的定义是[None, 784],会不会是输入维度不匹配的问题?
  • 加载模型的时候,有没有遗漏恢复某些必要的张量或者参数?

实在找不到问题所在,恳请各位帮忙分析一下,谢谢!

内容的提问来源于stack exchange,提问作者RACHIT JAIN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:08:31