讲解

须导入和函数库

mport torch
import numpy as np
from torch.autograd import Variable
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

设定目标多项式的参数

本次拟合的是三次多项式
y=a1x1+a2x2+a3x3+by=a_1x_1+a_2x_2+a_3x_3+by=a1​x1​+a2​x2​+a3​x3​+b
所以需要 w_target = [a1, a2, a3] 和 b_target

# 设定target参数
w_target = torch.tensor([0.5, 3, 2.4]).unsqueeze(1)    # unsqueeze 升维
b_target = torch.tensor([0.9])

生成w_target用到的.unsqueeze(axis)函数为升维函数。
如果不加该函数,w_targetshapetorch.Size([3]),并不是向量(矩阵)。

.unsqueeze(1) 是在w_target的第二维的位置加上一个维度,变为torch.Size([3, 1]),变为向量(矩阵)。

关于升维降维函数的讲解见本人的另一个博客增加维度或者减少维度 ——a.squeeze(axis) 和 a.unsqueeze(axis)

生成训练集

通过batch_size=256确定训练集内元素的个数

生成 x 的序列(以向量存在)

目标: 生成随机、有序的x的序列( 以向量存在 )
实现思路:

  1. 生成batch_size数量的随机数(tensor类型)
  2. 类型转换:tensor ==> numpyndarray
  3. 对生成的随机数(ndarray类型)排序
  4. 类型转换:ndarray ==> tensor
  5. 升维,构成矩阵
random = torch.randn(batch_size)    # 生成batch_size个随机数
random = random.numpy()
random.sort()                       # 升序排列random,涉及类型转换,tensor 2 array
random = torch.from_numpy(random)   # random 类型转换 array 2 tensor
random = random.unsqueeze(1)        # 升维构成矩阵
计算 y 的实际值

这里有一个很重要的知识点:矢量化编程

矢量化编程简单来说,就是用 矩阵运算 代替 显性的for循环
矢量化编程的作用:能极大提高运行速度(划重点:极大)

在通过
y=a1x1+a2x2+a3x3+by=a_1x_1+a_2x_2+a_3x_3+by=a1​x1​+a2​x2​+a3​x3​+b计算y时,我们用矢量化编程来代替显性的for循环

# 原理讲解
# torch.Size([256, 3])
# x = [[x_1 x_1^2 x_1^3]
#      [x_2 x_2^2 x_2^3]
#      [x_3 x_3^2 x_3^3]
#      ...
#      [x_256 x_256^2 x_256^3]]
#
# torch.Size([3, 1])
# w_target =([a_1],
#            [a_2],
#            [a_3]])# 根据**线性代数**知识:
# y = x * w_target + b
# torch.Size([256, 1])

代码实现如下:

 x = torch.cat([ random ** i for i in range(1, 4)], 1)            # 生成x, x^2, x^3 的列矩阵y = x.mm(w_target) + b_target[0]    # 生成真实y

关于 x = torch.cat([ random ** i for i in range(1, 4)], 1) 的原理,在本人的另一篇博客专门很仔细地讲过 拼接多个tensor:torch.cat((A,B),axis),故此处不再赘述。

GPU or CPU

这里首先要定义一个人为设定的超参数DEVICE

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

之后就可以用.to(DEVICE)tensor放到相应的GPUCPU上了。

return x.to(DEVICE), y.to(DEVICE)

生成训练集的整体代码如下:

DEVICE = ("cuda" if torch.cuda.is_available() else "cpu")# 生成训练集
def get_batch(batch_size=256):# 生成随机、有序的x的序列(组成 -> 向量)random = torch.randn(batch_size)    # 生成batch_size个随机数random = random.numpy()random.sort()                       # 升序排列random,涉及类型转换,tensor 2 arrayrandom = torch.from_numpy(random)   # random 类型转换 array 2 tensorrandom = random.unsqueeze(1)        # 升维x = torch.cat([ random ** i for i in range(1, 4)], 1)            # 生成x, x^2, x^3 的列矩阵y = x.mm(w_target) + b_target[0]    # 生成真实yreturn x.to(DEVICE), y.to(DEVICE)

搭建网络结构

class poly_model(nn.Module):def __init__(self):super(poly_model, self).__init__()self.poly = nn.Linear(3, 1)         # 输入三维,输出一维def forward(self, x):out = self.poly(x)return outmodel = poly_model().to(DEVICE)

model = poly_model().to(DEVICE)将网络实例化,使其有了输入输出接口

另外,注意每个网络层的输入输出维度
这个网络只有一个网络层。输入维度为 3 ,输出维度为 1。体现在self.poly = nn.Linear(3, 1) 的两个参数31上。

最后的model为:

poly_model((poly): Linear(in_features=3, out_features=1, bias=True)
)

定义损失函数和优化器

这部分没什么可说的。

#  ------------定义损失函数和优化函数--------------
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=1e-3)

训练网络

