使用keras进行深度学习时准确率很低的原因

keras单独使用CNN和LSTM时训练和测试的准确率都很低

import keras
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from keras.models import Model, load_model, Sequential
from keras.layers import *
from tensorflow import keras
from keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import SGD, Adam
from sklearn.preprocessing import minmax_scale
from sklearn.model_selection import train_test_split
import os

os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "1"
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

from tensorflow.python.client import device_lib

print(device_lib.list_local_devices())

# ——————————————————————————数据预处理————————————————————————————
data = pd.read_excel(r".\data\lncRNA(function).xlsx")  # lncRNA与其他分子的相互作用关系
for i in range(len(data)):
    data['cancer type'][i].lower()
data2 = pd.read_excel(r".\data\lncRNA(mechanism).xlsx")  # lncRNA与其他分子的相互作用关系
for i in range(len(data2)):
    data2['cancer type'][i].lower()
data = pd.merge(data, data2, on=['name', 'cancer type'], how='inner')  # 将两个表按cancer type进行内连接
output = data['cancer type']
print(len(output))
print(type(output))
# 用lncRNA的结构来判断该疾病产生原因
# 输入矩阵 10个RNA结构
data = [list(t) for t in zip(data['Immune'], data['autophagy/Apoptosis'], data['Cell Growth'], data['EMT'],
                             data['Survival'], data['TF'], data['Enhancer'], data['Variant'], data['MiRNA'],
                             data['Methylation'])]
# 将结构中的单词和字符串转换成数字便于后续处理
print(type(data))
for i in range(len(data)):
    if data[i][1] == '0':
        data[i][1] = 0
    else:
        data[i][1] = 1
    if data[i][0] == '0':
        data[i][0] = 0
    else:
        data[i][0] = 1
data = np.array(data)
input = data
mylist = set(output)
mydata = []
for item in mylist:
    mydata += [item]
print("type:", len(mydata))
# 将疾病名字标号成数字便于训练
for i in range(len(output)):
    output[i] = mydata.index(output[i])
output = list(output)
output = minmax_scale(output, feature_range=(0, 143))
output = np.array(output, dtype=int)
print("预处理完毕")
# ——————————————————————————模型训练————————————————————————————
train_rate = 0.6
y = output
x, test_X, _, test_y = train_test_split(input, output,  train_size=train_rate,test_size=1-train_rate,
                                                 random_state=2, shuffle=True)
print(x.shape, y.shape)

# design network
# CNN


def design_model():
    # 模型参数
    model = Sequential()
    # Convolution  卷积
    pool_length = 1  # 池化长度
    # LSTM
    lstm_output_size = 70  # LSTM 层输出尺寸
    # Training   训练参数
    batch_size = 64  # 批数据量大小
    nb_epoch = 10000  # 迭代次数
    learning_rate = 0.0001

    inputs = Input(shape=(10, 1))  # 输入特征接收维度
    a = Dropout(0.25)(inputs)
    conv1 = Convolution1D(1, 3, strides=1, padding="same", dilation_rate=1, activation='relu')(a)  # filters, kernel_size, strides=1
    max1 = MaxPooling1D(pool_size=pool_length)(conv1)
    conv2 = Convolution1D(2, 3, strides=1, padding="same", dilation_rate=1, activation='relu')(max1)  # filters, kernel_size, strides=1
    max2 = MaxPooling1D(pool_size=pool_length)(conv2)
    conv3 = Convolution1D(4, 3, strides=1, padding="same", dilation_rate=1, activation='relu')(max2)  # filters, kernel_size, strides=1
    max3 = MaxPooling1D(pool_size=pool_length)(conv3)
    lstm1 = LSTM(lstm_output_size)(max3)
    lstm1 = Dropout(0.25)(lstm1)
    output = Dense(144, activation='softmax')(lstm1)
    model = Model(inputs=inputs, outputs=output)
    model.summary()
    adam = Adam(lr=learning_rate)

    learningRate = 0.00001
    momentum = 0.9
    decay_rate = 0.01
    sgd = SGD(lr=learningRate, momentum=momentum, decay=decay_rate, nesterov=False)

    model.compile(optimizer=adam,
                  loss='sparse_categorical_crossentropy',
                  metrics=['sparse_categorical_accuracy'])
    # sparse_categorical_crossentropy
    # accuracy
    # 训练
    callback = keras.callbacks.EarlyStopping(monitor='loss', patience=100)
    # 读取已保存的模型
    #model = load_model('my_model9.h5')
    history = model.fit(x, y, batch_size=batch_size, epochs=nb_epoch,
                        validation_split=0.2, callbacks=[callback])
    # 保存模型 17.3%
    model.save('my_model9.h5')
    # plot history
    plt.plot(history.history['loss'], label='train')
    plt.plot(history.history['val_loss'], label='val')
    score = model.evaluate(test_X, test_y, batch_size=32)[1]
    print(score)  # [loss,accuracy]
    print("%s: %.2f%%" % (model.metrics_names[1], score * 100))

    plt.legend()
    plt.show()


