首页 文章

在Python多维列表中存储TensorFlow网络权重

提问于
浏览
0

我有点不知所措,一次学习这两件事 . EDIT: I found a solution myself and posted it below, however, more efficient solutions are wellcome

Short version of the question: How can I extract every weight and bias at any point from a neural network using TensorFlow and store it into a Python array with the shape [layers][neurons-previous-layer][neurons-current-layer]. The goal is NOT to store on the hdd but in variables with the same shape and type as the one explained below the last code snipet. I'd also like to know, which is the most efficient way to do so.

我想要执行的任务是创建一个具有预先训练的权重和偏差的神经网络(不是从Tensor获得,而是从完全不同的来源获得),使用Tensor优化训练,然后将精确的权重返回给程序 .

我已经研究了如何在Tensor Flow中创建NN,以及基于一些Tensor教程和StackOverflow的一些无关问题,使用以前在Python中创建的列表初始化网络权重的方法 .

所以,我的问题是,如果在TensorFlow中有一个训练有素的网络,我怎样才能提取每个权重和偏向变量(我的网络有大约2,800万个权重和偏差) in the fastest possible way? (请记住,此操作将重复进行以上)

为了澄清这个问题,这里有一些代码:

首先,整个网络创建和培训过程(网络布局除外)基于这篇文章:Autoencoder Example .

此示例的代码的相关部分如下(我切断了输出部分,因为没有必要解释我创建网络的方式):

num_hidden_1 = 256 # 1st layer num features
num_hidden_2 = 128 # 2nd layer num features (the latent dim)
num_input = 784 # MNIST data input (img shape: 28*28)
X = tf.placeholder("float", [None, num_input])

weights = {
    'encoder_h1': tf.Variable(tf.random_normal([num_input, num_hidden_1])),
    'encoder_h2': tf.Variable(tf.random_normal([num_hidden_1, num_hidden_2])),
}
biases = {
    'encoder_b1': tf.Variable(tf.random_normal([num_hidden_1])),
    'encoder_b2': tf.Variable(tf.random_normal([num_hidden_2])),
}

# Building the encoder
def encoder(x):
    # Encoder Hidden layer with sigmoid activation #1
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
                                   biases['encoder_b1']))
    # Encoder Hidden layer with sigmoid activation #2
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
                                   biases['encoder_b2']))
return layer_2

我为生成神经网络而创建的代码如下:

def create_network(layout, funciones, pesos, biases):
    capas = [tf.placeholder("float", [None, layout[0]])]
    for i in range(0, len(pesos)):
        #There's an element already, so capas[i] is the previous layer
        capas.append(tf.layers.dense(capas[i], layout[i+1], activation=funciones[i],
                                            kernel_initializer=tf.constant_initializer(pesos[i], dtype=tf.float32),
                                            bias_initializer=tf.constant_initializer(biases[i], dtype=tf.float32)))

    return capas

代码说明:比索和偏差三维列表包含权重("pesos")和TensorFlow格式的偏差可以接受 . Capas是一个包含网络所有层的数组 . "funcciones[]",它是ATM一个测试全局变量来调整NN的激活功能,它应该是"layout"的一部分,但我现在只是在测试 . 布局是一个数组,包含网络中每个图层的大小 . Layout [0]包含输入图层上的神经元数量,第一个隐藏图层上的布局1,依此类推 .

比索和偏差格式:第一级具有与网络层-1一样多的元素(输入不需要权重或偏差) . 在第二级,它具有与PREVIOUS层中存在的神经元一样多的元素,第三级具有与该列表中的神经元一样多的元素 . 第2级和第3级具有与示例中生成的形状相同的形状 tf.random_normal([num_input, num_hidden_1])

My question is: Assuming I'm use the same structure to execute my NN than the one used in the example provided in the URL above, how can I store the trained weights and biases back in two three dimensional lists with the same exact structure than the ones provided in my code, and which is the fastest way to do so

问题:有没有比上面提到的更有效的方法来构建/执行我的NN?这个的好参考也被接受为答案 .

2 回答

  • 1

    使用 tf.trainable_variables() 怎么样?

    这将返回所有可训练参数的列表,因为它是张量流模型,我认为它已经过优化 .

    您可以通过tensorname从此列表中访问特定权重:

    variable = [weight for weights in tf.trainable_variables() if weight.name == name_my_var]

  • 0

    我找到了解决方案并构建了一个工作功能 . 命名约定与我自己的问题相同 . 我不得不手动命名图层,否则它会在前一层上放置权重和偏差(我检查了图表并且最后连接正确,但脚本无法正确提取它们)

    def extraer_pesos(red, session):
        pesos = []
        biases = []
        for i in range(1, len(red)):
            pesos.append(session.run(tf.get_default_graph().get_tensor_by_name(
                os.path.split(red[i].name)[0] + '/kernel:0')).tolist())
            biases.append(session.run(tf.get_default_graph().get_tensor_by_name(
                os.path.split(red[i].name)[0] + '/bias:0')).tolist())
        return pesos, biases
    
    
    def create_network(layout, funciones, pesos,biases):
        capas = [(tf.placeholder("float", [None, layout[0]])]
        for i in range(0, len(pesos)):
            #There's an element already, so capas[i] is the previous layer
            capas.append(tf.layers.dense(capas[i], layout[i+1], activation=funciones[i],
                                                kernel_initializer=tf.constant_initializer(pesos[i], dtype=tf.float32),
                                                bias_initializer=tf.constant_initializer(biases[i], dtype=tf.float32),
                                                 name="layer"+str(i)))
    
        return capas
    

    请记住,必须初始化变量 . 如果您在训练网络后提取',那么应该没有任何问题 .

相关问题