Pytorch基础教程:从零实现手写数字分类

文章目录

  • 1.Pytorch简介
  • 2.理解tensor
    • 2.1 一维矩阵
    • 2.2 二维矩阵
    • 2.3 三维矩阵
  • 3.创建tensor
    • 3.1 你可以直接从一个Python列表或NumPy数组创建一个tensor:
    • 3.2 创建特定形状的tensor
    • 3.3 创建三维tensor
    • 3.4 使用随机数填充tensor
    • 3.5 指定tensor的数据类型
  • 4.tensor基本运算
    • 4.1 ‌算术运算:
      • 4.1.1 ‌加法‌:
      • 4.1.2 ‌减法‌:
      • 4.1.3 ‌乘法‌(逐元素乘法,不是矩阵乘法):
      • 4.1.4 ‌除法‌:
      • 4.1.5 ‌幂运算‌:
    • 4.2 ‌‌矩阵运算:
      • 4.2.1 ‌‌矩阵乘法‌:
      • 4.2.2 ‌‌‌矩阵转置‌:
      • 4.2.3 ‌‌‌逐元素运算的广播机制:
    • 4.3 ‌‌‌‌统计运算:
      • 4.3.1 ‌‌‌‌求和‌:
      • 4.3.2 ‌‌‌‌平均值‌:
      • 4.3.3 ‌‌‌‌最大值和最小值‌:
    • 4.4 形状操作:
      • 4.4.1 ‌‌‌‌改变形状‌:
      • 4.4.2 ‌‌‌‌展平‌:
  • 5.理解神经网络
    • 5.1 什么是分类,什么是回归
      • 5.1.1 分类
      • 5.1.2 回归
    • 5.2 有什么函数可以实现分类和回归?答案:线性回归
      • 5.2.1 从二元一次方程组到Simple Linear Regression
      • 5.2.1 什么是线性关系(Linear Relationship)?
    • 5.3 线性回归到神经网络
      • 5.3.1 理解新模型 - 简易版神经网络
  • 6.定义网络结构
  • 7.整理数据集
  • 8.训练模型
  • 9.保存模型
  • 10.加载模型
  • 11.使用GPU加速
    • 11.1 要将model(model里面的参数w和b)从内存放到显存。
    • 11.2 把加载的数据从内存加载到显存
    • 11.3 只要将模型的数据,测试数据和训练数据加载到显存,自然会使用GPU进行处理。

1.Pytorch简介

‌PyTorch是一个开源的深度学习框架,由Facebook的人工智能研究院(FAIR)开发,并于2017年1月正式推出。‌ PyTorch以其灵活性和易用性著称,特别适合于深度学习模型的构建和训练。它基于Torch张量库开发,提供了动态计算图的功能,允许在运行时改变计算图,这使得模型构建更加灵活

2.理解tensor

Tensor 是PyTorch中最近本的数据结构,可以将其视为n维数组或者矩阵。n维矩阵在我们生活里非常常见。

2.1 一维矩阵

在这里插入图片描述
基本操作
在这里插入图片描述

2.2 二维矩阵

二维矩阵是一个表格,其中包含行和列。例如:
在这里插入图片描述
在这个矩阵中,
a11a 11 、a12a12 、a13a13 、a21a21 、a22a22 、a23a23 、a31a31 、a32a32 、a33a33 是矩阵的元素。第一个方括号内的元素属于第一行,第二个方括号内的元素属于第二行,第三个方括号内的元素属于第三行。

2.3 三维矩阵

三维矩阵可以看作是由多个二维矩阵组成的“矩阵的矩阵”,通常用于表示多维数据。例如,一个3x3x3的三维矩阵可以表示为:
在这里插入图片描述
在这个三维矩阵中,每一个二维矩阵(由方括号包围的部分)可以看作是一个“层”,整个三维矩阵由这些层组成。

3.创建tensor

3.1 你可以直接从一个Python列表或NumPy数组创建一个tensor:

import torch# 从Python列表创建tensor
data = [[1, 2], [3, 4]]
tensor_from_list = torch.tensor(data)
print(tensor_from_list)# 从NumPy数组创建tensor
import numpy as np
np_array = np.array(data)
tensor_from_np = torch.from_numpy(np_array)
print(tensor_from_np)

在这里插入图片描述

3.2 创建特定形状的tensor

你可以使用torch的内置函数来创建具有特定形状和值的tensor:

