训练集在训练过程中,loss稳步下降,准确率上升,最后能达到97%
验证集准确率没有升高,一直维持在50%左右(二分类问题,随机概率)
测试集准确率57%

在网上搜索可能打的原因:
1.learning rate太小,陷入局部最优

2.训练集和测试集数据没有规律

3.数据噪声太大

4.数据量太小(总共1440个样本,80%为训练集)

5.训练集和测试集数据分布不同:如训练集正样本太少(如果训练集和测试集每次运行随机选择,则排除)

6.数据集存在问题,如标注有问题(如采用公开数据集,则排除)

7.学习率过大

8.模型参数量过多而数据量过少

9.过拟合,数据量太小但是模型的结构较为复杂
解决办法:降低模型的复杂度,增大L2正则项,在全连接层加入Dropout层;有了dropout,网络不会为任何一个特征加上很高的权重(因为那个特征的输入神经元有可能被随机删除),最终dropout产生了收缩权重平方范数的效果

10.输入到网络中的特征有问题,特征与label之间没有很明确的关联,或特征太少

11.数据没有归一化

12.修改学习率,使得每次梯度下降低于某个值或者停止下降时,降低学习率,来使得梯度进一步下降。(我使用该方法,使得问题得到解决)

【备注:
batch size过小,花费时间多,同时梯度震荡严重,不利于收敛;batch size过大,不同batch的梯度方向没有任何变化,容易陷入局部极小值。】

针对第12点,修改学习率的举例如下:(基于pytorch)

optimizer = torch.optim.SGD(model.parameters(), lr=0.1)  # 优化器
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)  # 设定优优化器更新的时刻表def train(...):for i, data in enumerate(train_loader):     ......y_ = model(x)   loss = criterion(y_,y)     optimizer.zero_grad()     loss.backward()             optimizer.step()            ......# 开始训练
for epoch in range(epochs):scheduler.step()        #在每轮epoch之前更新学习率train(...)veritf(...)

等间隔调整学习率 StepLR
torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)
每训练step_size个epoch,学习率调整为lr=lr*gamma.
参数:
optimizer: 神经网络训练中使用的优化器,如optimizer=torch.optim.SGD(…)
step_size(int): 学习率下降间隔数,单位是epoch,而不是iteration.
gamma(float): 学习率调整倍数,默认为0.1
last_epoch(int): 上一个epoch数,这个变量用来指示学习率是否需要调整。当last_epoch符合设定的间隔时,就会对学习率进行调整;当为-1时,学习率设置为初始值。
学习率变化如下图所示:

当然调整学习率的方式还有很多:
多间隔调整学习率 MultiStepLR
指数衰减调整学习率 ExponentialLR
余弦退火函数调整学习率:
根据指标调整学习率 ReduceLROnPlateau
自定义调整学习率 LambdaLR

网上都可以查到,这里就不一一列举了。

欢迎留言讨论~ ^ _ ^

