Python Keras CNN预测输出仅在一个数字范围内进行预测
我正在尝试使用CNN根据3D医学大脑图像的评估分数进行预测,但是我收到的准确度分数在一个数字范围内(例如:有7个可能的测试分数:1、1.5、2、2.5、3、4、5,输出仅给出1-1.5范围内的预测) 我已经对图像进行了大小调整、标准化,并将其分为训练集(66个IMG)、测试集(22个IMG)和验证集(22个IMG)。由于图像太少,我添加了一个自定义的3D图像增强(来自github),因此图像总数增加到原来的10倍 我尝试过在我的网络中更改大多数(如果不是全部的话)参数(批量大小、优化器、学习率、简单/复杂的神经网络、激活、丢失等),但都无济于事。我也在网上寻找类似的问题,希望有人有同样的问题并解决了 下面是我正在使用的示例图像: 此图像的大小为(96,96,96),其数组值的条带为(在对其进行规格化后): 经过预处理步骤后,我将其输入CNN模型:Python Keras CNN预测输出仅在一个数字范围内进行预测,python,keras,deep-learning,regression,Python,Keras,Deep Learning,Regression,我正在尝试使用CNN根据3D医学大脑图像的评估分数进行预测,但是我收到的准确度分数在一个数字范围内(例如:有7个可能的测试分数:1、1.5、2、2.5、3、4、5,输出仅给出1-1.5范围内的预测) 我已经对图像进行了大小调整、标准化,并将其分为训练集(66个IMG)、测试集(22个IMG)和验证集(22个IMG)。由于图像太少,我添加了一个自定义的3D图像增强(来自github),因此图像总数增加到原来的10倍 我尝试过在我的网络中更改大多数(如果不是全部的话)参数(批量大小、优化器、学习率、
batch_size = 3
model = Sequential()
model.add(Conv3D(32, [3, 3, 3], padding='same', activation='relu',
input_shape=input_size))
model.add(Conv3D(32, [3, 3, 3], padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding='same'))
model.add(Conv3D(64, [3, 3, 3], padding='same', activation='relu'))
model.add(Conv3D(64, [3, 3, 3], padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding='same'))
model.add(Dropout(0.5))
model.add(Conv3D(128, [3, 3, 3], padding='same', activation='relu'))
model.add(Conv3D(128, [3, 3, 3], padding='same', activation='relu'))
model.add(Conv3D(128, [3, 3, 3], padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding='same'))
model.add(Conv3D(256, [3, 3, 3], padding='same', activation='relu'))
model.add(Conv3D(256, [3, 3, 3], padding='same', activation='relu'))
model.add(Conv3D(256, [3, 3, 3], padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding='same'))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='linear'))
opt = optimizers.Adam(lr=1e-6)
model.compile(loss='mean_squared_logarithmic_error', optimizer=opt, metrics=['accuracy'])
train_datagen = customImageDataGenerator(shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
val_datagen = customImageDataGenerator()
test_datagen = customImageDataGenerator()
training_set = train_datagen.flow(x_train, y_train, batch_size=batch_size, shuffle=True)
validation_set = val_datagen.flow(x_val, y_val, batch_size=batch_size, shuffle=False)
testing_set = test_datagen.flow(x_test, y_test, batch_size=batch_size, shuffle=False)
earlystop = EarlyStopping(monitor='val_loss', patience=30)
history = model.fit(
training_set,
steps_per_epoch = len(x_train)//batch_size,
epochs = 50,
#callbacks = [earlystop],
validation_data = validation_set,
validation_steps = len(x_val)//batch_size
)
我创建了一个自定义精度检查,以可视化输出:
Predicted score: [1.8405123] True score: 3.0
Predicted score: [1.4033222] True score: 3.0
Predicted score: [1.4690828] True score: 1.0
Predicted score: [1.5127727] True score: 3.0
Predicted score: [1.6159409] True score: 1.0
Predicted score: [1.4333361] True score: 1.5
Predicted score: [1.7470968] True score: 3.0
Predicted score: [1.2196972] True score: 1.5
Predicted score: [1.5940914] True score: 4.0
Predicted score: [1.4052064] True score: 1.0
Predicted score: [1.5127727] True score: 1.0
Predicted score: [1.4584785] True score: 1.0
Predicted score: [1.7860543] True score: 3.0
Predicted score: [1.4752649] True score: 2.5
Predicted score: [1.8568267] True score: 1.0
Predicted score: [1.4793051] True score: 3.0
Predicted score: [1.395096] True score: 2.5
Predicted score: [1.6011616] True score: 4.0
Predicted score: [1.9094267] True score: 1.0
Predicted score: [1.6322718] True score: 1.0
Predicted score: [1.7284409] True score: 4.0
Predicted score: [1.5262214] True score: 1.5
Out: 0.09090909090909091
如您所见,预测值在1-2范围内,即使测试分数在2.5、3、4和5范围内
print(y_pred.min(), y_pred.max())
1.2196972 1.9094267
最后,以下是我的图表:
正如你所看到的,损失减少得很漂亮,但是准确度在中途冻结了,我不确定原因可能是什么
很抱歉发了这么长的帖子,但如果有任何答案,我将不胜感激,谢谢 有几件事可能有助于提高模型的准确性
softmax
希望这至少有助于改进一点。Ahh,感谢您的回复!对于#2,由于分数是从1到5,我是否应该将它们全部除以5以将它们标为[0,1]?对于#3,包装器到底是什么?它如何比我的格式更好?对不起,我对深度学习还不太熟悉,也没有那么渊博。也许你可以给我一些资源,因为我自己找不到。谢谢你的第一个问题,最好是-1,然后是/4,所以它严格地介于0和1之间。包装器只会让东西变短。这是一件好事,因为您可以使用它实现更复杂的块,例如跳过连接。查看tensorflow指南。另外,尝试更高的学习率,从
1e-3
开始,因为1e-6
似乎太小。您好,我已经尝试了您提出的建议,但它们无法解决问题。添加batchnormalization增加了输出范围,但损失值停滞不前。较高的学习率给出了-500的不准确输出值。由于输出仍然在特定范围内,而不是在整个范围内,因此对分数进行缩放并没有多大改善。辍学率的下降使我的图表有点过拟合。我没有尝试过包装器技术,因为我觉得学习和实现它需要相当长的时间,而没有一定程度的工作保证,我也遇到了同样的问题。你解决问题了吗?
print(y_pred.min(), y_pred.max())
1.2196972 1.9094267
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Layer, Conv3D, BatchNormalization, Dropout, InputLayer
class ConvBlock(Layer):
def __init__(self, filters=32, kernel_size = [3, 3, 3],
padding='same', activation='relu', dropout=0.1):
super(ConvBlock, self).__init__()
self.conv = Conv3D(filters=filters,
kernel_size=kernel_size,
activation=activation,
padding=padding)
self.norm = BatchNormalization()
self.dropout = Dropout(dropout)
def call(self, input, training=False):
x = self.conv(input)
x = self.norm(x)
x = self.dropout(x, training=training)
return x
model = Sequential()
model.add(InputLayer((96, 96, 96, 1)))
model.add(ConvBlock())
model.summary()