keras class_weights创建错误“InvalidArgumentError:图形执行错误:“

g52tjvyc  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(134)

我正在Keras上训练一个时间序列LSTM模型来解决二进制分类问题。
标签非常不平衡(0约占75%)。
这影响了我的结果,因此我决定纠正这一点(特别是因为我想减少假阳性)。
我的型号:

model = Sequential()
model.add(LSTM(64, input_shape=(X_train.shape[1], X_train.shape[2]), use_bias=True, unroll=True, kernel_initializer='glorot_normal', return_sequences=True))
model.add(BatchNormalization())
model.add(Dropout(.25))
model.add(LSTM(32, return_sequences=False, use_bias=True, unroll=True))
model.add(Dense(num_points_per_inp, activation='sigmoid'))
model.compile(optimizer=Adam(beta_1=.8, beta_2=.9), loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), metrics=tf.keras.metrics.BinaryAccuracy())  # loss=weighted_binary_crossentropy, metrics='accuracy')
model.summary()

我尝试了BN和DO的不同排列,但如果这里有问题,请仍然让我知道。
输入大小为:

X_train.shape  --> (8000, 100, 4)
X_test.shape  --> (2000, 100, 4)
y_train.shape  --> (8000, 100)
y_test.shape  --> (2000, 100)

当不使用class_weights运行这个时,模型会编译和训练,但是当我添加class_weights时,它会产生以下错误:

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
<ipython-input-113-2ebc95d5f9f5> in <module>()
      7                     validation_data=(X_test, y_test),
      8                     class_weight=weights,
----> 9                     verbose=1)

1 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     53     ctx.ensure_initialized()
     54     tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
---> 55                                         inputs, attrs, num_outputs)
     56   except core._NotOkStatusException as e:
     57     if name is not None:

InvalidArgumentError: Graph execution error:

2 root error(s) found.
  (0) INVALID_ARGUMENT:  indices[2] = 52 is not in [0, 2)
     [[{{node GatherV2}}]]
     [[IteratorGetNext]]
     [[IteratorGetNext/_2]]
  (1) INVALID_ARGUMENT:  indices[2] = 52 is not in [0, 2)
     [[{{node GatherV2}}]]
     [[IteratorGetNext]]
0 successful operations.
0 derived errors ignored. [Op:__inference_train_function_769866]

class_weights是以两种不同的方式生成的(两者都不起作用):方法一:

# based on https://scikit-learn.org/stable/modules/generated/sklearn.utils.class_weight.compute_class_weight.html
from sklearn.utils import class_weight

w = class_weight.compute_class_weight(
          class_weight = 'balanced', 
          classes = np.unique(y_train), 
          y = y_train.flatten())
weights = dict(enumerate(np.round(w,2)))

方法二:

# based on https://www.youtube.com/watch?v=f6awaKc1L-Q (@ ~12mins)
counts = np.bincount(y_train.flatten().astype(int))
w0 = 1 / counts[0]
w1 = 1 / counts[1]
weights = {0: w0, 1: w1}

我的假设是,问题与我在每个预测中有100个时间点的事实有关(?),而我看到的例子每次只有1个。但即使在这里我也不确定。
尝试使用分类交叉熵,如建议的here也没有帮助

如何解决这个问题?

我也尝试了其他方法,例如。- 自定义损失,但他们也没有按预期工作:

import keras.backend as K
def weighted_binary_crossentropy(y_true, y_pred):
  weights =(tf.math.abs(y_true) * 59.) + 1.
  bce = K.binary_crossentropy(y_true, y_pred)
  weighted_bce = K.mean(bce * weights)
  return weighted_bce

(重定向自this medium article
有什么建议可以解决这个问题吗?

xfyts7mz

xfyts7mz1#

我今天遇到了这个问题。问题是类加权不适用于多维输出
为了解决这个问题,你可以使用样本加权,基本上你需要创建一个数组,形状与y_train减去最后一个维度相同(假设你使用的是one-hot编码),每个例子的权重,然后将sample_weight参数传递给model.fit

相关问题