import torch# 创建一个全为零的tensor,形状为(2, 3)
zeros_tensor = torch.zeros((2, 3))
print(zeros_tensor)# 创建一个全为一的tensor,形状为(2, 3)
ones_tensor = torch.ones((2, 3))
print(ones_tensor)# 创建一个未初始化的tensor,形状为(2, 3),其值可能是随机的
uninit_tensor = torch.empty((2, 3))
print(uninit_tensor)# 创建一个具有指定值的tensor,所有元素都设为5,形状为(2, 3)
full_tensor = torch.full((2, 3), 5)
print(full_tensor)

在这里插入图片描述

3.3 创建三维tensor

要创建一个三维tensor,你只需指定三个维度的大小:

import torch# 创建一个形状为(2, 3, 4)的三维tensor,所有元素都初始化为0
three_dim_tensor = torch.zeros((2, 3, 4))
print(three_dim_tensor)

3.4 使用随机数填充tensor

你还可以使用随机数来填充tensor:

import torch# 创建一个形状为(2, 3)的tensor,其元素是从均匀分布[0, 1)中抽取的随机数
rand_tensor = torch.rand((2, 3))
print(rand_tensor)# 创建一个形状为(2, 3)的tensor,其元素是从标准正态分布中抽取的随机数
randn_tensor = torch.randn((2, 3))
print(randn_tensor)

在这里插入图片描述

3.5 指定tensor的数据类型

在创建tensor时,你还可以指定其数据类型(dtype):

import torch# 创建一个形状为(2, 3)的tensor,元素类型为浮点数(默认)
float_tensor = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
print(float_tensor)
print(float_tensor.dtype)  # 输出: torch.float32# 创建一个形状为(2, 3)的tensor,元素类型为整数
int_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.int32)
print(int_tensor)
print(int_tensor.dtype)  # 输出: torch.int32

在这里插入图片描述

4.tensor基本运算

4.1 ‌算术运算:

4.1.1 ‌加法‌:

import torch
x = torch.tensor([1.0, 2.0, 3.0])
y = torch.tensor([4.0, 5.0, 6.0])
z = x + y  # 对应元素相加
print(z)  # 输出: tensor([5., 7., 9.])

4.1.2 ‌减法‌:

z = x - y  # 对应元素相减
print(z)  # 输出: tensor([-3., -3., -3.])

4.1.3 ‌乘法‌(逐元素乘法,不是矩阵乘法):

z = x * y  # 对应元素相乘
print(z)  # 输出: tensor([4., 10., 18.])

4.1.4 ‌除法‌:

z = x / y  # 对应元素相除
print(z)  # 输出: tensor([0.2500, 0.4000, 0.5000])

4.1.5 ‌幂运算‌:

z = x ** 2  # 每个元素求平方
print(z)  # 输出: tensor([1., 4., 9.])

4.2 ‌‌矩阵运算:

4.2.1 ‌‌矩阵乘法‌:

A = torch.tensor([[1, 2], [3, 4]])
B = torch.tensor([[5, 6], [7, 8]])
C = torch.mm(A, B)  # 或者使用 A @ B 在PyTorch 1.0及以上版本
print(C)  # 输出: tensor([[19, 22], [43, 50]])

4.2.2 ‌‌‌矩阵转置‌:

A_t = A.t()
print(A_t)  # 输出: tensor([[1, 3], [2, 4]])

4.2.3 ‌‌‌逐元素运算的广播机制:

PyTorch支持广播机制,当两个tensor的形状不完全相同时,较小的tensor会自动扩展以匹配较大的tensor的形状,然后进行逐元素运算。

x = torch.tensor([1.0, 2.0, 3.0])
y = torch.tensor(2.0)  # 这是一个标量,将被广播到与x相同的形状
z = x + y
print(z)  # 输出: tensor([3., 4., 5.])

4.3 ‌‌‌‌统计运算:

4.3.1 ‌‌‌‌求和‌:

sum_x = x.sum()  # 对所有元素求和
print(sum_x)  # 输出: tensor(6.)

4.3.2 ‌‌‌‌平均值‌:

mean_x = x.mean()  # 对所有元素求平均值
print(mean_x)  # 输出: tensor(2.)

4.3.3 ‌‌‌‌最大值和最小值‌:

max_x, _ = x.max()  # 返回最大值及其索引(这里只关心最大值)
min_x, _ = x.min()  # 返回最小值及其索引(这里只关心最小值)
print(max_x)  # 输出: tensor(3.)
print(min_x)  # 输出: tensor(1.)

