pytorch快速入门——手写数字分类GPU加速

👑主页:吾名招财
👓简介:工科学硕,研究方向机器视觉,爱好较广泛…
​💫签名:面朝大海,春暖花开!

pytorch快速入门——手写数字分类GPU加速

  • 一、tensor
    • 1,理解tensor
      • (1)一维矩阵(向量)
      • (2)二维矩阵(单通道灰度图像)
      • (3)三维矩阵(彩色三通道图像)
    • 2,创建tensor
      • (1)导入pytorch库
      • (2)创建一维矩阵
      • (3)创建两行四列的二维矩阵
      • (4)生成两行五列的随机矩阵
      • (5)生成两行五列全为1的随机矩阵
      • (6)生成两行五列全为0的随机矩阵
    • 3,tensor基本属性
      • (1)形状shape
      • (2)数据类型dtype
      • (3)转换数据类型data.to()
    • 4,tensor的基本操作
      • (1)通过下标获取对应的值(data[0][4].item())
      • (2)加减乘除运算(+ - * /)
      • (3)求所有值的和torch.sum()
      • (4)求平均值torch.mean()
      • (5)索引排序torch.argsort()
      • (6)最小值最大值索引(argmin,argmax)
      • (7)变形操作(如将其2行8列变成8行2列等)
  • 二、理解神经网络
    • 1,分类、回归、聚类
      • (1)分类
      • (2)回归
      • (3)聚类
    • 2,区分猫狗
      • (1)差异计算
      • (2)线性分类
      • (3)softmax
      • (4)损失函数
      • (5)梯度下降
      • (6)非线性分类
      • (7)激活函数
      • (8)预测
      • (9)训练
  • 三、手写数字分类
    • 1,定义网络结构
    • 2,整理数据集
    • 3,训练模型
    • 4,勘误
    • 5,保存模型
    • 6,加载模型并预测
    • 7,使用GPU加速

一、tensor

1,理解tensor

Tensor就是一个N维矩阵

(1)一维矩阵(向量)

在这里插入图片描述

(2)二维矩阵(单通道灰度图像)

二维矩阵:单通道图像,Excel数据等
在这里插入图片描述

(3)三维矩阵(彩色三通道图像)

在这里插入图片描述

2,创建tensor

create_tensor.py

(1)导入pytorch库

import torch
print(torch.cuda.is_available())

(2)创建一维矩阵

#一维向量
data = torch.tensor([1,2,3,4])
print(data)#tensor([1, 2, 3, 4])

(3)创建两行四列的二维矩阵

#两行四列的二维矩阵
data = torch.tensor([[1,2,3,4],[2,3,4,5]])
print(data)# tensor([[1, 2, 3, 4],
#         [2, 3, 4, 5]])

(4)生成两行五列的随机矩阵

#生成两行五列的随机矩阵
data = torch.randn(2, 5)
print(data)
# tensor([[ 1.4212,  0.0784, -1.0818, -0.6843,  0.9947],
#         [-1.3718,  0.9556,  1.1089, -0.8161, -0.2081]])

(5)生成两行五列全为1的随机矩阵

#生成两行五列全是一的矩阵
data = torch.ones(2, 5)
print(data)
# tensor([[1., 1., 1., 1., 1.],
#         [1., 1., 1., 1., 1.]])

(6)生成两行五列全为0的随机矩阵

#生成两行五列全是0的矩阵
data = torch.zeros(2, 5)
print(data)
# tensor([[0., 0., 0., 0., 0.],
#         [0., 0., 0., 0., 0.]])#tensor中非常重要的一些属性
data = torch.zeros(2, 5)

3,tensor基本属性

(1)形状shape

#1,形状
print(data.shape)
# torch.Size([2, 5])
print(data.shape[0],data.shape[1])  #2 5   (两行五列)

(2)数据类型dtype

#2,数据类型默认float32
print(data.dtype)
#torch.float32

(3)转换数据类型data.to()

#更改数据类型
data = data.to(torch.int)
print(data)
# tensor([[0, 0, 0, 0, 0],
#         [0, 0, 0, 0, 0]], dtype=torch.int32)
print(data.dtype)
# torch.int32

4,tensor的基本操作

(1)通过下标获取对应的值(data[0][4].item())

import torch#通过下标获取对应的值
data = torch.tensor([[1,2,3,4,5],[2,3,4,5,6]])
data = data.to(torch.int)
print(data)
print(data.dtype)
#拿到第0行4列的值(但还是tensor类型的)
print(data[0][4])
# tensor(5, dtype=torch.int32)
#将tensor转成真正要的数据
print(data[0][4].item())    #5

(2)加减乘除运算(+ - * /)

#加法运算,对应位置相加
data_a = torch.ones([3,3])
data_b = torch.zeros([3,3])
print(data_a+data_b)    #加完 后还是1data_a = torch.ones([3,3])
data_b = torch.tensor([[1,2,3],[2,3,4],[3,4,5]])
print(data_a+data_b)    #加完
# tensor([[2., 3., 4.],
#         [3., 4., 5.],
#         [4., 5., 6.]])print(data_a-data_b)
# tensor([[ 0., -1., -2.],
#         [-1., -2., -3.],
#         [-2., -3., -4.]])print(data_a*data_b)
# tensor([[1., 2., 3.],
#         [2., 3., 4.],
#         [3., 4., 5.]])print(data_a/data_b)
# tensor([[1.0000, 0.5000, 0.3333],
#         [0.5000, 0.3333, 0.2500],
#         [0.3333, 0.2500, 0.2000]])print(data_a/3)
# tensor([[0.3333, 0.3333, 0.3333],
#         [0.3333, 0.3333, 0.3333],
#         [0.3333, 0.3333, 0.3333]])

