当前位置:   article > 正文

pytorch进阶学习(一):使用远程服务器在pycharm上运行简单的小型网络模型,使用fashion-minist数据集进行训练_pycharm远程连接阿里云服务器训练模型

pycharm远程连接阿里云服务器训练模型

参考视频和代码来源详见up主Leo在这的b站教学视频:

1、Pytorch的安装与环境配置【小学生都会的Pytorch】_哔哩哔哩_bilibili

如何在pycharm上连接远程服务器详见:

(7条消息) 如何使用租用的云服务器实现神经网络训练过程(超详细教程,新手小白适用)_好喜欢吃红柚子的博客-CSDN博客

一、服务器上下载conda

如果你的服务器上没有conda,需要下载。

(7条消息) 远端服务器安装anaconda并创建conda环境_头秃的和尚的博客-CSDN博客

期间可能会遇到无法识别conda的命令,此时需要使用vim命令手动添加conda的环境变量。

(7条消息) conda: command not found解决办法_奥特曼熬夜不睡觉的博客-CSDN博客

下载完之后服务器文件中会出现对应的conda文件夹。

二、创建和激活环境

  1. 使用conda create -n xxx python = 3.8 创建虚拟环境,使用conda activate xxx激活该虚拟环境。

三、安装torch和对应包

进入虚拟环境后,使用pip install torch 和 pip install torchvision下载代码所需的pytorch框架、matplotlib和numpy

可以看到numpy之前以及下载好了,不用重新下载。耐心等待下载安装即可,最后可使用pip list命令查看一下现有的包,发现已经全部下载完毕

四、把程序上传到服务器中

  1. 准备代码

