当前位置:   article > 正文

利用GPU训练模型的两种方法及Google colab的使用_imgs.cuda()没有

imgs.cuda()没有

本文主要介绍了利用GPU训练模型的两种方法,以及如何利用Google collab来进行训练模型。


文章目录

一、利用GPU训练模型

1 方法一

2 方法二

二、Google colab的使用


一、利用GPU训练模型

1 方法一

需要3个变量
网络模型
损失函数
数据(输入,输出)

像数据集,优化器都没有cuda()这个方法, 所以无法调用

方法一是调用.cuda() 方法, 再进行返回

具体代码如下:

# 网络模型转移到 gpu 上
if torch.cuda.is_available():
    test = test.cuda()   # 利用GPU训练模型, 调用.cuda() 方法, 返回

损失函数转移到 gpu 上
if torch.cuda.is_available():
    loss_fc = loss_fc.cuda()

# 训练数据转移到 gpu 上
        if torch.cuda.is_available():
            imgs = imgs.cuda()
            targets = targets.cuda()

# 测试数据转移到 gpu 上
            if torch.cuda.is_available():
                imgs = imgs.cuda()
                targets = targets.cuda()

其中:

if torch.cuda.is_available():  的作用就是,如果你的电脑有gpu则可以利用gpu来训练模型,没有gpu则跳过,在cpu上运行。

我们这里,如果不写:if torch.cuda.is_available():
由于我的电脑没有gpu, 所以它会直接报错:
AssertionError: Torch not compiled with CUDA enabled

完整代码:

  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.utils.data import DataLoader
  5. from torch.utils.tensorboard import SummaryWriter
  6. import time
  7. # from model import *
  8. # 准备数据集
  9. train_data = torchvision.datasets.CIFAR10("./dataset", train=True, transform=torchvision.transforms.ToTensor(),
  10. download=True)
  11. test_data = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(),
  12. download=True)
  13. # 数据集的 length 长度
  14. train_data_size = len(train_data)
  15. test_data_size = len(test_data)
  16. print("训练数据集的长度为:{}".format(train_data_size))
  17. print("测试数据集的长度为:{}".format(test_data_size))
  18. # 利用 DataLoader 来加载数据集
  19. dataloder_train = DataLoader(train_data, batch_size=64, drop_last=False)
  20. dataloder_test = DataLoader(test_data, batch_size=64, drop_last=False)
  21. # 搭建神经网络
  22. class Test(nn.Module):
  23. def __init__(self):
  24. super(Test, self).__init__()
  25. self.model = nn.Sequential(
  26. nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
  27. nn.MaxPool2d(kernel_size=2),
  28. nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
  29. nn.MaxPool2d(kernel_size=2),
  30. nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
  31. nn.MaxPool2d(kernel_size=2),
  32. nn.Flatten(),
  33. nn.Linear(in_features=1024, out_features=64),
  34. nn.Linear(in_features=64, out_features=10)
  35. )
  36. def forward(self, x):
  37. x = self.model(x)
  38. return x
  39. # 创建网络模型
  40. test = Test()
  41. # 网络模型转移到 gpu 上
  42. if torch.cuda.is_available():
  43. test = test.cuda() # 利用GPU训练模型, 调用.cuda() 方法, 返回
  44. # 损失函数
  45. loss_fc = nn.CrossEntropyLoss()
  46. # 损失函数转移到 gpu 上
  47. if torch.cuda.is_available():
  48. loss_fc = loss_fc.cuda()
  49. # 优化器
  50. learning_rate = 1e-2 # 1e-2 = 1 * 10^(-2) = 1/100 = 0.01
  51. optimizer = torch.optim.SGD(test.parameters(), lr=learning_rate)
  52. # 设置训练网络的一些参数
  53. # 记录训练的次数
  54. total_train_step = 0
  55. # 记录测试的次数
  56. total_test_step = 0
  57. # 训练的轮数
  58. epoch = 10
  59. # 添加 tensorboard
  60. writer = SummaryWriter("logs")
  61. # 获取开始的时间
  62. start_time = time.time()
  63. for i in range(epoch):
  64. print("----------第{}轮训练开始:-------------".format(i+1))
  65. # 训练步骤开始
  66. test.train() #只对一些特殊的层起作用,代码中没有这些层也可以写上
  67. for data in dataloder_train:
  68. imgs, targets = data
  69. # 训练数据转移到 gpu 上
  70. if torch.cuda.is_available():
  71. imgs = imgs.cuda()
  72. targets = targets.cuda()
  73. output_train = test(imgs)
  74. loss = loss_fc(output_train, targets) # 获得损失值 loss
  75. # 使用优化器优化模型
  76. optimizer.zero_grad() # 梯度清零
  77. loss.backward() # 调用损失 loss,得到每一个参数的梯度
  78. optimizer.step() #调用优化器 optimizer 对我们的参数进行优化
  79. total_train_step = total_train_step + 1 #记录训练次数
  80. if total_train_step % 100 == 0:
  81. end_time = time.time() # 没运行100次结束的时间
  82. print("{}秒".format(end_time - start_time)) # 模型运行需要多长时间
  83. print("训练次数:{}, 损失值:{}".format(total_train_step, loss.item()))
  84. # loss.item()与loss时有区别的,loss.item()返回的是数字
  85. writer.add_scalar("train_loss", loss.item(), total_train_step) # 逢100的整数记录
  86. # 测试步骤开始
  87. test.eval() #只对一些特殊的层起作用,代码中没有这些层也可以写上
  88. total_test_loss = 0
  89. # 正确率
  90. total_accuracy = 0
  91. with torch.no_grad(): # 表示在 with 里的代码,它的梯度就没有了,保证不会进行调优
  92. for data in dataloder_test:
  93. imgs, targets = data
  94. # 测试数据转移到 gpu 上
  95. if torch.cuda.is_available():
  96. imgs = imgs.cuda()
  97. targets = targets.cuda()
  98. output_test = test(imgs)
  99. loss = loss_fc(output_test, targets)
  100. total_test_loss = total_test_loss + loss
  101. accuracy = (output_test.argmax(1) == targets).sum() # 计算预测与实际 一致的个数
  102. total_accuracy = total_accuracy + accuracy # 总的正确的个数
  103. print("整体测试集的损失值:{}".format(total_test_loss.item()))
  104. print("整体测试的正确率为:{}".format(total_accuracy/test_data_size))
  105. writer.add_scalar("test_loss", total_test_loss, total_test_step)
  106. writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
  107. total_test_step = total_test_step + 1
  108. # 保存每一轮训练的模型
  109. torch.save(test, "test_{}.pth".format(i)) #方法以保存
  110. # 下面是方法二保存模型,将参数保存成字典型
  111. # torch.save(test.state_dict(), "test_{}".format(i))
  112. print("模型已保存")
  113. writer.close()

因为我的电脑没有gpu,所以程序就是在cpu上运行的。

输出结果(部分):

Files already downloaded and verified
Files already downloaded and verified
训练数据集的长度为:50000
测试数据集的长度为:10000
----------第1轮训练开始:-------------
10.618798971176147秒
训练次数:100, 损失值:2.286679744720459
21.838643789291382秒
训练次数:200, 损失值:2.284773111343384
33.31450796127319秒
训练次数:300, 损失值:2.24947190284729
44.44334530830383秒
训练次数:400, 损失值:2.1513400077819824
55.304163217544556秒
训练次数:500, 损失值:2.0602264404296875
66.77502679824829秒
训练次数:600, 损失值:2.056307792663574

可以看见,运行的速度还是比较慢的。如果在gpu上运行,速度会快不少。

2 方法二

方法二也需要3个变量
网络模型
损失函数
数据(输入,输出)

调用.to(device)   调用.to到一个设备上去,设备叫device

device = torch.device("cpu")    代表这个device是cpu,
如果 device = torch.device("cuda")  这代表它在gpu上运行
device = torch.device("cpu") 中    “ ”里的变量,决定模型在gpu上运行还是在cpu上运行

也可以:
torch.device("cuda")   这样写       这个等于torch.device("cuda: 0")
torch.device("cuda: 0")   这是调用第一张显卡的意思
torch.device("cuda: 1")   这是调用第二张显卡的 意思

  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.utils.data import DataLoader
  5. from torch.utils.tensorboard import SummaryWriter
  6. import time
  7. # 调用训练的设备
  8. device = torch.device("cpu")
  9. # device = torch.device("cuda" if torch.cuda.is_available() else "cpu" )
  10. # 准备数据集
  11. train_data = torchvision.datasets.CIFAR10("./dataset", train=True, transform=torchvision.transforms.ToTensor(),
  12. download=True)
  13. test_data = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(),
  14. download=True)
  15. # 数据集的 length 长度
  16. train_data_size = len(train_data)
  17. test_data_size = len(test_data)
  18. print("训练数据集的长度为:{}".format(train_data_size))
  19. print("测试数据集的长度为:{}".format(test_data_size))
  20. # 利用 DataLoader 来加载数据集
  21. dataloder_train = DataLoader(train_data, batch_size=64, drop_last=False)
  22. dataloder_test = DataLoader(test_data, batch_size=64, drop_last=False)
  23. # 搭建神经网络
  24. class Test(nn.Module):
  25. def __init__(self):
  26. super(Test, self).__init__()
  27. self.model = nn.Sequential(
  28. nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
  29. nn.MaxPool2d(kernel_size=2),
  30. nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
  31. nn.MaxPool2d(kernel_size=2),
  32. nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
  33. nn.MaxPool2d(kernel_size=2),
  34. nn.Flatten(),
  35. nn.Linear(in_features=1024, out_features=64),
  36. nn.Linear(in_features=64, out_features=10)
  37. )
  38. def forward(self, x):
  39. x = self.model(x)
  40. return x
  41. # 创建网络模型
  42. test = Test()
  43. test = test.to(device) # 方法二
  44. # test.to(device)
  45. # 损失函数
  46. loss_fc = nn.CrossEntropyLoss()
  47. loss_fc = loss_fc.to(device) # 方法二
  48. # loss_fc.to(device)
  49. # 优化器
  50. learning_rate = 1e-2 # 1e-2 = 1 * 10^(-2) = 1/100 = 0.01
  51. optimizer = torch.optim.SGD(test.parameters(), lr=learning_rate)
  52. # 设置训练网络的一些参数
  53. # 记录训练的次数
  54. total_train_step = 0
  55. # 记录测试的次数
  56. total_test_step = 0
  57. # 训练的轮数
  58. epoch = 10
  59. # 添加 tensorboard
  60. writer = SummaryWriter("logs")
  61. # 获取开始的时间
  62. start_time = time.time()
  63. for i in range(epoch):
  64. print("----------第{}轮训练开始:-------------".format(i+1))
  65. # 训练步骤开始
  66. test.train() #只对一些特殊的层起作用,代码中没有这些层也可以写上
  67. for data in dataloder_train:
  68. imgs, targets = data
  69. imgs = imgs.to(device) # 方法二
  70. targets = targets.to(device)
  71. output_train = test(imgs)
  72. loss = loss_fc(output_train, targets) # 获得损失值 loss
  73. # 使用优化器优化模型
  74. optimizer.zero_grad() # 梯度清零
  75. loss.backward() # 调用损失 loss,得到每一个参数的梯度
  76. optimizer.step() #调用优化器 optimizer 对我们的参数进行优化
  77. total_train_step = total_train_step + 1 #记录训练次数
  78. if total_train_step % 100 == 0:
  79. end_time = time.time() # 没运行100次结束的时间
  80. print("{}秒".format(end_time - start_time)) # 模型运行需要多长时间
  81. print("训练次数:{}, 损失值:{}".format(total_train_step, loss.item()))
  82. # loss.item()与loss时有区别的,loss.item()返回的是数字
  83. writer.add_scalar("train_loss", loss.item(), total_train_step) # 逢100的整数记录
  84. # 测试步骤开始
  85. test.eval() #只对一些特殊的层起作用,代码中没有这些层也可以写上
  86. total_test_loss = 0
  87. # 正确率
  88. total_accuracy = 0
  89. with torch.no_grad(): # 表示在 with 里的代码,它的梯度就没有了,保证不会进行调优
  90. for data in dataloder_test:
  91. imgs, targets = data
  92. imgs = imgs.to(device) # 方法二
  93. targets = targets.to(device)
  94. output_test = test(imgs)
  95. loss = loss_fc(output_test, targets)
  96. total_test_loss = total_test_loss + loss
  97. accuracy = (output_test.argmax(1) == targets).sum() # 计算预测与实际 一致的个数
  98. total_accuracy = total_accuracy + accuracy # 总的正确的个数
  99. print("整体测试集的损失值:{}".format(total_test_loss.item()))
  100. print("整体测试的正确率为:{}".format(total_accuracy/test_data_size))
  101. writer.add_scalar("test_loss", total_test_loss, total_test_step)
  102. writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
  103. total_test_step = total_test_step + 1
  104. # 保存每一轮训练的模型
  105. torch.save(test, "test_{}.pth".format(i)) #方法以保存
  106. # 下面是方法二保存模型,将参数保存成字典型
  107. # torch.save(test.state_dict(), "test_{}".format(i))
  108. print("模型已保存")
  109. writer.close()

