ResNet训练准确率太低

ResNet训练准确率太低,不知道怎么更改,请求帮助
这是训练的结果:

img

下面是我的代码:

from keras.models import Model
from keras.optimizers import Adam
from keras.layers import Conv2D, Input, MaxPooling2D, Dropout, concatenate, UpSampling2D
import numpy as np
from keras.callbacks import ModelCheckpoint, LearningRateScheduler
from PIL import Image
import matplotlib.pyplot as plt

# import the necessary packages
from keras.layers import BatchNormalization
from tensorflow.python.keras.layers import Conv2D
from tensorflow.python.keras.layers import AveragePooling2D
from tensorflow.python.keras.layers import MaxPooling2D
from tensorflow.python.keras.layers import ZeroPadding2D
from tensorflow.python.keras.layers import Activation
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras.layers import Flatten
from tensorflow.python.keras.layers import Input
from tensorflow.python.keras.models import Model
from tensorflow.python.keras.layers import add
from tensorflow.python.keras.regularizers import l2
from tensorflow.python.keras import backend as K
from tensorflow.python.keras.optimizers import adam_v2
from tensorflow.python.keras.optimizers import gradient_descent_v2

def generateds(path, txt):#图片路径, 标签文件
    f = open(txt, 'r')  # 以只读形式打开txt文件
    contents = f.readlines()  # 读取文件中所有行
    f.close()  # 关闭txt文件
    x, y_ = [], []  # 建立空列表
    for content in contents:  # 逐行取出
        value = content.split()  # 以空格分开,图片路径为value[0] , 标签为value[1] , 存入列表
        print(path)
        print(value[0])
        img_path = path + value[0]  # 拼出图片路径和文件名
        print(img_path)
        img = Image.open(img_path)  # 读入图片
        img = img.resize((64, 64), Image.ANTIALIAS)
        img = np.array(img.convert('RGB'))  # 图片变为8位宽灰度值的np.array格式
        img = img / 255.  # 数据归一化 (实现预处理)
        x.append(img)  # 归一化后的数据,贴到列表x
        y_.append(value[1])  # 标签贴到列表y_
        print('loading : ' + content)  # 打印状态提示

    x = np.array(x,dtype='float32')  # 变为np.array格式
    y_ = np.array(y_)  # 变为np.array格式
    y_ = y_.astype(np.int64)  # 变为64位整型
    return x, y_  # 返回输入特征x,返回标签y_

train_path = r'D:/ningyupeng/pythonProject/data_cell_images/'  # 训练集图片路径
train_txt = r'D:/ningyupeng/pythonProject/data_cell_images/train.txt'  # 训练集标签文件
x_train_savepath = r'D:/ningyupeng/pythonProject/data_cell_images/mnist_x_train.npy'
y_train_savepath = r'D:/ningyupeng/pythonProject/data_cell_images/mnist_y_train.npy'

test_path = r'D:/ningyupeng/pythonProject/data_cell_images/'  # 测试集图片路径
test_txt = r'D:/ningyupeng/pythonProject/data_cell_images/test.txt'  # 测试集标签文件
x_test_savepath = r'D:/ningyupeng/pythonProject/data_cell_images/mnist_x_test.npy'
y_test_savepath = r'D:/ningyupeng/pythonProject/data_cell_images/mnist_y_test.npy'

x_train, y_train = generateds(train_path, train_txt)
x_test, y_test = generateds(test_path, test_txt)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train, x_test = x_train / 255.0, x_test / 255.0  # 归一化,将每一个像素缩放到0-1之间
print("x_train.shape", x_train.shape)
x_train = x_train.reshape(x_train.shape[0], 64, 64, 3)
x_test = x_test.reshape(x_test.shape[0], 64, 64, 3)
print("x_train.shape", x_train.shape)

