仅使用线性代数执行训练的张量流模型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了仅使用线性代数执行训练的张量流模型相关的知识,希望对你有一定的参考价值。

我按照以下方式训练图像分类模型: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中“引擎盖下”进行的各种矩阵变换来执行模型?

答案

如果仔细观察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 modelGitHub issue)。

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


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

inception-module-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)

以上是关于仅使用线性代数执行训练的张量流模型的主要内容,如果未能解决你的问题,请参考以下文章

张量流对象检测训练中的标签文件

如何测试我在真实图片上训练过的张量流模型?

使用队列时如何在张量流中训练期间测试网络

如何计算张量流模型中可训练参数的总数?

如何使用内置的张量流方法对特征和标签张量执行 sklearn 风格的训练测试拆分?

张量流模型不更新权重