繁体   English   中英

ResNet50 Model 总是预测 1 Class

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM