首页 > 编程语言 >零基础学习人工智能—Python—Pytorch学习(五)

零基础学习人工智能—Python—Pytorch学习(五)

时间:2024-08-18 14:38:11浏览次数:7  
标签:Python torch shape 学习 Pytorch train test model numpy

前言

上文有一些文字打错了,已经进行了修正。
本文主要介绍训练模型和使用模型预测数据,本文使用了一些numpy与tensor的转换,忘记的可以第二课的基础一起看。

线性回归模型训练

结合numpy使用

首先使用datasets做一个数据X和y,然后结合之前的内容,求出y_predicted。

# pip install matplotlib
# pip install scikit-learn
import torch
import numpy as np
import torch.nn as nn
from sklearn import datasets
import matplotlib.pyplot as plt
# 0)准备数据
# 生成100行1列的数据X_numpy和Y_numpy
# noise=20: 值越大,数据越具有随机性。
# random_state=1: 设置随机种子,以确保每次生成的X_numpy和Y_numpy相同
X_numpy, Y_numpy = datasets.make_regression( n_samples=100, n_features=1, noise=20, random_state=1) 

X = torch.from_numpy(X_numpy.astype(np.float32))
y = torch.from_numpy(Y_numpy.astype(np.float32))
y = y.view(y.shape[0], 1) #  100 行 1 列 y.shape是100行1列,所以y.shape[0]=100,y.shape[1]=1
n_samples, n_features = X.shape
# 1)模型
input_size = n_features
output_size = 1
model = nn.Linear(input_size, output_size)
# 2)损失函数和优化器
learning_rate = 0.01
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
n_iter = 100
#下面循环的调用了model里的前向传播和反复的使用损失函数进行反向传播来更新w和b,就是训练模型
for epoch in range(n_iter):
    # forward pass and loss
    y_predicted = model(X)
    loss = criterion(y_predicted, y)
    # backward pass
    loss.backward()
    # update
    optimizer.step()
    optimizer.zero_grad()
    if (epoch+1) % 10 == 0:
        print(f'epoch:{epoch+1},loss ={loss.item():.4f}')
# plot
# model(X).detach()是从model里分离出一个张量,这个张量跟model没有关系了,简单理解为生成了新张量对象,内存地址和model不一样了。
div_tensor = model(X).detach()
predicted = div_tensor.numpy() # 返回numpy.ndarray类型的张量,相当于转了类型
# plt.plot是在坐标系上绘制图像 
# 参数1是x坐标轴的值,参数2是y坐标轴的值,参数3=是fmt (格式字符串)
# 参数3介绍:ro是红色圆点r=red o=circle  bo是蓝色圆点 b是蓝色 g是绿色
plt.plot(X_numpy,Y_numpy,'ro')
plt.plot(X_numpy, predicted, 'bo')
plt.show()

这里我们已经提到了训练的模型的概念了。
我们在for循环的调用了model里的前向传播,然后再反复的使用损失函数进行反向传播来更新w和b,这操作就是训练模型。
训练结束后,我们就可以使用model,接受新矩阵,来预测y。
这里,我们是在循环结束后,又重新对x进行了一次预测。
运行如下图:
image

可以看到预测的y都在一条线上,这是因为预测值是基于w和b计算而得,所以,值总是在直线上。
注:所谓x和y的线性关系就是x和y的元素之间的很复杂的倍数关系。
关于线性回归,可以参考下图,稍微了解一下就行。

image

完整的训练例子

下面是一个完整的训练模型,然后使用模型预测的例子。
首先使用datasets.load_breast_cancer()获取数据。数据X可以理解为一个患者的指标数据,Y可以理解为这个患者是否是癌症患者(数据都是0和1)。
然后通过训练模型,我们给一组患者的X指标数据,就可以预测患者是否是癌症患者了。

