Pytorch深度学习笔记之三(构建一个完整的神经网络)

news/2024/5/6 15:45:33/文章来源:https://blog.csdn.net/nirendao/article/details/127159425

本篇笔记是基于一个印度人写的《Pytorch深度学习》一书的第二章,主要用来描述一个麻雀虽小五脏俱全的完整的神经网络,包含了建模、训练等。原书的代码基于较老版本的Pytorch,有多处编译不过,笔者都做了调整,并在文末给出完整的代码和运行结果。

假设我们为一家互联网公司工作,该公司提供在线电影服务。
训练数据集包含了用户在平台上观看电影的平均时间的特征,而神经网络据此预测每个用户下周使用平台的时间。

一个典型的神经网络的构建过程分为以下5个阶段。

  1. 准备数据
    get_data()准备输入输出的张量(数组)

这个神经网络中的get_data()函数创建了2个变量: x和y,尺寸分别为(17,1) 和 (17).

def get_data():train_X = np.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,7.042,10.791,5.313,7.997,5.654,9.27,3.1])train_Y = np.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,2.827,3.465,1.65,2.904,2.42,2.94,1.3])dtype = torch.FloatTensorx = Variable(torch.from_numpy(train_X).type(dtype),requires_grad=False).view(17,1)y = Variable(torch.from_numpy(train_Y).type(dtype),requires_grad=False)return x,y

这里的 x 是一个 17x1 的二维张量;y 是一个一维张量。

加、减和矩阵乘法这些基础运算可以构建复杂运算,如卷积神经网络(CNN)和递归神经网络(RNN)。这些以后再讲。

  1. 创建学习参数
    get_weights()函数提供以随机值初始化的张量。神经网络通过自动优化这些参数来解决问题。

这个例子要构建一个线性的神经网络,即y=wx+b,因此只有2个学习参数:w和b,还有2个不变的参数:x和y .
torch.randn()函数为任意给定形状创建随机值。

def get_weights():w = Variable(torch.randn(1),requires_grad=True)b = Variable(torch.randn(1),requires_grad=True)return w,b
  1. 构建网络模型
    simple_network()函数应用线性规则为输入数据生成输出。计算时,先用权重w乘以输入数据,再加上偏差b,即:y=wx+b

模型是用来学习如何将输入映射到输出的。
在传统编程中,我们手动实现逻辑,将输入映射到输出,是“已知输入和逻辑,求输出”。
在深度学习和机器学习中,是把输入和输出展示给模型,让模型完成对逻辑的学习,是“已知输入和输出,求逻辑”。
这里的网络模型是 y=wx+b, 其中w和b是学习参数,神经网络要学习w和b的值。

网络的实现如下:

def simple_network(x):y_pred = torch.matmul(x,w)+breturn y_pred

torch.nn提供了层(Layer)的高级抽象。
层负责后台的初始化和运算工作,而这些技术是很多常见的技术都需要用到的。

  1. 评估损失
    loss_fn()函数提供了评估模型优劣的信息。

学习参数w和b以随机值开始,产生结果y_pred, 这样必定和真实值y相去甚远。
因此需要定义一个函数,来告知模型预测值和真实值的差距。
我们使用误差平方和(也称为方差,即 SSE)来定义损失函数。

def loss_fn(y,y_pred):loss = (y_pred-y).pow(2).sum()for param in [w,b]:if param.grad is not None: param.grad.data.zero_()loss.backward()if loss.data is None:print("loss.data is None")else:print("loss.data.size = %d" % len(loss.data))return loss.data

(笔者注:原文是return loss.data[0], 这应该是Pytorch早期版本支持的写法,但在笔者的1.12.1版本里,对于0维张量,直接返回loss.data即可。另外,对本函数中的 if 语句略作调整,使其更符合Python编程习惯。)

除了计算损失值,我们还进行了backward操作,计算出学习参数w和b的梯度。
我们会不止一次地使用loss函数,因此需要通过 grad.data.zero_()方法来清除前面计算出的梯度值。
在第一次调用backward函数的时候,梯度是空的; 因此当梯度不为None时,需将梯度值设为0.

  1. 优化器
    optimize()函数用于调整初始随机权重,并帮助模型更准确地计算目标值。

前面使用随机值作为初始权重来预测目标,然后计算损失,再调用loss变量上的backward函数来计算梯度值。每次迭代在整个样例集合上重复整个过程。
损失值计算出来后,用计算出的梯度值进行优化,让损失值降低。

learning_rate = 1e-4def optimize(learning_rate):w.data -= learning_rate * w.grad.datab.data -= learning_rate * b.grad.data

learning_rate是一个超参数,可以让用户通过较小的梯度值的变化来调整变量的值。
梯度值指明了每个变量(w和b)需要调整的方向。