(3)求所有值的和torch.sum()

#求所有的值的和
data_b = torch.tensor([[1,2,3],[2,3,14],[3,4,25]])
print(torch.sum(data_b))
# tensor(27)# 1   2   3
# 2   3   14
# 3   4   25
print(torch.sum(data_b,axis=0)) #axis=0表示竖着相加
# tensor([ 6,  9, 42])
print(torch.sum(data_b,axis=1)) #axis=1表示横着相加
# tensor([ 6, 19, 32])

(4)求平均值torch.mean()

#求平均值(输入类型必须为浮点型或者复数)
print(torch.mean(data_b.to(torch.float),axis=1))
# tensor([ 2.0000,  6.3333, 10.6667])#
#假设下方为模型预测的结果
predict = torch.tensor([1,0,1,0,2,0,1,0,1,2])
#假设下方为标签即所知的标准答案
label = torch.tensor([0,1,1,0,0,0,1,0,2,2])
#这里计算一下预测出来的东西和标准答案之间有多少是重合的
#判断大于号
print(predict > label)
#tensor([ True, False, False, False,  True, False, False, False, False, False])
#判断等于号是否为真
print(predict == label)
# tensor([False, False,  True,  True, False,  True,  True,  True, False,  True])
#查看10个中总共对了几个(True认为1,Flase认为0)
print(torch.sum(predict == label))
#tensor(6)   总共6个是预测值与标签相等的#使用mean来求其准确率
print(torch.mean((predict == label).to(torch.float)).item())
#0.6000000238418579

(5)索引排序torch.argsort()

#argsort将tensor值中从小到大的排序的索引拿到
data = torch.tensor([1,2,3,0,9,8,-1,-10])print(torch.argsort(data))
# tensor([7, 6, 3, 0, 1, 2, 5, 4])

(6)最小值最大值索引(argmin,argmax)

#数据中最小的值的索引得到
print(torch.argmin(data))
# tensor(7)
#数据中最大的值的索引得到
print(torch.argmax(data))
# tensor(4)#arg也可以接受轴的概念
data = torch.tensor([[1,2,3,0,9,8,-1,-10],[5,2,3,6,9,8,11,-10]])
print(torch.argmax(data, axis=0))
# tensor([1, 0, 0, 1, 0, 0, 1, 0])  #第一列5大,5是索引1。

(7)变形操作(如将其2行8列变成8行2列等)

##最后说一个操作变形
data = data.view(8,2) #将其2行8列变成8行两列
print(data)
# tensor([[  1,   2],
#         [  3,   0],
#         [  9,   8],
#         [ -1, -10],
#         [  5,   2],
#         [  3,   6],
#         [  9,   8],
#         [ 11, -10]])##最后说一个操作变形
data = data.view(8,-1) #第2列写个-1表示根据8行自动推断有多少列
print(data)##最后说一个操作变形
data = data.view(-1,2) #第1列写个-1表示根据2列自动推断有多少行
print(data)#将二维矩阵变为一个向量,直接-1即可
data = data.view(-1)
print(data)
# tensor([  1,   2,   3,   0,   9,   8,  -1, -10,   5,   2,   3,   6,   9,   8,
#          11, -10])

二、理解神经网络

1,分类、回归、聚类

神经网络、深度学习本质上就是数学再加上玄学

但我们仅仅是个开发者,我们要做的就是使用知名的框架如pytorch等来实现功能

至于里面的数学公式、神经网络结构为什么这样,最底层的机理暂时不用管,只要知道这样,这样 就能达到这样的效果即可

什么是分类、什么是回归、什么是聚类,这些都是机器学习或者深度学习中最简单的任务了

左边这些就是数据,右侧就是结果

阅片无数的宅男(看做是神经网络、模型)

(1)分类

对离散值的预测就是分类
在这里插入图片描述

(2)回归

对连续值的预测就是回归

颜值打分神器

在这里插入图片描述

(3)聚类

还是阅片无数的宅男,但是记性不太好,不认识这些人,潜移默化的将这些照片归类,会发现好看的在一类,不好看的一类

但是不知道这个类别叫什么,也不知道 这个类别叫什么,这种任务就是聚类

分类与聚类都是把数据进行区分,但是最大的一个区别就是聚类中的数据是没有所谓的标签的

在这里插入图片描述

2,区分猫狗

(1)差异计算

在这里插入图片描述

把两张图片的像素矩阵算一个差异程度,算完差异度后跟谁的差异度最小就是那个类别

区分是猫还是狗
在这里插入图片描述

(2)线性分类

更好的解决方案线性分类
假设有个函数,f()

x就是像素值,W、b
是函数中的参数,如果W、b确定了,随便一张图x进来都能给这张图算出一个结果,结果表示 如下方右侧

这个函数能分出10类

在这里插入图片描述

在这里插入图片描述

437.9是这里面最大的,所以这张图就是狗,如果w、b比较厉害的话,那么随便哪个都能预测的准确

(3)softmax

得到了得分,分数越高代表,但没有好的解释性,怎么看437.9到底高还是不高,使用

Softmax将得分变成概率

在这里插入图片描述

Softmax怎么算的
在这里插入图片描述

就是算个比例吧

现在的w、b就是最好的了吗
在这里插入图片描述

(4)损失函数

怎么度量这个结果的好坏标准,使用损失函数

