【问题标题】:Caffe - multi-class and multi-label image classificationCaffe - 多类和多标签图像分类
【发布时间】:2019-03-25 12:42:50
【问题描述】:

我正在尝试在 caffe 中创建一个单一的多类和多标签网络配置。

让我们说狗的分类: 狗是小还是大? (班级) 它是什么颜色? (班级) 它有领子吗? (标签)

这件事可以使用 caffe 吗? 这样做的正确方法是什么? 构建 lmdb 文件的正确方法是什么?

所有关于多标签分类的出版物都是从 2015 年左右开始的,从那以后这个主题发生了什么变化?

谢谢。

【问题讨论】:

    标签: deep-learning caffe multilabel-classification


    【解决方案1】:

    谢谢Shai

    只是想了解实际的方法.. 创建包含图像所有标签的 2 个 .text 文件(一个用于训练,一个用于验证)后,例如:

    /train/img/1.png 0 4 18
    /train/img/2.png 1 7 17 33
    /train/img/3.png 0 4 17
    

    运行 py 脚本:

    import h5py, os
    import caffe
    import numpy as np
    
    SIZE = 227 # fixed size to all images
    with open( 'train.txt', 'r' ) as T :
        lines = T.readlines()
    # If you do not have enough memory split data into
    # multiple batches and generate multiple separate h5 files
    X = np.zeros( (len(lines), 3, SIZE, SIZE), dtype='f4' ) 
    y = np.zeros( (len(lines),1), dtype='f4' )
    for i,l in enumerate(lines):
        sp = l.split(' ')
        img = caffe.io.load_image( sp[0] )
        img = caffe.io.resize( img, (SIZE, SIZE, 3) ) # resize to fixed size
        # you may apply other input transformations here...
        # Note that the transformation should take img from size-by-size-by-3 and transpose it to 3-by-size-by-size
        # for example
        transposed_img = img.transpose((2,0,1))[::-1,:,:] # RGB->BGR
        X[i] = transposed_img
        y[i] = float(sp[1])
    with h5py.File('train.h5','w') as H:
        H.create_dataset( 'X', data=X ) # note the name X given to the dataset!
        H.create_dataset( 'y', data=y ) # note the name y given to the dataset!
    with open('train_h5_list.txt','w') as L:
        L.write( 'train.h5' ) # list all h5 files you are going to use
    

    并创建 train.h5 和 val.h5(X 数据集是否包含图像,Y 包含标签?)。

    从以下位置替换我的网络输入层:

    layers { 
     name: "data" 
     type: DATA 
     top:  "data" 
     top:  "label" 
     data_param { 
       source: "/home/gal/digits/digits/jobs/20181010-191058-21ab/train_db" 
       backend: LMDB 
       batch_size: 64 
     } 
     transform_param { 
        crop_size: 227 
        mean_file: "/home/gal/digits/digits/jobs/20181010-191058-21ab/mean.binaryproto" 
        mirror: true 
      } 
      include: { phase: TRAIN } 
    } 
    layers { 
     name: "data" 
     type: DATA 
     top:  "data" 
     top:  "label" 
     data_param { 
       source: "/home/gal/digits/digits/jobs/20181010-191058-21ab/val_db"  
       backend: LMDB 
       batch_size: 64
     } 
     transform_param { 
        crop_size: 227 
        mean_file: "/home/gal/digits/digits/jobs/20181010-191058-21ab/mean.binaryproto" 
        mirror: true 
      } 
      include: { phase: TEST } 
    } 
    

    layer {
      type: "HDF5Data"
      top: "X" # same name as given in create_dataset!
      top: "y"
      hdf5_data_param {
        source: "train_h5_list.txt" # do not give the h5 files directly, but the list.
        batch_size: 32
      }
      include { phase:TRAIN }
    }
    
    layer {
      type: "HDF5Data"
      top: "X" # same name as given in create_dataset!
      top: "y"
      hdf5_data_param {
        source: "val_h5_list.txt" # do not give the h5 files directly, but the list.
        batch_size: 32
      }
      include { phase:TEST }
    }
    

    我猜 HDF5 不需要 mean.binaryproto?

    接下来,输出层应该如何改变以输出多个标签概率? 我想我需要交叉熵层而不是 softmax? 这是当前的输出层:

    layers {
      bottom: "prob"
      bottom: "label"
      top: "loss"
      name: "loss"
      type: SOFTMAX_LOSS
      loss_weight: 1
    }
    layers {
      name: "accuracy"
      type: ACCURACY
      bottom: "prob"
      bottom: "label"
      top: "accuracy"
      include: { phase: TEST }
    }
    

    【讨论】:

    • 这是一个答案吗?还是另一个问题?
    • 您的 prototxt 中不需要 mea.binaryproto,但如果您想减去均值(并且确实如此),则需要在创建 hdf5 文件时进行。
    • 您只保存文本文件中的一个标签(第一个),而忽略其余所有标签。
    • 这是一个后续问题,因为我仍在尝试理解您的原始答案。我不明白你的最后一个答案,我正在尝试对多标签网络进行分类,因此每张图片都有几个相关的标签。 “忽略所有其他内容”是什么意思?
    • 然后将其发布为答案并不是一个好主意:我无法知道您发布了它,我也不明白您在这里问什么。如果您有问题,请直接发布(您可以将一个问题链接到另一个问题以获取上下文)。
    【解决方案2】:

    Caffe 的 LMDB 接口的问题在于它只允许single int label per image
    如果您希望每个图像有多个标签,则必须使用不同的输入层。
    我建议使用"HDF5Data" 层:
    这允许更灵活地设置输入数据,您可以为该层拥有任意数量的"top"s。每个输入图像可能有多个标签,并且网络训练有多个损失。

    请参阅this post,了解如何为 caffe 创建 hdf5 数据。

    【讨论】:

      猜你喜欢
      • 2019-04-02
      • 2017-03-07
      • 2017-03-15
      • 2020-03-07
      • 2016-01-18
      • 2021-11-18
      • 2018-12-01
      • 2021-02-07
      • 2020-02-21
      相关资源
      最近更新 更多