4.4 形状操作:

4.4.1 ‌‌‌‌改变形状‌:

x_reshaped = x.view(-1, 1)  # 将x改变为列向量
print(x_reshaped)  # 输出: tensor([[1.], [2.], [3.]])

4.4.2 ‌‌‌‌展平‌:

x_flattened = x.flatten()  # 将x展平为一维数组
print(x_flattened)  # 输出: tensor([1., 2., 3.])

5.理解神经网络

在开始之前,我觉得有必要提个醒, 神经网络本质上是数学,但我们仅仅作为开发者,我们要做的事情是通过pytorch或类似的工具实现我们想要的功能,达到我们想要的目的。至于为什么里面的数学公式是这样子,为什么神经网络的架构是这样搭,为什么他这个结构这么好,我们根本不用去管里面的最底层机理。我们只需要知道这样子这样子就能达到效果,就可以了。我们不要被这些数学公式吓跑了。

5.1 什么是分类,什么是回归

‌分类和回归是机器学习中两种基本的预测方法,它们的核心区别在于预测的输出类型‌。

5.1.1 分类

分类,简单来说,就是给数据打上标签,预测它属于哪一个类别。比如,我们有一堆邮件,需要判断哪些是垃圾邮件,哪些是正常邮件。这就是一个典型的二分类问题,因为输出只有两种可能:垃圾邮件或正常邮件。再比如,我们有一张动物图片,需要判断它是猫、狗还是其他动物,这就是一个多分类问题,因为输出有多个可能的类别‌。

举例:想象你手里有一堆水果,你需要把它们分成苹果和橙子两类,这就是分类任务。你要看水果的颜色、形状等特征,然后决定它是苹果还是橙子。

5.1.2 回归

回归,则是预测一个具体的数值,这个数值可以是任何实数。比如,我们想知道一套房子的价格,根据它的面积、位置等特征来预测。这就是一个回归问题,因为输出是一个连续的数值,而不是一个类别标签。再比如,我们想预测明天的温度或者股票的价格,这些都是回归问题‌。

举例:想象你要预测一辆汽车的价格,你会考虑它的品牌、型号、年份、里程数等特征,然后给出一个具体的价格预测,比如10万元、15万元等,这就是回归任务。
图片转自‘人工智能教学实践’
上图转自‘人工智能教学实践’博客,我觉得这张图很好地解析什么是分类,什么是回归,预测天气的是分类,预测温度是多少,是回归。

5.2 有什么函数可以实现分类和回归?答案:线性回归

5.2.1 从二元一次方程组到Simple Linear Regression

初中时,我们通过两个点的坐标求解二元一次方程。例如:已知直线y = ax + b 经过点(1,1)和(3,2),求解a, b的值。
在这里插入图片描述

解法是将坐标值带入方程,得到一个二元一次方程组,并对其进行求解:

在这里插入图片描述
坐标图如下:
在这里插入图片描述
以上二元一次方程组的求解可以看作一个简单的线性回归问题,估算出x和y之间的线性关系,得到公式:y = 1/2*x + 1/2

5.2.1 什么是线性关系(Linear Relationship)?

在这里插入图片描述
在这里插入图片描述
需要注明的是,线性关系不仅仅指存在于两个变量之间,它也可以存在于三个或者更多变量之间。比如y = a + bx1 + cx2,这条直线可以在三维空间中表达。
但实际情况是,我们在真实世界的数据不会完美的落在一个直线上,即使两个数据存在线性关系,它们或多或少离完美的直线都还有一些偏差。图像表示如下:
在这里插入图片描述
以上直线表达的是predictor和outcome之间近似的线性关系:y ≈ ax + b

5.3 线性回归到神经网络