在这里插入图片描述

交叉熵损失函数

在这里插入图片描述

可以看到这个损失值是比较大的,那么怎么让他的损失值变小呢,这里就需要靠梯度下降

(5)梯度下降

在这里插入图片描述

梯度下降就是为了算出(w、b)

在这里插入图片描述

(6)非线性分类

线性分类是尝试使用直线将猫狗分割开,但是如果其分布如下非线性的话
在这里插入图片描述

就无法将其分割开了

接下来就是使用神经网络将其分隔开

神经网络就是在搭积木

有两个全连接层,除了最上面的和最下面的,搭积木一样

(7)激活函数

每个格子都有(w*x+b)(激活函数)
在这里插入图片描述

如下三角形和圆圈,找不到任何直线将其区分开
在这里插入图片描述

那如果使用一个线性分类器,线性分类的方式将其分隔开,会有漏判
在这里插入图片描述

没激活函数的nn 要画n条直线
在这里插入图片描述

有激活函数的NN 拟合一条曲线
在这里插入图片描述
在这里插入图片描述

激活函数种类如下
在这里插入图片描述

神经网络就是一个个的格子,去算一个w、b再算一个激活函数

接下来看其怎么预测的

(8)预测

在这里插入图片描述

Relu激活函数,若是大于0等于其本身 ,若是小于则等于0

-8套一个激活函数就是0
在这里插入图片描述

在这里插入图片描述

(9)训练

神经网络的训练流程就是找到一组合适的w、b使得损失值最小

在这里插入图片描述

在这里插入图片描述

三、手写数字分类

接下来的几集视频会带着大家用pytorch搭建一个神经网络
实现一个图像分类的任务

使用的数据为train.csv

资源链接:https://download.csdn.net/download/qq_44870829/90487677
在这里插入图片描述

使用Excel表格打开后如下整个数据集有42000张图片,每张图片都是由784个像素点组成的灰度图,label数据是从0~9。
在这里插入图片描述

一共784列即784个像素点,每行代表一张灰度图,一共42000行即42000张图片

若是使用pytorch搭建神经网络来做这样一个图像分类任务的话,先捋一下逻辑

1,定义网络结构

#3神经网络,可以将其看成黑盒子,或者一个 python函数,这个函数有了输入就有了输出#784个像素点构成的灰度图——》函数——》10个概率(0 1 2 3 4 5 6 7 8 9的概率)#那么函数该怎么定义呢,这个步骤就是定义网络结构的步骤
#定义网络结构#[1,784]*[784,444] = [1,444]*[444,512] = [1,512]*[512,512] = [1,512]*[512,10] = [1,10]
#输入层  	in_channel 784   out_channel  444#隐藏层1    in_channel 444   out_channel  512#隐藏层2    in_channel 512   out_channel  512#输出层    in_channel 512   out_channel  10

(无论中间层是多少,都会有输出层)

全连接层有两个最重要的属性一个叫in_channel 一个叫out_channel,输入输出频道看做成有多少个点,或者 叫多少个特征,或者叫多少个数据

能被数据所确定的只有输入层的in_channel,输出层的out_channel,中间层的输入输出频道都是可以 自定义的

接下来就是使用pytorch将上方的网络搭建起来了,使用torch.nn模块中的东西