# pip install matplotlib
# pip install scikit-learn
import torch
import numpy as np
import torch.nn as nn
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# 0)prepare data
bc = datasets.load_breast_cancer() #加载乳腺癌数据集
print(bc.keys()) #data(特征数据)、target(标签)、feature_names(特征名)
X, y = bc.data, bc.target  #取特征数据作为输入数据x(通常是一个二维数组或 DataFrame),取标签作为目标数据y(通常是一维数组或 Series)
print("x 569*30",X.shape,"y 569*1",y.shape)
n_samples, n_features = X.shape # n_samples=569 n_features=30
#train_test_split用于随机地将数据集拆分成训练集和测试
# X_train: 拆分后的训练集的特征部分,包含用于训练模型的大部分数据。
# X_test: 拆分后的测试集的特征部分,包含用于评估模型的小部分数据。
# y_train: 对应 X_train 的目标值,用于训练模型。
# y_test: 对应 X_test 的目标值,用于评估模型。
# test_size=0.2表示将 20% 的数据用于测试,剩下的 80% 用于训练
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=1234)

print("X_train 455*30",X_train.shape,"X_test 114*1",X_test.shape,"y_train 455*1",y_train.shape,"y_test 114*1",y_test.shape)
print("类型1:X_train", type(X_train),"X_test", type(X_test),"y_train", type(y_train),"y_test", type(y_test))
# scale
# StandardScaler 用于对数据进行标准化(即缩放),缩放的方法是使用[标准化公式],
# 大概计算逻辑就是每个x调整为 (x-x集合的平均值)/根号((x-x集合的平均值)²  )
# 经过标准化后,每个特征(特征=列)的均值会变为 0,标准差(平方差)变为 1。 
sc = StandardScaler()

# fit_transform函数里会计算均值和标准差,然后下面的transform会使用fit_transform里的均值和方差
X_train = sc.fit_transform(X_train) #使用计算的均值和方差来标准化X_train
X_test = sc.transform(X_test) #使用fit_transform计算的均值和方差来标准化X_test

#x,y相关数据转tensor数组
X_train = torch.from_numpy(X_train.astype(np.float32))
X_test = torch.from_numpy(X_test.astype(np.float32))
y_train = torch.from_numpy(y_train.astype(np.float32))
y_test = torch.from_numpy(y_test.astype(np.float32))

print("类型2:X_train", type(X_train),"X_test", type(X_test),"y_train", type(y_train),"y_test", type(y_test))

print("X_train 455*30",X_train.shape,"X_test 114*1",X_test.shape,"y_train 455*1",y_train.shape,"y_test 114*1",y_test.shape)

# 转成tensor的y格式不对,进行view调整,原始size为torch.Size([114]) 调整后为:torch.Size([114, 1])
y_train = y_train.view(y_train.shape[0],1)
y_test = y_test.view(y_test.shape[0], 1)
 
# 1)model
# f=wx + b,sigmoid at the end


class LogisticRegression(nn.Module):
    def __init__(self, n_input_features):
        super(LogisticRegression, self).__init__()
        self.linear = nn.Linear(n_input_features, 1) # 参数1:30(x的列)参数2:1(预测y的列)

    def forward(self, x):
        y_predicted = torch.sigmoid(self.linear(x)) #self.linear(x)执行的前向传播,sigmoid它将返回值转换为 [0, 1] 之间的概率值(概率值就是百分比,例如返回0.7,就是70%的意思)
        return y_predicted


model = LogisticRegression(n_features)
# 2)loss and optimizer
learning_rate = 0.01
criterion = nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 3)training loop
num_epochs = 100
for epoch in range(num_epochs):
    # forward pass and loss
    y_predicted = model(X_train)
    loss = criterion(y_predicted,y_train)
    # backward pass
    loss.backward()
    # updates
    optimizer.step()
    # zero gradients
    optimizer.zero_grad()
    if(epoch+1)% 10 == 0:print(f'epoch:{epoch+1},loss ={loss.item():.4f}')
# 模型的使用,这里是以前没有的
with torch.no_grad():
    y_predicted = model(X_test) #把X_test传到模型里,得到X_test的预期y
    y_predicted_cls=y_predicted.round() #四舍五入 y_predicted = torch.tensor([0.3, 0.7, 0.5, 0.2, 0.9])  y_predicted.round()的结果为: tensor([0., 1., 0., 0., 1.])
    #eq(y_test): 这个方法比较 y_predicted_cls 和 y_test 之间的每个元素,如果两个值相等则返回 True,否则返回 False。返回的结果是一个布尔张量。
    eq = y_predicted_cls.eq(y_test)
    print("equal",eq)
    eqsum = eq.sum()
    print("eqsum",eqsum)
    print("y_test.shape[0]", y_test.shape[0]) # y_test.shape[0]是 返回y_test的行,他原来是114行1列的矩阵,所以返回114
    float_y_test= float(y_test.shape[0]) #转为float为下面除法准备
    print("float(y_test.shape[0])", float_y_test)
    acc=eqsum/float_y_test
    print(f'X_test预测的y与y_test的相似度 accuracy ={acc:.4f}')

