on colab - class_weight is causing a ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
on colab - class_weight is causing a ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我是 运行 CNN,在 google colab 上使用 keras sequential。
我收到以下错误:
ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
当我从 model.fit 函数中删除 class_weight 参数时,错误消失并且网络训练成功。然而,我真的很想解释不平衡的数据
我检查了我的 class_weights 向量的形状,它很好(和 nd.array,就像你从 sklearn 计算 class 权重生成 class_Weights 时得到的一样功能)
不确定哪些细节是相关的,但我很乐意提供有关版本和所有混乱的更多细节。
p.s
一个可能很重要的事实 -
我的数据是 FER2013 数据,我使用的是 FERplus 标签。
意思是,我的样本与一个唯一的 class 无关,而是每个样本对每个 class 都有自己的概率分布。
最重要的是,我的标签是大小为 class_names 的向量,所有元素加起来为 1。
为了清楚起见,举个例子:
img1
标签 = [0,0,0,0,0.2,0,0.3,0,0,0.5]
无论如何,我将 class_weights 计算为大小为 10 的 nd.array,元素介于 0 和 1 之间,应该平衡更多代表的 classes。
我不确定这是否与错误有关,但我提出来以防万一。
我的代码:
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)
希望有人知道该怎么做!
谢谢!!!
问题是 sklearn API returns 是一个 numpy 数组,但 keras 需要字典作为 class_weight 的输入(参见 here)。您可以使用以下方法解决错误:
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)}
class_weights = sklearn.utils.class_weight.compute_class_weight('balanced', np.unique(labels[i]), labels[i])
class_weights = {l:c for l,c in zip(np.unique(labels[i]), class_weights)}
我是 运行 CNN,在 google colab 上使用 keras sequential。
我收到以下错误: ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
当我从 model.fit 函数中删除 class_weight 参数时,错误消失并且网络训练成功。然而,我真的很想解释不平衡的数据
我检查了我的 class_weights 向量的形状,它很好(和 nd.array,就像你从 sklearn 计算 class 权重生成 class_Weights 时得到的一样功能)
不确定哪些细节是相关的,但我很乐意提供有关版本和所有混乱的更多细节。
p.s
一个可能很重要的事实 - 我的数据是 FER2013 数据,我使用的是 FERplus 标签。 意思是,我的样本与一个唯一的 class 无关,而是每个样本对每个 class 都有自己的概率分布。 最重要的是,我的标签是大小为 class_names 的向量,所有元素加起来为 1。
为了清楚起见,举个例子: img1 标签 = [0,0,0,0,0.2,0,0.3,0,0,0.5]
无论如何,我将 class_weights 计算为大小为 10 的 nd.array,元素介于 0 和 1 之间,应该平衡更多代表的 classes。
我不确定这是否与错误有关,但我提出来以防万一。
我的代码:
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)
希望有人知道该怎么做! 谢谢!!!
问题是 sklearn API returns 是一个 numpy 数组,但 keras 需要字典作为 class_weight 的输入(参见 here)。您可以使用以下方法解决错误:
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)}
class_weights = sklearn.utils.class_weight.compute_class_weight('balanced', np.unique(labels[i]), labels[i])
class_weights = {l:c for l,c in zip(np.unique(labels[i]), class_weights)}