TensorFlow Keras的计算机视觉教程运行存在问题

人工智能 2026-07-12

我正通过Tensorflow Keras CV教程开始学习机器学习,其中有两个教程项目运行不正常。

我使用这些教程:
https://www.tensorflow.org/tutorials/load_data/images
https://www.tensorflow.org/tutorials/keras/classification

第一个总是说图片里有蒲公英。即使图片是玫瑰或郁金香也一样。

另一个总是说这是一个包(bag)。即使实际是裤子或T 恤也会这样。

这些项目位于不同的目录中。

flowers.py

import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
import pickle
import pathlib

data_dir = pathlib.Path("C:/Users/admin/.keras/datasets/flower_photos")
image_count = len(list(data_dir.glob('*/*.jpg')))

batch_size = 32
img_height = 180
img_width = 180

train_ds = tf.keras.utils.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

val_ds = tf.keras.utils.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="validation",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

class_names = train_ds.class_names
print(class_names)

normalization_layer = tf.keras.layers.Rescaling(1./255)

normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(normalized_ds))
first_image = image_batch[0]

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

num_classes = 5

model = tf.keras.Sequential([
  tf.keras.layers.Rescaling(1./255),
  tf.keras.layers.Conv2D(32, 3, activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Conv2D(32, 3, activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Conv2D(32, 3, activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(num_classes)
])

model.compile(
  optimizer='adam',
  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
  metrics=['accuracy'])

model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=14
)

model.save('flower_classifier_model.keras')

with open('class_names.pkl', 'wb') as f:
    pickle.dump(class_names, f)

predicting_script.py

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import pickle
from PIL import Image
import pathlib

def predict_flower(image_path, model, class_names, img_height=180, img_width=180):
    """
    Функция для предсказания класса цветка на изображении

    Параметры:
    - image_path: путь к изображению
    - model: загруженная модель
    - class_names: список названий классов
    - img_height, img_width: размер, к которому нужно привести изображение

    Возвращает:
    - predicted_class: предсказанный класс
    - confidence: уверенность модели в процентах
    - all_probabilities: вероятности для всех классов
    """
    img = Image.open(image_path)

    img = img.resize((img_width, img_height))

    img_array = np.array(img) / 255.0

    img_array = np.expand_dims(img_array, axis=0)  # форма становится (1, 180, 180, 3)

    predictions = model.predict(img_array, verbose=0)

    probabilities = tf.nn.softmax(predictions[0]).numpy()

    predicted_index = np.argmax(probabilities)
    predicted_class = class_names[predicted_index]
    confidence = probabilities[predicted_index] * 100

    return predicted_class, confidence, probabilities

with open('class_names.pkl', 'rb') as f:
    class_names = pickle.load(f)

loaded_model = tf.keras.models.load_model('flower_classifier_model.keras')

from os import listdir
from os.path import isfile, join
files = [f for f in listdir("C:/Users/Admin/Documents/Projects/KerasCV_try_1/daisy") if isfile(join("C:/Users/Admin/Documents/Projects/KerasCV_try_1/daisy", f))]

for file in files:
    print(predict_flower(f"daisy/{file}", loaded_model, class_names))

That's for fashion

fashion.py

import tensorflow as tf
import numpy as np
import pickle

fashion_mnist = tf.keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

train_images = train_images / 255.0

test_images = test_images / 255.0

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10)
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=10)

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)

model.save('clothes_classifier_model.keras')

with open('class_names.pkl', 'wb') as f:
    pickle.dump(class_names, f)

test_fashion.py

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import pickle
from PIL import Image
import pathlib

def predict_cloths(image_path, model, class_names, img_height=28, img_width=28):
    img = Image.open(image_path)

    if img.mode == 'RGB':
        img = img.convert('L')

    img = img.resize((img_height, img_width))
    img_array = np.array(img) / 255.0

    img_array = np.expand_dims(img_array, axis=0)

    predictions = model.predict(img_array, verbose=0)

    probabilities = tf.nn.softmax(predictions[0]).numpy()

    predicted_index = np.argmax(probabilities)
    predicted_class = class_names[predicted_index]
    confidence = probabilities[predicted_index] * 100

    return predicted_class, confidence, probabilities

with open('class_names.pkl', 'rb') as f:
    class_names = pickle.load(f)

loaded_model = tf.keras.models.load_model('clothes_classifier_model.keras')

print(predict_cloths("test_image.jpg", loaded_model, class_names))

解决方案

After reviewing your code and the problem and also check the docs from TensorFlow it seems like you have an error in predicting_script.py because you are dividing by 255 manually, but your model already has Rescaling(1./255) as the first layer, i would changed it to something like this

img_array = np.array(img)
img_array = np.expand_dims(img_array, axis=0)

i also have to let you know that both files or projects are overwriting the same class_names.pkl, because flowers.py and fashion.py save to class_names.pkl in the same directory.

So one overwrites the other and your prediction script loads the wrong class names, so either keep them in separate directories or rename them, i did the code for that either

(Just make sure to update your prediction scripts to load the correct file accordingly)

#flowers.py
with open('flower_class_names.pkl', 'wb') as f:
    pickle.dump(class_names, f)

#fashion.py
with open('fashion_class_names.pkl', 'wb') as f:
    pickle.dump(class_names, f)

Finally, after searching a little bit deeper fashion MNIST will not work well with real photos because the model was trained on 28x28 grayscale images with white figures on black background.

Real photos of clothes look very different, so predictions will be unreliable and is basically a limitation of the dataset, not a bug in your code.

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章