# 训练网络 直到误差小于1e-3
epoch = 0
while True:# get databatch_x, batch_y = get_batch()      # 得到训练集# forwardpredict = model(batch_x)     # 用模型计算predictloss = criterion(predict, batch_y)       #计算损失函数,前者为预测值,后者为真实值# backward passoptimizer.zero_grad()   # 优化器梯度归零loss.backward()optimizer.step()epoch+=1if (epoch-1)%500 == 0:batch_x = batch_x.cpu()batch_y = batch_y.cpu()predict = predict.cpu()predict = predict.detach().numpy()print('epoch:{}'.format(epoch))print('loss:{}',format(loss))predict = torch.from_numpy(predict)batch_x = batch_x.cuda()batch_y = batch_y.cuda()output = predict.cuda()# --------------------------------------------------------------------------if loss < 1e-3:print('Done!')print('epoch:{}'.format(epoch))break

前向传播可反向传播没什么可说的。如果想看可以去本人的另一篇博客 基于python和pytorch的线性拟合(完结),那里说得详细些。

这里要讨论的一点,是if (epoch-1)%500 == 0:这部分中,GPU --> CPU 然后 CPU -->GPU,在这儿是没什么意义的(单纯的输出数值在GPU上也行)。
但是如果想要画图的话GPU --> CPU 然后 CPU -->GPU的过程就是必须的(画图时要求的数据类型为ndarray,再跑下一个epoch的时候数据类型又要变回tensor)。
这里依旧保留GPU --> CPU 然后 CPU -->GPU的过程,就是为了说明以下常规流程(当然像现在的情况可以简化)。

显示结果

# GPU ==> CPU
batch_x = batch_x.cpu()
batch_y = batch_y.cpu()
output = predict.cpu()output = output.detach().numpy()
plt.plot(batch_x.numpy()[:,0], batch_y.data.numpy(), color='b', label='real curve')
plt.show()

唯一要说的.detach(),在 基于python和pytorch的线性拟合(完结)中也讲到了,这里也不说了。

查看训练后的参数

for param in model.named_parameters():print(param[0])        # poly.weightprint(param[1])            # poly.bias

要说的在注释里了。

整体源代码

代码如下

import torch
import numpy as np
from torch.autograd import Variable
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt# 设定target参数
w_target = torch.tensor([0.5, 3, 2.4]).unsqueeze(1)  # unsqueeze 升维
b_target = torch.tensor([0.9])DEVICE = ("cuda" if torch.cuda.is_available() else "cpu")# 返回x y
def get_batch(batch_size=256):random = torch.randn(batch_size)  # 生成batch_size个随机数random = random.numpy()random.sort()  # 升序排列random,涉及类型转换,tensor 2 arrayrandom = torch.from_numpy(random)  # random 类型转换 array 2 tensorrandom = random.unsqueeze(1)  # 升维x = torch.cat([random ** i for i in range(1, 4)], 1)  # 生成x, x^2, x^3 的列矩阵y = x.mm(w_target) + b_target[0]  # 生成真实yreturn x.to(DEVICE), y.to(DEVICE)# -------------------------定义模型---------------------------
class poly_model(nn.Module):def __init__(self):super(poly_model, self).__init__()self.poly = nn.Linear(3, 1)  # 输入三维,输出一维def forward(self, x):out = self.poly(x)return outmodel = poly_model().to(DEVICE)#  ------------定义损失函数和优化函数--------------
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=1e-3)# 训练网络 直到误差小于1e-3
epoch = 0
while True:# get databatch_x, batch_y = get_batch()  # 得到数据集# forwardpredict = model(batch_x)  # 用模型计算predictloss = criterion(predict, batch_y)  # 计算损失函数,前者为预测值,后者为真实值# backward passoptimizer.zero_grad()  # 优化器梯度归零loss.backward()optimizer.step()epoch += 1if (epoch - 1) % 500 == 0:batch_x = batch_x.cpu()batch_y = batch_y.cpu()predict = predict.cpu()predict = predict.detach().numpy()print('epoch:{}'.format(epoch))print('loss:{}', format(loss))predict = torch.from_numpy(predict)batch_x = batch_x.cuda()batch_y = batch_y.cuda()output = predict.cuda()# --------------------------------------------------------------------------if loss < 1e-3:print('Done!')print('epoch:{}'.format(epoch))break# 去cuda化
batch_x = batch_x.cpu()
batch_y = batch_y.cpu()
output = predict.cpu()output = output.detach().numpy()plt.plot(batch_x.numpy()[:, 0], batch_y.data.numpy(), color='b', label='real curve')plt.show()for param in model.named_parameters():print(param[0])print(param[1])

结果

# epoch:1
# loss:{} 107.65440368652344
# epoch:501
# loss:{} 0.17065830528736115
# epoch:1001
# loss:{} 0.02675577811896801
# epoch:1501
# loss:{} 0.010034649632871151
# epoch:2001
# loss:{} 0.0034075819421559572
# epoch:2501
# loss:{} 0.0011402576928958297
# Done!
# epoch:2522
# poly.weight
# Parameter containing:
# tensor([[0.4681, 2.9867, 2.4066]], device='cuda:0', requires_grad=True)
# poly.bias
# Parameter containing:
# tensor([0.9329], device='cuda:0', requires_grad=True)