注意:

(1) 调用训练的设备
device = torch.device("cpu")

device = torch.device("cuda" if torch.cuda.is_available() else "cpu" )

这两行代码都可以,但是用第二种的较多

if torch.cuda.is_available() ,返回为true, 则返回 device = torch.device("cuda")   在gpu上运行 ,

若返回为false, 则返回 device = torch.device("cpu")   在cpu上运行

(2) 网络模型和损失函数调用.to(device)有两种写法

test = test.to(device)    
test.to(device)

loss_fc = loss_fc.to(device)    
loss_fc.to(device)

这两种写法都是对的,但是test.to(device)和loss_fc.to(device)这样写比较常见,不需要返回值

与之对比,数据(输入,输出) 则必须这样写:

imgs = imgs.to(device)  
targets = targets.to(device)

二、Google colab的使用

在cpu运行的速度还是比较慢的。在gpu上运行,速度会快不少。

但是如果我们电脑上没有gpu,那 怎么用gpu运行呢?

谷歌为我们提供了应该免费的gpu可以使用,

登录 https://colab.research.google.com 这个网站,就可以直接使用,

注意,需要科学上网登录google账号

这个网站很像jupyter
 

输入代码,可以查看是否正常gpu,
如果输入print(torch.cuda.is_available())
返回的是false

这时侯,只需要修改一下即可,

修改完成,输入上面的代码运行,

将上面的代码输入Google colab中,使用gpu运行,

结果如下:

训练数据集的长度为:50000
测试数据集的长度为:10000
----------第1轮训练开始:-------------
模型训练100次需要:4.819949626922607秒
训练次数:100, 损失值:2.296015501022339
模型训练100次需要:5.75621485710144秒
训练次数:200, 损失值:2.287379026412964
模型训练100次需要:6.697075128555298秒
训练次数:300, 损失值:2.2827587127685547
模型训练100次需要:7.62299370765686秒
训练次数:400, 损失值:2.236856460571289
模型训练100次需要:8.568002700805664秒
训练次数:500, 损失值:2.142932891845703
模型训练100次需要:9.562170505523682秒
训练次数:600, 损失值:2.0706043243408203
模型训练100次需要:10.492522954940796秒
训练次数:700, 损失值:2.0014054775238037
整体测试集的损失值:313.5710144042969
整体测试的正确率为:0.2870999872684479
模型已保存

可以看见运行的速度明显变快了。

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

闽ICP备14008679号