如何将 sample_weights 与 3D 医疗数据一起使用,而没有 model.fit(x=tf.data.Dataset) 导致无法挤压最后一个暗淡等错误

Posted

技术标签:

【中文标题】如何将 sample_weights 与 3D 医疗数据一起使用,而没有 model.fit(x=tf.data.Dataset) 导致无法挤压最后一个暗淡等错误【英文标题】:How to use sample_weights with 3D medical data, without model.fit(x=tf.data.Dataset) causing an error like can't squeeze the last dim 【发布时间】:2021-12-02 18:52:23 【问题描述】:

环境:

python = 3.8.12  
tensorflow =  2.6.0.  
keras = 2.6.0

所以问题是我正在尝试训练高度不平衡的数据,所以我尝试使用sample_weights 作为model.fit() 的一部分,但我总是得到同样的错误:

ValueError: Can not squeeze dim[4], expected a dimension of 1, got 4 for 'node categorical_crossentropy/weighted_loss/Squeeze = Squeeze[T=DT_FLOAT, squeeze_dims=[-1]](Cast)' with input shapes: [?,48,48,80,4].

所以这是数据的形状,其中y_s 是使用tf.keras.utils.to_categorical 转换的,其中num_classes = 4

x_train (54, 48, 48, 80)  
y_train (54, 48, 48, 80, 4)   
x_test (18, 48, 48, 80)  
y_test (18, 48, 48, 80, 4)  
x_val (18, 48, 48, 80)   
y_val (18, 48, 48, 80, 4)

架构是U-NET:

inputs = Input((number_of_layers, height, width, 1))  
c1 = Conv3D(filters=16, kernel_size=3, activation='relu', kernel_initializer='he_normal', padding='same')(inputs)  
c1 = Dropout(0.1)(c1)
c1 = Conv3D(16, kernel_size=3, activation='relu', kernel_initializer='he_normal', padding='same')(c1)
p1 = MaxPooling3D(pool_size=2)(c1)
...............
...............
...............
outputs = Conv3D(num_classes, kernel_size=1, activation='softmax')(u9)
model = Model(inputs=[inputs], outputs=[outputs])

关于compile 部分,如下所示:

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'], sample_weight_mode="temporal")

注意:我没有使用metrics=[‘accuracy’] 进行评估,我使用了一些IOU

问题来了,我使用的时候:

from sklearn.utils.class_weight import compute_sample_weight
weights = compute_sample_weight(class_weight='balanced', y=y_train.flatten())
weights = weights.reshape(y_train.shape)
weights.shape # => (54, 48, 48, 80, 4) (same as y_train)

所以直到这里它都可以正常工作,没有任何错误,但是当我将weights 添加到以下数据集时:

tf_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train, weights)).batch(4)

然后我尝试运行model.fit:

model.fit(x=tf_ds, verbose=1, epochs=5, validation_data=(x_val, y_val))

我收到以下错误:

ValueError: Can not squeeze dim[4], expected a dimension of 1, got 4 for 'node categorical_crossentropy/weighted_loss/Squeeze = Squeeze[T=DT_FLOAT, squeeze_dims=[-1]](Cast)' with input shapes: [?,48,48,80,4].

任何想法,如何解决这个问题?

【问题讨论】:

你试过了吗:model.fit(x=tf_ds, verbose=1, epochs=5, validation_data=(x_val, y_val), sample_weight=weights) 不喂weights 也喂给tf.data.Dataset.from_tensor_slices 我需要sample_weight prarm,为了平衡数据,model.fit() 没有它也可以工作,主要问题是loss 函数,在上面的场景中,我不需要不知道怎么解决! 我假设您的标签绝对是一种热编码,这就是您使用categorical_crossentropy 的原因?如果不是,那么您可以试试sparse_categorical_crossentropy 感谢您的评论,我删除了tf.keras.utils.to_categorical,并将y_train 更改为非分类,一切顺利!您能否写下这个答案以接受它! 【参考方案1】:

我假设您的标签绝对是一种热编码,这就是您使用categorical_crossentropy 的原因?如果不是,那么您可以试试sparse_categorical_crossentropy

【讨论】:

以上是关于如何将 sample_weights 与 3D 医疗数据一起使用,而没有 model.fit(x=tf.data.Dataset) 导致无法挤压最后一个暗淡等错误的主要内容,如果未能解决你的问题,请参考以下文章

将 sample_weights 用于平衡数据集是不是有意义?

如何纠正 sklearn.naive_bayes 中的 sample_weight?

sample_weight 在 SGDClassifier 中是如何工作的?

scikit 随机森林 sample_weights 的使用

聚力共赢创未来,城链科技与韩妃医美达成战略合作

Python SkLearn Gradient Boost Classifier Sample_Weight Clarification