Cifar100 имеет только 16 тренировочных образов и 16 тренировочных ярлыков - PullRequest
0 голосов
/ 25 октября 2019

Я использую Tensorflow с Python 3.7 и пытаюсь создать классификатор изображений с помощью CIFAR-100. Я хочу как можно больше держаться подальше от Keras, потому что у него есть только ограниченное количество наборов данных, которые я могу использовать. Это мой код:

import tensorflow as tf
import tensorflow_datasets as tfds
import numpy as np
import matplotlib.pyplot as plt
import PIL.Image as Image
from tensorflow import keras

tf.compat.v1.enable_eager_execution()

shape = (224, 224)

labels = '/home/pi/tf/cifar_labels.txt'
labels = np.array(open(labels).read().splitlines())

img = '/home/pi/tf/lobster.jpeg'
img = Image.open(img).resize(shape)
img = np.array(img)/255.0
img = np.reshape(img, (224, 224, 3))

train = tfds.load(name="cifar100", split="train")
test = tfds.load(name="cifar100", split="test")

train = train.shuffle(1024).batch(32).prefetch(tf.data.experimental.AUTOTUNE)
test = test.shuffle(1024).batch(32).prefetch(tf.data.experimental.AUTOTUNE)

for features in train:
    train_images, train_labels = features["image"], features["label"]

for features in test:
    test_images, test_labels = features["image"], features["label"]

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(32, 32, 3)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(100, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

history = model.fit(train_images, train_labels, epochs=200, verbose=2)

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

print('\nTest accuracy:', test_acc)

Я предполагаю, что что-то не так с циклом for features in train for. Когда я печатаю len обучающих изображений / этикеток, я получаю 16. Из-за этого моя модель получает точность обучения 0% и потерю 16.1181%. Кто-нибудь может помочь?

Ответы [ 2 ]

0 голосов
/ 27 октября 2019

Для непосредственного использования CIFAR-100 в вашей модели keras вы должны вызвать функцию tfds.load с параметром as_supervised=True. Затем он загрузит набор данных только с клавишами «image» и «label». Вы можете видеть, что набор данных CIFAR-100 содержит три ключа :

FeaturesDict({
    'coarse_label': ClassLabel(shape=(), dtype=tf.int64, num_classes=20),
    'image': Image(shape=(32, 32, 3), dtype=tf.uint8),
    'label': ClassLabel(shape=(), dtype=tf.int64, num_classes=100),
})

Следовательно, он не может быть напрямую введен в model.fit(). Если для as_supervised установлено значение True, возвращенный набор данных будет содержать только ключи (u'image', u'label').

Подводя итог,

import tensorflow_datasets as tfds
from tensorflow import keras

tf.compat.v1.enable_eager_execution()

train= tfds.load(name="cifar100", split="train", as_supervised=True)
test = tfds.load(name="cifar100", split="test", as_supervised=True)


train = train.shuffle(1024).batch(32).prefetch(tf.data.experimental.AUTOTUNE)
test = test.shuffle(1024).batch(32).prefetch(tf.data.experimental.AUTOTUNE)

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(32, 32, 3)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(100, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

history = model.fit(train, epochs=200, verbose=1)

test_loss, test_acc = model.evaluate(test, verbose=1)

print('\nTest accuracy:', test_acc)

Примечание. Чтобы использовать набор данных без as_supervised, установленного в True, вы можете использовать функцию model.train_on_batch. например,

import tensorflow_datasets as tfds
from tensorflow import keras

tf.compat.v1.enable_eager_execution()

train= tfds.load(name="cifar100", split="train")
test = tfds.load(name="cifar100", split="test")


train = train.shuffle(1024).repeat(200).batch(32).prefetch(tf.data.experimental.AUTOTUNE)
test = test.shuffle(1024).batch(32).prefetch(tf.data.experimental.AUTOTUNE)

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(32, 32, 3)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(100, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

for epoch in range(200):
  for features in train:
    image_batch, label_batch = features["image"], features["label"]
    loss, acc = model.train_on_batch(image_batch, label_batch)

for features in test:
  image_batch, label_batch = features["image"], features["label"]
  loss, acc = model.test_on_batch(image_batch, label_batch)

0 голосов
/ 25 октября 2019

Вместо этих строк,

train = tfds.load(name="cifar100", split="train")
test = tfds.load(name="cifar100", split="test")

train = train.shuffle(1024).batch(32).prefetch(tf.data.experimental.AUTOTUNE)
test = test.shuffle(1024).batch(32).prefetch(tf.data.experimental.AUTOTUNE)

for features in train:
    train_images, train_labels = features["image"], features["label"]

for features in test:
    test_images, test_labels = features["image"], features["label"]

мы можем заменить их на:

ds = keras.datasets.cifar100

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

Кстати, я думаю, что эпохи слишком велики, потому что этозанимает очень много времени.

...