如何在Keras中将权重传递为均方误差

时间:2019-09-08 09:34:56

标签: keras

我正在尝试解决一个回归问题,该问题是具有8个标签的多标签,对此我正在使用均方误差损失,但数据集不平衡,我想将权重传递给损失函数。当前我正在编译这种方式的模型。

model.compile(loss='mse', optimizer=Adam(lr=0.0001), metrics=['mse', 'acc'])

有人可以建议是否可以增加权重来表示平方误差,如果可以,我该怎么做?

预先感谢

标签看起来像这样

enter image description here

model = Sequential()    
model.add(effnet)
model.add(GlobalAveragePooling2D())
model.add(Dropout(0.5))
model.add(Dense(8,name = 'nelu', activation=elu))
model.compile(loss=custom_mse(class_weights), 
optimizer=Adam(lr=0.0001), metrics=['mse', 'acc'])

2 个答案:

答案 0 :(得分:4)

import keras
from keras.models import Sequential
from keras.layers import Conv2D, Flatten, Dense, Conv1D, LSTM, TimeDistributed
import keras.backend as K


# custom loss function
def custom_mse(class_weights):
    def loss_fixed(y_true, y_pred):
        """
        :param y_true: A tensor of the same shape as `y_pred`
        :param y_pred:  A tensor resulting from a sigmoid
        :return: Output tensor.
        """
        # print('y_pred:', K.int_shape(y_pred))
        # print('y_true:', K.int_shape(y_true))
        y_pred = K.reshape(y_pred, (8, 1))
        y_pred = K.dot(class_weights, y_pred)
        # calculating mean squared error
        mse = K.mean(K.square(y_pred - y_true), axis=-1)
        # print('mse:', K.int_shape(mse))
        return mse

model = Sequential()
model.add(Conv1D(8, (1), input_shape=(28, 28)))
model.add(Flatten())
model.add(Dense(8))

# custom class weights
class_weights = K.variable([[0.25, 1., 2., 3., 2., 0.6, 0.5, 0.15]])
# print('class_weights:', K.int_shape(class_weights))

model.compile(optimizer='adam', loss=custom_mse(class_weights), metrics=['accuracy'])

这是基于您的问题陈述的自定义损失函数的一个小实现

  • 您可以从losses.py中找到有关角膜损失函数的更多信息,还可以从here中查看其官方文档

  • Keras本身不处理诸如张量积,卷积之类的底层操作。取而代之的是,它依赖于专门的,经过优化的张量操纵库来实现,它是Keras的“后端引擎”。有关keras backend的更多信息,请参见此处,也可以从here

  • 中查看其官方文档。
  • 使用K.int_shape(tensor_name)查找dimensions of a tensor

答案 1 :(得分:0)

首先创建一个字典,该字典要给每个类加权多少,例如:

class_weights = {0: 1,
                 1: 1,
                 2: 1, 
                 3: 9, 
                 4: 1...} # Do this for all eight classes

然后将它们传递给model.fit:

model.fit(X, y, class_weight=class_weights)