Tensorflow 使用tf.contrib.layers时内核和偏差的设备放置

Tensorflow 使用tf.contrib.layers时内核和偏差的设备放置,tensorflow,Tensorflow,有没有可能告诉在tf.contrib.layers中定义的层来存储定义CPU内核和偏差的变量(例如/CPU:0),同时仍在其他设备上执行类似于卷积的操作?我似乎找到了一个解决方法,这使我可以使用tf.contrib.layer中的层保留模型描述。诀窍是在使用get\u Variable方法创建变量时,将变量节点添加到层期望变量所在的图形中 例如: from tensorflow.contrib.framework.python.ops import variables layer_scope

有没有可能告诉在
tf.contrib.layers
中定义的层来存储定义CPU内核和偏差的变量(例如
/CPU:0
),同时仍在其他设备上执行类似于卷积的操作?

我似乎找到了一个解决方法,这使我可以使用
tf.contrib.layer
中的层保留模型描述。诀窍是在使用
get\u Variable
方法创建变量时,将变量节点添加到层期望变量所在的图形中

例如:

from tensorflow.contrib.framework.python.ops import variables

layer_scope = 'fully_connected'
with tf.device('/cpu:0'):
    weights = variables.model_variable(layer_scope+'/weights', shape=...)
    biases = variables.model_variable(layer_scope+'/biases', shape=...)

fc = tf.contrib.layers.fully_connected(some_input, ...)
可以找到函数
model_变量

记录设备位置并查看tensorboard中的图表,现在可以看到变量放置在
cpu
上,而其他操作可以放置在
gpu上的
完全连接的

下面你可以找到我编写的一个脚本来测试这种行为。运行时,它将创建一个名为
layer\u device\u placement\u summary
的文件夹,在其中可以找到张力板摘要和图形

在我看来,这是相当骇客的,但在我看来,您不会丢失任何功能,同时不会添加许多代码行

如果有人也有兴趣测试的话,我很乐意得到反馈

import tensorflow as tf
from tensorflow.contrib.framework.python.ops import variables


# Data and ground truth
with tf.variable_scope('inputs'):
    X = tf.random_normal([50, 100], seed=42)
with tf.variable_scope('outputs'):
    Y = tf.to_int32(tf.reduce_mean(X, axis=-1) > 0)
    Y_oneHot = tf.one_hot(Y, 2)

def test_fn ( inputs, num_outputs, layer_scope ):
    '''Implements a FC-layer with parameters on `/cpu:0`.

    To ensure the weights and biases are recognized by the layer I use the fact,
    that the the function `tf.contrib.layers.fully_connected` tries to get the
    variable befor creating it. Thus ensuring the correct scope and name of the
    weights and biases does the trick.
    '''

    in_dimension = inputs.shape.as_list()[-1]

    with tf.device('/cpu:0'):
        weights = variables.model_variable(
                layer_scope+'/weights',  # <= Ensure correct scope here
                [in_dimension, num_outputs],
                initializer=tf.contrib.layers.xavier_initializer(),
                regularizer=tf.contrib.layers.l2_regularizer(0.1))

        biases = variables.model_variable(
                layer_scope+'/biases',  # <= Ensure correct scope here
                [num_outputs],
                initializer=tf.zeros_initializer(),
                regularizer=None)

    fc = tf.contrib.layers.fully_connected(
            inputs=inputs, 
            num_outputs=num_outputs, 
            scope=layer_scope, # <= Ensure correct scope here
            activation_fn=None)

    return fc

# Create various layers with different scopes.
with tf.variable_scope('model'):
    with tf.device('/gpu:0'):
        fc11 = test_fn( X, 75, 'fc_1')
        fc12 = test_fn( fc11, 50, 'fc_2')

    with tf.device('gpu:1'):
        fc21 = test_fn( fc12, 25, 'fc_3')
        fc22 = test_fn( fc21, 2, 'fc_4')

with tf.variable_scope('loss'):
    loss = tf.losses.softmax_cross_entropy(logits=fc22, onehot_labels=Y_oneHot)
    # regularization still works:
    loss += tf.add_n(tf.losses.get_regularization_losses())  

with tf.variable_scope('accuracy'):
    equal = tf.equal(tf.to_int32(tf.argmax(fc22, axis=-1)), Y)
    acc = tf.to_float(tf.reduce_mean(tf.to_int32(equal)))

train_op = tf.contrib.layers.optimize_loss(
        loss=loss, 
        global_step=None, 
        learning_rate=1e-4, 
        optimizer='Adam')

summary = tf.summary.merge_all()

# Uncomment below and comment the line below that to get device placement logging
#with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:
with tf.Session() as sess:
    writer = tf.summary.FileWriter('layer_device_placement_summary', sess.graph)
    sess.run(tf.global_variables_initializer())
    for i in range(100):
        if i % 10 == 0:
            a = sess.run(acc)
            l = sess.run(loss)
            s = sess.run(summary)
            writer.add_summary(s, i)
            print "{}:\tacc: {}\tloss: {}".format(i, round(a, 5), round(l, 5))
        sess.run(train_op)
将tensorflow导入为tf
从tensorflow.contrib.framework.python.ops导入变量
#数据和地面真相
使用tf.variable_scope('inputs'):
X=tf.随机_正常([50100],种子=42)
使用tf.variable_scope('outputs'):
Y=tf.to_int32(tf.reduce_平均值(X,轴=-1)>0)
Y_oneHot=tf.one_hot(Y,2)
def测试fn(输入、数量输出、层范围):
''在'/cpu:0'上使用参数实现FC层。
为确保层识别权重和偏差,我使用事实,
函数“tf.contrib.layers.fully_connected”尝试获取
变量,然后再创建它。从而确保项目的范围和名称正确
权重和偏差就是关键。
'''
in_dimension=inputs.shape.as_list()[-1]
使用tf.device('/cpu:0'):
权重=变量。模型\变量(

层_scope+/weights',#有一种更简单的方法:

def net(x):
    res = tf.contrib.layers.conv2d(x, 10, [3, 3])
    # and define other layers
    return res


with tf.device('/CPU:0'):
    with tf.name_scope('CPU'):
        net(x)
for i in range(num_gpus):
    with tf.device('/GPU:%d' % i):
        with tf.name_scope('GPU_%d' % i):
            with tf.variable_scope(tf.get_variable_scope(), reuse=True):
                y = net(x)
                loss = ...
                grad = ...