当前位置:   article > 正文

pytorch进阶学习(四):使用不同分类模型进行数据训练(alexnet、resnet、vgg等)_pytorch训练分类模型

pytorch训练分类模型

课程资源5、帮各位写好了十多个分类模型,直接运行即可【小学生都会的Pytorch】_哔哩哔哩_bilibili

 

目录

一、项目介绍

 1. 数据集准备

2. 运行CreateDataset.py

3. 运行TrainModal.py 

4. 如何切换显卡型号

二、代码

1. CreateDataset.py

2.TrainModal.py 

3. 运行结果


一、项目介绍

 1. 数据集准备

数据集在data文件夹下

 

2. 运行CreateDataset.py

运行CreateDataset.py来生成train.txt和test.txt的数据集文件。

 

3. 运行TrainModal.py 

进行模型的训练,从torchvision中的models模块import了alexnet, vgg, resnet的多个网络模型,使用时直接取消注释掉响应的代码即可,比如我现在训练的是vgg11的网络。

  1. # 不使用预训练参数
  2. # model = alexnet(pretrained=False, num_classes=5).to(device) # 29.3%
  3. ''' VGG系列 '''
  4. model = vgg11(weights=False, num_classes=5).to(device) # 23.1%
  5. # model = vgg13(weights=False, num_classes=5).to(device) # 30.0%
  6. # model = vgg16(weights=False, num_classes=5).to(device)
  7. ''' ResNet系列 '''
  8. # model = resnet18(weights=False, num_classes=5).to(device) # 43.6%
  9. # model = resnet34(weights=False, num_classes=5).to(device)
  10. # model = resnet50(weights= False, num_classes=5).to(device)
  11. #model = resnet101(weights=False, num_classes=5).to(device) # 26.2%
  12. # model = resnet152(weights=False, num_classes=5).to(device)

 同时需要注意的是, vgg11中的weights参数设置为false,我们进入到vgg的定义页发现weights即为是否使用预训练参数,设置为FALSE说明我们不使用预训练参数,因为vgg网络的预训练类别数为1000,而我们自己的数据集没有那么多类,因此不使用预训练。

 

把最后一行中产生的pth的文件名称改成对应网络的名称,如model_vgg11.pth。 

  1. # 保存训练好的模型
  2. torch.save(model.state_dict(), "model_vgg11.pth")
  3. print("Saved PyTorch Model Success!")

4. 如何切换显卡型号

我在运行过程中遇到了“torch.cuda.OutOfMemoryError”的问题,显卡的显存不够,在服务器中使用查看显卡占用情况命令:

nvidia -smi

可以看到我一直用的是默认显卡0,使用情况已经到了100%,但是显卡1使用了67%,还用显存使用空间,所以使用以下代码来把显卡0换成显卡1.

  1. # 设置显卡型号为1
  2. import os
  3. os.environ['CUDA_VISIBLE_DEVICES'] = '1'

 

二、代码

1. CreateDataset.py

  1. '''
  2. 生成训练集和测试集,保存在txt文件中
  3. '''
  4. ##相当于模型的输入。后面做数据加载器dataload的时候从里面读他的数据
  5. import os
  6. import random#打乱数据用的
  7. # 百分之60用来当训练集
  8. train_ratio = 0.6
  9. # 用来当测试集
  10. test_ratio = 1-train_ratio
  11. rootdata = r"data" #数据的根目录
  12. train_list, test_list = [],[]#读取里面每一类的类别
  13. data_list = []
  14. #生产train.txt和test.txt
  15. class_flag = -1
  16. for a,b,c in os.walk(rootdata):
  17. print(a)
  18. for i in range(len(c)):
  19. data_list.append(os.path.join(a,c[i]))
  20. for i in range(0,int(len(c)*train_ratio)):
  21. train_data = os.path.join(a, c[i])+'\t'+str(class_flag)+'\n'
  22. train_list.append(train_data)
  23. for i in range(int(len(c) * train_ratio),len(c)):
  24. test_data = os.path.join(a, c[i]) + '\t' + str(class_flag)+'\n'
  25. test_list.append(test_data)
  26. class_flag += 1
  27. print(train_list)
  28. random.shuffle(train_list)#打乱次序
  29. random.shuffle(test_list)
  30. with open('train.txt','w',encoding='UTF-8') as f:
  31. for train_img in train_list:
  32. f.write(str(train_img))
  33. with open('test.txt','w',encoding='UTF-8') as f:
  34. for test_img in test_list:
  35. f.write(test_img)

