我正在用Keras训练cnn模型(图像和LiDAR中的物体检测(Kaggle Lyft Competition)。作为输出,我有一个34通道围带。因此,输出尺寸为:LENGTH x WIDTH X 34。 前10个通道用于不同类别的对象(最好是一个热矢量),其余24个通道是3D边界框的坐标。
对于前10个频道,我想使用:keras.losses.categorical_crossentropy
,对于其余24个频道:keras.losses.mean_squared_error
此外,由于对象的数量差异很大,为避免偏差,我在对每个类进行权衡。由于输出是ndarray,因此我不得不编写自定义损失函数(用于类加权)。代码主要来自: Custom loss function for U-net in keras using class weights: `class_weight` not supported for 3+ dimensional targets
def weightedLoss(weightsList):
def lossFunc(true,pred):
axis = -1 #if channels last
#axis= 1 #if channels first
#argmax returns the index of the element with the greatest value
#done in the class axis,it returns the class index
classSelectors = K.argmax(true,axis=axis)
#considering weights are ordered by class,for each class
#true(1) if the class index is equal to the weight index
one64 = np.ones(1,dtype=np.int64) #Needed to avod int32 and int64 error
classSelectors = [K.equal(one64[0]*i,classSelectors) for i in range(len(weightsList))]
#casting boolean to float for calculations
#each tensor in the list contains 1 where ground true class is equal to its index
#if you sum all these,you will get a tensor full of ones.
classSelectors = [K.cast(x,K.floatx()) for x in classSelectors]
#for each of the selections above,multiply their respective weight
weights = [sel * w for sel,w in zip(classSelectors,weightsList)]
#sums all the selections
#result is a tensor with the respective weight for each element in predictions
weightMultiplier = weights[0]
for i in range(1,len(weights)):
weightMultiplier = weightMultiplier + weights[i]
op_chan_loss = keras.losses.categorical_crossentropy
op_box_loss = keras.losses.mean_squared_error
#make sure your originalLossFunc only collapses the class axis
#you need the other axes intact to multiply the weights tensor
print(type(true),type(pred))
loss = op_chan_loss(true,pred)
loss = loss * weightMultiplier
return loss
return lossFunc
但是,我不确定如何在此自定义损失函数中将两个损失函数组合在一起。请帮忙。