可以看出,线性回归非常直观且易于实现,同时也过于简单,只能适用于比较简单的模型,如果模型稍显复杂,则不能很好地反映数据的分布。
在这里插入图片描述
例如在该图中,红色线段为我们想要拟合的图形,蓝色线段为我们的线性回归模型,无论怎样调整斜率w 或截距 b,都无法与红色较好地匹配。说明在此例中,线性函数模型过于简单,我们需要一个稍微复杂一些的模型。这里我们引入一个分段函数作为模型:
在这里插入图片描述
可以看出,当 x<x1 或 x>x2 时,函数值恒等于一个值,而当 x∈[x1,x2] 时,函数值则是呈线性变化的。该函数图像如下:
在这里插入图片描述
所以如果用这个分段函数来模拟上面的红色线段的话,可以采用下面几个步骤:
在这里插入图片描述
step 0:取常数 b 作为红色线段在 y 轴上的截距;
step 1:令分段函数中间部分的斜率和长度与红色线段第一部分相同(w1,b1);
step 2:令分段函数中间部分的斜率和长度与红色线段第二部分相同(w2,b2);
step 3:令分段函数中间部分的斜率和长度与红色线段第三部分相同(w3,b3)。
所以红色线段可用几个不同的蓝色线段表示为:
在这里插入图片描述
问题又来了,这种分段函数看着非常复杂,而且计算不方便,能否再使用一个近似的函数进行替换呢?于是这里又引入了 Sigmoid 函数:
在这里插入图片描述
Sigmoid 函数可以很好的表现上面的蓝色线段,而且是非线性的,没有线性的那么直(或者说hard),所以也把上面蓝色的图形叫做hard sigmoid。
于是,我们的模型又等价于:
在这里插入图片描述
这里 n 的大小,取决于我们要模拟多复杂的函数,n越大,意味着要模拟的函数越复杂。
在这里插入图片描述

5.3.1 理解新模型 - 简易版神经网络

对于我们的新模型
在这里插入图片描述
来说,可以看做是先进行线性计算,然后放入Sigmoid函数计算后,再加上常数b的过程。可用下图表示:
在这里插入图片描述
如此一来,原本稍显繁琐的公式一下子就显得直观了不少。而且整个图看起来与神经网络非常相似,线性函数 wx+b 为输入层,Sigmoid 可看做隐藏层,加总后的y可看做输出层。如果让模型变得更复杂点,就更像了:
在这里插入图片描述
这里,我们增加了输入样本的复杂度(由单一连接变成了全连接),并且增加了多层 Sigmoid 函数,虽然模型整体更加复杂,但本质上还是没有变。所以我们完全可以从一个简单的线性模型过渡到一个复杂的神经网络。
再来看公式,看到这个加总符号 ∑,就说明里面进行的都是一系列相似的计算,所以用向量替换比较合适。
如果先约定好,统一使用列向量来表示数据,并使用 σ(x) 表示 Sigmoid 函数,则以上数据及参数可表示为:
在这里插入图片描述
然后我们就可以用这些向量来表示模型的公式了:
在这里插入图片描述

使用这种表示方式,不仅显得更简洁,而且计算速度也非常快,特别是当样本非常多的情况下。

6.定义网络结构

如果觉得上面讲解还是有点复杂,我们可以将神经网络简单粗暴地理解成是多对多的线性方程,比如说,我现在有个784像素的图片,图片里都是0-9的单独数字,想通过一张图片,预测是哪个数字。

输入: 784个参数
输出: 10个预测的概率

哪个概率最大哪个就是预测的数字。这就是我们要搭建的结构。
之前提过了, 一个神经网络中间是有几个隐藏层。而且隐藏层的参数个数我们可以自己定义,那上面的结构就可以这样表示。

输入: 784个参数
隐藏层1: 555个参数
隐藏层2: 888个参数
输出: 10个预测的概率

隐藏层的参数个数我们可以自己定义,这里隐藏层1参数个数我随便设置成555,隐藏层2参数个数设置成888.
但层与层之前的我们通过什么的方式连接呢?我们可以通过in_features, out_features的数值来设置,比如说这一层的输入的参数个数,是上一层的输出参数的个数, 这一层的输出的参数个数,是下一成的输入的参数个数。

输入: in_features = 784,out_features = 555
隐藏层1: in_features = 555,out_features = 888
隐藏层2: in_features = 888,out_features = 888
输出: in_features = 888,out_features = 10

到这里,大体的网络框架大概搭建了,但刚才说到了除了输入和输出外,我们还需要一个激活函数,激活函数我们之前学到了Sigmoid ,让线性的函数变得更加符合现实化,非线性化。也就是:

输入: in_features = 784,out_features = 555
激活函数: Sigmoid()
隐藏层1: in_features = 555,out_features = 888
激活函数: Sigmoid()
隐藏层2: in_features = 888,out_features = 888
激活函数: Sigmoid()
输出: in_features = 888,out_features = 10

到这里的话其实神经网络已经体现出来了,但这个输出的值是一个正无穷到负无穷的值。它还不是一个概率值。

