на colab - class_weight вызывает ValueError: значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any() или a.all()

Я запускаю CNN с последовательностью keras в google colab.

я получаю следующую ошибку: ValueError: Значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any() или a.all()

когда я удаляю аргумент class_weight из функции model.fit, ошибка исчезает, и сеть успешно обучается. однако я действительно хочу учитывать несбалансированные данные

я проверил форму моего вектора class_weights, и это хорошо (и nd.array, точно так же, как вы получили бы при создании class_Weights из функции весов класса вычислений sklearn)

не уверен, какие детали важны, но я с удовольствием предоставлю более подробную информацию о версии и всей этой каше.

p.s

факт, который может быть важен - мои данные - это данные FER2013, и я использую метки FERplus. это означает, что мои выборки не связаны с одним уникальным классом, а каждая выборка имеет свое собственное распределение вероятностей для каждого класса. Суть в том, что мои метки представляют собой векторы размера class_names, где все элементы составляют единицу.

просто для ясности, пример: img1 label = [0,0,0,0,0.2,0,0.3,0,0,0.5]

во всяком случае, я вычислил class_weights как nd.array размера 10 с элементами в диапазоне от 0 до 1, чтобы сбалансировать более представленные классы.

я не был уверен, имеет ли это отношение к ошибке, но я поднимаю это на всякий случай.

мой код:

def create_model_plus():
  return tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(filters=32,kernel_size=5,strides=1,input_shape=(48, 48, 1),padding='same',use_bias=True,kernel_initializer='normal',bias_initializer=tf.keras.initializers.Constant(0.1),activation=tf.nn.relu),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D((2, 2), strides=2),
    tf.keras.layers.Conv2D(filters=64,kernel_size=5,strides=1,padding='same',use_bias=True,kernel_initializer='normal',bias_initializer=tf.keras.initializers.Constant(0.1),activation=tf.nn.relu),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D((2, 2), strides=1),
    tf.keras.layers.Conv2D(filters=128,kernel_size=5,strides=1,padding='same',use_bias=True,kernel_initializer='normal',bias_initializer=tf.keras.initializers.Constant(0.1),activation=tf.nn.relu),
    tf.keras.layers.BatchNormalization(),    
    tf.keras.layers.MaxPooling2D((2, 2), strides=1),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(1008, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
  ])


history_df=[]
history_object=tf.keras.callbacks.History()
#save_best_object=tf.keras.callbacks.ModelCheckpoint('/Users/nimrodros', monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)

early_stop_object=tf.keras.callbacks.EarlyStopping(monitor='val_loss',min_delta=0.001, patience=4)
gony_adam=tf.keras.optimizers.Adam(
    lr=0.001
)
reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.3,patience=3, min_lr=0.0001, verbose=1)

#log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
#tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)

datagen = tf.keras.preprocessing.image.ImageDataGenerator(rotation_range=8, width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True,
    validation_split=0.3
    )
datagen.fit(images.reshape(28709,48,48,1))
model = create_model_plus()
model.compile(optimizer=gony_adam,
        loss='categorical_crossentropy',
        metrics=['accuracy'])
history = model.fit(x=datagen.flow(images.reshape(28709,48,48,1), FER_train_labels, batch_size=32,subset='training'),validation_data=datagen.flow(images.reshape(28709,48,48,1), FER_train_labels, batch_size=32,subset='validation'),steps_per_epoch=600,validation_steps=250,epochs=60,callbacks=[history_object,early_stop_object,reduce_lr],class_weight=cl_weigh)
history_df=pd.DataFrame(history.history)

надеюсь кто-нибудь знает что делать! Благодарность!!!


person ether212    schedule 16.04.2020    source источник


Ответы (1)


Проблема в том, что sklearn API возвращает пустой массив, но keras требует словарь в качестве входных данных для class_weight (см. здесь). Вы можете устранить ошибку, используя следующий метод:

from sklearn.utils import class_weight
weight = class_weight.compute_class_weight('balanced', np.unique(y_train), y_train)
weight = {i : weight[i] for i in range(5)}
person Paras Gulati    schedule 17.04.2020