通常,标准网络实施的唯一馈送是输入/标签。您将输入和标签/真实作为占位符,并将具体数据传递给feed_dict
以进行训练循环。
我的模型由多个网络组成,就像一个网络,每个网络本身就是一个网络。模型中的每个层网络都接受两个输入:数据输入和图形卷积的邻接列表。
如果所需的唯一输入是数据输入,我就不会遇到使用占位符的问题,因为不需要在模型的层网络之间进行馈送。但是,邻接列表由numpy
和sklearn
函数创建,这些函数需要真正的数据输入(如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。
答案 0 :(得分:0)
@mikkola建议用tf.py_func
包裹函数为我工作。
我如何使用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
再次感谢mikkola!