2.TrainModal.py 

  1. '''
  2. 加载pytorch自带的模型,从头训练自己的数据
  3. '''
  4. import time
  5. import torch
  6. from torch import nn
  7. from torch.utils.data import DataLoader
  8. from utils import LoadData
  9. import os
  10. os.environ['CUDA_VISIBLE_DEVICES'] = '1'
  11. from torchvision.models import alexnet #最简单的模型
  12. from torchvision.models import vgg11, vgg13, vgg16, vgg19 # VGG系列
  13. from torchvision.models import resnet18, resnet34,resnet50, resnet101, resnet152 # ResNet系列
  14. from torchvision.models import inception_v3 # Inception 系列
  15. # 定义训练函数,需要
  16. def train(dataloader, model, loss_fn, optimizer):
  17. size = len(dataloader.dataset)
  18. # 从数据加载器中读取batch(一次读取多少张,即批次数),X(图片数据),y(图片真实标签)。
  19. for batch, (X, y) in enumerate(dataloader):
  20. # 将数据存到显卡
  21. X, y = X.cuda(), y.cuda()
  22. # 得到预测的结果pred
  23. pred = model(X)
  24. # 计算预测的误差
  25. # print(pred,y)
  26. loss = loss_fn(pred, y)
  27. # 反向传播,更新模型参数
  28. optimizer.zero_grad()
  29. loss.backward()
  30. optimizer.step()
  31. # 每训练10次,输出一次当前信息
  32. if batch % 10 == 0:
  33. loss, current = loss.item(), batch * len(X)
  34. print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")
  35. def test(dataloader, model):
  36. size = len(dataloader.dataset)
  37. # 将模型转为验证模式
  38. model.eval()
  39. # 初始化test_loss 和 correct, 用来统计每次的误差
  40. test_loss, correct = 0, 0
  41. # 测试时模型参数不用更新,所以no_gard()
  42. # 非训练, 推理期用到
  43. with torch.no_grad():
  44. # 加载数据加载器,得到里面的X(图片数据)和y(真实标签)
  45. for X, y in dataloader:
  46. # 将数据转到GPU
  47. X, y = X.cuda(), y.cuda()
  48. # 将图片传入到模型当中就,得到预测的值pred
  49. pred = model(X)
  50. # 计算预测值pred和真实值y的差距
  51. test_loss += loss_fn(pred, y).item()
  52. # 统计预测正确的个数
  53. correct += (pred.argmax(1) == y).type(torch.float).sum().item()
  54. test_loss /= size
  55. correct /= size
  56. print(f"correct = {correct}, Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
  57. if __name__=='__main__':
  58. batch_size = 8
  59. # # 给训练集和测试集分别创建一个数据集加载器
  60. train_data = LoadData("train.txt", True)
  61. valid_data = LoadData("test.txt", False)
  62. train_dataloader = DataLoader(dataset=train_data, num_workers=4, pin_memory=True, batch_size=batch_size, shuffle=True)
  63. test_dataloader = DataLoader(dataset=valid_data, num_workers=4, pin_memory=True, batch_size=batch_size)
  64. # 如果显卡可用,则用显卡进行训练
  65. device = "cuda" if torch.cuda.is_available() else "cpu"
  66. print(f"Using {device} device")
  67. '''
  68. 随着模型的加深,需要训练的模型参数量增加,相同的训练次数下模型训练准确率起来得更慢
  69. '''
  70. # 不使用预训练参数
  71. # model = alexnet(pretrained=False, num_classes=5).to(device) # 29.3%
  72. ''' VGG系列 '''
  73. model = vgg11(weights=False, num_classes=5).to(device) # 23.1%
  74. # model = vgg13(weights=False, num_classes=5).to(device) # 30.0%
  75. # model = vgg16(weights=False, num_classes=5).to(device)
  76. ''' ResNet系列 '''
  77. # model = resnet18(weights=False, num_classes=5).to(device) # 43.6%
  78. # model = resnet34(weights=False, num_classes=5).to(device)
  79. # model = resnet50(weights= False, num_classes=5).to(device)
  80. #model = resnet101(weights=False, num_classes=5).to(device) # 26.2%
  81. # model = resnet152(weights=False, num_classes=5).to(device)
  82. print(model)
  83. # 定义损失函数,计算相差多少,交叉熵,
  84. loss_fn = nn.CrossEntropyLoss()
  85. # 定义优化器,用来训练时候优化模型参数,随机梯度下降法
  86. optimizer = torch.optim.SGD(model.parameters(), lr=1e-3) # 初始学习率
  87. # 一共训练1次
  88. epochs = 1
  89. for t in range(epochs):
  90. print(f"Epoch {t+1}\n-------------------------------")
  91. time_start = time.time()
  92. train(train_dataloader, model, loss_fn, optimizer)
  93. time_end = time.time()
  94. print(f"train time: {(time_end-time_start)}")
  95. test(test_dataloader, model)
  96. print("Done!")
  97. # 保存训练好的模型
  98. torch.save(model.state_dict(), "model_vgg11.pth")
  99. print("Saved PyTorch Model Success!")

3. 运行结果

vgg11的运行结果:,可以看到最后的准确率是24.8%,因为没有用预训练模型,所以准确率很低。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/686448
推荐阅读
相关标签
  

闽ICP备14008679号