[PyTorch] 基于python和pytorch的多项式回归相关推荐

  1. [PyTorch] 基于Python和PyTorch的线性拟合

    用神经网络实现线性拟合,代码源自<深度学习入门之pytorch>,本人根据新版本的PyTorch做了挺大的修改. <深度学习入门之pytorch>的使用体验 关于这个书好不好, ...

  2. [PyTorch] 基于Python和PyTorch的MNIST的手写数字数据集的分类

    文章目录 讲解 MNIST的介绍 须导入的函数库 检查 pytorch 的版本 定义超参数 下载 MNIST的数据集 定义网络 网络实例化 定义训练函数 定义测试函数 主函数 全部源代码 2020.0 ...

  3. [PyTorch] 基于Python和PyTorch的cifar-10分类

    cifar-10数据集介绍 CIFAR-10数据集由10个类的60000个32x32彩色图像组成,每个类有6000个图像.有50000个训练图像和10000个测试图像. 数据集分为5个训练批次和1个测 ...

  4. 基于python nlp PyTorch智能对联生成系统 附完整代码 毕业设计

    软件标题:智能对联生成系统 b 系统概述 使用项目:智能对联生成系统 软件用途:通过网页端可以获取到根据已有上联只能生成的下联. 开发历史:本项目未曾有前置版本.但在服务器搭建,Tensorflow ...

  5. Python深度学习:基于PyTorch [Deep Learning with Python and PyTorch]

    作者:吴茂贵,郁明敏,杨本法,李涛,张粤磊 著 出版社:机械工业出版社 品牌:机工出版 出版时间:2019-11-01 Python深度学习:基于PyTorch [Deep Learning with ...

  6. 基于C++的PyTorch模型部署

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 引言 PyTorch作为一款端到端的深度学习框架,在1.0版本之后 ...

  7. 推荐:常见NLP模型的代码实现(基于TensorFlow和PyTorch)

    推荐github上的一个NLP代码教程:nlp-tutorial,教程中包含常见的NLP模型代码实现(基于TensorFlow和Pytorch),而且教程中的大多数NLP模型都使用少于100行代码. ...

  8. 【深度学习】基于MindSpore和pytorch的Softmax回归及前馈神经网络

    1 实验内容简介 1.1 实验目的 (1)熟练掌握tensor相关各种操作: (2)掌握广义线性回归模型(logistic模型.sofmax模型).前馈神经网络模型的原理: (3)熟练掌握基于mind ...

  9. 在python中用pyTorch实现数字(0~9)语音识别

    基于python的数字(0~9)语音识别 1.收集训练数据 speech_commands_v0.01.tar.gz http://download.tensorflow.org/data/speec ...

最新文章

  1. 今晚8点直播 | 详解微软小冰全双工语音对话技术
  2. python中类的嵌套_python中的嵌套类 | 学步园
  3. springboot 中根据数据库表生成所有表的model,mapper和xml文件
  4. SpringBoot-拦截器和文件上传
  5. jq处理返回来json_(转)JQuery处理json与ajax返回JSON实例
  6. vm linux数据恢复,VMWARE虚拟机数据恢复
  7. AFNnetworking详解
  8. python接口自动化(四十)- logger 日志 - 下(超详解)
  9. Show time来了,欢迎投注俺家小宝宝一票啊
  10. Mysql中的where条件子句的使用方法
  11. 《破茧成蝶——用户体验设计师的成长之路》一1.2 邂逅用户体验设计
  12. 前端 linux ps,Linux ps命令
  13. RT-Thread 4.0 + STM32F407 学习笔记1
  14. android bool转字符串,Android 知识点——当json传入字符串,使用Boolean接收时,GSON会将其转换为false...
  15. xml简单理解,xml增删改操作,仅作笔记,不作为学习借鉴
  16. 渗透测试工具之——WVSS(绿盟web应用漏洞扫描系统)概述
  17. VHDL-任意分频器(50%占空比)
  18. Flink On K8S终极实现方案
  19. msgbox.html5.qq.com,怎样制作qq透明背景皮肤
  20. vue百度地图自定义标记图标

热门文章

  1. python编程语言-python与其他编程语言区别全在这
  2. echarts环形图
  3. 全参考视频质量评价方法(PSNR,SSIM)以及相关数据库
  4. jpa内网mysql_mysql+jpa简单实现步骤
  5. c# 火狐浏览器怎么嵌入窗体中_「C#上位机必看」你们想要的练手项目来了
  6. 计算机知识wendang,计算机基础知识Microsoft Word 文档
  7. 【ICPC 2021网络赛2】The 2021 ICPC Asia Regionals Online Contest (II)签到题5题
  8. java发布rest服务器_ArcGIS Server 10 Java 版的Rest服务的部署方法
  9. java 引用类快捷键_Java数据类型及其转换经常用到的快捷键
  10. html图片鼠标动态效果代码,纯css3实现鼠标经过图片显示描述的动画效果