比如: [[-0.0575, -0.0059, 0.0094, 0.0205, -0.0239, 0.0034, -0.0519, -0.0335, 0.0502, 0.0181]]

我们还需要对他进行归一化。我们会用到一个函数叫Softmax(), 这个函数的作用就是对这些正无穷到负无穷的值进行处理,使其变成0-1之间的数,变成0-1之间的数后,我们就可以大胆地称之为概率。
在这里插入图片描述
在这里插入图片描述
ok, 那经过上面的套路,总结起来,神经网络就是

输入: in_features = 784,out_features = 555
激活函数: Sigmoid()
隐藏层1: in_features = 555,out_features = 888
激活函数: Sigmoid()
隐藏层2: in_features = 888,out_features = 888
激活函数: Sigmoid()
输出: in_features = 888,out_features = 10
归一化: Softmax()

到此为止,我们已经手撕了一个简单的神经网络,回到我们的主题,如何通过Pytorch搭建神经网络。Here we go!

import torch
import torch.nn as nn#784个像素点构成的灰度图->函数->10个概念(0,1,2,3,4,5,6,7,8,9)#输入层 in_channel=784 out_channel=555
#隐藏层1 in_channel=555 out_channel=888
#隐藏层2 in_channel=888 out_channel=888
#输出层 in_channel=888 out_channel=10data = torch.rand(1, 784)model = nn.Sequential(nn.Linear(784, 555),nn.Sigmoid(),nn.Linear(555, 888),nn.Sigmoid(),nn.Linear(888, 888),nn.Sigmoid(),nn.Linear(888, 10),nn.Softmax()
)predict = model(data)
print(model)
print(predict)

在这里插入图片描述
Pytorch已经帮我们封装好了函数,我们更重要的是理解然后手撕了一个简单的神经网络,然后通过Pytorch提供的函数进行调用了完事了。

7.整理数据集

我们可以从kaggle比赛中下载数据集。
https://www.kaggle.com/competitions/digit-recognizer/data

在这里插入图片描述
在这里插入图片描述
又或者到我的CSDN资源直接下载: kaggle手写数字识别竞赛中用到的数据集


下载完后,我们主要来看train.csv
在这里插入图片描述
从train.csv可以看到,第一列是标签, 其他列就是像素,0,1,2。。。。783
我们需要python中pandas的工具包来帮我们分解train.csv,并且用来隔开特征和标签。

import pandas as pdraw_df = pd.read_csv('dataset/train.csv')
# 标签
label = raw_df['label'].values
# 特征
feature = raw_df.drop(['label'], axis=1)

特征这一列中,我们先删除label这一列,然后保留其他列,剩下的就是特征。
分割完标签和特征后,我们还要分测试集和训练集。我采取4:1的分割方式。

import torch
import torch.nn as nn
import pandas as pdraw_df = pd.read_csv('dataset/train.csv')
# 标签
label = raw_df['label'].values
# 特征
feature = raw_df.drop(['label'], axis=1).values#整个数据集划分成两个数据集 训练集 测试集, 4:1train_feature = feature[:int(len(feature)*0.8)]
train_label = label[:int(len(label)*0.8)]
test_feature = feature[int(len(feature)*0.8):]
test_label = label[int(len(label)*0.8):]print(len(train_feature),len(train_label),len(test_feature),len(test_label))

打印结果

33600 33600 8400 8400

至此,数据准备完成。

8.训练模型

模型架构有了, 数据也准备好了,我们可以训练起来了。
说到训练,我们就要进行梯度下降。找到一组合适的w和b,让损失值越小越好。
优先我们要准备一个损失函数,交叉熵损失函数。用来计算损失值。

lossfunction = nn.CrossEntropyLoss()

计算完损失值,我们下一步就是优化里面的w和b, pytorch给我们提供了很多优化函数,我们用Adam就足够了。

optimizer = torch.optim.Adam(params=model.parameters(), lr=0.0001)

