tf.data.Dataset: Das Argument `batch_size` darf für den angegebenen Eingabetyp nicht angegeben werden

10

Ich verwende Talos und Google Colab TPU , um die Hyperparameter- Optimierung eines Keras- Modells durchzuführen . Beachten Sie, dass ich Tensorflow 1.15.0 und Keras 2.2.4-tf verwende.

import os
import tensorflow as tf
import talos as ta
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import train_test_split

def iris_model(x_train, y_train, x_val, y_val, params):

    # Specify a distributed strategy to use TPU
    resolver = tf.contrib.cluster_resolver.TPUClusterResolver(tpu='grpc://' + os.environ['COLAB_TPU_ADDR'])
    tf.contrib.distribute.initialize_tpu_system(resolver)
    strategy = tf.contrib.distribute.TPUStrategy(resolver)

    # Use the strategy to create and compile a Keras model
    with strategy.scope():
      model = Sequential()
      model.add(Dense(32, input_shape=(4,), activation=tf.nn.relu, name="relu"))
      model.add(Dense(3, activation=tf.nn.softmax, name="softmax"))
      model.compile(optimizer=Adam(learning_rate=0.1), loss=params['losses'])

    # Convert data type to use TPU
    x_train = x_train.astype('float32')
    x_val = x_val.astype('float32')

    dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    dataset = dataset.cache()
    dataset = dataset.shuffle(1000, reshuffle_each_iteration=True).repeat()
    dataset = dataset.batch(params['batch_size'], drop_remainder=True)

    # Fit the Keras model on the dataset
    out = model.fit(dataset, batch_size=params['batch_size'], epochs=params['epochs'], validation_data=[x_val, y_val], verbose=0, steps_per_epoch=2)

    return out, model

# Load dataset
X, y = ta.templates.datasets.iris()

# Train and test set
x_train, x_val, y_train, y_val = train_test_split(X, y, test_size=0.30, shuffle=False)

# Create a hyperparameter distributions 
p = {'losses': ['logcosh'], 'batch_size': [128, 256, 384, 512, 1024], 'epochs': [10, 20]}

# Use Talos to scan the best hyperparameters of the Keras model
scan_object = ta.Scan(x_train, y_train, params=p, model=iris_model, experiment_name='test', x_val=x_val, y_val=y_val, fraction_limit=0.1)

Nach dem Konvertieren des Zugsatzes in einen Datensatz mit tf.data.Datasetwird beim Anpassen des Modells mit Folgendes angezeigt out = model.fit:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-c812209b95d0> in <module>()
      8 
      9 # Use Talos to scan the best hyperparameters of the Keras model
---> 10 scan_object = ta.Scan(x_train, y_train, params=p, model=iris_model, experiment_name='test', x_val=x_val, y_val=y_val, fraction_limit=0.1)

8 frames
/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/training.py in _validate_or_infer_batch_size(self, batch_size, steps, x)
   1813             'The `batch_size` argument must not be specified for the given '
   1814             'input type. Received input: {}, batch_size: {}'.format(
-> 1815                 x, batch_size))
   1816       return
   1817 

ValueError: The `batch_size` argument must not be specified for the given input type. Received input: <DatasetV1Adapter shapes: ((512, 4), (512, 3)), types: (tf.float32, tf.float32)>, batch_size: 512

Wenn ich dann diesen Anweisungen folge und das Argument für die Stapelgröße nicht auf setze model.fit. Ich erhalte einen weiteren Fehler in:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-c812209b95d0> in <module>()
      8 
      9 # Use Talos to scan the best hyperparameters of the Keras model
---> 10 scan_object = ta.Scan(x_train, y_train, params=p, model=iris_model, experiment_name='test', x_val=x_val, y_val=y_val, fraction_limit=0.1)

8 frames
/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/training.py in _distribution_standardize_user_data(self, x, y, sample_weight, class_weight, batch_size, validation_split, shuffle, epochs, allow_partial_batch)
   2307             strategy) and not drop_remainder:
   2308           dataset_size = first_x_value.shape[0]
-> 2309           if dataset_size % batch_size == 0:
   2310             drop_remainder = True
   2311 

TypeError: unsupported operand type(s) for %: 'int' and 'NoneType'
Sami Belkacem
quelle
Für diesen letzten Fehler wäre es hilfreich, wenn Sie einen gesamten Stack-Trace veröffentlichen könnten, da diese Funktion an einer Reihe von Stellen in dieser Datei aufgerufen zu werden scheint. Daher
mdaoust
Ich habe gerade die Frage bearbeitet. Sie können die Stapelverfolgung überprüfen. Vielen Dank für Ihre Zeit und Ihre Überlegung.
Sami Belkacem

Antworten:

0

vom Github-Code :

ValueError wird ausgelöst, wenn xes sich um einen Generator oder eine SequenceInstanz handelt, und batch_sizewird so angegeben, wie wir erwarten, dass Benutzer Batch-Datasets bereitstellen.

