如何恢复图中定义的功能?

时间:2017-12-25 12:20:31

标签: python tensorflow

我在tensorflow中定义了一个函数,如下所示:

def generator(keep_prob, z, out_channel_dim, alphag1, is_train=True):
    """
    Create the generator network
    :param z: Input z
    :param out_channel_dim: The number of channels in the output image
    :param is_train: Boolean if generator is being used for training
    :return: The tensor output of the generator
    """
    # TODO: Implement Function
    # when it is training reuse=False
    # when it is not training reuse=True
    alpha=alphag1
    with tf.variable_scope('generator',reuse=not is_train):
        layer = tf.layers.dense(z, 3*3*512,activation=None,\
                                 kernel_initializer=tf.contrib.layers.xavier_initializer(uniform=False))
        layer = tf.reshape(layer, [-1, 3,3,512])
        layer = tf.layers.batch_normalization(layer, training=is_train)
        layer = tf.maximum(layer*alpha, layer)
        #layer = layer+tf.random_normal(shape=tf.shape(layer), mean=0.0, stddev=0.0001, dtype=tf.float32)
        #layer = tf.nn.dropout(layer,keep_prob)

        layer = tf.layers.conv2d_transpose(layer, 256, 4, strides=2, padding='same',\
                                 kernel_initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=False))
        layer = tf.layers.batch_normalization(layer, training=is_train)
        layer = tf.maximum(layer*alpha, layer)
        #layer = layer+tf.random_normal(shape=tf.shape(layer), mean=0.0, stddev=0.00001, dtype=tf.float32)
        #layer = tf.nn.dropout(layer,keep_prob)

        layer = tf.layers.conv2d_transpose(layer, 128, 4, strides=2, padding='same',\
                                 kernel_initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=False))
        layer = tf.layers.batch_normalization(layer, training=is_train)
        layer = tf.maximum(layer*alpha, layer)
        #layer = layer+tf.random_normal(shape=tf.shape(layer), mean=0.0, stddev=0.000001, dtype=tf.float32)
        #layer = tf.nn.dropout(layer,keep_prob)

        layer = tf.layers.conv2d_transpose(layer, 64, 4, strides=2, padding='same',\
                                 kernel_initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=False))
        layer = tf.layers.batch_normalization(layer, training=is_train)
        layer = tf.maximum(layer*alpha, layer)
        #layer = layer+tf.random_normal(shape=tf.shape(layer), mean=0.0, stddev=0.0000001, dtype=tf.float32)
        #layer = tf.nn.dropout(layer,keep_prob)

        layer = tf.layers.conv2d_transpose(layer, out_channel_dim, 4, strides=2, padding='same',\
                                 kernel_initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=False))
        #layer = layer+tf.random_normal(shape=tf.shape(layer), mean=0.0, stddev=0.00000001, dtype=tf.float32)

        layer = tf.tanh(layer)
    return layer

这很复杂,因此难以跟踪每一层中的每个变量。 之后我使用tf.train.Saver()和saver.save来训练后保存所有内容。

现在我想恢复此功能,以便我可以使用它来进行进一步的操作,同时保持每层的训练重量不变。

我在网上发现大多数函数如tf.get_default_graph()。get_tensor_by_name或其他一些函数仅限于恢复变量的值而不是此函数。

例如,此函数发生器的输入z(keep_prob,z,out_channel_dim,alphag1,is_train = True)是来自另一个函数的张量。 我想恢复这个功能,这样我可以使用两个新的张量z1和z2,其形状与z相同。

layer1 = generator(keep_prob, z1, out_channel_dim, alphag1, is_train=False) 
layer2 = generator(keep_prob, z2, out_channel_dim, alphag1, is_train=False) 
layer = layer1 - layer2

我可以把这个新的张量层放到另一个函数中。 这里layer1和layer2使用带有保存权重的函数。

难以理解的是,当我使用函数生成器时,我必须使用Saver()存储的trianed权重来指定它。我发现很难用它的权重指定这个函数。对于,1。太多层要跟踪和2.我不知道如何为tf.layers.conv2()指定权重。

那么有谁知道如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

为什么需要恢复功能,这甚至意味着什么?如果需要使用模型,则必须恢复相应的图形。您的函数所做的是定义图的节点。您可以使用您的函数再次构建或重建该图形,然后使用Saver()加载存储在某处的权重,或者您可以从protobuf文件恢复图形。

为了重建图形,尝试调用output_layer=generator(keep_prob, z, out_channel_dim, alphag1, is_train=True)某处的函数调用函数,而不是像往常一样使用Saver类来恢复权重。您的函数不计算,它定义图的一部分或全部。所有计算都由图表执行。

在最后一种情况下,您会发现以下thread有用。通常,您需要知道输入和输出图层的名称。这可以通过the code获得:

[n.name for n in tf.get_default_graph().as_graph_def().node]

答案 1 :(得分:0)

经过长时间的搜索,似乎以下是一个解决方案。

预先定义所有变量,即layer1 = generator(keep_prob,z1,

out_channel_dim, alphag1, is_train=False) 
layer2 = generator(keep_prob, z2, out_channel_dim, alphag1, is_train=False) 
layer = layer1 - layer2.

现在您可以使用tf.get_collection来查找运算符。

似乎tensorflow不会为您提供预定义的功能。它仅保留图形和值,但不保留函数形式。需要在图表中设置所需的所有内容,或者应该跟踪每个权重,即使是太多。

答案 2 :(得分:0)

这是一个普遍的问题: 我将整个模型保存到文件中,需要将部分模型恢复为新模型的一部分。

这里name_map是一个dict:键是图中的新名称,value是ckpt文件中的名称。

def get_restore_saver(self, name_map, restore_optimise_var=True):

    var_grp = {_.op.name:_ for _ in tf.global_variables()}
    varm = {}
    for main_name in var_grp:
        if main_name in name_map:
            varm[name_map[main_name]] = var_grp[main_name]
        elif restore_optimise_var: # I use adam to optimise
            var_arr = main_name.split('/')
            tail = var_arr[-1]
            _ = '/'.join(var_arr[: -1])
            if tail in ['Adam', 'Adam_1', 'ExponentialMovingAverage'] and _ in name_map:
                varm[name_map[_] + "/" + tail] = var_grp[main_name]

    return tf.train.Saver(varm)