各种优化器,如Adam,RmsProp, SGD等,在 torch.optim包中已经实现好。

  1. 完整的程序
    完整的程序如下。在这个程序中,我们最后会调用matplotlib来绘制一幅图。图中的红点的x轴坐标即为上周用户观影时间,y轴坐标为本周用户观影时间,蓝色的线条代表了预测线,即根据 x 坐标,预测 y 坐标。
import torch 
import numpy as np 
import matplotlib.pyplot as plt 
from torch.autograd import Variable learning_rate = 1e-4# Training Data
def get_data():train_X = np.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,7.042,10.791,5.313,7.997,5.654,9.27,3.1])train_Y = np.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,2.827,3.465,1.65,2.904,2.42,2.94,1.3])dtype = torch.FloatTensorx = Variable(torch.from_numpy(train_X).type(dtype),requires_grad=False).view(17,1)y = Variable(torch.from_numpy(train_Y).type(dtype),requires_grad=False)return x,ydef get_weights():w = Variable(torch.randn(1),requires_grad=True)b = Variable(torch.randn(1),requires_grad=True)return w,bdef simple_network(x):y_pred = torch.matmul(x,w)+breturn y_preddef loss_fn(y,y_pred):loss = (y_pred-y).pow(2).sum()for param in [w,b]:if param.grad is not None: param.grad.data.zero_()loss.backward()return loss.datadef optimize(learning_rate):w.data -= learning_rate * w.grad.datab.data -= learning_rate * b.grad.datadef plot_variable(x,y,z='',**kwargs):l = []for a in [x,y]:if type(a) == torch.Tensor:l.append(a.data.numpy())# print(l)plt.plot(l[0],l[1],z,**kwargs)return pltx,y = get_data()               # x - represents training data,y - represents target variables
w,b = get_weights()            # w,b - Learnable parameters
for i in range(500):y_pred = simple_network(x) # function which computes wx + bloss = loss_fn(y,y_pred)   # calculates sum of the squared differences of y and y_predif i % 50 == 0: print(loss)optimize(learning_rate)    # Adjust w,b to minimize the lossplt1 = plot_variable(x,y,'ro')
plt2 = plot_variable(x,y_pred,label='Fitted line')
plt2.show()

(笔者注:对于plot_variable函数,笔者也略作了修改,否则有语法错误;究其原因,应该也是原来代码是基于较老版本的Pytorch所致。)

运行的截图如下:
在这里插入图片描述

(完)

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

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

相关文章

几种常见的概率分布表

参考:《概率论与数理统计 第四版》

Jenkins+Maven+Gitlab+Tomcat 自动化构建打包、部署

一、环境需求 本帖针对的是Linux环境,Windows或其他系统也可借鉴。具体只讲述Jenkins配置以及整个流程的实现。 1.JDK(或JRE)及Java环境变量配置,我用的是JDK1.8。 2.Jenkins 持续集成和持续交付项目。 3.现有项目及gitlab&#…

Redis实战 - 03 RedisTemplate 的 hash 结构

文章目录1. put(H var1, HK var2, HV var3)2. get(H var1, Object var2)3. entries(H key)4. keys(H key)5. values(H key)6. hasKey(H key, Object var2)7. size(H key)8. putAll(H key, Map<? extends HK, ? extends HV> map)1. put(H var1, HK var2, HV var3) 新增…

机器学习之验证曲线绘制-调参可视化-sklearn

验证曲线是什么&#xff1f; 验证曲线和学习曲线的区别是&#xff0c;横轴为某个超参数的一系列值&#xff0c;由此来看不同参数设置下模型的准确率(评价标准)&#xff0c;而不是不同训练集大小下的准确率。 从验证曲线上可以看到随着超参数设置的改变&#xff0c;模型可能从…

Java Web 12.1 Filter 12.1.2 Filter 快速入门

Java Web 【黑马程序员新版JavaWeb基础教程&#xff0c;Java web从入门到企业实战完整版】 12 Filter & Listener & Ajax 文章目录Java Web12 Filter & Listener & Ajax12.1 Filter12.1.2 Filter 快速入门12.1 Filter 12.1.2 Filter 快速入门 【开发步骤】…

论如何参与一个开源项目(上)

写在前面的一些话 说起开源项目&#xff0c;好像人人都懂&#xff1a;不过就是一群人一起写了些东西&#xff0c;并且这些东西是公开的&#xff0c;大家都能看。但要细说&#xff0c;可能大多数的开发者都说不出个所以然&#xff0c;甚至不知道怎么提issue。 所以我就想写这样…

这,这,是个神人,我喜欢

国庆的第三天&#xff0c;跟一个好友聊天&#xff0c;他本来是准备回老家的&#xff0c;但是因为疫情搁浅在原地了。上来就直接给我搞一个有难度的代码如果没有人跟你说这个是输出helloworld的&#xff0c;鬼知道这个代码。然后&#xff0c;我就说我想对他进行一个采访&#xf…

QX-A51智能小车实现-物联网应用系统设计项目开发

