tf.data.Dataset: L'argument `batch_size` ne doit pas être spécifié pour le type d'entrée donné


10

J'utilise Talos et Google colab TPU pour exécuter le réglage hyperparamétrique d'un modèle Keras . Notez que j'utilise Tensorflow 1.15.0 et Keras 2.2.4-tf.

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)

Après avoir converti le train en jeu de données à l'aide de tf.data.Dataset, j'obtiens l'erreur suivante lors de l'ajustement du modèle avec 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

Ensuite, si je suis ces instructions et que je ne définis pas l'argument batch-size sur model.fit. J'obtiens une autre erreur dans:

---------------------------------------------------------------------------
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'

Il serait utile pour cette dernière erreur si vous pouviez publier une trace de pile entière, car cette fonction semble être appelée à plusieurs endroits dans ce fichier, donc je ne peux pas dire où vous êtes: github.com/tensorflow/tensorflow /blob/r1.15/tensorflow/python/…
mdaoust

Je viens de modifier la question, vous pouvez vérifier la trace de la pile, merci pour votre temps et votre considération.
Sami Belkacem

Réponses:


0

du code github :

ValueError sera levée s'il xs'agit d'un générateur ou d'une Sequenceinstance et batch_sizeest spécifiée car nous attendons des utilisateurs qu'ils fournissent des ensembles de données par lots.

Essayez d'utiliser batch_size = None


J'obtiens une autre erreur dans _distribution_standardize_user_data (self, x, y, sample_weight, class_weight, batch_size, validation_split, shuffle, epochs, allow_partial_batch) TypeError: type (s) d'opérande non pris en charge pour *: 'NoneType' et 'int
Sami Belkacem

vous devez également définir steps_per_epoch = None
Ioannis Nasios

Cela ne fonctionne pas, j'obtiens une autre erreur: ValueError: Tentative de convertir une valeur (None) avec un type non pris en charge (<class 'NoneType'>) en un tenseur. Je pense que vous pouvez facilement reproduire l'erreur en copiant le programme court
Sami Belkacem

0

Je ne sais pas si ce qui suit conviendra à votre facture, mais quelque chose à essayer. Tout ce que j'ai fait est retiré de la répétition () de l'ensemble de données et de batch_size = params ['batch_size'] de model.fit

Si ce qui précède n'est pas ce que vous êtes prêt à sacrifier, veuillez ignorer le message.

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')

Cela ne fonctionne pas: TypeError: type (s) d'opérande non pris en charge pour *: 'NoneType' et 'int'
Sami Belkacem

0

Cette deuxième erreur que vous obtenez, en _distribution_standardize_user_data, lorsque vous ne passez pas l' batch_sizeajustement.

Le code que vous utilisez pour cette fonction est ici:

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

Vous n'avez pas posté de trace, mais je parie que cela échoue à la ligne 2294 , car c'est le seul endroit où batch_sizeest multiplié par quelque chose.

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))

Il semble que vous puissiez l'éteindre en le réglant shuffle=False.

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

Est-ce que ça marche?


Merci, mais j'obtiens toujours la même erreur avec shuffle = False. Il échoue sur la ligne 2309, pas 2294.
Sami Belkacem

@SamiBelkacem, that '
mdaoust

0

Pourriez-vous supprimer ces lignes de votre code et essayer:

    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)

Sinon, ce que vous avez écrit tf.data.Dataset.from_tensor_slicesa quelque chose à voir avec l'erreur.


Ne fonctionne toujours pas. Comme vous l'avez dit, tf.data.Dataset a quelque chose à voir avec l'erreur. Mais, la documentation indique qu'il est nécessaire de l'inclure lors de l'utilisation d'un tensorflow.org
Sami Belkacem
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.