【问题标题】:Using tf.train.Saver() on convolutional layers in tensorflow在张量流的卷积层上使用 tf.train.Saver()
【发布时间】:2017-09-30 20:26:18
【问题描述】:

我正在尝试使用 tf.train.Saver() 在 tensorflow 中的两个卷积神经网络图之间应用迁移学习,并且我想验证我的方法是否按预期工作。有没有办法检查tf.layers.conv2d() 层中的可训练特征?

我的方法

1。初始化图层

conv1 = tf.layers.conv2d(inputs=X_reshaped, filters=conv1_fmaps, kernel_size=conv1_ksize,
                             strides=conv1_stride, padding=conv1_pad, 
                             activation=tf.nn.relu, 
                             kernel_initializer=tf.contrib.layers.xavier_initializer(), 
                             bias_initializer=tf.zeros_initializer(), trainable=True, 
                             name="conv1")

2。 {训练网络}

3。保存当前图表

tf.train.Saver().save(sess, "./my_model_final.ckpt")

4。构建包含相同层的新图,使用Saver() 加载指定的权重

reuse_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                               scope="conv[1]") 
reuse_vars_dict = dict([(var.op.name, var) for var in reuse_vars])
restore_saver = tf.train.Saver(reuse_vars_dict)

...

restore_saver.restore(sess, "./my_model_final.ckpt")

5。 {训练和评估新图表}

我的问题:

1) 我的代码“按预期”工作并且没有错误,但我不能 100% 确信它的工作方式与我认为的一样。有没有办法从图层打印可训练特征以确保我正确加载和保存权重?是否有使用tf.layers API 保存/加载参数的“更好”方法?我注意到 GitHub 上与此相关的 request。理想情况下,我想在第一张图 a) 初始化 b) 训练后和新图 i) 加载权重 ii) 训练/评估后检查这些值。

【问题讨论】:

    标签: tensorflow


    【解决方案1】:
    • 有没有办法从图层打印可训练的特征,以确保我正确加载和保存权重?

    是的,您首先需要处理层的变量。有几种方法可以做到这一点,但可以说最简单的是使用 get_collection() 函数:

    conv1_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                                   scope="conv1")
    

    请注意,这里的作用域被视为正则表达式,因此如果您想要来自作用域conv1conv2conv3 的所有变量,则可以编写conv[123] 之类的内容。

    如果您只想要可训练的变量,可以将GLOBAL_VARIABLES 替换为TRAINABLE_VARIABLES

    如果你只想检查单个变量,比如层的内核,那么你可以像这样使用get_tensor_by_name()

    graph = tf.get_default_graph()
    kernel_var = graph.get_tensor_by_name("conv1/kernel:0")
    

    另一种选择是迭代所有变量并根据它们的名称进行过滤:

    conv1_vars = [var for var in tf.global_variables()
                  if var.op.name.startswith("conv1/")]  
    

    一旦掌握了这些变量,您就可以在不同的点对它们进行评估,例如在初始化之后、在恢复图之后、在训练之后等等,然后比较这些值。例如,这是您在初始化后获取值的方式:

    with tf.Session() as sess:
        init.run()
        conv1_var_values_after_init = sess.run(conv1_vars)
    

    然后,一旦您捕获了您感兴趣的各个点的变量值,您就可以检查它们是否相等(或足够接近,考虑到微小的浮点不精度),如下所示:

    same = np.allclose(conv1_var_values_after_training,
                       conv1_var_values_after_restore)
    
    • 有没有“更好”的方法来使用 tf.layers API 保存/加载参数?

    我不知道。您指向的功能请求并不是真正将参数保存/加载到磁盘,而是能够轻松获取层变量的句柄,并轻松创建分配节点来设置它们的值。

    例如,可以(在 TF 1.4 中)获取层内核的句柄并非常简单地获取其值,如下所示:

    conv1_kernel_value = conv1.kernel.eval()
    

    当然,您可以使用它来获取/设置变量的值并将其加载/保存到磁盘,如下所示:

    conv1 = tf.layers.conv2d(...)
    new_kernel = tf.placeholder(...)
    assign_kernel = conv1.kernel.assign(new_kernel)
    init = tf.global_variables_initializer()
    
    with tf.Session() as sess:
        init.run()
        loaded_kernel = my_function_to_load_kernel_value_from_disk(...)
        assign_kernel.run(feed_dict={new_kernel: loaded_kernel})
        ...
    

    不漂亮。如果您想加载/保存到数据库(而不是平面文件),它可能会很有用,但总的来说,我建议使用 Saver

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多