Jon*_*han 5 machine-learning neural-network keras
这是我正在使用的代码(主要从Kaggle提取):
inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))
...
outputs = Conv2D(4, (1, 1), activation='sigmoid') (c9)
model = Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer='adam', loss='dice', metrics=[mean_iou])
results = model.fit(X_train, Y_train, validation_split=0.1, batch_size=8, epochs=30, class_weight=class_weights)
Run Code Online (Sandbox Code Playgroud)
我有4个班级非常不平衡。A级等于70%,B级= 15%,C级= 10%,D级= 5%。但是,我最关心D类。因此,我进行了以下类型的计算:D_weight = A/D = 70/5 = 14B类和A类的权重依此类推。(如果有更好的方法来选择这些权重,那就放心了)
在最后一行,我想正确设置class_weights和我做它像这样:class_weights = {0: 1.0, 1: 6, 2: 7, 3: 14}。
但是,当我这样做时,出现以下错误。
class_weight3维尺寸目标不支持。
是否可以在最后一层之后添加一个密集层并将其用作虚拟层,以便我可以传递class_weights然后仅使用最后一个conv2d层的输出进行预测?
如果这不可能,那么我将如何修改损失函数(不过我知道这篇文章,但是,将权重传递给损失函数并不会减少损失,因为损失函数是针对每个类分别调用的)?目前,我正在使用以下损失函数:
def dice_coef(y_true, y_pred):
smooth = 1.
y_true_f = K.flatten(y_true)
y_pred_f = K.flatten(y_pred)
intersection = K.sum(y_true_f * y_pred_f)
return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)
def bce_dice_loss(y_true, y_pred):
return 0.5 * binary_crossentropy(y_true, y_pred) - dice_coef(y_true, y_pred)
Run Code Online (Sandbox Code Playgroud)
但是我看不到任何可以输入班级权重的方法。如果有人想要完整的工作代码,请参阅此文章。但是请记住将最终conv2d层的num类更改为4而不是1。
Dan*_*ler 16
您始终可以自己应用权重。
在originalLossFunc下面你可以导入keras.losses。
这weightsList是您的列表,其中包含按类别排序的权重。
def weightedLoss(originalLossFunc, 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)
#if your loss is sparse, use only true as classSelectors
#considering weights are ordered by class, for each class
#true(1) if the class index is equal to the weight index
classSelectors = [K.equal(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]
#make sure your originalLossFunc only collapses the class axis
#you need the other axes intact to multiply the weights tensor
loss = originalLossFunc(true,pred)
loss = loss * weightMultiplier
return loss
return lossFunc
Run Code Online (Sandbox Code Playgroud)
用于在compile:
model.compile(loss= weightedLoss(keras.losses.categorical_crossentropy, weights),
optimizer=..., ...)
Run Code Online (Sandbox Code Playgroud)
您也可以更改输入样本的平衡。
例如,如果您有来自第 1 类的 5 个样本和来自第 2 类的 10 个样本,则在输入数组中两次传递第 5 类的样本。
.
sample_weight论据。除了“按班级”工作,您还可以“按样本”工作。
为输入数组中的每个样本创建一个权重数组: len(x_train) == len(weights)
而fit通过这个数组的sample_weight说法。
(如果是fit_generator,发电机将不得不与火车/真对一起返回的权重:return/yield inputs, targets, weights)
| 归档时间: |
|
| 查看次数: |
1991 次 |
| 最近记录: |