# 前面省略了一部分代码,下面的代码仅供代码格式参考:
args = parser.parse_args()
device = 'cuda' if torch.cuda.is_available() else 'cpu'
best_acc = 0
start_epoch = 0  # Data
print('==> Preparing data..')
transform_train = transforms.Compose([transforms.RandomCrop(32, padding=4),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])transform_test = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])dict_datasets={'CIFAR10':torchvision.datasets.CIFAR10, 'CIFAR100':torchvision.datasets.CIFAR100}trainset = dict_datasets[args.datasets](root='./data', train=True, download=True, transform=transform_train)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=args.batchsize, shuffle=True, num_workers=0)testset = dict_datasets[args.datasets](root='./data', train=False, download=True, transform=transform_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=args.batchsize_test, shuffle=False, num_workers=0)global_x.plot_lr=[]
best_acc=0
# Model
print('==> Building model..')
net = dict_model[args.model]net = net.to(device)
if device == 'cuda':net = torch.nn.DataParallel(net)cudnn.benchmark = Truecriterion = nn.CrossEntropyLoss()
#####################################################
optimizer = optim.SGD(net.parameters(), lr=args.lr,momentum=0.8, weight_decay=5e-4)scheduler = lr_scheduler.Warmup_lineardecay(optimizer, T_max=args.epochs, improved=args.improved)
##################################################
# Training
train_Acc=np.array([])
train_Loss=np.array([])
def train(epoch):global train_Accglobal train_Lossprint('\nEpoch: %d' % epoch)net.train()train_loss = 0correct = 0total = 0for batch_idx, (inputs, targets) in enumerate(trainloader):inputs, targets = inputs.to(device), targets.to(device)optimizer.zero_grad()outputs = net(inputs)loss = criterion(outputs, targets)loss.backward()##################梯度更新optimizer.step()##################train_loss += loss.item()_, predicted = outputs.max(1)total += targets.size(0)correct += predicted.eq(targets).sum().item()progress_bar(batch_idx, len(trainloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'% (train_loss/(batch_idx+1), 100.*correct/total, correct, total))train_Acc=np.append(train_Acc,100.*correct/total)train_Loss=np.append(train_Loss,train_loss/(batch_idx+1))if not os.path.exists(args.model):os.mkdir(args.model)np.savetxt(args.model+'/result_of_train_acc.txt',train_Acc,fmt='%f')np.savetxt(args.model+'/result_of_train_loss.txt',train_Loss,fmt='%f')test_Acc=np.array([])
test_Loss=np.array([])
def test(epoch):global test_Accglobal test_Lossglobal best_accnet.eval()test_loss = 0correct = 0total = 0with torch.no_grad():DATA_predict=np.empty([0,10])DATA_predict_index=np.empty([0,1])for batch_idx, (inputs, targets) in enumerate(testloader):inputs, targets = inputs.to(device), targets.to(device)outputs = net(inputs)loss = criterion(outputs, targets)test_loss += loss.item()_, predicted = outputs.max(1)total += targets.size(0)correct += predicted.eq(targets).sum().item()DATA_predict=np.append(DATA_predict,outputs.cpu(),axis=0)DATA_predict_index=np.append(DATA_predict_index,targets.view(-1,1).cpu(),axis=0)progress_bar(batch_idx, len(testloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'% (test_loss/(batch_idx+1), 100.*correct/total, correct, total))test_Acc=np.append(test_Acc,100.*correct/total)global_x.reference_acc = correct/totaltest_Loss=np.append(test_Loss,test_loss/(batch_idx+1))np.savetxt(args.model+'/result_of_test_acc.txt',test_Acc,fmt='%f')np.savetxt(args.model+'/result_of_test_loss.txt',test_Loss,fmt='%f')# Save checkpoint.acc = 100.*correct/totalif acc > best_acc:np.savetxt(args.model+'_DATA_predict.txt',DATA_predict,fmt='%f')np.savetxt(args.model+'_DATA_predict_index.txt',DATA_predict_index,fmt='%d')print('Saving..')state = {'net': net.state_dict(),'acc': acc,'epoch': epoch,}if not os.path.isdir('checkpoint'):os.mkdir('checkpoint')torch.save(state, './checkpoint/ckpt.pth')best_acc = accfor epoch in range(start_epoch, start_epoch+args.epochs):train(epoch)test(epoch)################学习率更新,每轮更新一次,有些学习率的更新是每次迭代更新一次,注意区分,如果是每次迭代更新一次,可以把这一行放在梯度更新的下一行scheduler.step()###################

对于此问题,进行的更新:
以下内容参考
版权声明:本文为CSDN博主「TinaO-O」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013249853/article/details/89393982

0.学习率设置太高,一个epoch直接收敛,所以损失不会下降
比如学利率一开始设置为1,因为下降太快,那么很有可能在一个epoch旧完全收敛。所以看到的validation数值并不下降,第一个epoch就已经处于谷底了。所以如果使用的是系统默认的学习率,最好检查下默认值是什么。

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类,这显然就是不合理的。
遇到这种情况,建议:

1.使用别的大的数据集预训练
2.使用DATA augment
3.可以考虑迁移学习

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

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

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

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

9.batch normalization需要batch size至少16张
https://mp.csdn.net/postedit/89456400
由于做dense prediction图片通常比较大。所以一个batch一般都只有1-2张图片,不建议使用 BN。
因为BN一般是16张图片以上一起跑。所以吧,如果是BN,那么请用多GPU,16以上的batch size。s
另外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

训练集准确率很高,验证集准确率低问题相关推荐

  1. 使用resnet, inception3进行fine-tune出现训练集准确率很高但验证集很低的问题

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 最近用keras跑基于resnet50,inception3的一些迁移学习的实验,遇到一些问题 ...

  2. 【已解决】使用keras对resnet, inception3进行fine-tune出现训练集准确率很高但验证集很低的问题(BN)

    最近用keras跑基于resnet50,inception3的一些迁移学习的实验,遇到一些问题.通过查看github和博客发现是由于BN层导致的,国外已经有人总结并提了一个PR(虽然并没有被merge ...

  3. keras训练模型,训练集的准确率很高,但是测试集准确率很低的原因

    今天在测试模型时发现一个问题,keras训练模型,训练集准确率很高,测试集准确率很低,因此记录一下希望能帮助大家也避坑: 首先keras本身不同的版本都有些不同的或大或小的bug,包括之前也困扰过我的 ...

  4. 【问题解决】训练和验证准确率很高,但测试准确率很低

    前情提要: 采用ResNet50预训练模型训练自己的图像分类模型.训练和验证阶段准确率很高,但随机输入一张图片时,大多数情况下依旧预测得不准确. (于是开始搜索各种"验证准确率高但测试准确率 ...

  5. 【转载】如何理解数据集中【训练集】、【验证集】和【测试集】

    转自<吴恩达深度学习笔记(28)-网络训练验证测试数据集的组成介绍> 训练,验证,测试集(Train / Dev / Test sets) 在配置训练.验证和测试数据集的过程中做出正确决策 ...

  6. 十个原因可能导致 训练集明明很高,验证集,测试集 validation accuracy stuck 准确率 很低 损失不减小

    损失函数一直在下降,为什么识别率上不去. ----------------2021-01-08更新----------------------- 0.学习率设置太高,一个epoch直接收敛,所以损失不 ...

  7. 训练模型的准确率很高,但是验证集准确率特别低

    训练图的过程如下: 训练结果: 训练的loss很低,而且正确率已经很高了,但是在验证集上面,loss比较高,而且准确率特别低,还一直不稳定. 产生原因: 将每个类别的数据集中的放在一起,而且数据标签也 ...

  8. pytorch实现图像分类,训练集准确率很高,测试集准确率总是很低

    在使用pytorch运行图像分类的代码的时候,发现测试集准确率总是只有30%左右, 但是训练集准确率基本可以达到80%以上,那么存在的问题可能是一下几个方面导致的: 1.学习率设置得太高,可以尽量将学 ...

  9. 训练集明明很高,验证集,测试集精度却很低

    损失函数一直在下降,为什么识别率上不去. 1.最常见的原因:过拟合 过拟合值得单独开个章节.主要包括 1.数据量小,网络复杂 2.learning rate 比较高,又没有设置任何防止过拟合的机制 解 ...

最新文章

  1. Centos7安装Nginx+PHP
  2. python【力扣LeetCode算法题库】257- 二叉树的所有路径
  3. 集合还有这么优雅的运算法?
  4. 【Python学习】 - sklearn学习 - 数据集分割方法 - 随机划分与K折交叉划分与StratifiedKFold与StratifiedShuffleSplit
  5. 【语音加密】基于matlab混沌+AES语音加密解密【含Matlab源码 1593期】
  6. 2022爱分析·营销服务一体化实践报告
  7. PGP加密解密QQ邮箱邮件
  8. 网页进行pdf打印_将多个pdf文档合并为一个pdf
  9. excel合并两列内容_Excel中如何跳过空单元格进行粘贴
  10. 别有幽愁暗恨生,此时无声胜有声——python循环结构
  11. matlab表达式中的省略号,使用正则表达式匹配省略号
  12. 删除联想硬盘OEM分区——最简单方法
  13. 如何解决程序员沟通之痛?
  14. 使用dd命令制作固定大小的文件
  15. CentOS 7 YUM安装MariaDB 10.1
  16. C/C++常用的文件函数注释格式
  17. R语言中的countif——dplyr包中的filter函数和nrow
  18. 沃尔玛腾讯云 Serverless 应用实践,全力保障消费者购物体验
  19. 详解搜索引擎的工作原理
  20. 论文阅读 [TPAMI-2022] Incremental Density-Based Clustering on Multicore Processors

热门文章

  1. 按钮button,submit添加鼠标点击事件
  2. ZCMU-1677-小学生小明,圣光会制裁你!!!
  3. pytorch实现图像上采样的几种方式
  4. 集成电路测试简介(1)
  5. 王者荣耀服务器维护s24赛季,《王者荣耀》s24赛季更新到什么时候 S24赛季停机更新时间...
  6. QT 录音同时动态显示声音大小 及 一个噪音问题
  7. 创新实训——飞讯(十)
  8. scp免密登录,同时也适应ssh免密登录
  9. 使用Vue+go实现前后端文件的上传下载,csv文件上传下载可直接照搬
  10. Leetcode 289:生命游戏(最详细的解法!!!)