服务器上的环境都下载完毕后,回到pycharm中,打开运行的文件,我这里名为main.py,是一个简单地训练模型,代码如下。

  1. import torch
  2. from torch import nn
  3. from torch.utils.data import DataLoader
  4. from torchvision import datasets
  5. from torchvision.transforms import ToTensor, Lambda, Compose
  6. import matplotlib.pyplot as plt
  7. # 采用torchvision里面的datasets里面的FashionMNIST数据集,该数据集在第一次用时需要下载,
  8. # 数据集分为训练集(用于模型训练)和测试集(验证模型性能)
  9. # 下面是训练集
  10. training_data = datasets.FashionMNIST(
  11. root="data",
  12. train=True,
  13. download=True,
  14. transform=ToTensor(),
  15. )
  16. # 下面是测试集,同样需要下载
  17. test_data = datasets.FashionMNIST(
  18. root="data",
  19. train=False,
  20. download=True,
  21. transform=ToTensor(),
  22. )
  23. batch_size = 64
  24. # 给训练集和测试集分别创建一个数据集加载器
  25. train_dataloader = DataLoader(training_data, batch_size=batch_size)
  26. test_dataloader = DataLoader(test_data, batch_size=batch_size)
  27. for X, y in test_dataloader:
  28. print("Shape of X [N, C, H, W]: ", X.shape)
  29. print("Shape of y: ", y.shape, y.dtype)
  30. break
  31. # 如果显卡可用,则用显卡进行训练
  32. device = "cuda" if torch.cuda.is_available() else "cpu"
  33. print("Using {} device".format(device))
  34. # 定义网络模型
  35. class NeuralNetwork(nn.Module):
  36. def __init__(self):
  37. super(NeuralNetwork, self).__init__()
  38. # 碾平,将数据碾平为一维
  39. self.flatten = nn.Flatten()
  40. # 定义linear_relu_stack,由以下众多层构成
  41. self.linear_relu_stack = nn.Sequential(
  42. # 全连接层
  43. nn.Linear(28*28, 512),
  44. # ReLU激活函数
  45. nn.ReLU(),
  46. # 全连接层
  47. nn.Linear(512, 512),
  48. nn.ReLU(),
  49. nn.Linear(512, 10),
  50. nn.ReLU()
  51. )
  52. # x为传入数据
  53. def forward(self, x):
  54. # x先经过碾平变为1维
  55. x = self.flatten(x)
  56. # 随后x经过linear_relu_stack
  57. logits = self.linear_relu_stack(x)
  58. # 输出logits
  59. return logits
  60. # 调用刚定义的模型,将模型转到GPU(如果可用)
  61. model = NeuralNetwork().to(device)
  62. print(model)
  63. # 定义损失函数,计算相差多少
  64. loss_fn = nn.CrossEntropyLoss()
  65. # 定义优化器,用来训练时候优化模型参数
  66. optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
  67. # 定义训练函数,需要
  68. def train(dataloader, model, loss_fn, optimizer):
  69. size = len(dataloader.dataset)
  70. # 从数据加载器中读取batch(一次读取多少张,即批次数),X(图片数据),y(图片真实标签)。
  71. for batch, (X, y) in enumerate(dataloader):
  72. # 将数据存到显卡
  73. X, y = X.to(device), y.to(device)
  74. # 得到预测的结果pred
  75. pred = model(X)
  76. # 计算预测的误差
  77. loss = loss_fn(pred, y)
  78. # 反向传播,更新模型参数
  79. optimizer.zero_grad()
  80. loss.backward()
  81. optimizer.step()
  82. # 每训练100次,输出一次当前信息
  83. if batch % 100 == 0:
  84. loss, current = loss.item(), batch * len(X)
  85. print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")
  86. def test(dataloader, model):
  87. size = len(dataloader.dataset)
  88. # 将模型转为验证模式
  89. model.eval()
  90. # 初始化test_loss 和 correct, 用来统计每次的误差
  91. test_loss, correct = 0, 0
  92. # 测试时模型参数不用更新,所以no_gard()
  93. with torch.no_grad():
  94. # 加载数据加载器,得到里面的X(图片数据)和y(真实标签)
  95. for X, y in dataloader:
  96. # 将数据转到GPU
  97. X, y = X.to(device), y.to(device)
  98. # 将图片传入到模型当中就,得到预测的值pred
  99. pred = model(X)
  100. # 计算预测值pred和真实值y的差距
  101. test_loss += loss_fn(pred, y).item()
  102. # 统计预测正确的个数
  103. correct += (pred.argmax(1) == y).type(torch.float).sum().item()
  104. test_loss /= size
  105. correct /= size
  106. print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
  107. # 一共训练5次
  108. epochs = 5
  109. for t in range(epochs):
  110. print(f"Epoch {t+1}\n-------------------------------")
  111. train(train_dataloader, model, loss_fn, optimizer)
  112. test(test_dataloader, model)
  113. print("Done!")
  114. # 保存训练好的模型
  115. torch.save(model.state_dict(), "model.pth")
  116. print("Saved PyTorch Model State to model.pth")
  117. # 读取训练好的模型,加载训练好的参数
  118. model = NeuralNetwork()
  119. model.load_state_dict(torch.load("model.pth"))
  120. # 定义所有类别
  121. classes = [
  122. "T-shirt/top",
  123. "Trouser",
  124. "Pullover",
  125. "Dress",
  126. "Coat",
  127. "Sandal",
  128. "Shirt",
  129. "Sneaker",
  130. "Bag",
  131. "Ankle boot",
  132. ]
  133. # 模型进入验证阶段
  134. model.eval()
  135. x, y = test_data[0][0], test_data[0][1]
  136. with torch.no_grad():
  137. pred = model(x)
  138. predicted, actual = classes[pred[0].argmax(0)], classes[y]
  139. print(f'Predicted: "{predicted}", Actual: "{actual}"')

2. 上传到服务器

按照我前面说的方法配置服务器,可以看到我的Python解释器已经变成了服务器上的conda虚拟环境,pycharm右下角也对应改变成了该环境。

依次点击tools->deployment->upload to xxx,xxx为你连接的服务器的主机,即可完成对代码的上传。

五、在pycharm上运行代码

