Błąd typu: argument float() musi być liczbą lub ciągiem znaków, a nie 'BatchDataset' przy zwiększeniu danych za pomocą fit_generator()

0

Pytanie

Mam problem z użyciem powiększenia danych w szkoleniu modelu. W szczególności, o zastosowaniu metody fit_generator ().

Początkowo z powodzeniem uruchomił swój model bez powiększenia za pomocą metody fit (), jednak, zdaniem innych, zaleca się korzystać z fit_generator(). Wygląda na to, że obie metody wymagają tego samego wejścia, jeśli chodzi o zdjęcia i etykiet, ale po uruchomieniu kodu poniżej, otrzymuję następujący BŁĄD:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_35/139227558.py in <module>
    105 
    106 # train the network
--> 107 model.fit_generator(aug.flow(train_ds,  batch_size=batch_size),
    108         validation_data=val_ds, steps_per_epoch=len(train_ds[0]) // batch_size,
    109     epochs=epochs)

/opt/conda/lib/python3.7/site-packages/keras/preprocessing/image.py in flow(self, x, y, batch_size, shuffle, sample_weight, seed, save_to_dir, save_prefix, save_format, subset)
    894         save_prefix=save_prefix,
    895         save_format=save_format,
--> 896         subset=subset)
    897 
    898   def flow_from_directory(self,

/opt/conda/lib/python3.7/site-packages/keras/preprocessing/image.py in __init__(self, x, y, image_data_generator, batch_size, shuffle, sample_weight, seed, data_format, save_to_dir, save_prefix, save_format, subset, dtype)
    472         save_format=save_format,
    473         subset=subset,
--> 474         **kwargs)
    475 
    476 

/opt/conda/lib/python3.7/site-packages/keras_preprocessing/image/numpy_array_iterator.py in __init__(self, x, y, image_data_generator, batch_size, shuffle, sample_weight, seed, data_format, save_to_dir, save_prefix, save_format, subset, dtype)
    119                     y = y[split_idx:]
    120 
--> 121         self.x = np.asarray(x, dtype=self.dtype)
    122         self.x_misc = x_misc
    123         if self.x.ndim != 4:

/opt/conda/lib/python3.7/site-packages/numpy/core/_asarray.py in asarray(a, dtype, order)
     81 
     82     """
---> 83     return array(a, dtype, copy=False, order=order)
     84 
     85 

TypeError: float() argument must be a string or a number, not 'BatchDataset'

Ukończyłem google, próbując naprawić TypeError: argument float() musi być liczbą lub ciągiem znaków, a nie błędem "BatchDataset", ale bezskutecznie. Czy ktoś ma jakieś sugestie, jak iść dalej?

import pathlib
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt

# Set data directory
data_dir = pathlib.Path("../input/validatedweaponsv6/images/")

# Set image size
img_height = 120
img_width = 120

# Hyperparameters
batch_size = 128
epochs = 50
learning_rate = 0.001

# Create the training dataset
train_ds = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    label_mode='categorical',
    validation_split=0.2,
    subset="training",
    shuffle=True,
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# Create the validation dataset
val_ds = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    label_mode='categorical',
    validation_split=0.2,
    subset="validation",
    shuffle=True,
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# Create sequential model
model = Sequential([

    # Preprocessing
    layers.Rescaling(1./127.5, offset=-1,
                     input_shape=(img_height, img_width, 3)),

    # Encoder
    layers.Conv2D(8, 3, activation='relu'),
    layers.MaxPooling2D(),
    layers.Conv2D(16, 3, activation='relu'),
    layers.MaxPooling2D(),
    layers.Conv2D(32, 3, activation='relu'),
    # layers.Conv2D(2, 3, activation='relu'), ???
    layers.Flatten(),

    # Decoder
    layers.Dense(64, activation='relu'),
    layers.Dropout(0.5),
    layers.Dense(2, activation='softmax')
])

# Print the model to see the different output shapes
print(model.summary())

# Compile model
model.compile(loss='categorical_crossentropy',
              optimizer=keras.optimizers.SGD(learning_rate=learning_rate), metrics=['accuracy'])

# construct the training image generator for data augmentation
aug = tf.keras.preprocessing.image.ImageDataGenerator(rotation_range=20, zoom_range=0.15,
    width_shift_range=0.2, height_shift_range=0.2, shear_range=0.15,
    horizontal_flip=True, fill_mode="nearest")

# train the network
model.fit_generator(aug.flow(train_ds,  batch_size=batch_size),
validation_data=val_ds, steps_per_epoch=len(train_ds[0]) // batch_size,
epochs=epochs)

# Print scores
score = model.evaluate(train_ds, verbose=0)
print('Validation loss:', score[0])
print('Validation accuracy:', score[1])

# Show loss and accuracy models
show_history(history)

Dziękuję, że obejrzeli mój post! :)

deep-learning keras tensorflow
2021-11-19 13:25:05
1

Najlepsza odpowiedź

0

Po pierwsze, artykuł, na które się powoływali, 3 lata i jest trochę przestarzały. Od tensorflow 2.1.0, metoda .fit bierze również generatory, i w chwili obecnej jest on w pełni zastąpić .fit_generator. Proponuję zaktualizować swój тензорный strumień, jeśli to możliwe.

Po drugie, błąd, najwyraźniej, nie w metodzie fit_generator, a w tym, jak można zdefiniować zestawy danych. Oni po prostu najpierw dzwonili fit_generator, i dlatego komunikat o błędzie śledzić cię tam.

Co do samego błędu, nie rozumiem, na czym polega gniazdować generatorów, i myślę, że może to spowodować problemy tutaj. Próbujesz przekazać пакетированный zbiór danych uzyskany z katalogu tf.keras.utils.image_dataset_from_directory, drugiego generatora, co wydaje się niemożliwe.

Jeśli dobrze zrozumiałem, masz tylko jeden znacznik na każdym obrazie, i zdjęcia każdej klasy są przechowywane w oddzielnych folderach, więc proponuję użyć metody flow_from_directory tf.keras.preprocessing.image.Bezpośrednio procesor obrazów. Ten generator będzie zarówno odczytywać, jak i uzupełnienia obrazu, więc można usunąć część katalogu tf.keras.utils.image_dataset_from_directory.

Aby użyć tego generatora, trzeba mieć zdjęcia w postaci:

  • katalog główny
    • folder class1
    • folder klasa2
    • itp.

i twój kod będzie mniej więcej tak:

gen = tf.keras.preprocessing.image.ImageDataGenerator( #desired augmentation, ...) 
train_generator = gen.flow_from_directory(directory = root_directory,
target_size=(256, 256), classes= *list of class names*,
class_mode='categorical', batch_size=32, shuffle=True, ...)
model.fit(train_generator, ...)

Można również przekazać argument "validation_split", aby uzyskać poszczególne zestawy danych dla nauki i sprawdzania. Więcej informacji o metodzie ImageDataGenerator i flow_from_directory czytaj w oficjalnej dokumentacji.

2021-11-19 18:51:15

W innych językach

Ta strona jest w innych językach

Русский
..................................................................................................................
Italiano
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................