import torch
import torch.nn as nn
import pandas as pdraw_df = pd.read_csv('dataset/train.csv')
# 标签
label = raw_df['label'].values
# 特征
feature = raw_df.drop(['label'], axis=1).values#整个数据集划分成两个数据集 训练集 测试集, 4:1train_feature = feature[:int(len(feature)*0.8)]
train_label = label[:int(len(label)*0.8)]
test_feature = feature[int(len(feature)*0.8):]
test_label = label[int(len(label)*0.8):]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)print(len(train_feature),len(train_label),len(test_feature),len(test_label))#784个像素点构成的灰度图->函数->10个概念(0,1,2,3,4,5,6,7,8,9)#输入层 in_channel=784 out_channel=555
#隐藏层1 in_channel=555 out_channel=888
#隐藏层2 in_channel=888 out_channel=888
#输出层 in_channel=888 out_channel=10data = torch.rand(1, 784)model = nn.Sequential(nn.Linear(784, 555),nn.Sigmoid(),nn.Linear(555, 888),nn.Sigmoid(),nn.Linear(888, 888),nn.Sigmoid(),nn.Linear(888, 10),nn.Softmax()
)# predict = model(data)
# print(model)
# print(predict)# 梯度下降。找到一组合适的w和b,让损失值越小越好。
lossfunction = nn.CrossEntropyLoss()
# 优化器
optimizer = torch.optim.Adam(params=model.parameters(), lr=0.0001)# 训练的轮数
for i in range(100):# 清空优化器的梯度(偏导)optimizer.zero_grad()predict = model(train_feature)loss = lossfunction(predict, train_label)loss.backward()optimizer.step()print(loss.item())

至此,简单的神经网络训练程序已经搭建出来了, 我们可以开始运行,打印损失值。
在这里插入图片描述
我们可以看到损失值越来越小。意味着我们预测的准确率越来越高。
其实到这里我们已经结束了,但我们还想看看准确率,那我们可以在中间打印一下。首先

predict = model(train_feature)

这个predict 是一个数组,是包含所有概率的数组,我们简单理解成这样的数据。

0.3,0.1,0.2,0.1,0.0,0.0,0.0,0.0,0.0,0.0
0.1,0.1,0.2,0.1,0.0,0.0,0.0,0.0,0.5,0.0
0.2,0.1,0.2,0.1,0.0,0.0,0.0,3.0,0.3,0.0
0.1,0.1,0.2,0.1,0.0,0.0,0.0,0.1,0.0,0.0
0.1,0.1,0.2,0.1,0.0,0.0,0.0,0.3,0.0,0.0

我们首先要是每一行里面找到最大值,然后拿出它对应的数字,这里的数字其实就是对应的索引

result = torch.argmax(predict, axis=1)

然后准确率我们可以用这个result和train_label进行对比

train_acc = torch.mean((result==train_label).to(torch.float))

打印结果再看看

# 训练的轮数
for i in range(100):# 清空优化器的梯度(偏导)optimizer.zero_grad()predict = model(train_feature)result = torch.argmax(predict, axis=1)train_acc = torch.mean((result == train_label).to(torch.float))loss = lossfunction(predict, train_label)loss.backward()optimizer.step()print('train loss:{} train acc:{}'.format(loss.item(), train_acc.item()))

在这里插入图片描述

损失值越来越小,准确率越来越高,这就是我们想要的结果。

9.保存模型

torch.save(model.state_dict(), '/mymodel.pt')

就这么简单。model.state_dict()就是训练完的w和b, '/mymodel.pt’就是要保存的路径和名称。

10.加载模型

这里我新建了一个python文件check_model.py

parameters = torch.load('/mymodel.pt')

先拿到之前模型的参数。
但我们要先把之前定义的网络结构搬回来。

model = nn.Sequential(nn.Linear(784, 555),nn.Sigmoid(),nn.Linear(555, 888),nn.Sigmoid(),nn.Linear(888, 888),nn.Sigmoid(),nn.Linear(888, 10),nn.Softmax()
)

然后再将参数塞进model

model.load_state_dict(parameters)

然后我们再用pandas加载数据, 拿出对应的标签和我们预测的值进行对比。

import torch
import torch.nn as nn
import pandas as pdmodel = nn.Sequential(nn.Linear(784, 555),nn.Sigmoid(),nn.Linear(555, 888),nn.Sigmoid(),nn.Linear(888, 888),nn.Sigmoid(),nn.Linear(888, 10),nn.Softmax()
)parameters = torch.load('/mymodel.pt')model.load_state_dict(parameters)raw_df = pd.read_csv('dataset/train.csv')
# 标签
label = raw_df['label'].values
# 特征
feature = raw_df.drop(['label'], axis=1).values
test_feature = feature[int(len(feature)*0.8):]
test_label = label[int(len(label)*0.8):]
test_feature = torch.tensor(test_feature).to(torch.float)
test_label = torch.tensor(test_label)new_test_feature = test_feature[100:111]
new_test_label = test_label[100:111]predict = model(new_test_feature)
result = torch.argmax(predict, axis=1)
print(new_test_label)
print(result)

