为什么我的多类keras模型没有在高精度下训练,尽管有参数?

txu3uszq  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(125)

首先,我在我的cvs文件中读取包含1或0的矩阵

df = pd.read_csv(url)
print(df.head())    
print(df.columns)

接下来,我收集了图片并调整了它们的大小

image_directory = 'Directory/'
dir_list = os.listdir(path)
print("Files and directories in '", image_directory, "' :")  
# print the list
print(dir_list)

它们被保存到X2变量中。

SIZE = 200
X_dataset = []
for i in tqdm(range(df.shape[0])):
    img2 = cv2.imread("Cell{}.png".format(i), cv2.IMREAD_UNCHANGED)
    img = tf.keras.preprocessing.image.load_img(image_directory +df['ID'][i], target_size=(SIZE,SIZE,3))
    #numpy array of each image at size 200, 200, 3 (color)
    img = np.array(img)
    img = img/255.
    X_dataset.append(img)

X2 = np.array(X_dataset)
print(X2.shape)

我创建了y2数据,方法是获取cvs数据,删除两列并得到一个形状(1000,16)

y2 = np.array(df.drop(['Outcome', 'ID'], axis=1))
print(y2.shape)

然后我做了train_test_split * 我想知道我的随机状态或test_size是否不是最优的 *

X_train2, X_test2, y_train2, y_test2 = train_test_split(X2, y2, random_state=10, test_size=0.3)

接下来,我创建了一个序列模型SIZE =(200,200,3),它是在上面调整大小的模型中创建的。

model2 = Sequential()

model2.add(Conv2D(filters=16, kernel_size=(10, 10), activation="relu", input_shape=(SIZE,SIZE,3)))
model2.add(BatchNormalization())
model2.add(MaxPooling2D(pool_size=(5, 5)))
model2.add(Dropout(0.2))

model2.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))
model2.add(MaxPooling2D(pool_size=(2, 2)))
model2.add(BatchNormalization())
model2.add(Dropout(0.2))

model2.add(Conv2D(filters=64, kernel_size=(5, 5), activation="relu"))
model2.add(MaxPooling2D(pool_size=(2, 2)))
model2.add(BatchNormalization())
model2.add(Dropout(0.2))

model2.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
model2.add(MaxPooling2D(pool_size=(2, 2)))
model2.add(BatchNormalization())
model2.add(Dropout(0.2))

model2.add(Flatten())
model2.add(Dense(512, activation='relu'))
model2.add(Dropout(0.5))
model2.add(Dense(128, activation='relu'))
model2.add(Dropout(0.5))
model2.add(Dense(16, activation='sigmoid'))

#Do not use softmax for multilabel classification
#Softmax is useful for mutually exclusive classes, either cat or dog but not both.
#Also, softmax outputs all add to 1. So good for multi class problems where each
#class is given a probability and all add to 1. Highest one wins. 

#Sigmoid outputs probability. Can be used for non-mutually exclusive problems.
#like multi label, in this example.
#But, also good for binary mutually exclusive (cat or not cat). 

model2.summary()

#Binary cross entropy of each label. So no really a binary classification problem but
#Calculating binary cross entropy for each label. 
opt = tf.keras.optimizers.Adamax(
    learning_rate=0.02,
    beta_1=0.8,
    beta_2=0.9999,
    epsilon=1e-9,
    name='Adamax')

model2.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy', 'mse' ])

该模型使用自定义优化器,生成的形状具有473,632个可训练参数。
然后指定样本权重,该权重是通过取最高采样数并将其他数除以该值计算得出的。

sample_weight = {     0:1,
                      1:0.5197368421,
                      2:0.4385964912,
                      3:0.2324561404,
                      4:0.2302631579,
                      5:0.399122807,
                      6:0.08114035088,
                      7:0.5723684211,
                      8:0.08552631579,
                      9:0.2061403509,
                      10:0.3815789474,
                      11:0.125,
                      12:0.08333333333,
                      13:0.1206140351,
                      14:0.1403508772,
                      15:0.4824561404
                      }

最后我运行了model.fit

history = model2.fit(X_train2, y_train2, epochs=25, validation_data=(X_test2, y_test2), batch_size=64, class_weight = sample_weight, shuffle = False)

我的问题是,模型的最大准确率在30%到40%左右。我调查了一下,他们说调整学习率很重要。我还发现,在一定程度上,提高历元会有所帮助,降低批量大小也是如此。我还遗漏了什么吗?我注意到,较差的模型经常只能预测一个类(100%正常,0%其他),但更好的模型是按滑动比例预测的,其中一些项目为10%,一些为70%。
我还想知道我是否颠倒了样本权重,我的项目0中包含的项目最多...是否应该颠倒,其中1个样本1对应2个样本0?

  • 谢谢-谢谢
    我试过的东西。
  • 将批处理大小向下更改为16或8。(导致更长的历元时间,结果略好)
  • 将学习速率更改为较低的数值(结果稍好,但时间更长)
  • 将其更改为100个历元(结果通常在20个历元左右稳定。)
  • 尝试创建更多参数、更高过滤器、更大初始内核大小、更大初始池大小、更多且值更高的密集层。(这会导致占用RAM,并且没有获得更好的结果。)
  • 将优化器改为Adam、RAdam或AdamMax。(实际上并没有改变太多,其他的优化器都很糟糕)。我还把beta_1和epsilon弄得一团糟。
  • 修改简历。(数据相当模糊,有帮助,仍然很难分辨)
  • 删除坏数据(我不想摆脱太多的图片。)