目录介绍说明展示介绍 STC89C52系列单片机是STC推出的新一代高速/低功耗/超强抗干扰/超低价的单片机&#xff0c;指令代码完全兼容传统8051单片机&#xff0c;12时钟每机器周期和6时钟每机器周期可以任意选择 QX-A51智能小车原理图 QX-A51智能小车配置 硬件组成&#xff1a;电…

QT模型索引使用QModelIndex

QT模型索引使用QModelIndex QModelIndex有三个要素&#xff1a;行row 列column 父节点索引parent 但是注意我们并不能定义一个QModelIndex QModelIndex的构造函数QModelIndex()的功能是创建一个新的空的QModelIndex QModelIdex()是一个空索引&#xff0c;它其实可以代表任意mo…

数据库-MySQL基础(9)-多表关系

目录 概述 1、一对多 2、多对多 3、一对一 多表查询概述 多表查询分类 1、连接查询 2、子查询 概述 项目开发中&#xff0c;在进行数据库表结构关系设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析设计表结构&#xff0c;由于业务之间相互关联…

5、android 数据存储(2)(数据库SQLite:SQLiteDatabase)

1、数据库管理器SQLiteDatabase SQLiteDatabase是SQLite的数据库管理类&#xff0c;它提供了若干操作数据表的API&#xff0c;常用的方法有3类&#xff1a; 1. 管理类&#xff0c;用于数据库层面的操作。 openDatabase&#xff1a;打开指定路径的数据库。 isOpen&#xff1a…

机器学习之学习曲线绘制Python-skleran

学习曲线作用&#xff1a; 学习曲线是什么&#xff1f;简单来说&#xff0c;就是用学习曲线(learning curve)来判断模型状态&#xff1a;过拟合还是欠拟合。 学习曲线定义&#xff1a; 学习曲线是根据不同训练集大小&#xff0c;模型在训练集和验证集上的得分变化曲线。 学…

虚拟机搭建Redis 远程密码可访问,并且后台运行

1、关闭系统防火墙 操作指令备注查看防火墙状态systemctl status firewalld / firewall-cmd --state暂时关闭防火墙systemctl stop firewalld永久关闭防火墙(禁用开机自启)systemctl disable firewalld下次启动,才生效暂时开启防火墙systemctl start firewalld永久开启防火墙(…

基于python+django框架+Mysql数据库的校园新生报到系统设计与实现

项目背景和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于python的校园新生报到系统&#xff0c;整体网站系统基于B/S架构&#xff0c;技术上使用基于python的Django框架来实现&#xff1b;通过后台添加设置校园信息、录入和管理校园资讯、校园风光、学校分院信…

Linux 用户管理 文件目录指令 时间日期指令 搜索查找类 解压压缩类

目录 用户管理 添加用户: 指定/修改密码 删除用户 查询用户信息指令 切换用户 查看当前用户/登录用户 用户组 修改用户的组 用户和组相关文件 指定运行级别1 指定运行级别2 找回root密码 帮助指令 文件目录指令 文件目录类 pwd 指令 ls 指令 cd 指令 mkdir指…

Android Automotive(五) CarService

Android Automotive&#xff08;五&#xff09; CarService CarService是Android Automotive在系统框架层的核心服务。它类似SystemServer在服务内部管理着数十个子服务。 启动流程 CarService是由SystemServer启动的&#xff0c;启动流程如下。 SystemServer 启动CarServi…

【GNN从入门到精通】第一章 图的基本知识

文章目录一、图的表示1.1 什么是图&#xff1f;二、图的特征2.1 子图2.2 连通分量2.3 接通图2.3.1 无向图连通图2.3.2 有向连通图2.4 最短路径2.5 图直径三、图中心性3.1 度中心性3.2 特征向量中心性3.3 中介中心性3.4 连接中心性四、网页排序算法4.1 PageRank4.2 HITS4.3 例子…

游程描述的任意区域最小旋转矩形算法实现

效果 采用游程描述了多个区域,经过算法计算,找到最小包围矩形。 白色是指定的区域,黄色是该区域的最小旋转矩形。 算法原理 有时候算法不一定很高深,只要把道理点破,实现起来很简单,难的是最开始的算法构思过程。 区域最小旋转矩形的算法原理也很简单:将区域从0到90…

Dapper 在继承层次结构中处理数据

Dapper 包含一项功能,用于处理可能逐行映射到不同类型的数据。在处理使用Table Per Hierarchy存储模式的继承层次结构时,此功能特别有用,即一个表用于表示层次结构中的所有类。“鉴别器”列用于区分类型。 以下类定义表示基于抽象Contract类型的继承层次结构。还定义了三种派…

16.python实现线性单元和梯度下降-10月4日编程作业-Relu函数

目录 课堂笔记 代码实现1 运行结果1 代码实现2 评定一个学生的综合绩点 运行结果2 小结 课堂笔记 代码实现1 from cgi import print_environ from functools import reduce import numpy as np#定义感知器类 class perceptron(object):#感知器初始化函数(参数个数&…