如何将任意数据集转换为caffe中的孪生网络数据集格式?

How to convert an arbitrary dataset to the siamese network dataset format in caffe?

我有一个由灰度图像创建的数据集,我想将其与 caffe 中的孪生网络示例一起使用,其中文档使用 mnist 数据集。我想用我自己的数据集替换mnist数据集

我看到要执行此操作,我需要我的数据集采用 siamese netwrk 要求的格式。这可以使用 'create_mnist_siamese.sh' 创建,它以 idx3-ubyte 格式加载 mnist 数据集,并在 lmdb 数据库的每个位置创建一个包含两个图像和一个 matching/non 匹配标签的数据集 lmdb 数据库。

所以我想我可以使用 'create_mnist_siamese.sh' 脚本,我的数据集也需要采用 idx-ubyte 格式。我尝试使用 'mnisten' 将我的数据集转换为 idx-ubyte 格式。但是我收到错误 'error:total images are less than num_tests'。我猜脚本没有识别我的图像。数据集的文件夹结构是这样的:

parent-directory
  - subfolder
  - subfolder 
  .
  .
  .
  -txt file

parent 目录名 - 'generated dataset'
子文件夹 - 1 ,2 ,3 ...(子文件夹标题为 1 - 30,因为我想用子文件夹的名称标记每个子文件夹中的数据)
txt 文件包含每行带有 class 标签的图像标题。

如何在 caffe 的孪生网络上使用我的数据集?有没有直接的方法可以将我的数据集转换为 siamese 网络的 lmdb 格式?还是我必须使用 mnisten?如果我这样做那么我该如何解决我的错误? Anu 的帮助将不胜感激。谢谢

您不需要使用完全相同的格式 - 这只是一个教程....您需要做的就是提供一个或多个数据层,总共三个顶部 Blob:datadata_psim。你可以用任何你喜欢的方式做到这一点,例如LMDB(如 MNIST 示例)、HDF5 或其他任何东西。

一般说明

在教程中,他们进一步展示了加载图像对的简便方法:在通道维度中连接两个图像。对于 gray-scale,您需要两个输入图像,例如每个图像的维度为 [1, 1, 28, 28](即 1 个图像、1 个通道、28x28 分辨率)。然后将它们连接成一张大小为 [1, 2, 28, 28] 的图像并保存它们,例如到 LMDB。

在网络中,加载数据后的第一步是“切片”层,它获取此图像并沿该轴对其进行切片(即拆分),从而创建两个 Top blob,datadata_p.

如何创建数据文件?

没有唯一正确的方法可以做到这一点。本教程中的 code 仅适用于 MNIST 集,因此除非您具有 完全相同的 格式,否则您无法在不进行更改的情况下使用它。您有两种可能性:

  1. 将您的图像转换为 MNIST-format。然后,Caffe 教程中的代码有效 out-of-the-box。您似乎正在尝试这个 - 如果您需要这方面的帮助,请具体说明:什么是“mnisten”,包括您的代码,等等。

  2. 编写您自己的脚本来转换图像。 这其实很简单:你需要做的就是用你最喜欢的编程语言读取图像,select 对,计算标签,然后 re-save 作为 LMDB。 这绝对是更灵活的方式。

  3. 创建具有多个 Top blob 的 HDF5 文件。这很容易做到,但可能比使用 LMDB 慢一点。

您使用什么取决于您 - 我可能会选择 HDF5,因为这是一种简单且非常灵活的启动方式。

如何生成对?

现在,这是一个难题。本教程中的代码只是 select 的随机对,这并不是真正的最佳选择,并且会使学习变得相当缓慢。您不仅需要随机对,还需要有意义、困难但仍可解决的对。如何做到这一点完全取决于您的数据集。

在 (Radenović, 2016) 中提出了一个非常复杂的示例:他们使用 Siamese 网络学习建筑物图像检索的表示。他们使用 Structure-from-Motion (SfM) 算法创建建筑物的 3-D 重建,然后从这些重建中采样图像对。

如何准确地创建对取决于您的数据 - 也许您可以使用随机对 - 也许您需要一种复杂的方法。

文献:

F. Radenović、G. Tolias 和 O. Chum。 “CNN 图像检索从 BoW 中学习:无监督 Fine-Tuning 与硬示例”。在:欧洲计算机视觉会议 (ECCV),2016 年。arXiv:1604.02426

生成对是孪生网络中最重要的一步。但是,有一种使用 caffe 的简单方法可以做到这一点。

将数据作为单独的 lmdbs 加载

使用 create_imagenet.shconvert_imageset.cpp 脚本创建 2 个 lmdbs data_1data_2。对两个集合使用相同的数据,除了 data_2 包含一张少于 data_1.

的图像

这将确保在每个 epoc 中,将比较不同的一对图像,从而使我们能够涵盖所有 nC2 组合(n^2实际上)

layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  data_param{
      source: "/home/subho/SSD2/data_1/"
      batch_size: 8
      backend: LMDB
     }
  }
layer {
name: "data_p"
type: "Data"
top: "data_p"
top: "label_p"
data_param {
    source: "/home/subho/SSD2/data_2/"
    batch_size: 8
    backend: LMDB
   }
}

在prototxt中引入相似度层

layer {
  name: "sim_check"
  type: "Similarity"
  bottom: "label"
  bottom: "label_p"
  top: "sim_check"
  propagate_down: false # for each bottom_blob
  propagate_down: false
  }
layer {
    name: "loss"
    type: "ContrastiveLoss"
    contrastive_loss_param {
    margin: 1.0
    }
    bottom: "feat"
    bottom: "feat_p"
    bottom: "sim_check"
    top: "loss"
  }

为相似层创建文件

Download files for similarity layer

similarity_layer.cpp 放入 caffe/src/caffe/layers/ 并将 similarity_layers.hpp 放入 caffe/include/caffe/layers/ 并重建 caffe。

cd build
cmake ..
make -j12

备注 如果您的网络使用上述技术没有收敛,那么您应该看看以下内容:

  • 使用硬底片选择图像对
  • 确保正负对(不同对)的平衡