这样,我们不仅训练了模型,还使用模型预测了一组没有训练过的数据,并成功的预测出了,Y的值(患者是否是癌症),然后拿我们的预测数据,跟真实数据比较一下,正确率是91.23%
image
传送门:
零基础学习人工智能—Python—Pytorch学习(一)
零基础学习人工智能—Python—Pytorch学习(二)
零基础学习人工智能—Python—Pytorch学习(三)
零基础学习人工智能—Python—Pytorch学习(四)
零基础学习人工智能—Python—Pytorch学习(五)


注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!



若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!

https://www.cnblogs.com/kiba/p/18356904

标签:Python,torch,shape,学习,Pytorch,train,test,model,numpy
From: https://www.cnblogs.com/kiba/p/18356904

相关文章

  • DP学习笔记
    动态规划算法与分治法类似,是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始......
  • tarjan之LCA学习笔记
    tarjan之LCA学习笔记tarjan算法求LCA可谓是一个极其巧妙的离线算法其本质是利用DFS遍历时产生的DFS序和并查集来在线性的时间复杂度内求出所有询问的结果既然是离线算法,其和在线算法的区别就在与离线算法需要记录下所有查询,对查询进行一定操作来得到更高的效率,而这......
  • 【python】一文带你领略,Python中非常强大的加密库--pycryptodome
    ✨✨欢迎大家来到景天科技苑✨✨......
  • python基于Python的热门微博数据可视化分析(源码+文档+调试+讲解)
    收藏关注不迷路!!......
  • 二分查找算法详解及Python实现
    目录引言二分查找算法步骤二分查找的Python实现性能分析注意事项引言二分查找算法(BinarySearch)是一种在有序数组中查找某一特定元素的搜索算法。它的基本思想是:通过比较数组中间的元素与目标值的大小,将搜索区间缩小为一半,直到找到目标值或搜索区间被缩小为0。二分查......
  • C语言学习————常量和宏、初识指针
    #define定义常量和宏define是一个预处理指令用途:1.define定义符号#defineMAX1000intmain(){ printf("%d\n",MAX); return0;}2.define定义宏#defineADD(X,Y)((X)+(Y))intmain(){ printf("%d\n",ADD(2,3)); return0;}指针内存内存是计算机上特......
  • 【防忘笔记】Spring+Struts2古董框架学习
    Spring+Struts2项目框架梳理若基于Spring+Struts2的方式进行开发,前后端的交互逻辑会与boot系以及MCV的组织结构有所不同这里是对于学习过程的一些记录前置通用知识Struts2框架资料Struts2基础篇之基本概念Java之struts2框架学习一般情况的Spring前后端调试流程要理解基于......
  • ssy中学暑假集训有关数学及多项式学习笔记
    8.16日集训倒数第\(7\)天唉,不知不觉间在ssy中学的暑假集训就要结束了,只剩下一周的时间了,然而byn和yzh还有bao学姐\(21\)号就要走了,暑假就要过去了....今天模拟赛的第二题很有意思,涉及到了许多的数学知识,正好来恶补一下:浅谈反演原理和二项式反演首先来说说什么是反演(inversio......
  • Python-程序语法 - Python注释&基本函数
    Python注释以#为行开头为注释相关函数str()---传入一个整型值,并求值为它的字符串形式Python2.7.17(default,Mar82023,18:40:28)[GCC7.5.0]onlinux2Type"help","copyright","credits"or"license"formoreinformation.>>>str......
  • Python之层次聚类/系统聚类(Hierarchical Clustering)、变量聚类
    1.层次聚类简介别称:系统聚类英文名:HierarchicalClustering基本原理:假设数据类别之间存在层次结构,通过对数据集在不同层次的划分,构造出树状结构的聚类结果实现方法:聚合方法、分裂方法实现方法方向步骤描述经典算法聚合方法自底向上首先,每个样本自成一簇;然后,开始迭代,每......