【发布时间】:2021-11-03 20:10:32
【问题描述】:
我正在处理以下问题:
-我必须创建一个 CNN,它以 3D 图像作为输入并输出 4 个类(详情如下) - 所有 4 个标签必须为 0 或 1:True 或 False,取决于输入图像
例如输出:
[0, 1, 0, 1]:这意味着我的预测是 2 类和 4 类对那个图像有好处(应用程序不是 相关)。因此,我有一个 [X,4] 形式的标签张量,其中 X 是样本(或图像)的数量。
我现在面临的问题是巨大的班级不平衡(例如 第三类几乎 98% 的案例是 1,只有 2% 是 0)。一世 不知道如何解决这个问题?我试着用谷歌搜索了一些 好时光,但根本没有答案。我使用了类权重(来自 sklearn) 以前,不过这次好像也不能用了。
我观察到的使用类权重的问题是它会 加权输入的每个数组(即'什么是权重
[0,1,1,0]在整个标签矩阵中') 这显然不是 可取的。我希望每个班级都有一个 0 和 1 的权重 1s的权重(总计8个权重)。我见过有人尝试过这样做,我手动创建了一个 计算权重并输出概率的函数 每个类为 0 或 1(例如 class1 weight0 和 class1 weight1)。
接下来,我必须创建一个权重字典。例如。为一个 单标签分类:
{0: 0.9210526315789473, 1: 1.09375}。一世 需要将其作为我的 model.fit() 函数中的参数。显然,我无法创建包含 4 个不同键的字典 0 和 1 的 4 键。我应该从这里做什么??
我的第一个想法是更改以下标签中的数字 方式:第一类:0=假; 1=真二等:2=假; 3=真正的三等 : 4=假; 5=真第四类:6=假; 7=真
基本上我只是为每个标签添加了一些 2 的倍数,现在 我的标签矩阵的每一行都有 0 到 7 之间的元素。
我能够以以下形式创建字典
{0:w0;1:w1;2:w2,3:w3...}对我来说似乎是个好主意。比我还面临一个问题:当我拟合我的模型时,预测 在
(0,1)范围内,因为我使用的是 sigmoid 激活 最后一个神经元上的函数(即Dense(4,activation='sigmoid'))。一世 以前从未使用过不在 0 和 1 之间的数字 但改变激活函数对我来说有点道理 从 sigmoid 到线性。此时我的权重字典如下所示:
{0: 0.8714285714285714, 1: 0.12857142857142856, 2: 0.5428571428571428, 3: 0.45714285714285713, 4: 0.02857142857142857, 5: 0.9714285714285714, 6: 0.8142857142857143, 7: 0.18571428571428572}又在哪里,例如6:表示第4类的权重为0或 1:表示第1类的权重为1,以此类推。
完成所有这些后,我的模型仍然表现得很奇怪。输出是 不太符合预期(例如,第一个值介于 0 和 1 之间 类,第二类的值介于 2 和 3 之间,依此类推)。这 准确度不稳定,变化很大,验证准确度 只是在 0 和 1 之间跳转?
这是输出现在的样子:
array([[ 0.2878278, 1.3507844, -1.563219 , 0.5500042]]这显然是完全错误的。
我会将代码与我正在使用的模型和功能一起附加 计算权重(我知道它是嵌套的,不使用任何 矢量化,但它仅用于测试目的)。
我真的希望任何人都可以帮助我诊断这个问题 能够预测每个类别的权利值或计算 以不同的方式加权。
CNN:
from tensorflow.keras import datasets, layers, models
from tensorflow.keras.optimizers import SGD, Adam
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.initializers import RandomNormal
from tensorflow.keras.regularizers import l2
callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)
model=models.Sequential();
model.add(layers.Conv3D(16, (2,2,2) , kernel_regularizer=l2(0.01), strides= (1,1,1),input_shape=images['06S'].shape))
model.add(layers.MaxPooling3D(pool_size=(2,2,2),strides=(1,1,1)))
model.add(BatchNormalization(epsilon=1e-01,momentum=0.65))
model.add(tf.keras.layers.LeakyReLU(alpha=0.8))
model.add(layers.Dropout(0.7))
model.add(layers.Conv3D(8, (2,2,2) , kernel_regularizer=l2(0.01), strides=(1,1,1)))
model.add(layers.MaxPooling3D(pool_size=(2,2,2),strides=(1,1,1)))
model.add(BatchNormalization(epsilon=1e-01,momentum=0.65))
model.add(tf.keras.layers.LeakyReLU(alpha=0.8))
model.add(layers.Dropout(0.7))
model.add(layers.Conv3D(4, (2,2,2) , kernel_regularizer=l2(0.01), strides=(1,1,1)))
model.add(layers.MaxPooling3D(pool_size=(2,2,2),strides=(1,1,1)))
model.add(BatchNormalization(epsilon=1e-01,momentum=0.65))
model.add(tf.keras.layers.LeakyReLU(alpha=0.8))
model.add(layers.Dropout(0.7))
model.add(layers.Conv3D(16, (3,3,3) , kernel_regularizer=l2(0.01),strides=(1,1,1)))
model.add(layers.MaxPooling3D(pool_size=(3,3,3),strides=(1,1,1)))
model.add(BatchNormalization(epsilon=1e-01,momentum=0.65))
model.add(tf.keras.layers.LeakyReLU(alpha=0.8))
model.add(layers.Dropout(0.7))
model.add(layers.Dense(32,activation=None))
model.add(BatchNormalization(epsilon=1e-04,momentum=0.1))
model.add(tf.keras.layers.LeakyReLU(alpha=0.4))
model.add(layers.Dropout(0.6))
model.add(layers.Dense(16,activation=None))
model.add(BatchNormalization(epsilon=1e-04,momentum=0.1))
model.add(tf.keras.layers.LeakyReLU(alpha=0.4))
model.add(layers.Dropout(0.6))
model.add(layers.Dense(4, activation='linear'))
model.summary()
model.compile(optimizer='adam',
loss='mse',
metrics=['accuracy'])
Compute weights:
def class_weighting(arr):
arr_np=np.array(arr)
for j in range (arr_np.shape[0]):
ones=0
zeros=0
for i in range (arr_np.shape[1]):
if(j==0):
if (arr[j][i] == 1):
ones+=1
else:
zeros+=1
PVI0=zeros/arr_np.shape[1];
PVI1=ones/arr_np.shape[1];
elif(j==1):
if (arr[j][i] == 1):
ones+=1
else:
zeros+=1
FIBRO0=zeros/arr_np.shape[1];
FIBRO1=ones/arr_np.shape[1];
elif(j==2):
if (arr[j][i] == 1):
ones+=1
else:
zeros+=1
ROTOR0=zeros/arr_np.shape[1];
ROTOR1=ones/arr_np.shape[1];
elif(j==3):
if (arr[j][i] == 1):
ones+=1
else:
zeros+=1
ROOF0=zeros/arr_np.shape[1];
ROOF1=ones/arr_np.shape[1];
return PVI0,PVI1,FIBRO0,FIBRO1,ROTOR0,ROTOR1,ROOF0,ROOF1
Fitting:
PVI0,PVI1,FIBRO0,FIBRO1,ROTOR0,ROTOR1,ROOF0,ROOF1=class_weighting(arr)
classWeight={0:(PVI0),1:(PVI1),2:(FIBRO0),3:(FIBRO1),4:(ROTOR0),5:(ROTOR1),6:(ROOF0),
7:(ROOF1)}
history=model.fit(train_dataset,epochs=10,validation_data=val_dataset,
class_weight=classWeight))
【问题讨论】:
-
要跟踪这个,我遇到了几乎相同的问题,但从未找到完美的解决方案。
标签: python tensorflow machine-learning keras deep-learning