Numpy 无信息层

Numpy 无信息层,numpy,neural-network,protocol-buffers,deep-learning,caffe,Numpy,Neural Network,Protocol Buffers,Deep Learning,Caffe,我希望在我的模型中使用损失层类型。但我很难正确地定义它 关于INFOGAIN\u LOSS层的使用,是否有任何教程/示例 该层的输入(类概率)是SOFTMAX层的输出,还是足以输入完全连接层的“顶部” INFOGAIN\u LOSS需要三个输入:类别概率、标签和矩阵H。 矩阵H可以作为层参数infogain\u loss\u param{source:“fiename”} 假设我有一个python脚本,它将H计算为numpy.array形状(L,L),带有dtype='f4'(其中L是我模型中的

我希望在我的模型中使用损失层类型。但我很难正确地定义它

  • 关于
    INFOGAIN\u LOSS
    层的使用,是否有任何教程/示例

  • 该层的输入(类概率)是
    SOFTMAX
    层的输出,还是足以输入完全连接层的“顶部”

  • INFOGAIN\u LOSS
    需要三个输入:类别概率、标签和矩阵
    H
    。 矩阵
    H
    可以作为层参数
    infogain\u loss\u param{source:“fiename”}

    假设我有一个python脚本,它将
    H
    计算为
    numpy.array
    形状
    (L,L)
    ,带有
    dtype='f4'
    (其中
    L
    是我模型中的标签数量)

  • 如何将我的
    numpy.array
    转换为
    binproto
    文件,该文件可以作为
    infogain\u loss\u param{source}
    提供给模型

  • 假设我希望
    H
    作为损失层的第三个输入(底部)(而不是作为模型参数)提供。我该怎么做?
    我是否定义了一个新的数据层,其“top”是
    H
    ?如果是这样,该层的数据是否会像训练数据一样在每次训练迭代中递增? 我如何定义多个不相关的输入“数据”层,caffe如何知道从培训/测试“数据”层逐批读取,而从
    H
    的“数据”层知道在整个培训过程中只读取一次

  • 一,。关于InfogainLoss图层的使用,是否有任何教程/示例?:
    我们可以找到一个很好的例子:使用InfogainLoss解决班级失衡问题


    二,。该层的输入,即类概率,是否应该是Softmax层的输出?
    从历史上看,过去的答案是肯定的。
    “InfogainLoss”
    的旧实现需要是
    “Softmax”
    层或确保输入值在[0..1]范围内的任何其他层的输出

    研究人员注意到,在
    “Softmax”
    层上使用
    “InfogainLoss”
    会导致数值不稳定,将这两个层合并为一个层(很像
    “SoftmaxWithLoss”
    层),于2017年4月14日被接受并合并到Caffe官方存储库中。给出了该组合层的数学模型

    升级后的“外观”层与旧层完全相同,只是不再需要通过
    “Softmax”
    层显式传递输入。


    三,。如何将numpy.array转换为binproto文件:

    用python

    H = np.eye( L, dtype = 'f4' ) 
    import caffe
    blob = caffe.io.array_to_blobproto( H.reshape( (1,1,L,L) ) )
    with open( 'infogainH.binaryproto', 'wb' ) as f :
        f.write( blob.SerializeToString() )
    
    现在,您可以将
    INFOGAIN\u LOSS
    层作为参数添加到模型原型中:

    layer {
      bottom: "topOfPrevLayer"
      bottom: "label"
      top: "infoGainLoss"
      name: "infoGainLoss"
      type: "InfogainLoss"
      infogain_loss_param {
        source: "infogainH.binaryproto"
      }
    }
    

    四,。如何将
    H
    作为数据层的一部分加载

    引述:

    目前还没有办法让数据层以不同的速率加载输入。每向前传递一次,所有数据层都将前进。但是,恒定的H输入可以通过生成一个输入lmdb/leveldb/hdf5文件来实现,该文件仅为H,因为数据层将循环并继续加载相同的H。这显然会浪费磁盘IO


    这一层正在总结

    -log(p_i)
    
    因此p_i需要在(0,1)中才能作为损失函数来解释(否则,置信度越高,损失越大)。关于log(p)的值,请参见下面的曲线


    我不认为它们必须加起来等于1,但是通过Softmax层将它们传递到一起将实现这两个属性。

    因为我必须搜索许多网站才能猜出完整的属性 代码,我想我可以分享我的实现:

    Python层,用于计算H矩阵以及每个类的权重:

    import numpy as np
    import caffe
    
    
    class ComputeH(caffe.Layer):
        def __init__(self, p_object, *args, **kwargs):
            super(ComputeH, self).__init__(p_object, *args, **kwargs)
            self.n_classes = -1
    
        def setup(self, bottom, top):
            if len(bottom) != 1:
                raise Exception("Need (only) one input to compute H matrix.")
    
            params = eval(self.param_str)
            if 'n_classes' in params:
                self.n_classes = int(params['n_classes'])
            else:
                raise Exception('The number of classes (n_classes) must be specified.')
    
        def reshape(self, bottom, top):
            top[0].reshape(1, 1, self.n_classes, self.n_classes)
    
        def forward(self, bottom, top):
            classes, cls_num = np.unique(bottom[0].data, return_counts=True)
    
            if np.size(classes) != self.n_classes or self.n_classes == -1:
                raise Exception("Invalid number of classes")
    
            cls_num = cls_num.astype(float)
    
            cls_num = cls_num.max() / cls_num
            weights = cls_num / np.sum(cls_num)
    
            top[0].data[...] = np.diag(weights)
    
        def backward(self, top, propagate_down, bottom):
            pass
    
    以及train_val.prototxt中的相关部分:

    layer {
        name: "computeH"
        bottom: "label"
        top: "H"
        type: "Python"
        python_param {
            module: "digits_python_layers"
            layer: "ComputeH"
            param_str: '{"n_classes": 7}'
        }
        exclude { stage: "deploy" }
    }
    layer {
      name: "loss"
      type: "InfogainLoss"
      bottom: "score"
      bottom: "label"
      bottom: "H"
      top: "loss"
      infogain_loss_param {
        axis: 1  # compute loss and probability along axis
      }
      loss_param {
          normalization: 0
      }
      exclude {
        stage: "deploy"
      }
    }
    

    这不完全是这个和,也有权重,有权重,但它们不是约束p_i.log(p)<0的因子,所以-log(p)会随着p变小而增加。这与损失函数应该做的相反。这就是为什么p需要在(0,1)中。log(0)=-无穷大,因此应注意不要使p=0,但这已在层本身中实现。因此,如果我理解正确,您对问题2的回答是:
    info\u gain
    层的输入应为“顶部”是的。这将是确保值在正确范围内的一个好方法。这完全解决了第3部分和第4部分,对于任何想要重新称重(或平衡)的人来说都是一个完美的解决方案使用InfoGain layer和HI的prototxt定义,Caffe中的每类损失有2类,我的训练/测试批大小为16,如果在该批中采样时,我的所有标签都是相同的(即多数类)。这使得
    np.unique(底部[0]。数据,return_counts=True)
    return
    (数组([1.],dtype=float32),数组([16])
    这意味着我的
    num_类
    被分配
    1
    而不是
    2
    。如果您事先知道类的数量,可以将其指定为常量。