编辑:增加了样本准确度。这一个异常低,但开始时足够好(准确度最初是25. 9%)
14/14 [==================================] -79秒6秒/步-损耗:0.4528 -精度:0.2592 -均方根误差:0.1594 -瓦尔_损失:261.8521 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1416时间点2/25 14/14 [=========================================] -85 s 6s/阶跃-损耗:0.2817 -精度:0.3188 -平均误差:0.1310 -瓦尔_损失:22.7037 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1416时间点3/25 14/14 [=========================================] -79秒6秒/阶跃-损耗:0.2611 -精度:0.3555 -均方根误差:0.1243 -瓦尔_损失:11.9977 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1416时间点4/25 14/14 [============================================] -80秒6秒/阶跃-损耗:0.2420 -精度:0.3521 -均方根误差:0.1172 -瓦尔_损失:6.6056 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1416时间点5/25 14/14 [==========================================] -80秒6秒/阶跃-损耗:0.2317 -精度:0.3899 -均方根误差:0.1151 -瓦尔_损失:4.9567 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1415时间点6/25 14/14 [=========================================] -80秒6秒/阶跃-损耗:0.2341 -精度:0.3899 -均方根误差:0.1141 -瓦尔_损失:2.7395 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1389时间点7/25 14/14 [======================================] -76秒5秒/阶跃-损耗:0.2277 -精度:0.4128 -均方根误差:0.1107 -瓦尔_损失:2.3758 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1375时间点8/25 14/14 [=========================================] -85秒6秒/步-损耗:0.2199 --精度:0.4106 -均方根误差:0.1094 -瓦尔_损失:1.4526 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1319时间点9月25日14月14日[=======================================] -76秒5秒/阶跃-损耗:0.2196 --精度:0.4151 -均方根误差:0.1086 -瓦尔_损失:0.7962 -瓦尔_准确度:0.3881 -瓦尔_最小误差:0.1212纪元10/25 14/14 [=============================================] -80秒6秒/阶跃-损耗:0.2187 --精度:0.4140 -均方根误差:0.1087 -瓦尔_损失:0.6308 -瓦尔_准确度:0.3744 -瓦尔_最小误差:0.1211时间点11/25 14/14 [==========================================] -81秒6秒/阶跃-损耗:0.2175 -精度:0.4071 -均方根误差:0.1086 -瓦尔_损失:0.5986 -瓦尔_准确度:0.3242 -瓦尔_MSE:0.1170纪元12/25 14/14 [==============================================] -80秒6秒/阶跃-损耗:0.2087 -准确度:0.3968 -均方根误差:0.1034 -瓦尔_损失:0.4003 -瓦尔_准确度:0.3333 -瓦尔_MSE:0.1092时间点13/25 12/14 [预计到达时间:10 s-损失:0.2092 -准确度:0.3945 -均方根误差:0.1044

2eafrhcq

2eafrhcq1#

以下是一些可能有所帮助的注意事项:

  • 当使用批处理规范化时,避免太小的批处理大小。有关详细信息,请参阅Yuxin Wu和Kaiming He的 Group Normalization 论文。
  • 如果你有一个不平衡的多类案例,那么你可能需要看看像AUC和F1这样的指标,你可以把tf.keras.metrics.AUC(curve='PR')添加到你的指标列表中。
  • 训练损失似乎在第13个时段结束时停止。如果训练损失不再减少,您可能需要1.使用较小的学习速率,和/或2.减少您的退出参数。特别是,在您的最后一层之前相对较大的退出对我来说似乎是可疑的。首先,尝试获得与训练数据集非常吻合的模型这是一个重要的步骤。如果您的模型在没有任何正则化的情况下不能很好地拟合您的训练数据集,它可能需要更多的可训练参数。2在获得一个适合训练数据集的最小模型之后,你可以添加正则化机制来缓解过度拟合的问题。
  • 除非您有充分的理由,否则请设置shuffle = True(也是默认设置),以便在每个历元之前打乱训练数据。
  • 虽然这可能不是问题的根本原因,但对于规范化应该在激活之前还是之后进行,仍存在争议。有些人倾向于在激活之前使用规范化。
  • 我不清楚以下几点:

然后指定样本权重,该权重是通过取最高采样数并将其他数除以该值计算得出的。
你的类权重可能已经计算正确了。我想强调的是,代表性不足的类应该被分配一个更大的权重。如果需要的话,请参考tutorial from TensorFlow

相关问题