#python #tensorflow #keras
#python #тензорный поток #keras
Вопрос:
Для тестирования я разделил модель на две модели, и я хочу вычислить потери и применить градиент к обеим моделям, как будто это будет одна.
Вот мои две простые модели:
model1 = tf.keras.models.Sequential([
tf.keras.layers.Dense(10, activation="relu", input_shape=(10,)),
])
model2 = tf.keras.models.Sequential([
tf.keras.layers.Dense(10, activation="softmax", input_shape=(10,)),
])
И я выполняю прямой проход через две модели, вычисляю потери второй модели и применяю градиенты:
optimizer = tf.keras.optimizers.SGD()
loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
x = tf.random.normal((1, 10)) # Input of the 1st model
y = tf.random.normal((1, 10)) # Expected output of the 2nd model
with tf.GradientTape() as tape:
pred1 = model1(x, training=True)
pred2 = model2(pred1, training=True)
loss_value2 = loss(y, pred2) # Compute the loss for the second model prediction
grads = tape.gradient(loss_value2, model2.trainable_variables)
optimizer.apply_gradients(zip(grads, model2.trainable_variables))
Но как мне получить ожидаемый результат первой модели по второй модели, чтобы вычислить потери и применить к ним градиенты?
Редактировать:
Конечная цель тестирования — иметь две модели 1, которые отправляют свои выходные данные в одну третью модель. И каждая модель 1 обучена на двух графических процессорах:
with tf.device('/gpu:0'):
pred1_1 = model1_1(x, training=True)
with tf.device('/gpu:1'):
pred1_2 = model1_2(x, training=True)
pred1 = tf.keras.layers.concatenate([pred1_1, pred1_2])
with tf.device('/gpu:0'):
pred2 = model2(pred1, training=True)
Ответ №1:
@Begoodpy, я предлагаю вам объединить 2 модели в одну и обучить ее, как вы обычно делаете.
supermodel = keras.Sequential(
[
model1(),
model2(),
]
Если вам нужно больше контроля над моделями, попробуйте это:
all_vars = model1.trainable_variables model2.trainable_variables
grads = tape.gradient(loss_value2, all_vars)
optimizer.apply_gradients(zip(grads, all_vars))
Комментарии:
1. Спасибо, но я намерен отправлять каждую модель на один графический процессор, поэтому я не могу использовать их в одной модели
2. С 2 графическими процессорами почему бы не объединить мой ответ с другим от Александра Каталано? TF выполнит разделение между графическими процессорами за вас.
3. Потому что это обходные пути и не решает мою проблему. У меня есть ограничения, такие как размер моделей, которые не могут поместиться в один графический процессор, и ни объединение моделей, ни распределенная стратегия не помогут.
4. вы можете объединить 2 списка переменных и передать их функциям backprop. Я добавил пример выше.
5. Это выглядит потрясающе! Разве это не то же самое, что дважды вызывать
tape.gradient(loss_value2, model1.trainable_variables)
иtape.gradient(loss_value2, model2.trainable_variables)
?