[英]ResNet50 Model Always Predicts 1 Class
我正在研究 ResNet50 model 来预测胸部 X 光片中是否存在 covid/non-covid。 However, my model currently only predicts class label 1... I have tried 3 different optimizers, 2 different loss functions, changing the learning rate multiple times from 1e-6 to 0.5, and changing the weights on the class labels...
有谁知道问题可能是什么? 为什么它总是预测 class label 1?
这是代码:
# import data
# train_ds = tf.keras.utils.image_dataset_from_directory(
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
DATASET_PATH+"Covid/",
labels="inferred",
batch_size=64,
image_size=(256, 256),
shuffle=True,
seed=COVID_SEED,
validation_split=0.2,
subset="training",
)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
DATASET_PATH+"Covid/",
labels="inferred",
batch_size=64,
image_size=(256, 256),
shuffle=True,
seed=COVID_SEED,
validation_split=0.2,
subset="validation",
)
# split data
train_X = list()
train_y = list()
test_X = list()
test_y = list()
for image_batch_train, labels_batch_train in train_ds:
for index in range(0, len(image_batch_train)):
train_X.append(image_batch_train[index])
train_y.append(labels_batch_train[index])
for image_batch, labels_batch in val_ds:
for index in range(0, len(image_batch)):
test_X.append(image_batch[index])
test_y.append(labels_batch[index])
Conv_Base = ResNet50(weights=None, input_shape=(256, 256, 3), classes=2)
# The Convolutional Base of the Pre-Trained Model will be added as a Layer in this Model
for layer in Conv_Base.layers[:-8]:
layer.trainable = False
model = Sequential()
model.add(Conv_Base)
model.add(Flatten())
model.add(Dense(units = 1024, activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(units = 1, activation = 'sigmoid'))
model.summary()
opt = Adadelta(learning_rate=0.3)
model.compile(optimizer = opt, loss = 'BinaryCrossentropy', metrics = ['accuracy'])
# try to add class weights to make it predict 0, since we currently only predict class label 1
class_weight = {0: 50.,
1: 1.}
r=model.fit(x = train_ds, validation_data = val_ds, epochs = COVID_EPOCHS, class_weight=class_weight)
#print the class labels of prediction
predictions = model.predict(val_ds)
predictions = np.ndarray.flatten(predictions)
predictions = np.where(predictions < 0, 0, 1) # Convert to 0 and 1.
np.set_printoptions(threshold=np.inf)
print(predictions)
做得好。 我也会在这里留下一个答案,因为我认为除了标准化之外你还需要做更多的事情。
当权重为 None 时(参见此处),resnet 权重是随机的。 您正在使用大型卷积特征提取器(Resnet 的第一层),但该提取器没有经过任何训练。 您可能会获得不错的性能,因为成功的 Dense 层会补偿这种随机初始化,但很可能这不是您的目标。 请记住,您的 resnet 权重是不可训练的,因此特征提取永远不会改变。
我建议使用 imagenet 权重的原因是因为您正在处理图像,因此可以合理地假设您的卷积特征提取器需要提取重要的图像特征,例如 colors、形状、边缘等。 imagenet resnet 是在 1000 上训练的事实类左右是无关紧要的,因为您在它到达 output 层之前将其切断,这是 class 数量瓶颈发生的地方。 我会追求 weights = 'imagenet' 的东西。
替换这一行:
model.add(Dense(units = 1, activation = 'sigmoid'))
从这里(如果你有二进制类):
model.add(Dense(units = 2, activation = 'sigmoid'))
否则使用这一行(对于多个类):
model.add(Dense(units = len(classes), activation = 'softmax'))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.