Я не могу добавлять метки к своим обучающим данным

#python #numpy #tensorflow #keras

#python #тупой #тензорный поток #keras

Вопрос:

Когда я добавляю свои метки, я получаю 20580 для длины y, когда я надеюсь получить 120, что соответствует количеству категорий. Как я могу добавить категории к своим меткам?

 import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
import random as rand
import time

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Activation, Dropout, Flatten, MaxPooling2D
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.keras.optimizers import Adam

config = tf.compat.v1.ConfigProto(gpu_options=tf.compat.v1.GPUOptions(allow_growth=True))
sess = tf.compat.v1.Session(config=config)

DATADIR = "C:/Users/samue/Documents/Datasets/DogBreeds/images/Images"
CATEGORIES = os.listdir("C:/Users/samue/Documents/Datasets/DogBreeds/images/Images")

IMG_SIZE = 100

training_data = []



def create_training_data():
    for category in CATEGORIES:
        path = os.path.join(DATADIR, category)
        class_num = CATEGORIES.index(category)
        for img in os.listdir(path):
            try:
                img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)
                new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
                training_data.append([new_array, class_num])
            except Exception as e:
                pass
create_training_data()

rand.shuffle(training_data)

X = []
y = []

for features, label in training_data:
    X.append(features)
    y.append(label)

X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
y = np.array(y).reshape(-1,)

print(len(CATEGORIES))
print(len(X))
print(len(y))

 

Результаты, которые я получаю в конце, следующие:
120
20580
20580

Комментарии:

1. Судя по всему, у вас есть 20 580 точек данных, в X (входном массиве) и y (целевом массиве) должно быть одинаковое количество элементов. Почему вы ожидаете y , что у вас будет только 120 элементов?

2. Хорошо, я объясню, что, по моему мнению, должно произойти, возможно, у меня полное непонимание функций и меток. Я пытаюсь построить модель машинного обучения. Насколько я понимаю, объекты (X) — это ваши точки данных или фотографии в данном случае, а метки (y) — это разные группы, в которые вы хотите поместить точки данных. Поэтому, если мой набор данных содержит 120 категорий, мне потребуется 120 меток для соответствия. так ли это работает?

Ответ №1:

Я думаю, вам следует немного отступить от деталей реализации или даже этой конкретной проблемы, чтобы попытаться понять, что происходит. В классификации изображений цель состоит в том, чтобы классифицировать входные данные, тензор 2D или — 3D, если это многоканальное изображение, путем присвоения ему метки. Количество меток конечно, вы можете классифицировать только определенное количество классов.

Чтобы привести пример, давайте возьмем MNIST базу данных. Это хорошо известный фиктивный набор данных, используемый для задач классификации изображений. В обучающем наборе имеется 60 1x28x28 000 изображений, представляющих рукописные цифры. Вообще говоря, цель этого набора данных — правильно классифицировать каждое изображение до 10 меток. Метки соответствуют числам «0», «1», «2», …, и так далее до «9». Итак, вопрос в данном конкретном случае задается изображением X, моя модель должна предсказать класс для этого изображения: либо «0», «1», …, или «9», есть только 10 возможностей. В обучении под наблюдением мы используем метки для обучения модели. Для любого заданного ввода нам нужно знать основную истину, то есть реальный класс, к которому принадлежит этот ввод. Таким образом, в свою очередь, вы получаете столько входных данных, сколько есть меток: потому что каждому присваивается своя собственная метка, независимо от количества уникальных возможных меток.

В вашем случае использования кажется, что вы работаете в общей сложности с 120 классами и 20 580 изображениями. Это 20,580 уникальные входные данные. Помните, что нам нужно иметь для каждого из этих изображений соответствующую базовую истину: реальный класс, к которому принадлежит это изображение. Поэтому, естественно, в итоге у вас также будет 20 580 меток.

Возможно, это было источником вашей путаницы: в моих собственных терминах label отличается от class . Набор классов — это уникальный набор объектов (животные, цифры, …), в то время как метка ссылается на определенный класс внутри набора классов.

Ответ №2:

Я думаю, вы немного сбиты с толку. У вас должен быть набор данных, состоящий из 120 классов. Для каждого из этих классов вам нужны изображения, характерные для этого класса. Например, предположим, что вы создаете классификатор для различения изображений собак и изображений кошек. Итак, у вас есть 2 класса. Вы можете структурировать свои каталоги следующим образом

 source_dir
----------cats_dir
------------------cats first image
------------------cats second images

------------------cats nth image

----------dogs_dir
------------------dogs first image
------------------dogs second image

------------------dogs m th image
 

Для вашего случая у вас будет 120 подкаталогов (каталогов классов) под source_dir, и каждый из них должен содержать изображения, связанные с классом. В вашем случае может показаться, что у вас всего 20580 изображений. Если они распределены равномерно, у вас есть примерно 171 изображение для каждого класса. Теперь вы хотите использовать эти изображения для обучения CNN. Вы можете сделать это так, как вы действовали, однако я не рекомендую этого делать, потому что в конечном итоге вы сразу поместите все 20580 изображений 100 X 100 в память. Это займет очень большую память, и вы, вероятно, получите ошибку ООМ (нехватка памяти). Способ решения этой проблемы — передавать данные в вашу модель пакетами. Например, 32 изображения одновременно. Теперь Keras имеет полезные функции, которые помогут вам в этом. Если у вас есть структура каталогов, как показано выше, вы можете использовать ImageDataGenerator.flow_from_directory для пакетной загрузки ваших изображений в модель. Документация здесь . Эта функция также позволяет вам использовать увеличение изображения, чтобы помочь расширить разнообразие вашего набора данных. Ниже приведен код, который я рекомендую для примера классификации собак / кошек, о которой я упоминал выше.

 source_dir-r'c:tempcats_and_dogs'
v_split=.2 # set this to determine the percentage of data to allocate to the validation set
data_gen=ImageDataGenerator(rescale=1/255,validation_split=v_split)
train_gen=data_gen.flow_from_directory(source_dir, target_size=(100,100),
                                       class_mode='categorical', batch_size=32,
                                       subset='training', color_mode='grayscale)
valid_gen=data_gen.flow_from_directory(source_dir, target_size=(100,100),
                                       class_mode='categorical', batch_size=32,
                                       subset='validation', color_mode='grayscale, shuffle=False)
 

при компиляции вашей модели set loss=’categorical_crossentropy’ .
вы можете использовать два приведенных выше генератора в качестве входных данных для model.fit