#定义nn神经网络
import torch
import torch.nn as nn#3神经网络,可以将其看成黑盒子,或者一个 python函数,这个函数有了输入就有了输出
#784个像素点构成的灰度图——》函数——》10个概率(0 1 2 3 4 5 6 7 8 9的概率)
#那么函数该怎么定义呢,这个步骤就是定义网络结构的步骤
#定义网络结构#[1,784]*[784,444] = [1,444]*[444,512] = [1,512]*[512,512] = [1,512]*[512,10] = [1,10]
#输入层    in_channel 784   out_channel  444
#隐藏层1    in_channel 444   out_channel  512
#隐藏层2    in_channel 512   out_channel  512
#输出层    in_channel 512   out_channel  10#伪造个随机数据
data = torch.rand(1, 784) #共784个像素,将其转为一行784列的数据#序列化(搭积木),里面可以放入任意想要的层,从前向后
model = nn.Sequential(nn.Linear(784, 444),    #Linear全连接层或者称线性层nn.ReLU(),                                   #加入激活层nn.Linear(444, 512),nn.ReLU(),nn.Linear(512, 512),nn.ReLU(),nn.Linear(512, 10),nn.Softmax()                                #将值转换成概率)#这个函数可以返回一个模型对象给我们
print(model)
# Sequential(
#   (0): Linear(in_features=784, out_features=444, bias=True)
#   (1): ReLU()
#   (2): Linear(in_features=444, out_features=512, bias=True)
#   (3): ReLU()
#   (4): Linear(in_features=512, out_features=512, bias=True)
#   (5): ReLU()
#   (6): Linear(in_features=512, out_features=10, bias=True)
#   (7): Softmax(dim=None)
# )
#现在的model已经是一个模型了 ,但是现在模型里面的w和b是随机值,是不好用的
#后面还需要通过数据驱动其进行训练(但是训练之前还要做一件事情要验证一下此模型搭建出来合不合理)
#随机一个数据进行能否得到输出的十个概率值predict = model(data)   #进行相关的算
print(predict)
# tensor([[0.0944, 0.0975, 0.1039, 0.0938, 0.1050, 0.1013, 0.1024, 0.1010, 0.0998,
#          0.1011]], grad_fn=<SoftmaxBackward0>)

2,整理数据集

接下来就是读取数据并对其进行一定的整理
训练是需要数据推动的

import pandas as pdraw_df = pd.read_csv('train.csv')
print(raw_df.head())
#    label  pixel0  pixel1  pixel2  ...  pixel780  pixel781  pixel782  pixel783
# 0      1       0       0       0  ...         0         0         0         0
# 1      0       0       0       0  ...         0         0         0         0
# 2      1       0       0       0  ...         0         0         0         0
# 3      4       0       0       0  ...         0         0         0         0
# 4      0       0       0       0  ...         0         0         0         0
#
# [5 rows x 785 columns]#将标签那列数据拿出来
label = raw_df['label']
print(label)
# 0        1
# 1        0
# 2        1
# 3        4
# 4        0
#         ..
# 41995    0
# 41996    1
# 41997    7
# 41998    6
# 41999    9
# Name: label, Length: 42000, dtype: int64#将df的数据类型转成numpy的,去掉索引
label = raw_df['label'].values
print(label)
# [1 0 1 ... 7 6 9]#特征(删除label列,剩下的就是特征
raw_df = raw_df.drop(['label'], axis=1) #axis=1表示y轴
feature = raw_df.values
print(len(label),len(feature))#将整个数据集划分成两个数据集,一个训练集、一个测试集,80%是用来神经网络训练的
#训练集相当于日常作业,测试集就是考试,日常作业做的好不代表考试做的好,所以还需要测试
#这里的数据集实际上已经被打乱过了,现在直接做个切片即可train_feature = feature[:int(0.8*len(feature))]
train_label = label[:int(0.8*len(label))]
test_feature = feature[int(0.8*len(feature)):]
test_label = label[int(0.8*len(label)):]print(len(train_feature),len(train_label),len(test_feature),len(test_label))
#33600 33600 8400 8400

3,训练模型

import pandas as pd
#定义nn神经网络
import torch
import torch.nn as nnraw_df = pd.read_csv('train.csv')
print(raw_df.head())
#    label  pixel0  pixel1  pixel2  ...  pixel780  pixel781  pixel782  pixel783
# 0      1       0       0       0  ...         0         0         0         0
# 1      0       0       0       0  ...         0         0         0         0
# 2      1       0       0       0  ...         0         0         0         0
# 3      4       0       0       0  ...         0         0         0         0
# 4      0       0       0       0  ...         0         0         0         0
#
# [5 rows x 785 columns]#将标签那列数据拿出来
label = raw_df['label']
print(label)
# 0        1
# 1        0
# 2        1
# 3        4
# 4        0
#         ..
# 41995    0
# 41996    1
# 41997    7
# 41998    6
# 41999    9
# Name: label, Length: 42000, dtype: int64#将df的数据类型转成numpy的,去掉索引
label = raw_df['label'].values
print(label)
# [1 0 1 ... 7 6 9]#特征(删除label列,剩下的就是特征
raw_df = raw_df.drop(['label'], axis=1) #axis=1表示y轴
feature = raw_df.values
print(len(label),len(feature))#将整个数据集划分成两个数据集,一个训练集、一个测试集,80%是用来神经网络训练的
#训练集相当于日常作业,测试集就是考试,日常作业做的好不代表考试做的好,所以还需要测试
#这里的数据集实际上已经被打乱过了,现在直接做个切片即可train_feature = feature[:int(0.8*len(feature))]
train_label = label[:int(0.8*len(label))]
test_feature = feature[int(0.8*len(feature)):]
test_label = label[int(0.8*len(label)):]print(len(train_feature),len(train_label),len(test_feature),len(test_label))
#33600 33600 8400 8400#将numpy转为tensor,还要将其数据类型变为float
train_feature = torch.tensor(train_feature).to(torch.float)         #数据应该是浮点数
train_label = torch.tensor(train_label)                             #标签 应该是整数
test_feature = torch.tensor(test_feature).to(torch.float)
test_label = torch.tensor(test_label)#3神经网络,可以将其看成黑盒子,或者一个 python函数,这个函数有了输入就有了输出
#784个像素点构成的灰度图——》函数——》10个概率(0 1 2 3 4 5 6 7 8 9的概率)
#那么函数该怎么定义呢,这个步骤就是定义网络结构的步骤
#定义网络结构#[1,784]*[784,444] = [1,444]*[444,512] = [1,512]*[512,512] = [1,512]*[512,10] = [1,10]
#输入层    in_channel 784   out_channel  444
#隐藏层1    in_channel 444   out_channel  512
#隐藏层2    in_channel 512   out_channel  512
#输出层    in_channel 512   out_channel  10#伪造个随机数据
data = torch.rand(1, 784) #共784个像素,将其转为一行784列的数据#序列化(搭积木),里面可以放入任意想要的层,从前向后
model = nn.Sequential(nn.Linear(784, 444),    #Linear全连接层或者称线性层nn.ReLU(),                                   #加入激活层nn.Linear(444, 512),nn.ReLU(),nn.Linear(512, 512),nn.ReLU(),nn.Linear(512, 10),nn.Softmax()                                #将值转换成概率)#这个函数可以返回一个模型对象给我们
print(model)
# Sequential(
#   (0): Linear(in_features=784, out_features=444, bias=True)
#   (1): ReLU()
#   (2): Linear(in_features=444, out_features=512, bias=True)
#   (3): ReLU()
#   (4): Linear(in_features=512, out_features=512, bias=True)
#   (5): ReLU()
#   (6): Linear(in_features=512, out_features=10, bias=True)
#   (7): Softmax(dim=None)
# )
#现在的model已经是一个模型了 ,但是现在模型里面的w和b是随机值,是不好用的
#后面还需要通过数据驱动其进行训练(但是训练之前还要做一件事情要验证一下此模型搭建出来合不合理)
#随机一个数据进行能否得到输出的十个概率值# predict = model(data)   #进行相关的算
# print(predict)
# # tensor([[0.0944, 0.0975, 0.1039, 0.0938, 0.1050, 0.1013, 0.1024, 0.1010, 0.0998,
# #          0.1011]], grad_fn=<SoftmaxBackward0>)# 梯度下降(找到一组合适的w和b,让损失值越小越好),w和b再上面的模型结构中已经定义好了,但是损失值并不知道
# 损失值 使用损失函数,一般都使用交叉熵损失函数
# 瞎子下山
lossfunction = nn.CrossEntropyLoss()
#训练的时候要使用什么样的优化器,一般使用Adam
optimizer = torch.optim.Adam(params=model.parameters(), lr=0.001)  #params参数优化,学习率lr(步子)#训练的轮数
for i in range(100):#清空优化器的梯度(偏导),Adam会存放一些历史的一些偏导数,所以我们要把它们清空optimizer.zero_grad()#接着走前向传播的流程(即预测的流程)predict = model(train_feature)#将概率转换成0~10的索引并打印result = torch.argmax(predict, axis=1)# print(result)                           #tensor([5, 0, 7,  ..., 0, 5, 5])train_acc = torch.mean((result == train_label).to(torch.float))#算预测结果与标准结果之间有多少误差,即损失值loss = lossfunction(predict, train_label)#有了损失值后要做梯度下降# (在神经网络中要做梯度下降,要干的事情是先做反向传播)loss.backward()#梯度下降在optimizer中进行的optimizer.step()    #梯度下降一步#到此整个更新过程就都完事了,每一轮训练完了,他的损失值和准确率是多少# print(loss.item())      #损失值随着训练和迭代是越来越小的,那说明这里面的w和b越来越好#接下来还有个东西就是准确率,准确率怎么搞呢,先分析这个predict出来的是什么print('train loss:{} train acc:{}'.format(loss.item(),train_acc.item()))#清空一下优化器的梯度,再对测试集数据进行预测optimizer.zero_grad()predict = model(test_feature)result = torch.argmax(predict, axis=1)test_acc = torch.mean((result == test_label).to(torch.float))loss = lossfunction(predict, test_label)#测试的时候是不需要更新的,loss.backward() optimizer.step() 就不用写了print('test loss:{} test acc:{}'.format(loss.item(), test_acc.item()))

4,勘误

当我们用神经网络做分类的时候
如对手写数字图片进行分类,那在做分类的时候呢,一般是在最后加入softmax的运算

但由于pytorch它的交叉熵损失loss_fn = nn.CrossEntropyLoss()

它里面会默认把算出来的结果进行一次softmax的运算,所以一般来说nn的softmax是多余的,可以删除掉
在这里插入图片描述

若是不将其删掉,上面做了一次softmax, nn.CrossEntropyLoss()又会计算了一次损失

loss_fn = nn.CrossEntropyLoss()

当然如果你的网络数据和网络结构都比较简单,那么做两次softmax也能收敛
但当这个数据比较复杂,任务复杂,网络也比较复杂的时候呢,做两次softmax,那么他的一个收敛的可能性就会大大降低

所以当你的损失函数是CrossEntropyLoss时,最后是不需要加入softmax的

5,保存模型

如果没保存模型的话一退出就没了,所以保存模型加个torch.save()

torch.save(model.state_dict(), 'model.pt') #model.state_dict()就是模型中的w和b

6,加载模型并预测

我们保存模型的真正目的其实是为了我们在预测的时候可以加载我们之前已经训练好的模型,直接拿过来用

而不是我在预测之前还要重新训练一下模型

#加载模型文件里的参数w、b
import torch
import torch.nn as nnimport pandas as pdraw_df = pd.read_csv('train.csv')
print(raw_df.head())
#    label  pixel0  pixel1  pixel2  ...  pixel780  pixel781  pixel782  pixel783
# 0      1       0       0       0  ...         0         0         0         0
# 1      0       0       0       0  ...         0         0         0         0
# 2      1       0       0       0  ...         0         0         0         0
# 3      4       0       0       0  ...         0         0         0         0
# 4      0       0       0       0  ...         0         0         0         0
#
# [5 rows x 785 columns]#将标签那列数据拿出来
label = raw_df['label']
print(label)
# 0        1
# 1        0
# 2        1
# 3        4
# 4        0
#         ..
# 41995    0
# 41996    1
# 41997    7
# 41998    6
# 41999    9
# Name: label, Length: 42000, dtype: int64#将df的数据类型转成numpy的,去掉索引
label = raw_df['label'].values
print(label)
# [1 0 1 ... 7 6 9]#特征(删除label列,剩下的就是特征
raw_df = raw_df.drop(['label'], axis=1) #axis=1表示y轴
feature = raw_df.values
print(len(label),len(feature))#将整个数据集划分成两个数据集,一个训练集、一个测试集,80%是用来神经网络训练的
#训练集相当于日常作业,测试集就是考试,日常作业做的好不代表考试做的好,所以还需要测试
#这里的数据集实际上已经被打乱过了,现在直接做个切片即可train_feature = feature[:int(0.8*len(feature))]
train_label = label[:int(0.8*len(label))]
test_feature = feature[int(0.8*len(feature)):]
test_label = label[int(0.8*len(label)):]#将numpy转为tensor,还要将其数据类型变为float
train_feature = torch.tensor(train_feature).to(torch.float)         #数据应该是浮点数
train_label = torch.tensor(train_label)                             #标签 应该是整数
test_feature = torch.tensor(test_feature).to(torch.float)
test_label = torch.tensor(test_label)#把参数塞进模型里面
#首先要有一个模型对象,模型结构
#序列化(搭积木),里面可以放入任意想要的层,从前向后
model = nn.Sequential(nn.Linear(784, 444),    #Linear全连接层或者称线性层nn.ReLU(),                                   #加入激活层nn.Linear(444, 512),nn.ReLU(),nn.Linear(512, 512),nn.ReLU(),nn.Linear(512, 10),nn.Softmax()                                #将值转换成概率)#加载模型文件参数
params = torch.load("model.pt")
model.load_state_dict(params) #把模型中的参数全部塞到model中去了#加载完模型后就是预测了
new_test_data = test_feature[100:111]
new_test_label = test_label[100:111]predict = model(new_test_data)
result = torch.argmax(predict,axis=1)
print(new_test_label)
print(result)
#对比两者结果是差不多的,可以看到如下所示,有个别预测不对
# tensor([5, 1, 8, 3, 6, 2, 7, 9, 6, 3, 6])
# tensor([5, 1, 8, 8, 6, 2, 4, 4, 6, 5, 6])

7,使用GPU加速

Pytorch的

能够定义模型结构,能够加载模型,能够使用模型进行预测
但是这里面还有一个功能是欠缺的,就是使用GPU进行加速

这个时候有人问了,不是装好了GPU版本的pytorch吗
如果没有在代码中真正调用GPU加速的命令,它是不会把数据放到显存里面去存储,并且使用GPU进行计算的
在这里插入图片描述

在这里插入图片描述

import pandas as pd
#定义nn神经网络
import torch
import torch.nn as nnraw_df = pd.read_csv('train.csv')
print(raw_df.head())
#    label  pixel0  pixel1  pixel2  ...  pixel780  pixel781  pixel782  pixel783
# 0      1       0       0       0  ...         0         0         0         0
# 1      0       0       0       0  ...         0         0         0         0
# 2      1       0       0       0  ...         0         0         0         0
# 3      4       0       0       0  ...         0         0         0         0
# 4      0       0       0       0  ...         0         0         0         0
#
# [5 rows x 785 columns]#将标签那列数据拿出来
label = raw_df['label']
print(label)
# 0        1
# 1        0
# 2        1
# 3        4
# 4        0
#         ..
# 41995    0
# 41996    1
# 41997    7
# 41998    6
# 41999    9
# Name: label, Length: 42000, dtype: int64#将df的数据类型转成numpy的,去掉索引
label = raw_df['label'].values
print(label)
# [1 0 1 ... 7 6 9]#特征(删除label列,剩下的就是特征
raw_df = raw_df.drop(['label'], axis=1) #axis=1表示y轴
feature = raw_df.values
print(len(label),len(feature))#将整个数据集划分成两个数据集,一个训练集、一个测试集,80%是用来神经网络训练的
#训练集相当于日常作业,测试集就是考试,日常作业做的好不代表考试做的好,所以还需要测试
#这里的数据集实际上已经被打乱过了,现在直接做个切片即可train_feature = feature[:int(0.8*len(feature))]
train_label = label[:int(0.8*len(label))]
test_feature = feature[int(0.8*len(feature)):]
test_label = label[int(0.8*len(label)):]print(len(train_feature),len(train_label),len(test_feature),len(test_label))
#33600 33600 8400 8400#
#将numpy转为tensor,还要将其数据类型变为float
train_feature = torch.tensor(train_feature).to(torch.float)         #数据应该是浮点数
train_label = torch.tensor(train_label)                             #标签 应该是整数
test_feature = torch.tensor(test_feature).to(torch.float)
test_label = torch.tensor(test_label)#将数据存放到显存中
train_feature = train_feature.cuda()
train_label = train_label.cuda()
test_feature = test_feature.cuda()
test_label = test_label.cuda()#3神经网络,可以将其看成黑盒子,或者一个 python函数,这个函数有了输入就有了输出
#784个像素点构成的灰度图——》函数——》10个概率(0 1 2 3 4 5 6 7 8 9的概率)
#那么函数该怎么定义呢,这个步骤就是定义网络结构的步骤
#定义网络结构#[1,784]*[784,444] = [1,444]*[444,512] = [1,512]*[512,512] = [1,512]*[512,10] = [1,10]
#输入层    in_channel 784   out_channel  444
#隐藏层1    in_channel 444   out_channel  512
#隐藏层2    in_channel 512   out_channel  512
#输出层    in_channel 512   out_channel  10#伪造个随机数据
data = torch.rand(1, 784) #共784个像素,将其转为一行784列的数据#序列化(搭积木),里面可以放入任意想要的层,从前向后
model = nn.Sequential(nn.Linear(784, 444),    #Linear全连接层或者称线性层nn.ReLU(),                                   #加入激活层nn.Linear(444, 512),nn.ReLU(),nn.Linear(512, 512),nn.ReLU(),nn.Linear(512, 10),#nn.Softmax()                                #将值转换成概率)model = model.cuda()    #将model的数据从内存转到显存中#这个函数可以返回一个模型对象给我们
print(model)
# Sequential(
#   (0): Linear(in_features=784, out_features=444, bias=True)
#   (1): ReLU()
#   (2): Linear(in_features=444, out_features=512, bias=True)
#   (3): ReLU()
#   (4): Linear(in_features=512, out_features=512, bias=True)
#   (5): ReLU()
#   (6): Linear(in_features=512, out_features=10, bias=True)
#   (7): Softmax(dim=None)
# )
#现在的model已经是一个模型了 ,但是现在模型里面的w和b是随机值,是不好用的
#后面还需要通过数据驱动其进行训练(但是训练之前还要做一件事情要验证一下此模型搭建出来合不合理)
#随机一个数据进行能否得到输出的十个概率值# predict = model(data)   #进行相关的算
# print(predict)
# # tensor([[0.0944, 0.0975, 0.1039, 0.0938, 0.1050, 0.1013, 0.1024, 0.1010, 0.0998,
# #          0.1011]], grad_fn=<SoftmaxBackward0>)# 梯度下降(找到一组合适的w和b,让损失值越小越好),w和b再上面的模型结构中已经定义好了,但是损失值并不知道
# 损失值 使用损失函数,一般都使用交叉熵损失函数
# 瞎子下山
lossfunction = nn.CrossEntropyLoss()
#训练的时候要使用什么样的优化器,一般使用Adam
optimizer = torch.optim.Adam(params=model.parameters(), lr=0.001)  #params参数优化,学习率lr(步子)#训练的轮数
for i in range(100):#清空优化器的梯度(偏导),Adam会存放一些历史的一些偏导数,所以我们要把它们清空optimizer.zero_grad()#接着走前向传播的流程(即预测的流程)predict = model(train_feature)#将概率转换成0~10的索引并打印result = torch.argmax(predict, axis=1)# print(result)                           #tensor([5, 0, 7,  ..., 0, 5, 5])train_acc = torch.mean((result == train_label).to(torch.float))#算预测结果与标准结果之间有多少误差,即损失值loss = lossfunction(predict, train_label)#有了损失值后要做梯度下降# (在神经网络中要做梯度下降,要干的事情是先做反向传播)loss.backward()#梯度下降在optimizer中进行的optimizer.step()    #梯度下降一步#到此整个更新过程就都完事了,每一轮训练完了,他的损失值和准确率是多少# print(loss.item())      #损失值随着训练和迭代是越来越小的,那说明这里面的w和b越来越好#接下来还有个东西就是准确率,准确率怎么搞呢,先分析这个predict出来的是什么print('train loss:{} train acc:{}'.format(loss.item(),train_acc.item()))#清空一下优化器的梯度,再对测试集数据进行预测optimizer.zero_grad()predict = model(test_feature)result = torch.argmax(predict, axis=1)test_acc = torch.mean((result == test_label).to(torch.float))loss = lossfunction(predict, test_label)#测试的时候是不需要更新的,loss.backward() optimizer.step() 就不用写了print('test loss:{} test acc:{}'.format(loss.item(), test_acc.item()))torch.save(model.state_dict(), 'model.pt') #model.state_dict()就是模型中的w和b

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34775.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里wan2.1本地部署

1.安装虚拟环境&#xff0c; a) 安装python-3.11.8 b)在本地目录运行 - python -m venv Wan2.1-env - cd Scripts - activate 2.下载代码 git clone https://github.com/Wan-Video/Wan2.1.git cd Wan2.1 3.安装依赖库 pip install torch torchvision --index-url https://…

HTTPS建立连接过程

一、混合加密 通过混合加密的方式可以保证信息的机密性&#xff0c;解决了窃听的风险。 HTTPS采用的是对称加密和非对称加密结合的混合加密方式&#xff1a; &#xff08;1&#xff09; 在通信建立前采用非对称加密的方式交换会话密钥&#xff0c;后续就不再使用非对称加密。 &…

Leetcode-2272. Substring With Largest Variance [C++][Java]

目录 一、题目描述 二、解题思路 【C】 【Java】 Leetcode-2272. Substring With Largest Variancehttps://leetcode.com/problems/substring-with-largest-variance/description/2272. 最大波动的子字符串 - 力扣&#xff08;LeetCode&#xff09;2272. 最大波动的子字符串…

蓝桥杯备赛 Day0_移动零

&#x1f388; 个人主页&#x1f449;&#xff1a;tbRNA-CSDN博客tbRNA-CSDN博客tbRNA-CSDN博客 &#x1f4af; 个人简介&#xff1a;在校大学生一枚&#x1f48b;. &#x1f60d; 希望我的文章对大家有着不一样的帮助&#xff0c;欢迎大家关注我&#xff0c;感谢大家的多多支持…

EDAS:投稿经验-word版本-问题解决

1. 字体不对&#xff0c;字体未嵌入问题 问题&#xff1a;word转PDF后&#xff0c;总是显示有字体格式不对&#xff08;忘记截图了&#xff09;。 办法&#xff1a;1. EDAS投稿PDF格式问题-CSDN博客-PDF上修改 IEEE论文检测的字体未嵌入问题Times New Ro…

TCP/IP协议中三次握手(Three-way Handshake)与四次挥手(Four-way Wave)

TCP/IP协议中三次握手&#xff08;Three-way Handshake&#xff09;与四次挥手&#xff08;Four-way Wave&#xff09; 一、TCP三次握手&#xff08;Three-way Handshake&#xff09;二、TCP四次挥手&#xff08;Four-way Wave&#xff09;三、常见问题解答总结为什么三次握手不…

代码随想录Day16

Day16 二叉树part06 LeetCode 530.二叉搜索树的最小绝对差 题目描述 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 输入&#xff1a;root [4,2,6,1,3] 输出&…

用通义大模型写爬虫程序,汇总各科成绩

需求&#xff1a;根据各科网址&#xff0c;输入学号、姓名查询成绩。 中间反反复复很多次&#xff0c;本文只记下重点的几次和大模型的沟通历史。 输入界面 查询界面 round0&#xff08;最初的问题&#xff09; 请在windows下&#xff0c;使用python的selenium库&#xff0…

Java算法OJ(12)

目录 1.前言 2.正文 2.1Fib数列 2.2单词搜索 2.3杨辉三角 3.小结 1.前言 哈喽大家好吖&#xff0c;今天来分享几道的练习题&#xff0c;欢迎大家在评论区多多交流&#xff0c;废话不多说让我们直接开始吧。 2.正文 2.1Fib数列 题目&#xff1a;斐波那契数列_牛客题霸…

使用傅里叶变换测量声卡的频率失真

文章目录 一、说明二、关于声卡的技术详述三、实验代码获取四、结论 一、说明 假如我希望使用我的声卡来模拟软件无线电&#xff0c;利用声音而不是射频信号。我的声卡能胜任这项任务吗&#xff1f;本文将研究一种技术来找出答案。另外&#xff0c;需要了解音频技术的读者也可…

LeetCode 解题思路 18(Hot 100)

解题思路&#xff1a; 继承 LinkedHashMap&#xff1a; 内置双向链表&#xff0c;自动维护节点的插入顺序和访问顺序。LRU 淘汰逻辑&#xff1a; 覆盖 removeEldestEntry&#xff0c;当元素数量超过 capacity 时&#xff0c;移除最旧条目。removeEldestEntry 方法提供钩子&…

JS基础部分

引入方式 内部脚本 外部脚本 变量 使用let声明变量&#xff0c;弱类型&#xff0c;使用const声明常量 因为箭头函数中this指针有问题&#xff0c;会默认指向父级对象 DOM 文档对象模型&#xff0c;将标记语言的各个部分封装成对应的对象。js通过dom就能够对html进行操作 …

Linux与深入HTTP序列化和反序列化

深入HTTP序列化和反序列化 本篇介绍 在上一节已经完成了客户端和服务端基本的HTTP通信&#xff0c;但是前面的传递并没有完全体现出HTTP的序列化和反序列化&#xff0c;为了更好得理解其工作流程&#xff0c;在本节会以更加具体的方式分析到HTTP序列化和反序列化 本节会在介绍…

QT入门笔记2

目录 一、前言 二、串口助手实现 2.1、串口 2.1.1、可用串口信息-QSerialPortInfo 2.1.2、打开串口-QSerialPort 2.1.3、串口发送接收信息 2.2、定时器-QTimer 2.3、常用属性类型转换&#xff08;会更新&#xff09; 2.4、子控件组规则命名优化 一、前言 这个是学习Q…

DeepSeek(3):DeepSeek R1 提示词⼯程

1 提示词⼯程 5W1H&#xff08;What, Who, When, Where, Why, How&#xff09;是⼀种常⽤的信息收集和指令下达的⽅法。以下是根据这个⽅法为DeepSeek R1模型下指令的例⼦&#xff0c;以“学习⼤模型应⽤开发”为例&#xff1a; &#xff08;1&#xff09;What&#xff08;是什…

Linux入门 全面整理终端 Bash、Vim 基础命令速记

Linux入门 2025 超详细全面整理 Bash、Vim 基础命令速记 刚面对高级感满满的 终端窗口是不是有点懵&#xff1f;于是乎&#xff0c;这份手册就是为你准备的高效学习指南&#xff01;我把那些让人头大的系统设置、记不住的命令都整理成了对你更友好的格式&#xff0c;让你快速学…

RBA+minibatch的尝试

目录 还是咬着牙来写 RBA了 JAX JAX->TORCH torch tensor的变形 pytorch怎么把一个【3,3,5】的tensor变成【3,10,5】&#xff0c;多的用0填充 pytorch如何把shape【100】转成【100,1】 把torch shape【100,1】变成【100】 SQUEEZE grad_fn 不能两次反向传播 还…

Jupyter notebook的安装与使用

jupyter notebook的安装需要在已经安装配置好的conda环境下 win r 打开运行窗口 输入cmd回车 在cmd窗口中输入以下命令 conda install jupyter notebook安装完成后启动 jupyter notebook 也是在cmd窗口 输入 : jupyter notebook运行成功后第一次打开的时候需要选择一个浏览…

如何在Ubuntu上构建编译LLVM和ISPC,以及Ubuntu上ISPC的使用方法

之前一直在 Mac 上使用 ISPC&#xff0c;奈何核心/线程太少了。最近想在 Ubuntu 上搞搞&#xff0c;但是 snap 安装的 ISPC不知道为什么只能单核&#xff0c;很奇怪&#xff0c;就想着编译一下&#xff0c;需要 Clang 和 LLVM。但是 Ubuntu 很搞&#xff0c;他的很多软件版本是…

特殊的数字排序

0特殊的数字排序 - 蓝桥云课 问题描述 小明被挑选去参加一个ACM比赛。他的任务是解决一个很特别的问题&#xff1a;给定一个整数数组&#xff0c;但是只能通过交换任意两个数的方式来排序。听起来很简单对吗&#xff1f;但是这个问题的难点在于&#xff0c;只有某些数字是可以…