Недавно мы перешли на Keras для TF 2.0, но когда мы сравнили его с оценщиком DNNClassifier на 2.0, мы испытали примерно в 4 раза более медленные скорости с Keras.Но я не могу на всю жизнь понять, почему это происходит.Остальная часть кода для обоих идентична, с использованием input_fn (), которая возвращает тот же tf.data.Dataset, и с использованием идентичных feature_columns.Бороться с этой проблемой уже несколько дней.Любая помощь будет принята с благодарностью.Спасибо
Код оценки:
estimator = tf.estimator.DNNClassifier(
feature_columns = feature_columns,
hidden_units = [64,64],
activation_fn = tf.nn.relu,
optimizer = 'Adagrad',
dropout = 0.4,
n_classes = len(vocab),
model_dir = model_dir,
batch_norm = false)
estimator.train(input_fn=train_input_fn, steps=400)
Код Keras:
feature_layer = tf.keras.layers.DenseFeatures(feature_columns);
model = tf.keras.Sequential([
feature_layer,
layers.Dense(64, input_shape = (len(vocab),), activation = tf.nn.relu),
layers.Dropout(0.4),
layers.Dense(64, activation = tf.nn.relu),
layers.Dropout(0.4),
layers.Dense(len(vocab), activation = 'softmax')]);
model.compile(
loss = 'sparse_categorical_crossentropy',
optimizer = 'Adagrad'
distribute = None)
model.fit(x = train_input_fn(),
epochs = 1,
steps_per_epoch = 400,
shuffle = True)
ОБНОВЛЕНИЕ: Для дальнейшего тестирования я написал собственную модель с подклассами (см .: Get Started For Experts ), который работает быстрее, чем Keras, но медленнее, чем оценщики.Если Estimator тренируется за 100 секунд, пользовательская модель занимает около 180 секунд, а Keras - около 350 секунд.Интересно отметить, что Estimator работает медленнее с Adam (), чем с Adagrad (), а Keras работает быстрее.С Adam () Keras занимает менее чем вдвое больше времени, чем DNNClassifier.Предполагая, что я не испортил пользовательский код, я начинаю думать, что DNNClassifier просто имеет много внутренних функций оптимизации / эффективности, которые делают его работу быстрее, чем Keras.
Пользовательский код:
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.features = layers.DenseFeatures(feature_columns, trainable=False)
self.dense = layers.Dense(64, activation = 'relu')
self.dropout = layers.Dropout(0.4)
self.dense2 = layers.Dense(64, activation = 'relu')
self.dropout2 = layers.Dropout(0.4)
self.softmax = layers.Dense(len(vocab_of_codes), activation = 'softmax')
def call(self, x):
x = self.features(x)
x = self.dense(x)
x = self.dropout(x)
x = self.dense2(x)
x = self.dropout2(x)
return self.softmax(x)
model = MyModel()
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
optimizer = tf.keras.optimizers.Adagrad()
@tf.function
def train_step(features, label):
with tf.GradientTape() as tape:
predictions = model(features)
loss = loss_object(label, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
itera = iter(train_input_fn())
for i in range(400):
features, labels = next(itera)
train_step(features, labels)
ОБНОВЛЕНИЕ: Возможно, это набор данных.Когда я печатаю строку набора данных в train_input_fn (), в оценщиках он выводит не требующее усилий определение Tensor.В Керасе он печатает нетерпеливые значения.Проходя через бэкэнд-код Keras, когда он получает tf.data.dataset в качестве входных данных, он обрабатывает его с нетерпением (и ТОЛЬКО с нетерпением), именно поэтому он падал всякий раз, когда я использовал tf.function на train_input_fn ().По сути, я предполагаю, что DNNClassifier обучается быстрее, чем Keras, потому что он выполняет больше кода набора данных в графическом режиме.Буду публиковать любые обновления / находки.