##train = train[0]
# 定义u-Net网络模型
# def Resnet():
class ResNet:
    @staticmethod
    def residual_module(data, K, stride, chanDim, red=False, reg=0.0001, bnEps=2e-5, bnMom=0.9):
        # the shortcut branch of the ResNet module should be
        # initialize as the input (identity) data
        shortcut = data
        # the first block of the ResNet module are the 1x1 CONVs
        bn1 = BatchNormalization(axis=chanDim, epsilon=bnEps, momentum=bnMom)(data)
        act1 = Activation("relu")(bn1)
        conv1 = Conv2D(int(K * 0.25), (1, 1), use_bias=False, kernel_regularizer=l2(reg))(act1)

        # the second block of the ResNet module are the 3x3 CONVs
        bn2 = BatchNormalization(axis=chanDim, epsilon=bnEps, momentum=bnMom)(conv1)
        act2 = Activation("relu")(bn2)
        conv2 = Conv2D(int(K * 0.25), (3, 3), strides=stride, padding="same", use_bias=False,
                       kernel_regularizer=l2(reg))(act2)

        # the third block of the ResNet module is another set of 1x1
        # CONVs
        bn3 = BatchNormalization(axis=chanDim, epsilon=bnEps, momentum=bnMom)(conv2)
        act3 = Activation("relu")(bn3)
        conv3 = Conv2D(K, (1, 1), use_bias=False, kernel_regularizer=l2(reg))(act3)

        # if we are to reduce the spatial size, apply a CONV layer to
        # the shortcut
        if red:
            shortcut = Conv2D(K, (1, 1), strides=stride, use_bias=False, kernel_regularizer=l2(reg))(act1)

        # add together the shortcut and the final CONV
        x = add([conv3, shortcut])
        # return the addition as the output of the ResNet module
        return x

    @staticmethod
    def build(width, height, depth, classes, stages, filters, reg=0.0001, bnEps=2e-5, bnMom=0.9, dataset="cifar"):
        # initialize the input shape to be "channels last" and the
        # channels dimension itself
        inputShape = (height, width, depth)
        chanDim = -1
        # if we are using "channels first", update the input shape
        # and channels dimension
        if K.image_data_format() == "channels_first":
            inputShape = (depth, height, width)
            chanDim = 1

        # set the input and apply BN
        inputs = Input(shape=inputShape)
        x = BatchNormalization(axis=chanDim, epsilon=bnEps, momentum=bnMom)(inputs)
        # check if we are utilizing the CIFAR dataset
        if dataset == "cifar":
            # apply a single CONV layer
            x = Conv2D(filters[0], (3, 3), use_bias=False, padding="same", kernel_regularizer=l2(reg))(x)

        # loop over the number of stages
        for i in range(0, len(stages)):
            # initialize the stride, then apply a residual module
            # used to reduce the spatial size of the input volume
            stride = (1, 1) if i == 0 else (2, 2)
            x = ResNet.residual_module(x, filters[i + 1], stride, chanDim, red=True, bnEps=bnEps, bnMom=bnMom)

            # loop over the number of layers in the stage
            for j in range(0, stages[i] - 1):
                x = ResNet.residual_module(x, filters[i + 1], (1, 1), chanDim, bnEps=bnEps, bnMom=bnMom)

        # apply BN => ACT => POOL
        x = BatchNormalization(axis=chanDim, epsilon=bnEps, momentum=bnMom)(x)
        x = Activation("relu")(x)
        x = AveragePooling2D((8, 8))(x)
        # softmax classifier
        x = Flatten()(x)
        x = Dense(classes, kernel_regularizer=l2(reg))(x)
        x = Activation("softmax")(x)

        # create the model
        model = Model(inputs, x, name="resnet")

        # return the constructed network architecture
        return model



# 开始训练
model = ResNet.build(64, 64, 3, 2, (3, 4, 6), (64, 128, 256, 512), reg=0.0005)
# 每个epoch后保存模型到 uNet_Skin.hdf5
model_checkpoint = ModelCheckpoint('./uNet_Skin_test.ckpt',monitor='loss',verbose=1,save_weights_only=True,save_best_only=True)

opt = gradient_descent_v2.SGD(lr=1e-1, momentum=0.9)
# 优化器为 Adam,损失函数为 binary_crossentropy,评价函数为 accuracy
model.compile(optimizer=opt,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
# 训练
history = model.fit(x_train, y_train, batch_size=32, epochs=5, verbose=1,
                   validation_data=(x_test, y_test), validation_freq=1, shuffle=True, callbacks=[model_checkpoint])
# 展示一下精确度随训练的变化图
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['accuracy', 'val_accuracy'], loc='upper left')
plt.show()
# 展示一下loss随训练的变化图
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['loss', 'val_loss'], loc='upper left')
plt.show()


该回答引用GPTᴼᴾᴱᴺᴬᴵ
从训练结果来看,准确率确实很低,可能存在一些问题。下面我会根据代码提供一些可能出现的问题以及解决方案。

  1. 数据预处理是否正确
    在深度学习中,数据预处理非常重要。你需要确保你的数据已经被正确预处理。例如,如果你的数据是RGB图像,你需要将它们转换为合适的张量形状,并对像素值进行归一化。你需要检查一下你的数据预处理部分是否正确。

  2. 训练集与测试集是否正确划分
    你需要确保你的训练集和测试集划分正确。训练集应该用于模型的训练和验证集应该用于模型的验证。你可以通过打印一下你的训练集和测试集的形状来确保它们的划分是正确的。

  3. 损失函数是否正确选择
    在代码中,你使用了sparse_categorical_crossentropy作为损失函数,但是如果你的标签是one-hot编码的,你应该使用categorical_crossentropy作为损失函数。如果你的标签是整数编码的,那么使用sparse_categorical_crossentropy是正确的。

  4. 学习率是否合适
    学习率是优化算法中非常重要的一个参数。如果学习率太大,模型可能会发散;如果学习率太小,模型可能会收敛得太慢。你需要尝试不同的学习率来找到一个合适的学习率。

  5. 模型架构是否正确
    模型的架构可能会影响模型的性能。你可以尝试使用更深的模型或者更广的模型来提高模型的性能。

  6. 过拟合
    在深度学习中,过拟合是一个常见的问题。你需要确保你的模型没有过拟合。你可以使用正则化技术、dropout等方法来避免过拟合。

综上所述,我建议你可以检查一下以上问题,尝试不同的解决方案来提高模型的准确率。同时,你也可以尝试使用其他的优化器、损失函数、正则化方法等来提高模型的性能。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^