使用预训练 (Tensorflow) CNN 提取特征

Posted

技术标签:

【中文标题】使用预训练 (Tensorflow) CNN 提取特征【英文标题】:Extract features using pre-trained (Tensorflow) CNN 【发布时间】:2016-03-14 12:16:35 【问题描述】:

深度学习已成功应用于多个大型数据集,用于对少数类别(猫、狗、汽车、飞机等)进行分类,其性能优于简单的描述符,如 SIFT 上的特征袋、颜色直方图等.

尽管如此,训练这样的网络需要每个类的大量数据和大量的训练时间。然而,在花时间设计和训练这样的设备并收集训练数据之前,通常没有足够的数据,或者只是想了解卷积神经网络的性能。

在这种特殊情况下,使用最先进的出版物使用的一些基准数据集配置和训练网络可能是理想的,并将其简单地应用于您可能拥有的一些数据集作为特征提取器.

这会为每个图像生成一组特征,可以将其提供给经典分类方法,如 SVM、逻辑回归、神经网络等。

特别是当没有足够的数据来训练 CNN 时,我可能希望这会优于在少数样本上训练 CNN 的管道。

我在看 tensorflow 教程,但它们似乎总是有一个明确的训练/测试阶段。我找不到带有预配置 CNN 特征提取器的 pickle 文件(或类似文件)。

我的问题是:这样的预训练网络是否存在,我在哪里可以找到它们。或者:这种方法有意义吗?我在哪里可以找到 CNN+权重?

编辑 W.r.t. @john 的评论我尝试使用 'DecodeJpeg:0''DecodeJpeg/contents:0' 并检查了不同的输出 (:S)

import cv2, requests, numpy
import tensorflow.python.platform
import tensorflow as tf


response = requests.get('https://i.stack.imgur.com/LIW6C.jpg?s=328&g=1')
data = numpy.asarray(bytearray(response.content), dtype=np.uint8)
image = cv2.imdecode(data,-1)

compression_worked, jpeg_data = cv2.imencode('.jpeg', image)
if not compression_worked:
    raise Exception("Failure when compressing image to jpeg format in opencv library")
jpeg_data = jpeg_data.tostring()

with open('./deep_learning_models/inception-v3/classify_image_graph_def.pb', 'rb') as graph_file:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(graph_file.read())
    tf.import_graph_def(graph_def, name='')

with tf.Session() as sess:
    softmax_tensor = sess.graph.get_tensor_by_name('pool_3:0')

    arr0 = numpy.squeeze(sess.run(
        softmax_tensor,
        'DecodeJpeg:0': image
    ))

    arr1 = numpy.squeeze(sess.run(
        softmax_tensor,
        'DecodeJpeg/contents:0': jpeg_data
    ))

    print(numpy.abs(arr0 - arr1).max())

所以最大绝对差值是1.27649,并且通常所有元素都不同(尤其是因为arr0arr1 本身的平均值介于0 - 0.5 之间)。

我也希望'DecodeJpeg:0' 需要一个 jpeg 字符串,而不是一个 numpy 数组,为什么名称包含“Jpeg”。 @john:你能说明一下如何 你确定你的评论?

所以我想我不确定是什么,因为我希望经过训练的神经网络是确定性的(但最多是混乱的)。

【问题讨论】:

橡皮鸭:当谷歌搜索“在 ImageNet 上训练的 CNN”时,我发现:vlfeat.org/matconvnet/pretrained 我可以在我的笔记本电脑上编译和运行这个网络 - 并使用网络摄像头识别/分类图像 github.com/sermanet/OverFeat 【参考方案1】:

TensorFlow 团队最近发布了一个在 ImageNet 数据集上训练的深度 CNN。您可以从here 下载获取数据(包括模型图和训练的权重)的脚本。关联的Image Recognition tutorial 包含有关模型的更多详细信息。

虽然当前模型并未专门打包以在后续训练步骤中使用,但您可以探索修改脚本以在您自己的网络中重用模型的部分内容和经过训练的权重。

【讨论】:

这看起来很棒,当我让它工作时我会接受:)分类图像表明它会产生一个标签。我想要一个特征向量,因为我的标签不是来自 ImageNet 的标签。 按照日志使用这些 cmets:假设使用 softmax_tensor = sess.graph.get_tensor_by_name('pool_3:0') 而不是 softmax_tensor = sess.graph.get_tensor_by_name('softmax:0') 来获取特征。 我注意到这个特定网络的feed_dict 有一个'DecodeJpeg/contents:0'(我认为这是在文件classify_image_graph_def.pb 中定义的),你知道如何找出可能的feed_dict 配置吗?可能的?我也可以在里面扔一个带有图像的 numpy-array 吗? 如果您将 'DecodeJpeg/contents:0' 更改为 'DecodeJpeg:0',您可以使用 numpy 数组 @john 我没有对此进行测试,因为特定代码已经在生产中运行,但假设它可以工作,这是删除多余代码的好方法。谢谢。

以上是关于使用预训练 (Tensorflow) CNN 提取特征的主要内容,如果未能解决你的问题,请参考以下文章

CNN基础二:使用预训练网络提取图像特征

Tensorflow - 可视化预训练网络的学习过滤器

TensorFlow 对象检测 api:使用预训练模型在训练中更改类数时的分类权重初始化

python,tensorflow,CNN实现mnist数据集的训练与验证正确率

当用作预训练特征提取器时,VGG16 应该提取多少特征?

Keras 使用 TimeDistributed 预训练 CNN