python - 当我添加类权重时,训练模型会给出 ValueError
问题描述
我正在使用多类 U-Net 分割,在通过数据模型训练时遇到值错误。我的多类模型分为 4 个类。
训练模型代码:
from simple_multi_unet_model import multi_unet_model #Uses softmax
from tensorflow.keras.utils import normalize
import os
import glob
import cv2
import numpy as np
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
import tensorflow as tf
#Resizing images, if needed
SIZE_X = 128
SIZE_Y = 128
n_classes=4 #Number of classes for segmentation
#Capture training image info as a list
train_images = []
directory_path = '/home/Documents/Multiclass/images/'
list_of_files = sorted( filter( os.path.isfile, glob.glob(directory_path + '*.png', recursive=True) ) )
for img_path in list_of_files:
img = cv2.imread(img_path, 0)
img = cv2.resize(img, (SIZE_Y, SIZE_X))
train_images.append(img)
#Convert list to array for machine learning processing
train_images = np.array(train_images)
#Capture mask/label info as a list
train_masks = []
labels_path = '/home/Documents/Multiclass/labels/'
list_of_labels = sorted( filter( os.path.isfile, glob.glob(labels_path + '*.png', recursive=True) ) )
for mask_path in list_of_labels:
mask = cv2.imread(mask_path, 0)
mask = cv2.resize(mask, (SIZE_Y, SIZE_X), interpolation = cv2.INTER_NEAREST) #Otherwise ground truth changes due to interpolation
train_masks.append(mask)
#Convert list to array for machine learning processing
train_masks = np.array(train_masks)
###############################################
#Encode labels... but multi dim array so need to flatten, encode and reshape
from sklearn.preprocessing import LabelEncoder
labelencoder = LabelEncoder()
n, h, w = train_masks.shape
train_masks_reshaped = train_masks.reshape(-1,1)
train_masks_reshaped_encoded = labelencoder.fit_transform(train_masks_reshaped)
train_masks_encoded_original_shape = train_masks_reshaped_encoded.reshape(n, h, w)
np.unique(train_masks_encoded_original_shape)
#################################################
train_images = np.expand_dims(train_images, axis=3)
train_images = normalize(train_images, axis=1)
train_masks_input = np.expand_dims(train_masks_encoded_original_shape, axis=3)
#Create a subset of data for quick testing
#Picking 10% for testing and remaining for training
from sklearn.model_selection import train_test_split
x_train, X_test, y_train, y_test = train_test_split(train_images, train_masks_input, test_size = 0.10, random_state = 0)
print("Class values in the dataset are ... ", np.unique(y_train)) # 0 is the background/few unlabeled
from tensorflow.keras.utils import to_categorical
train_masks_cat = to_categorical(y_train, num_classes=n_classes)
y_train_cat = train_masks_cat.reshape((y_train.shape[0], y_train.shape[1], y_train.shape[2], n_classes))
test_masks_cat = to_categorical(y_test, num_classes=n_classes)
y_test_cat = test_masks_cat.reshape((y_test.shape[0], y_test.shape[1], y_test.shape[2], n_classes))
###############################################################
from sklearn.utils import class_weight
class_weights = class_weight.compute_class_weight('balanced',
np.unique(train_masks_reshaped_encoded),
train_masks_reshaped_encoded)
print("Class weights are...:", class_weights)
IMG_HEIGHT = x_train.shape[1]
IMG_WIDTH = x_train.shape[2]
IMG_CHANNELS = x_train.shape[3]
def get_model():
return multi_unet_model(n_classes=n_classes, IMG_HEIGHT=IMG_HEIGHT, IMG_WIDTH=IMG_WIDTH, IMG_CHANNELS=IMG_CHANNELS)
model = get_model()
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
#If starting with pre-trained weights.
#model.load_weights('???.hdf5')
history = model.fit(x_train, y_train_cat,
batch_size = 16,
verbose=1,
epochs=100,
validation_data=(X_test, y_test_cat),
class_weight=class_weights,
shuffle=False)
我使用以下方法来定义类权重:
from sklearn.utils import class_weight
class_weights = class_weight.compute_class_weight('balanced',
np.unique(train_masks_reshaped_encoded),
train_masks_reshaped_encoded)
print("Class weights are...:", class_weights)
结果是class_weights : 0.276965 ,13.5112 ,5.80929,6.97915
。
我在ValueError
训练我的模型时遇到。我怎么可能解决它?如果您认为我的方法不可行,请建议使用类权重的更好方法。
File "/home/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/data_adapter.py", line 1185, in _configure_dataset_and_inferred_steps
if class_weight:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
解决方案
我对这个错误消息的理解是,numpy
不知道是否将数组评估为True
好像任何元素都为真,或者True
仅当所有元素都为真时。因此,ValueError
返回 a 是因为布尔评估在这方面不明确。
因此,在评估数组时,您应该使用a.any()
or a.all()
,如随附的错误消息中所示。
当您尝试在布尔上下文中评估类权重时,错误可能发生在代码中的其他位置(未共享?)。
推荐阅读
- reactjs - react-scripts 2.1.8 --> 3.0.0 打破了 redux“连接”测试?
- python - Flask 循环未在 Bootstrap 下拉菜单中按预期迭代
- google-chrome - 在 Chrome 开发人员工具中重置网络选项卡默认表排序顺序?
- php - 在哪里可以找到多存储 prestathsop 表的前缀
- python - 为什么在打印时比较这两个日期在 python 中失败,它们是相同的
- mysql - 如何在 MySQL 中随机选择 HEX 颜色但避免特定颜色范围?
- nginx - Nginx - 子目录的单独 WebRoot
- sql-server - 将 SQL Server 数据复制到 Excel
- c# - 在 C# 中设置具有其值大小的字典会更好吗?
- python-3.x - 仅在某些图表上缺少次要刻度