【问题标题】:Providing output from one model to another model将一个模型的输出提供给另一个模型
【发布时间】:2018-09-24 23:23:19
【问题描述】:

我想将一个模型 (f) 的输出提供给另一个模型 (c)。以下代码有效

features_ = sess.run(f.features, feed_dict={x:x_, y:y_, dropout:1.0, training:False})

sess.run(c.optimize, feed_dict={x:x_, y:y_, features:features_, dropout:1.0, training:False})

c 只需要features_y_。它不需要x_。但是,如果我尝试删除 x_ 作为输入,即,

feed_dict={y:y_, features:features_}

我收到以下错误:

InvalidArgumentError(参见上面的回溯):您必须为占位符张量“Placeholder”提供一个值,其 dtype 为 float 和 shape [?,28,28,1] [[节点:Placeholder = Placeholderdtype=DT_FLOAT, shape=[?,28,28,1], _device="/job:localhost/replica:0/task:0/device:CPU:0"]]

这是有原因的吗? features_ 是一个 numpy ndarray,所以它似乎不是张量类型或类似的东西。

这是 f 的代码:

class ConvModelSmall(object):
    def __init__(self, x, y, settings, num_chan, num_features, lr, reg, dropout, training, scope):
        """ init the model with hyper-parameters etc """
        self.x = x
        self.y = y
        self.dropout = dropout
        self.training = training

        initializer = tf.contrib.layers.xavier_initializer(uniform=False)
        self.weights = get_parameters(scope=scope, initializer=initializer, dims)
        self.biases = get_parameters(scope=scope, initializer=initializer, dims)

        self.features = self.feature_model()
        self.acc = settings.acc(self.features, self.y)
        self.loss = settings.loss(self.features, self.y) + reg * reg_loss_fn(self.weights)
        update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
        with tf.control_dependencies(update_ops):
            self.optimize = tf.train.AdagradOptimizer(lr).minimize(self.loss)

    def feature_model(self):
        conv1 = conv2d('conv1', self.x, self.weights['wc1'], self.biases['bc1'], 2, self.training, self.dropout)
        conv2 = conv2d('conv2', conv1, self.weights['wc2'], self.biases['bc2'], 2, self.training, self.dropout)
        conv3 = conv2d('conv3', conv2, self.weights['wc3'], self.biases['bc3'], 2, self.training, self.dropout)

        dense1_reshape = tf.reshape(conv3, [-1, self.weights['wd1'].get_shape().as_list()[0]])
        dense1 = fc_batch_relu(dense1_reshape, self.weights['wd1'], self.biases['bd1'], self.training, self.dropout)
        dense2 = fc_batch_relu(dense1, self.weights['wd2'], self.biases['bd2'], self.training, self.dropout)

        out = tf.matmul(dense2, self.weights['wout']) + self.biases['bout']
        return out

这是c的代码:

class LinearClassifier(object):
    def __init__(self, features, y, training, num_features, num_classes, lr, reg, scope=""):
        self.features = features
        self.y = y
        self.num_features = num_features
        self.num_classes = num_classes

        initializer = tf.contrib.layers.xavier_initializer(uniform=False)
        self.W = get_scope_variable(scope=scope, var="W", shape=[num_features, num_classes], initializer=initializer)
        self.b = get_scope_variable(scope=scope, var="b", shape=[num_classes], initializer=initializer)

        scores = tf.matmul(tf.layers.batch_normalization(self.features, training=training), self.W) + self.b
        self.loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=self.y, logits=scores)) + reg * tf.nn.l2_loss(self.W)
        update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
        with tf.control_dependencies(update_ops):
            self.optimize = tf.train.GradientDescentOptimizer(lr).minimize(self.loss)

【问题讨论】:

  • 您如何将x_ 作为feed_dict={x:x_, y:y_, features:features_} 中的输入删除?
  • 我相信你需要发布网络代码来调试它,因为它看起来像依赖泄漏到x,即使你不打算这样做。
  • @nbro 抱歉,删除了 x_,如上所示。
  • @PeterSzoldan 我添加了代码。我在我的函数中用“dims”代替了一些变量名和维度值来获取参数,因为我认为它不相关,而且有点难以理解。

标签: tensorflow


【解决方案1】:

魔鬼可能就在这几行:

    update_ops = tf.get_collection( tf.GraphKeys.UPDATE_OPS )
    with tf.control_dependencies(update_ops):
        self.optimize = tf.train.GradientDescentOptimizer( lr ).minimize( self.loss )

当您定义c 时,f 已经定义,所以当您说update_ops = tf.get_collection( tf.GraphKeys.UPDATE_OPS ) 时,它将收集当前图表中的所有更新操作。这将包括与fx 相关的操作。

那么with tf.control_dependencies(update_ops): 的意思是“你应该只有在所有update_ops 都被执行之后才应该这样做,包括给x 赋值。但是x 没有值并且发生错误。

要解决这个问题,您可以将两个网络分成两个不同的tf.Graphs,或者,可能更简单,当您获得update_ops 时,您应该在tf.get_collection() 方法中按范围过滤它们。为此,您应该将tf.name_scopes 添加到您的网络类ConvModelSmallLinearClassifier

【讨论】:

    猜你喜欢
    • 2020-05-28
    • 2019-10-12
    • 1970-01-01
    • 2019-11-09
    • 2020-06-03
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多