点击运行,模型开始训练。可以看到虽然我们的pycharm中代码有报错,torch等环境都无法识别,但是服务器中以及进行了环境的配置,因此代码还是可以正常运行,因为代码实际是在远程服务器上运行的,pycharm担任了可视化界面的作用。

自动下载数据集,数据集会下载到服务器中的data文件夹下,下载后模型开始训练5轮,5轮后训练完成。

耐心等待训练……

等待……

训练完成!!!

六、代码解析

  1. fashion-minist数据集

灰度图像,channel=1,大小为28*28

2. 要点解析

2.1 dataloader

https://blog.csdn.net/weixin_45662399/article/details/127601983?spm=1001.2014.3001.5502

在dataloader中,每一个对象元组由batchsize张图片对象imgs和batchsize个标签targets组成。输入图片的batchsize=64,说明一次输入64张图

  • 故X有64张,每张图片通道=1,大小=28*28。

  • y为64张图像对应的标签,也为64个,为int型。

  1. # 测试训练集数据加载器,X为输入图片,y为对应标签
  2. for X, y in test_dataloader:
  3. print("Shape of X [N, C, H, W]: ", X.shape)
  4. print("Shape of y: ", y.shape, y.dtype)
  5. break

输出:

2.2 使用gpu/cpu训练

如果gpu可用,则使用gpu进行训练,否则使用cpu

  1. # 如果显卡可用,则用显卡进行训练
  2. device = "cuda" if torch.cuda.is_available() else "cpu"
  3. print("Using {} device".format(device))

2.3 定义神经网络

  1. # 定义网络模型
  2. class NeuralNetwork(nn.Module):
  3. def __init__(self):
  4. super(NeuralNetwork, self).__init__()
  5. # 碾平,将数据碾平为一维
  6. self.flatten = nn.Flatten()
  7. # 定义linear_relu_stack,由以下众多层构成
  8. self.linear_relu_stack = nn.Sequential(
  9. # 全连接层
  10. nn.Linear(28*28, 512),
  11. # ReLU激活函数
  12. nn.ReLU(),
  13. # 全连接层
  14. nn.Linear(512, 512),
  15. nn.ReLU(),
  16. nn.Linear(512, 10),
  17. nn.ReLU()
  18. )
  19. # x为传入数据
  20. def forward(self, x):
  21. # x先经过碾平变为1维
  22. x = self.flatten(x)
  23. # 随后x经过linear_relu_stack
  24. logits = self.linear_relu_stack(x)
  25. # 输出logits
  26. return logits

  1. 定义sequential
  • flatten:先把二维矩阵展平为一维向量,输入网络

  • 全连接层1:输入为28*28,输出为512

  • 激活层1:relu函数激活

  • 全连接层2:输入和输出都是512

  • 激活层2

  • 全连接层3:输入为512,输出变为10

把以上操作都放在sequential序列里,即可按顺序依次操作。

2. 前向传播forward

把x进行输入,然后经过sequential定义的神经网络结构后输出logits,即为训练后对x图片的预测结果y'。

3. 损失函数

计算预测值和真实值的差值,使用交叉熵损失。

loss_fn = nn.CrossEntropyLoss()

4. 优化器

随机梯度下降SSD

  1. # 定义优化器,用来训练时候优化模型参数
  2. optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

2.4 网络训练train

获取到图标真实标签y和预测后的标签pred,使用loss_fn计算两者差距并保存在loss中,使用反向传播更新参数。

每训练100张,输出一次loss,可以看到loss值是越来越小的,说明模型训练越来越成功。

