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解决班级失衡问题
二,。该层的输入,即类概率,是否应该是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
。如果您事先知道类的数量,可以将其指定为常量。