keras 努力让一个简单的3D二元分类器CNN运行

wwwo4jvm  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(109)

我正在制作一个3D CNN来将果蝇的3D图像分类为癌症或非癌症。该模型只是一个简单的两个卷积块,最大池化和批量归一化,然后是两个FC层和一个预测层。然而,我似乎无法让它运行得到一个InvalidArgumentError:图形执行错误:.
因此,模型定义如下:

inputs = keras.Input(shape = InSize + (1,))

    x = keras.layers.Conv3D(filters = 64, kernel_size = 3, activation = 'relu', name = '3DConv1')(inputs)
    x = keras.layers.Conv3D(filters = 64, kernel_size = 3, activation = 'relu', name = '3DConv2')(x)
    x = keras.layers.MaxPool3D(pool_size = 2, name = 'MaxPool1')(x)
    x = keras.layers.BatchNormalization(name = 'BatchNorm1')(x)

    # x = keras.layers.Conv3D(filters = 64, kernel_size = 3, activation = 'relu', name = '3DConv3')(x)
    # x = keras.layers.Conv3D(filters = 64, kernel_size = 3, activation = 'relu', name = '3DConv5')(x)
    # x = keras.layers.MaxPool3D(pool_size = 2, name = 'MaxPool2')(x)
    # x = keras.layers.BatchNormalization(name = 'BatchNorm2')(x)

    x = keras.layers.GlobalAveragePooling3D(name = 'GlobalNorm1')(x)
    # x = keras.layers.Flatten()(x)
    x = keras.layers.Dense(units = 50, activation = 'relu', name = 'FC1')(x)
    x = keras.layers.Dense(units = 50, activation = 'relu', name = 'FC2')(x)
    x = keras.layers.Dropout(0.3, name = 'Dropout1')(x)

    outputs = keras.layers.Dense(units = 1, activation = 'sigmoid', name = 'Classifier')(x)

    model = keras.Model(inputs, outputs)

    model.summary()

    model.compile(loss = loss,
                  optimizer = keras.optimizers.legacy.Adam(learning_rate = LR),
                  metrics = metrics)

它产生了模型:
型号:“3dcnn”

图层类型输出形状参数#

input_1(InputLayer)[(None,128,128,64,1)] 0
conv 3d(Conv 3D)(无,126,126,62,64)1792
max_pooling3d(MaxPooling 3D)(无,63,63,31,64)0
batch_normalization(BatchNo(None,63,63,31,64)256
conv3d_1(Conv 3D)(无,61,61,29,64)110656
max_pooling3d_1(MaxPooling3(None,30,30,14,64)0
batch_normalization_1(批次(无,30,30,14,64)256
conv3d_2(Conv 3D)(无,28,28,12,128)221312
max_pooling3d_2(MaxPooling3(None,14,14,6,128)0
batch_normalization_2(Batch(None,14,14,6,128)512
conv3d_3(Conv 3D)(无,12,12,4,256)884992
max_pooling3d_3(MaxPooling3(None,6,6,2,256)0
batch_normalization_3(批次(无,6,6,2,256)1024
global_average_pooling3d(Gl(None,256)0
密集(密集)(无,512)131584
dropout(辍学)(无,512)0

dense_1(密集)(无,1)513

总参数:1,352,897可训练参数:1,351,873不可训练的参数:1,024
我有30个输入图像的nparray形状(30,27,54,182)。图像的元素是强度数据(最大值为10965)。标签是一个具有uint 8元素的形状(30,)的数组。
执行我用途:的代码

history = model.fit(
        xTrain, 
        yTrain,
        batch_size = batch_size,
        epochs = epochs,
        verbose = verbose,
        shuffle = shuffle,
        validation_data = (xVal,yVal), 
        class_weight = class_weight
    )

并获得
InvalidArgumentError:图形执行错误:
找到2个根错误。(0)INVALID_ARGUMENT:indices[0] = 1不在[0,1){{node GatherV 2}}IteratorGetNextIteratorGetNext/_2(1)INVALID_ARGUMENT:indices[0] = 1不在[0,1){{node GatherV 2}}IteratorGetNext 0个成功操作中。忽略0个派生错误。[操作:__inference_train_function_21420]
作为错误。有人能帮我指出正确的方向来解决这个问题吗?
谢谢你,谢谢!
编辑:问题已解决!
对于将来发现这个问题的任何人来说,问题是我意外地定义了class_weights = {0:0.5,0:0.5}而不是{0:0.5,1:0.5}。如果你也有同样的问题,请仔细检查你的class_weight字典!

nfzehxib

nfzehxib1#

你知道下面这句话是什么意思吗?
它是“所有大于或等于0且小于1的数字”的数学符号。这意味着您的模型没有针对应该输出10的分类问题进行正确校准,因为它不能接受值1
以下是一些潜在的错误来源:

输入形状不匹配

您的输入Tensor需要(None, 128, 128, 64, 1)的形状,但实际数据是(30, 27, 54, 182)。你需要解决这个矛盾。

类权重

如果在训练过程中使用class_weight,请确保键与数据集中的标签匹配。如果你的输出层建议使用二进制分类,那么class_weight字典应该只包含0和/或1键。
正确格式示例:

class_weight = {0: weight_for_class_0, 1: weight_for_class_1}

确保没有错误地提供额外的密钥。

标签形状和值

标签的形状应该是(30, 1),而不是(30,),以确保兼容性。此外,确保标签为01

相关问题