Рассмотрим следующий пример.У вас есть первый график следующим образом:
import tensorflow as tf
graph1 = tf.Graph()
with graph1.as_default():
x1 = tf.placeholder(tf.float32, shape=[None, 2])
y1 = tf.placeholder(tf.int32, shape=[None])
with tf.name_scope('network'):
logits1 = tf.layers.dense(x1, units=2)
train_vars1 = tf.trainable_variables()
И второй график:
graph2 = tf.Graph()
with graph2.as_default():
x2 = tf.placeholder(tf.float32, shape=[None, 2])
y2 = tf.placeholder(tf.int32, shape=[None])
with tf.name_scope('network'):
logits2 = tf.layers.dense(x2, units=2)
with tf.name_scope('loss'):
xentropy2 = tf.nn.sparse_softmax_cross_entropy_with_logits(
labels=y2, logits=logits2)
loss_fn2 = tf.reduce_mean(xentropy2)
with tf.name_scope('optimizer'):
optimizer2 = tf.train.GradientDescentOptimizer(0.01)
train_op2 = optimizer2.minimize(loss_fn2)
train_vars2 = tf.trainable_variables()
Теперь вы хотите передать выходные данные слоя logits первого графика в качестве входных данных для второго графика.Мы делаем это, создавая два сеанса, инициализируя переменные, оценивая слой logits первого графа и затем передавая оцененное значение в качестве входных данных во второй граф.Я собираюсь использовать набор данных игрушечных блобов, чтобы проиллюстрировать:
from sklearn.datasets import make_blobs
x_train, y_train = make_blobs(n_samples=4,
n_features=2,
centers=[[1, 1], [-1, -1]],
cluster_std=0.5)
sess1 = tf.Session(graph=graph1)
sess2 = tf.Session(graph=graph2)
_ = sess1.run([v.initializer for v in train_vars1])
_ = sess2.run([v.initializer for v in train_vars2])
# feed the logits layer of graph1 as input to graph2
logits1_val = sess1.run(logits1, feed_dict={x1:x_train})
logits2_val = sess2.run(logits2, feed_dict={x2:logits1_val})
print(logits2_val)
# [[ 1.3904244 2.811252 ]
# [-0.39521402 -1.6812694 ]
# [-1.7728546 -4.522432 ]
# [ 0.6836863 3.2234416 ]]
Обратите внимание, что оценочное значение логитов первого графа (logits1_val
) уже является пустым массивом, поэтому вы можете использовать его какввод второго графика.То же самое, если вы хотите выполнить шаг поезда для второго графика:
# train step for the second graph
logits1_val = sess1.run(logits1, feed_dict={x1:x_train})
loss_val2, _ = sess2.run([loss_fn2, train_op2], feed_dict={x2:logits1_val, y2:y_train})
print(loss_val2) # 0.8134985
ОБНОВЛЕНИЕ , если мы определим обе сети на одном графике:
import tensorflow as tf
from sklearn.datasets import make_blobs
x_train, y_train = make_blobs(n_samples=4,
n_features=2,
centers=[[1, 1], [-1, -1]],
cluster_std=0.5)
with tf.variable_scope('network_1'):
x = tf.placeholder(tf.float32, shape=[None, 2])
y = tf.placeholder(tf.int32, shape=[None])
with tf.name_scope('network'):
logits1 = tf.layers.dense(x, units=2)
with tf.variable_scope('network_2'):
with tf.name_scope('network'):
logits2 = tf.layers.dense(logits1, units=2) # <-- output of `network_1` is input to `network_2`
with tf.name_scope('custom_loss'):
# Define your custom loss here. I use cross-entropy
# for illustration
xentropy2 = tf.nn.sparse_softmax_cross_entropy_with_logits(
labels=y, logits=logits2)
custom_loss2 = tf.reduce_mean(xentropy2)
with tf.name_scope('optimizer'):
optimizer2 = tf.train.GradientDescentOptimizer(0.01)
var_list = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
scope='network_2')
train_op2 = optimizer2.minimize(custom_loss2, var_list=var_list)
with tf.variable_scope('network_1'):
# Take the `custom_loss2` from `network_2` and create a new custom loss
# for `network_1`
xentropy1 = tf.nn.sparse_softmax_cross_entropy_with_logits(
labels=y, logits=logits1)
custom_loss1 = tf.reduce_mean(xentropy1) + custom_loss2 # <-- loss from `network_2`
optimizer1 = tf.train.AdamOptimizer(0.01)
var_list = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
scope='network_1')
train_op1 = optimizer1.minimize(custom_loss1, var_list=var_list)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# grad update step + loss computation for first network
loss1, _ = sess.run([custom_loss1, train_op1], feed_dict={x:x_train, y:y_train})
print(loss1) # 0.44655064
# grad update step + loss computation for second network
loss2, _ = sess.run([custom_loss2, train_op2], feed_dict={x:x_train, y:y_train})
print(loss2) # 0.3163877