tf.data.Dataset: l'argomento `batch_size` non deve essere specificato per il tipo di input specificato


10

Sto usando Talos e Google colab TPU per eseguire l'ottimizzazione dell'iperparametro di un modello di Keras . Nota che sto usando Tensorflow 1.15.0 e 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)

Dopo aver convertito il set di treni in un set di dati utilizzando tf.data.Dataset, viene visualizzato il seguente errore durante l'installazione del modello con 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

Quindi, se seguo queste istruzioni e non imposto l'argomento dimensione batch su model.fit. Ottengo un altro errore 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'

Sarebbe utile per l'ultimo errore se tu potessi pubblicare una traccia dello stack intero, perché quella funzione sembra essere chiamata in molti punti di questo file, quindi non posso dire dove sei: github.com/tensorflow/tensorflow /blob/r1.15/tensorflow/python/…
mdaoust

Ho appena modificato la domanda, puoi controllare la traccia dello stack, grazie per il tuo tempo e considerazione.
Sami Belkacem,

Risposte:


0

dal codice github :

ValueError verrà generato se xè un generatore oSequence un'istanza e batch_sizeviene specificato poiché prevediamo che gli utenti forniscano set di dati in batch.

Prova a usare batch_size = None


Ottengo un altro errore in _distribution_standardize_user_data (self, x, y, sample_weight, class_weight, batch_size, validation_split, shuffle, epochs, allow_partial_batch) TypeError: tipi di operando non supportati per *: 'NoneType' e 'int
Sami Belkacem

dovresti anche impostare steps_per_epoch = None
Ioannis Nasios,

Non funziona, viene visualizzato un altro errore: ValueError: tentativo di convertire un valore (None) con un tipo non supportato (<class 'NoneType'>) in un tensore. Penso che puoi facilmente riprodurre l'errore copiando il programma corto
Sami Belkacem,

0

Non sono sicuro se quanto segue si adatta al conto ma qualcosa da provare. Tutto quello che ho fatto è stato rimosso da repeat () dal set di dati e batch_size = params ['batch_size'] da model.fit

Se quanto sopra non è ciò che sei pronto a sacrificare, ti preghiamo di ignorare il post.

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

Non funziona: TypeError: tipi di operando non supportati per *: 'NoneType' e 'int'
Sami Belkacem

0

Quel secondo errore viene visualizzato _distribution_standardize_user_dataquando non si passa batch_sizeall'adattamento.

Il codice che stai eseguendo per quella funzione è qui:

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

Non hai pubblicato un trace-back, ma scommetto che non funziona sulla linea 2294 , dal momento che è l'unico posto dove batch_sizeviene moltiplicato per qualcosa.

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

Sembra che tu possa spegnerlo impostando shuffle=False.

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

Funziona?


Grazie, ma ho ancora lo stesso errore con shuffle = False. Sta fallendo sulla linea 2309, non 2294.
Sami Belkacem il

@SamiBelkacem, cioe'
mdaoust

0

Potresti rimuovere queste righe dal tuo codice e provare:

    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)

Altrimenti ciò che hai scritto tf.data.Dataset.from_tensor_slicesha qualcosa a che fare con l'errore.


Continua a non funzionare. Come hai detto, tf.data.Dataset ha a che fare con l'errore. Ma la documentazione dice che è necessario includerlo quando si utilizza un TPU Cloud tensorflow.org/guide/tpu#input_datasets
Sami Belkacem
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.