Versuchen Sie es mit batch_size = None

Ioannis Nasios
quelle
Ich erhalte einen weiteren Fehler in _distribution_standardize_user_data (self, x, y, sample_weight, class_weight, batch_size, validation_split, shuffle, epochs, allow_partial_batch) TypeError: Nicht unterstützte Operandentypen für *: 'NoneType' und 'int
Sami Belkacem
Sie sollten auch step_per_epoch = None
Ioannis Nasios
Es funktioniert nicht, ich erhalte einen weiteren Fehler: ValueError: Versuch, einen Wert (None) mit einem nicht unterstützten Typ (<class 'NoneType'>) in einen Tensor zu konvertieren. Ich denke, Sie können den Fehler leicht reproduzieren, indem Sie das kurze Programm kopieren
Sami Belkacem
0

Ich bin mir nicht sicher, ob das Folgende zu Ihrer Rechnung passt, aber etwas zum Ausprobieren. Alles, was ich getan habe, ist die Wiederholung () aus dem Datensatz und batch_size = params ['batch_size'] aus model.fit zu entfernen

Wenn das oben Genannte nicht das ist, was Sie zu opfern bereit sind, ignorieren Sie bitte den Beitrag.

import os
import tensorflow as tf
import talos as ta
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

def iris_model(x_train, y_train, x_val, y_val, params):

    # Specify a distributed strategy to use TPU
    resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='grpc://' + os.environ['COLAB_TPU_ADDR'])
    tf.config.experimental_connect_to_host(resolver.master())
    tf.tpu.experimental.initialize_tpu_system(resolver)
    strategy = tf.distribute.experimental.TPUStrategy(resolver)

    with strategy.scope():
        model = Sequential()
        model.add(Dense(32, input_dim=4, activation=params['activation']))
        model.add(Dense(3, activation='softmax'))
        model.compile(optimizer=params['optimizer'], loss=params['losses'])

    # Convert the train set to a Dataset to use TPU
    dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    dataset = dataset.cache().shuffle(1000, reshuffle_each_iteration=True).batch(params['batch_size'], drop_remainder=True)

    out = model.fit(dataset, epochs=params['epochs'], validation_data=[x_val, y_val], verbose=0)

    return out, model

x, y = ta.templates.datasets.iris()

p = {'activation': ['relu', 'elu'],
       'optimizer': ['Nadam', 'Adam'],
       'losses': ['logcosh'],
       'batch_size': (20, 50, 5),
       'epochs': [10, 20]}

scan_object = ta.Scan(x, y, model=iris_model, params=p, fraction_limit=0.1, experiment_name='first_test')
Amit
quelle
Es funktioniert nicht: TypeError: Nicht unterstützte Operandentypen für *: 'NoneType' und 'int'
Sami Belkacem
0

Dieser zweite Fehler tritt auf _distribution_standardize_user_data, wenn Sie die batch_sizePassform nicht bestehen .

Der Code, den Sie für diese Funktion ausführen, ist hier:

https://github.com/tensorflow/tensorflow/blob/r1.15/tensorflow/python/keras/engine/training.py#L2192

Sie haben kein Trace-Back gepostet, aber ich wette, es schlägt in Zeile 2294 fehl , da dies der einzige Ort batch_sizeist, an dem etwas multipliziert wird.

if shuffle:
          # We want a buffer size that is larger than the batch size provided by
          # the user and provides sufficient randomness. Note that larger
          # numbers introduce more memory usage based on the size of each
          # sample.
          ds = ds.shuffle(max(1024, batch_size * 8))

Es sieht so aus, als könnten Sie es durch Einstellen ausschalten shuffle=False.

fit(ds, shuffle=False,...)

Funktioniert es?

mdaoust
quelle
Danke, aber ich bekomme immer noch den gleichen Fehler mit shuffle = False. Es scheitert in Zeile 2309, nicht in 2294.
Sami Belkacem
@SamiBelkacem, das '
mdaoust
0

Könnten Sie diese Zeilen aus Ihrem Code entfernen und versuchen:

    dataset = dataset.cache()
    dataset = dataset.shuffle(1000, reshuffle_each_iteration=True).repeat()
    dataset = dataset.batch(params['batch_size'], drop_remainder=True)
WITH THESE:
    dataset = dataset.repeat()
    dataset = dataset.batch(128, drop_remainder=True)
    dataset = dataset.prefetch(1)

Ansonsten hat das, was Sie geschrieben tf.data.Dataset.from_tensor_sliceshaben, etwas mit dem Fehler zu tun.

Rishabh Sahrawat
quelle
Funktioniert immer noch nicht. Wie Sie sagten, hat tf.data.Dataset etwas mit dem Fehler zu tun. In der Dokumentation heißt es jedoch, dass es bei Verwendung einer Cloud-TPU erforderlich ist. Tensorflow.org/guide/tpu#input_datasets
Sami Belkacem