在这里插入图片描述
预测结果正常,有六个预测正确,因为之前的trainning里面只有0.5左右的正确率,有可能训练的次数有关,训练次数太少。所以这个结果符合我们预期。

11.使用GPU加速

有人会问,我们已经装好了GPU版本的pytorch,为什么还要GPU加速。因为我们默认是用CPU运行,我们需要对代码再进行GPU调用。
使用GPU加速主要可以用两个方向,model方向和数据方向

11.1 要将model(model里面的参数w和b)从内存放到显存。

model = model.cuda() 

11.2 把加载的数据从内存加载到显存

train_feature = torch.tensor(train_feature).to(torch.float).cuda() 
train_label = torch.tensor(train_label).cuda() 
test_feature = torch.tensor(test_feature).to(torch.float).cuda() 
test_label = torch.tensor(test_label).cuda() 

11.3 只要将模型的数据,测试数据和训练数据加载到显存,自然会使用GPU进行处理。

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

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

相关文章

CDP中的Hive3之Hive Metastore(HMS)

CDP中的Hive3之Hive Metastore&#xff08;HMS&#xff09; 1、CDP中的HMS2、HMS表的存储&#xff08;转换&#xff09;3、HWC授权 1、CDP中的HMS CDP中的Hive Metastore&#xff08;HMS&#xff09;是一种服务&#xff0c;用于在后端RDBMS&#xff08;例如MySQL或PostgreSQL&a…

C#,图论与图算法,任意一对节点之间最短距离的弗洛伊德·沃肖尔(Floyd Warshall)算法与源程序

一、弗洛伊德沃肖尔算法 Floyd-Warshall算法是图的最短路径算法。与Bellman-Ford算法或Dijkstra算法一样&#xff0c;它计算图中的最短路径。然而&#xff0c;Bellman Ford和Dijkstra都是单源最短路径算法。这意味着他们只计算来自单个源的最短路径。另一方面&#xff0c;Floy…

Android中下载 HAXM 报错 HAXM installation failed,如何解决?

AMD芯片的电脑在 Android Studio 中安装 Virtual Device 时&#xff0c;经常会出现一个 问题 Intel HAXM installation failed. To install Intel HAXM follow the instructions found at: https://github.com/intel/haxm/wiki/Installation-Instructions-on-Windows 一直提示H…

少一点If/Else - 状态模式(State Pattern)

状态模式&#xff08;State Pattern&#xff09; 状态模式&#xff08;State Pattern&#xff09;状态模式&#xff08;State Pattern&#xff09;概述状态模式&#xff08;State Pattern&#xff09;结构图状态模式&#xff08;State Pattern&#xff09;涉及的角色 talk is c…

mayavi -> python 3D可视化工具Mayavi的安装

前言 Mayavi是一个基于VTK&#xff08;Visualization Toolkit&#xff09;的科学计算和可视化工具&#xff0c;主要用于数据可视化和科学计算领域。 它提供了一系列的高级可视化工具&#xff0c;包括2D和3D图形、表面和体积渲染、流场可视化等。Mayavi可以通过Python脚本进行调…

idea 自动导包,并且禁止自动导 *(java.io.*)

自动导包配置 进入 idea 设置&#xff0c;可以按下图所示寻找位置&#xff0c;也可以直接输入 auto import 快速定位到配置。 Add unambiguous imports on the fly&#xff1a;自动帮我们优化导入的包Optimize imports on the fly&#xff1a;自动去掉一些没有用到的包 禁止导…

BI 是如何数据分析的?

企业部署商业智能BI前&#xff0c;需要进行详细的分析&#xff0c;了解BI能为企业带来多少价值&#xff1f;如何提高工作效率的等等&#xff0c;今天我们就来聊一聊 BI 的工作原理。 一、BI的取数方式 商业智能BI是通过访问和连接业务系统数据源数据库的方式来进行取数的&…

宇泰串口卡驱动在Ubuntu22.04编译、安装汇总

从官网下载驱动官网地址 上传到Ubuntu, 目录结构如下&#xff1a; 驱动源代码: 驱动代码是基于开源项目编译来的 编译路径不能有中文路径&#xff0c;否则可能有类似错误 源码是基于Linux2.3内核编译&#xff0c;我当前是6.8.0-51&#xff0c;数据结构有升级&#xff0c;需要调…

