Ha sido citado por muchos usuarios como la razón para cambiar a Pytorch, pero todavía tengo que encontrar una justificación/explicación para sacrificar la calidad práctica más importante, la velocidad, por una ejecución entusiasta.
A continuación se muestra el rendimiento de la evaluación comparativa del código, TF1 frente a TF2, con TF1 ejecutándose entre un 47 % y un 276 % más rápido .
Mi pregunta es: ¿qué es, a nivel gráfico o de hardware, lo que produce una desaceleración tan significativa?
Buscando una respuesta detallada, ya estoy familiarizado con conceptos generales. Git relevante
Especificaciones : CUDA 10.0.130, cuDNN 7.4.2, Python 3.7.4, Windows 10, GTX 1070
Resultados de referencia :

ACTUALIZACIÓN : deshabilitar Eager Execution según el código a continuación no ayuda. El comportamiento, sin embargo, es inconsistente: a veces la ejecución en modo gráfico ayuda considerablemente, otras veces se ejecuta más lentamente en relación con Eager.
Código de referencia :
# use tensorflow.keras... to benchmark tf.keras; used GPU for all above benchmarks from keras.layers import Input, Dense, LSTM, Bidirectional, Conv1D from keras.layers import Flatten, Dropout from keras.models import Model from keras.optimizers import Adam import keras.backend as K import numpy as np from time import time batch_shape = (32, 400, 16) X, y = make_data(batch_shape) model_small = make_small_model(batch_shape) model_small.train_on_batch(X, y) # skip first iteration which builds graph timeit(model_small.train_on_batch, 200, X, y) K.clear_session() # in my testing, kernel was restarted instead model_medium = make_medium_model(batch_shape) model_medium.train_on_batch(X, y) # skip first iteration which builds graph timeit(model_medium.train_on_batch, 10, X, y)Funciones utilizadas :
def timeit(func, iterations, *args): t0 = time() for _ in range(iterations): func(*args) print("Time/iter: %.4f sec" % ((time() - t0) / iterations)) def make_small_model(batch_shape): ipt = Input(batch_shape=batch_shape) x = Conv1D(128, 400, strides=4, padding='same')(ipt) x = Flatten()(x) x = Dropout(0.5)(x) x = Dense(64, activation='relu')(x) out = Dense(1, activation='sigmoid')(x) model = Model(ipt, out) model.compile(Adam(lr=1e-4), 'binary_crossentropy') return model def make_medium_model(batch_shape): ipt = Input(batch_shape=batch_shape) x = Bidirectional(LSTM(512, activation='relu', return_sequences=True))(ipt) x = LSTM(512, activation='relu', return_sequences=True)(x) x = Conv1D(128, 400, strides=4, padding='same')(x) x = Flatten()(x) x = Dense(256, activation='relu')(x) x = Dropout(0.5)(x) x = Dense(128, activation='relu')(x) x = Dense(64, activation='relu')(x) out = Dense(1, activation='sigmoid')(x) model = Model(ipt, out) model.compile(Adam(lr=1e-4), 'binary_crossentropy') return model def make_data(batch_shape): return np.random.randn(*batch_shape), np.random.randint(0, 2, (batch_shape[0], 1))