design_model()




数据集下载链接
链接:https://pan.baidu.com/s/1Ce1-ADIo8NtkBt_zH81BNg?pwd=7av9
提取码:7av9
训练和验证准确率:

img

测试准确率:

img

印象里做分类时,加了lstm 都不太好,只用卷积呢

可以参考一下这篇文章:https://blog.csdn.net/qq_52914392/article/details/120022268

如果纯是看你的代码的话,我感觉你这个网络太简单了点,还有可能你的学习速率调得太小,导致收敛得很慢,可以尝试将学习速率调大。
反正就是不断尝试嘛。(我并没有运行您的代码,若有说错,请多多包涵。)

更改为sigmoid

Dense(144, activation='softmax')

把上面改成下面

Dense(144, activation='sigmoid')

如有帮助,请采纳,十分感谢!

分类使用lstm这种时序信息感觉不是主要引导因素,可以使用transfomer建模,还有就是学习率实在太低了,我觉得网络学不到什么。给你几个建议,模型中加入一下batchnorm层,让数据分布平稳些;还有就是网络太过简单,可以换个vgg16这种,keras里有集成的,transfomer估计要用torch;还有使用sgd优化器试试,虽然没有adam稳定,但是它可以让loss下降的更快,收敛的更快,学习率也一样如此
望采纳!!

1,要确定问题要绘制一下loss 曲线如果收敛了很低说明过拟合了 少训练试试 如果 还是差说明模型表达不够 加参数或者是层数,
2,还有要画出混淆矩阵 pr 曲线 分析 数据集均衡与否,数据集类别要均衡 不均衡可以搜索均衡数据集的方法

(1).模型是否出现过拟合现象
(2).训练集与验证集是否存在随机处理。
(3).设置计算训练准确率跟验证准确率的计算方式不同。
(4).keras底层是否对训练集跟验证集的准确率,损失的计算方式不同。
https://www.zhihu.com/question/369432140/answer/2093336277

1.最常见的原因:过拟合
过拟合值得单独开个章节。主要包括

1.数据量小,网络复杂

2.learning rate 比较高,又没有设置任何防止过拟合的机制

解决方法主要包括

1.简化模型,利用现有深度学习手段增加数据(翻转,平移,随机裁剪,imgaug)

2.利用 dropout层

3.利用正则化

2.你犯了错误:没有把数据规格化
图片的话,img/255是肯定的

3.你犯了错误:没有在分验证集之前打乱数据
因为validation_split操作不会为你shuffle数据,所以如果你的数据前一半标签全是1 ,后一半全是0,validation=0.5。恭喜你,你压根也分不对,你的validation准确率会一直为0.因为你拿所有的正样本训练,却想判断负样本。

4.你犯了错误,数据和标签没有对上
有可能再读取自定义的数据库的时候出现问题,导致数据与标注不对应。比如第一张图片用第十张的标注

5.你的训练数据太少,validation数据太多,类别也太多
比如4000张训练,1000张validation,300类,这显然就是不合理的

6.最好使用预训练的权重
大多数流行的backone比如resnet都有再imagenet数据集上与训练过,那么使用这种权重,比起随即重新训练,显然要可靠不少注意调整学习率。

7.网络结构有问题
可以通过使用现在流行的网络(resnet,unet等)替入你的代码,如果结果没有问题,你的结果有问题那么肯定就是你网络结构出问题了。那么可以通过逐层注释掉排查究竟哪里出了问题

7.1 网络最后一层没有使用正确的激活函数
比如多类的应该使用softmax

8.relu后面是softmax
有一些说法是relu由于对于很大的数值直接复制,所以会对softmax产生不好的影响,从而输出不好的结果。所以可以使用tanh代替relu。

9.batch normalization
https://mp.csdn.net/postedit/89456400

由于做dense prediction图片通常比较大。所以一个batch一般都只有1-2张图片,不建议使用 BN。

另外keras TF1.x可能会出问题,https://github.com/keras-team/keras/pull/9965

10.你犯了错误,你可能设置了一些参数是不可训练的
在训练语句之前,检查以下你的trainable参数,是否设置了一些参数是不可训练的。这还可能导致你的输出只能是一个值,比如永远预测为标注0,因为你只有一点点的参数,而这并不是一个模型(比如只有100个参数是可以训练的,太简单了,无法模拟)。

11.附送一个调参论文
Bag of Tricks for Image Classification with Convolutional Neural Networks

https://arxiv.org/abs/1812.01187