Epoch 1
-------------------------------
loss: 2.302158 [ 0/60000]
loss: 2.293674 [ 6400/60000]
loss: 2.289693 [12800/60000]
loss: 2.289169 [19200/60000]
loss: 2.281888 [25600/60000]
loss: 2.273417 [32000/60000]
loss: 2.272296 [38400/60000]
loss: 2.256825 [44800/60000]
loss: 2.247419 [51200/60000]
loss: 2.276489 [57600/60000]
  1. def train(dataloader, model, loss_fn, optimizer):
  2. size = len(dataloader.dataset)
  3. # 从数据加载器中读取batch(一次读取多少张,即批次数),X(图片数据),y(图片真实标签)。
  4. for batch, (X, y) in enumerate(dataloader):
  5. # 将数据存到显卡
  6. X, y = X.to(device), y.to(device)
  7. # 得到预测的结果pred
  8. pred = model(X)
  9. # 计算预测的误差
  10. loss = loss_fn(pred, y)
  11. # 反向传播,更新模型参数
  12. #梯度置零
  13. optimizer.zero_grad()
  14. #调整参数,反向传播,训练
  15. loss.backward()
  16. #更新参数
  17. optimizer.step()
  18. # 每训练100次,输出一次当前信息
  19. if batch % 100 == 0:
  20. loss, current = loss.item(), batch * len(X)
  21. print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")

2.5 网络测试test

模型在结束训练进行测试时,无需再进行参数的反向传播来调整参数,因此使用torch.no_grad( )。

  1. def test(dataloader, model):
  2. size = len(dataloader.dataset)
  3. # 将模型转为验证模式
  4. model.eval()
  5. # 初始化test_loss 和 correct, 用来统计每次的误差
  6. test_loss, correct = 0, 0
  7. # 测试时模型参数不用更新,所以no_gard()
  8. with torch.no_grad():
  9. # 加载数据加载器,得到里面的X(图片数据)和y(真实标签)
  10. for X, y in dataloader:
  11. # 将数据转到GPU
  12. X, y = X.to(device), y.to(device)
  13. # 将图片传入到模型当中就,得到预测的值pred
  14. pred = model(X)
  15. # 计算预测值pred和真实值y的差距
  16. test_loss += loss_fn(pred, y).item()
  17. # 统计预测正确的个数
  18. correct += (pred.argmax(1) == y).type(torch.float).sum().item()
  19. test_loss /= size
  20. correct /= size
  21. print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

2.6 epoch次数

  1. # 一共训练5次
  2. epochs = 5
  3. for t in range(epochs):
  4. print(f"Epoch {t+1}\n-------------------------------")
  5. train(train_dataloader, model, loss_fn, optimizer)
  6. test(test_dataloader, model)
  7. print("Done!")

设置epoch=5,一共训练5轮,每一次训练完后都会进行一次测试

2.7 model.pth

把训练好的模型文件保存在model.pth中,等到需要使用模型进行验证时,直接读取该模型文件即可。

  1. # 保存训练好的模型
  2. torch.save(model.state_dict(), "model.pth")
  3. print("Saved PyTorch Model State to model.pth")
  4. # 读取训练好的模型,加载训练好的参数
  5. model = NeuralNetwork()
  6. model.load_state_dict(torch.load("model.pth"))

2.8 网络验证validation

  • 验证阶段和测试阶段一样,不进行梯度更新调整参数

  • 取测试集中的第一张图片和其对应标签,pred保存模型的预测类别,pred[0].argmax[0]得到所有预测类别得分最高的一类,然后找到classes中对应的具体类别,即可与真实类别比较判断预测结果。

  1. # 定义所有类别
  2. classes = [
  3. "T-shirt/top",
  4. "Trouser",
  5. "Pullover",
  6. "Dress",
  7. "Coat",
  8. "Sandal",
  9. "Shirt",
  10. "Sneaker",
  11. "Bag",
  12. "Ankle boot",
  13. ]
  14. # 模型进入验证阶段
  15. model.eval()
  16. x, y = test_data[0][0], test_data[0][1]
  17. with torch.no_grad():
  18. pred = model(x)
  19. predicted, actual = classes[pred[0].argmax(0)], classes[y]
  20. print(f'Predicted: "{predicted}", Actual: "{actual}"')

预测结果:可以看到模型预测的类别和真正类别一样,都是ankle boot。

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

闽ICP备14008679号