HarmonyOS 鸿蒙 ArkTs(5.0.1 13)实现Scroll下拉到顶刷新/上拉触底加载,Scroll滚动到顶部

HarmonyOS 鸿蒙 ArkTs(5.0.1 13)实现Scroll下拉到顶刷新/上拉触底加载 效果展示 使用方法 import LoadingText from "../components/LoadingText" import PageToRefresh from "../components/PageToRefresh" import FooterBar from "../components/…

上传自己的镜像到docker hub详细教程

上传自己的镜像到docker hub详细教程 本博客通B站视频一致&#xff1a; 上传自己的镜像到docker hub详细教程 1. 登录自己的hub.docker.com的账号 docker hub仓库 2. 点击Repositories&#xff0c;跳转到创建仓库页面 3. 点击Create a repository 创建repository&#xff0c…

[AI部署-tensorRT] customlayer定义添加过程解析

文章目录 tensorRT添加自定义层步骤1. trt如何解析onnx的&#xff1f; 整体流程图2. builtin_op_importor是干什么的&#xff1f;3. 怎么添加trt plugin4. 如何进行量化collection过程 references nvidia 官方plugin文档&#xff1a; https://www.nvidia.cn/content/dam/en-zz/…

[Do374]Ansible一键搭建sftp实现用户批量增删

[Do374]Ansible一键搭建sftp实现用户批量增删 1. 前言2. 思路3. sftp搭建及用户批量新增3.1 配置文件内容3.2 执行测试3.3 登录测试3.4 确认sftp服务器配置文件 4. 测试删除用户 1. 前言 最近准备搞一下RHCA LV V,外加2.9之后的ansible有较大变化于是练习下Do374的课程内容. 工…

易语言文字识别OCR

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

Docker 镜像制作原理 做一个自己的docker镜像

一.手动制作镜像 启动容器进入容器定制基于容器生成镜像 1.启动容器 启动容器之前我们首先要有一个镜像&#xff0c;这个镜像可以是从docker拉取&#xff0c;例如&#xff1a;现在pull一个ubuntu镜像到本机。 docker pull ubuntu:22.04 我们接下来可以基于这个容器进行容器…

网络编程 - - TCP套接字通信及编程实现

概述 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的传输层协议。在网络编程中&#xff0c;TCP常用于实现客户端和服务器之间的可靠数据传输。本文将基于C语言实现TCP服务端和客户端建立通信的过程。 三次握手 在…

近红外简单ROI分析matlab(NIRS_SPM)

本次笔记主要想验证上篇近红外分析是否正确&#xff0c;因为叠加平均有不同的计算方法&#xff0c;一种是直接将每个通道的5分钟实时长单独进行叠加平均&#xff0c;另一种是将通道划分为1分钟的片段&#xff0c;将感兴趣的通道数据进行对应叠加平均&#xff0c;得到一个总平均…

从玩具到工业控制--51单片机的跨界传奇【2】

咱们在上一篇博客里面讲解了什么是单片机《单片机入门》&#xff0c;让大家对单片机有了初步的了解。我们今天继续讲解一些有关单片机的知识&#xff0c;顺便也讲解一下我们单片机用到的C语言知识。如果你对C语言还不太了解的话&#xff0c;可以看看博主的C语言专栏哟&#xff…

Python调用go语言编译的库

要在 Python 中调用用 Go 语言编写的库&#xff0c;可以使用 Go 语言的 cgo 特性将 Go 代码编译成共享库&#xff08;如 .so 文件&#xff09;&#xff0c;然后在 Python 中通过 ctypes 或 cffi 模块加载和调用这个共享库。 新建main.go文件&#xff0c;使用go语言编写如下代码…

学成在线_内容管理模块_创建模块工程

学成在线模块工程 1.各个微服务依赖基础工程2.每个微服务都是一个前后端分离的项目3.xuecheng-plus-content&#xff1a;内容管理模块工程xuecheng-plus-content-modelxuecheng-plus-content-servicexuecheng-plus-content-api 1.各个微服务依赖基础工程 2.每个微服务都是一个前…

1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)

目录 01. Java中的集合体系 02. 单列集合体系​ 1. Collection系列集合的遍历方式 &#xff08;1&#xff09;迭代器遍历&#xff08;2&#xff09;增强for遍历​编辑&#xff08;3&#xff09;Lambda表达式遍历 03.List集合详解 04.Set集合详解 05.总结 Collection系列…