TensorFlow:如何有效地训练每一层都需要馈电的网络?

2024-06-16 11:13:25 发布

您现在位置:Python中文网/ 问答频道 /正文

通常,标准网络实现的唯一馈送是输入/标签。将input和label/truth作为占位符,并将具体数据传递给feed_dict进行训练循环。你知道吗

我的模型由多个网络组成,就像一个网络,每一层本身就是一个网络。模型中的每一层网络接受两个输入:一个数据输入和一个用于图卷积的邻接列表。你知道吗

如果唯一需要的输入是数据输入,我就不会有使用占位符的问题,因为不需要在模型的层网络之间馈电。但是,邻接列表是由numpysklearn函数创建的,它们需要真正的数据输入(如numpy数组),而不是占位符张量。你知道吗

我的网络如下所示:

# <make X* and alist* inputs placeholders>

# forwad through the layer-networks
H1 = network_fwd(X0, alist0, var_scope=SCOPE.format(0)) # params_0/*
H2 = network_fwd(H1, alist1, var_scope=SCOPE.format(1)) # params_1/*
H3 = network_fwd(H2, alist2, var_scope=SCOPE.format(2))
# ...
H10 = network_fwd(H9, alist9, var_scope=SCOPE.format(9))

# optimize on sum network error
error = loss_fn(H1, X1)
error += loss_fn(H2, X2)
error += loss_fn(H3, X3)
#...
error += loss_fn(H10, X10)

train = tf.train.AdamOptimizer(learning_rate).minimize(error)

# train
for step in range(num_steps):
    x_batch = numpy_ops.next_minibatch(X_train, mb_size) # list of data inputs

    # fill placeholders for true inputs X0, X1, ..., X10
    fdict = {placeholder_name: x for placeholder_name, x in zip(pnames, x_batch)}

    # layer-network predictions and adj lists
    adj_list0 = numpy_ops.get_adjacency_list(x_batch[0], K)
    fdict[alist0] = adj_list0
    #=====================================
    h1 = sess.run(H1, feed_dict=fdict)
    fdict[alist1] = numpy_ops.get_adjacency_list(h1, K)
    #=====================================
    h2 = sess.run(H2, feed_dict=fdict)
    fdict[alist2] = numpy_ops.get_adjacency_list(h2, K)
    # ...

    # and finally the actual training pass
    train.run(feed_dict=fdict)

我已经在我的示例代码中用硬编码行显式地说明了一些事情,所以我不需要关于这方面的清理技巧。问题是,每个network_fwd需要为alist馈电,因此每个后续层网络重新计算每个先前的预测/输出,以获得先前层输出上的下一层邻接列表。你知道吗

它的效率非常低,但是我不能对邻接列表函数使用tensorflow操作。有没有任何方法可以通过模型的网络进行单次传递(每个H*只计算一次)?你知道吗

在像Chainer这样的运行时autodiff框架中,这不会是一个问题,因为您可以在前向执行期间只执行邻接列表函数或任何其他非框架数据处理函数,但如何在TF中实现这一点我真的很困惑。你知道吗


Tags: 数据函数模型网络numpy列表varfeed
1条回答
网友
1楼 · 发布于 2024-06-16 11:13:25

@mikkola^{}包装函数的建议对我很有用。你知道吗

我如何使用tf.py_func

# <initialize all child network variables>

# make adjacency list function interface for tf.py_func
def alist_func(h_in):
    """ Given constraints on the input to the func arg in tf.py_func,
        you may need to interface the numpy function if it's signature
        has other args or kwargs
    """
    return numpy_ops.get_adjacency_list(h_in, K)

# direct graph
data_in_shape = (11, None, num_points, D)
X_input = tf.placeholder(tf.float32, shape=data_in_shape, name='X_input')
X_pred, loss = tensor_ops.multi_func_model_fwd(X_input, var_scopes, alist_func)

# optimizer
train = tf.train.AdamOptimizer(learning_rate).minimize(loss)

# train
for step in range(num_steps):
    x_batch = numpy_ops.next_minibatch(X_train, mb_size) # list of data inputs
    train.run(feed_dict={X_input: x_batch})



# in tensor_ops script, this is how I use tf.py_func
def meta_model_fwd(x_in, var_scopes, alist_fn, *args, **kwargs):
    alist = tf.py_func(alist_fn, [x_in[0]], tf.int32) # inp is float32, out is int32
    h = model_fwd(x_in[0], alist, var_scopes[0], *args, **kwargs)
    loss = loss_fn(h, x_in[1])
    for idx, vscope in enumerate(var_scopes[1:]):
        alist = tf.py_func(alist_fn, [h], tf.int32)
        h = model_fwd(h, alist, vscope, *args, **kwargs)
        loss += loss_fn(h, x_in[idx+1])
    return h, loss

再次感谢米科拉!你知道吗

相关问题 更多 >