【问题标题】:Execute trained tensorflow model using linear algebra only仅使用线性代数执行经过训练的张量流模型
【发布时间】:2018-08-07 17:22:17
【问题描述】:

我正在按照 https://www.tensorflow.org/tutorials/image_recognition 训练图像分类模型

我的目标是提取学习到的权重值(基于:Extracting weights values from a tensorflow model checkpoint)并仅使用线性代数运算来执行模型。

函数def run_inference_on_image(image) (src https://github.com/tensorflow/models/blob/master/tutorials/image/imagenet/classify_image.py) 对图像进行分类,但用于对图像进行分类的线性代数运算似乎不可见。是否可以使用我假设在函数run_inference_on_image 中“幕后”发生的各种矩阵变换来执行模型?

【问题讨论】:

    标签: python image-processing tensorflow neural-network deep-learning


    【解决方案1】:

    如果您仔细查看 run_inference_on_image 和整个 classify_image.py 脚本,它并没有定义模型。它只是一个运行脚本,从磁盘加载 预训练模型(参见 create_graph)并根据某些约定执行它(run_inference_on_image loos 用于名为 softmax:0 的张量)。

    tutorial 声明相同:

    classify_image.py 在程序第一次运行时从 tensorflow.org 下载训练好的模型。

    因此,您问题的确切答案实际上取决于您实际决定运行的模型(例如,您可以提供自己的模型)。我将重点介绍此脚本的默认选择,即Inception model(请参阅DATA_URL 常量)。顺便说一句,您也可以使用更新的预训练 Inception v3 model (GitHub issue)。

    旁注:this implementation 的确切源代码未公布,但我们可以在tf slim 中查看同一网络的最新实现。图中的命名略有不同,但模型实际上是相同的。


    一张图片中的整个模型看起来像this。本质上,它是一长串初始模块,由带有各种过滤器的卷积层组成。 inception模块v3的变种是:

    这里每个a x b 框表示一个卷积层,过滤器大小为[a, b]。它看起来很吓人,但如果你多年来一直关注history of its development,它就会开始变得有意义。

    上图翻译成如下代码(n=7):

      with tf.variable_scope(end_point):
        with tf.variable_scope('Branch_0'):
          branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')
        with tf.variable_scope('Branch_1'):
          branch_1 = slim.conv2d(net, depth(128), [1, 1], scope='Conv2d_0a_1x1')
          branch_1 = slim.conv2d(branch_1, depth(128), [1, 7],
                                 scope='Conv2d_0b_1x7')
          branch_1 = slim.conv2d(branch_1, depth(192), [7, 1],
                                 scope='Conv2d_0c_7x1')
        with tf.variable_scope('Branch_2'):
          branch_2 = slim.conv2d(net, depth(128), [1, 1], scope='Conv2d_0a_1x1')
          branch_2 = slim.conv2d(branch_2, depth(128), [7, 1],
                                 scope='Conv2d_0b_7x1')
          branch_2 = slim.conv2d(branch_2, depth(128), [1, 7],
                                 scope='Conv2d_0c_1x7')
          branch_2 = slim.conv2d(branch_2, depth(128), [7, 1],
                                 scope='Conv2d_0d_7x1')
          branch_2 = slim.conv2d(branch_2, depth(192), [1, 7],
                                 scope='Conv2d_0e_1x7')
        with tf.variable_scope('Branch_3'):
          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')
          branch_3 = slim.conv2d(branch_3, depth(192), [1, 1],
                                 scope='Conv2d_0b_1x1')
        net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3])
    

    至于您对“线性代数运算”的建议,请注意卷积层与线性层不同(有关详细信息,请参阅 CS231n tutorial),尽管存在可归结为矩阵乘法的高效 GPU 实现。

    如您所见,仅使用低级操作从头开始重复相同的模型需要大量代码(tf slim 中的full source code 是 600 行,它实际上由高级抽象)。如果你想自己从预训练状态重新训练它,像这样导入已经构建的模型会更简单:

    from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3
    ...
    inputs = tf.random_uniform((batch_size, height, width, 3))
    logits, end_points = inception_v3(inputs, num_classes)
    

    【讨论】:

    • “这个实现的确切源代码没有公布” 你指的是“Inception v3模型”吗?这不是 Inception 的 src 代码吗? github.com/tensorflow/models/tree/master/research/inception 是高级抽象吗?
    • 我从该 tar-ball 的 proto-buf 文件中检查了张量名称,它们似乎与该定义不同。 Tensorflow 代码更新过于频繁,以至于无法与 2 年前的权重匹配。至于高级代码:整个 TF Slim 库是主 TF 的包装器,它根据层而不是张量进行操作。实际操作更深入。
    • 谢谢,所以如果我想在不支持 python 的设备(例如某些 VR 耳机)上执行图像分类模型,请编写我自己的模型,然后可以在任何设备上执行支持线性代数或使用已经构建的模型(例如 Inception)并通过服务公开其分类功能?
    • Tensorflow 可以在各种平台上执行,因为底层代码都是 C++(例如:stackoverflow.com/q/47178371/712995)。在移动设备上,大多数模型都可以使用tensorflow lite 运行,尤其是 Inception v3。 Android中有绑定。所以我觉得你应该没问题,卷积是一个基本的运算,就像matmul一样,所有设备都必须支持。
    猜你喜欢
    • 2017-12-15
    • 1970-01-01
    • 2023-03-12
    • 2017-09-22
    • 2020-02-29
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多