pytorch 入门基础知识二(Pytorch 02)

一 微积分

1.1 导数和微分

微分就是求导

%matplotlib inline
import numpy as np
from matplotlib_inline import backend_inline
from d2l import torch as d2l
def f(x):return 3 * x ** 2 - 4 * x

定义:f(x) = 3x^2 - 4x

然后求 f(x) 在 x = 1 时的导数,实际导数:  {f(x)}' = 2*3*1(x=1) - 4 = 2

def numerical_lim(f, x, h):return (f(x + h) - f(x)) / hratio = 0.1
for i in range(5):print(f'ratio={ratio:.5f}, y_={numerical_lim(f, 1, ratio):.5f}')ratio *= 0.1# ratio=0.10000, y_=2.30000
# ratio=0.01000, y_=2.03000
# ratio=0.00100, y_=2.00300
# ratio=0.00010, y_=2.00030
# ratio=0.00001, y_=2.00003

当 ratio 越小的时候,倒数越接近我们要求的值, 画出x=1此时的原函数和切线函数看下。

x = np.arange(-2, 4, 0.1)
plot(x, [f(x), 2 * x - 3], 'x', 'y', legend=['y=3x²-4x', 'y=2x−3'], figsize=(6, 6))

偏导数,梯度:

连结一个多元函数对其所有变量的偏导数,来得到该函数的梯度(gradient)向量。

对于这种固定的函数可以直接计算它的导数,也就是梯度,机器学习的线性回归模型就是用的该方式直接计算,机器学习模块写过该计算过程。

1.2 自动微分

求导是几乎所有深度学习优化算法的关键步骤。

假设我们想对函数 y = 2x^Tx 关于列向量x求导。首先,我们创建变量x并为其分配一个初始值

对应的数学公式:y = 2x^2

import torch
x = torch.arange(4.0)
x
# tensor([0., 1., 2., 3.])

计算y关于x的梯度之前,需要一个地方来 存储梯度

x.requires_grad_(True)   # 等价于x=torch.arange(4.0,requires_grad=True)
print(x.grad)   
# None   # 默认值是None

计算y,torch.dot() 点积的计算规则是将两个向量对应位置的元素相乘,然后将 结果相加 得到一个标量值。

print(x)    
y = 2 * torch.dot(x, x)  # 点积 # (1*1+2*2+3*3)*2=28
y
# tensor([0., 1., 2., 3.], requires_grad=True)
# tensor(28., grad_fn=<MulBackward0>)

x是一个长度为4的向量,计算x和x的点积,得到了我们赋值给y的标量输出。接下来,通过调用反向传播函数 来自动计算y关于x每个分量的梯度,并打印这些梯度。

y.backward()
x.grad
# tensor([ 0.,  4.,  8., 12.])

函数 y = 2x^Tx 关于x的梯度应为 y=4x

x.grad == 4 * x
# tensor([True, True, True, True])

 1.3 继续计算另一个函数的自动微分

先梯度清零

# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
print(x.grad)
# tensor([0., 0., 0., 0.])

将所有x求和求导, 函数:y=x,导数: {f(x)}'=1

y = x.sum()   # y=0+1+2+3
print(x,y)
y.backward()
x.grad
# tensor([0., 1., 2., 3.], requires_grad=True) tensor(6., grad_fn=<SumBackward0>)
# tensor([1., 1., 1., 1.])

1.4 非标量变量的反向传播

当y不是标量时,向量y关于向量x的导数的最自然解释是一个矩阵。对于高阶和高维的y和x,求导的结果可以 是一个高阶张量

先梯度清零:

x.grad.zero_()
print(x.grad)  # tensor([0., 0., 0., 0.])

函数: y = x^2,  导函数:y = 2x

y = x * x
print(x, y)
# 等价于y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad
# tensor([0., 1., 2., 3.], requires_grad=True) 
# tensor([0., 1., 4., 9.], grad_fn=<MulBackward0>)
# tensor([0., 2., 4., 6.])

1.5 分离计算

梯度清零,先合并计算查看梯度::

# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
print(x.grad)
# tensor([0., 0., 0., 0.])y = x * x * x
print(x, y)
# 等价于y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad  # tensor([ 0.,  3., 12., 27.])
# tensor([0., 1., 2., 3.], requires_grad=True)
# tensor([ 0.,  1.,  8., 27.], grad_fn=<MulBackward0>)
# tensor([ 0.,  3., 12., 27.])

有时,我们希望 将某些计算移动到记录的计算图之外。例如,假设y是作为x的函数计算的,而z则是作为y和x的 函数计算的。想象一下,我们想计算z关于x的梯度,但由于某种原因,希望将y视为一个常数,并且 只考虑 到x在y被计算后发挥的作用

分离计算,先梯度清零

# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
print(x.grad)
# tensor([0., 0., 0., 0.])
print('x:', x)
y = x * x   # 导函数: y=2x, 梯度:[0, 2, 4, 6]
print('y:', y)
u = y.detach()
print('u:', u)z = u * x   # y = x^3  导函数:y = 3x^2  梯度:[0, 3, 12, 27]
print('z:', z)
z.sum().backward()
print('x.grad:', x.grad)
print('x.grad == u:', x.grad == u)
x.grad # x: tensor([0., 1., 2., 3.], requires_grad=True)
# y: tensor([0., 1., 4., 9.], grad_fn=<MulBackward0>)
# u: tensor([0., 1., 4., 9.])
# z: tensor([ 0.,  1.,  8., 27.], grad_fn=<MulBackward0>)
# x.grad: tensor([0., 1., 4., 9.])
# x.grad == u: tensor([True, True, True, True])
# tensor([0., 1., 4., 9.])

 分开计算后,x的梯度并不是按 函数 y = x^3 来计算的,而是使用的中间计算的变量 x^2,即是梯度不会向后流经u到x。

由于记录了y的计算结果,我们可以随后在y上调用反向传播,得到 y = x^2 关于的x的导数,即2x。

x.grad.zero_()
y.sum().backward()
print('x.grad == 2 * x:', x.grad == 2 * x)
x.grad
# x.grad == 2 * x: tensor([True, True, True, True])
# tensor([0., 2., 4., 6.])

分离计算后将 函数:y = x^3 拆分为了两个函数:y = kx 和 y = x^2

1.6 Python控制流的梯度计算

使用自动微分的一个好处是:即使构建函数的计算图需要通过Python控制流,我们仍然可以计算得到的变量的梯度

def f(a):b = a * 2while b.norm() < 1000:# print('b:', b)b = b * 2if b.sum() > 0:c = belse:c = 100 * breturn c

 给个初始值a,经过程序n次计算后得到结果值 d, 然后使用结果值和a计算梯度:

# a = torch.randn(size=(), requires_grad=True)
a = torch.tensor([10.], requires_grad=True)
d = f(a)
print(f'a:{a}, d:{d}')
d.backward()
a.grad# a:tensor([10.], requires_grad=True), d:tensor([1280.], grad_fn=<MulBackward0>)
# tensor([128.])

 1280 / 10 = 128   # 此时的梯度128。

a.grad == d / a
# tensor([True])

二 概率

掷骰子,想知道看到1的几率有多大,一共六个面,随机抽样:

%matplotlib inline
import torch
from torch.distributions import multinomial
from d2l import torch as d2l
fair_probs = torch.ones([6]) / 6
multinomial.Multinomial(1, fair_probs).sample()
# tensor([0., 0., 0., 0., 1., 0.])

使用深度学习框架的函数同时抽取多个样本,得到我们想要的任意形状的独立样本数组

multinomial.Multinomial(10, fair_probs).sample()
# tensor([1., 0., 1., 1., 6., 1.])
# 将结果存储为32位浮点数以进行除法
counts = multinomial.Multinomial(1000, fair_probs).sample()
counts / 1000 # 相对频率作为估计值# tensor([0.1730, 0.1590, 0.1780, 0.1640, 0.1730, 0.1530])

因为我们是从一个公平的骰子中生成的数据,我们知道每个结果都有真实的概率1 6,大约是0.167,所以上面 输出的估计值看起来不错。

我们也可以看到这些概率如何随着时间的推移收敛到真实概率。让我们进行 500组实验,每组抽取10个样本。

counts = multinomial.Multinomial(10, fair_probs).sample((500,))
cum_counts = counts.cumsum(dim=0)estimates = cum_counts / cum_counts.sum(dim=1, keepdims=True)
d2l.set_figsize((6, 4.5))
for i in range(6):d2l.plt.plot(estimates[:, i].numpy(), label=("P(die=" + str(i + 1) + ")"))
d2l.plt.axhline(y=0.167, color='black', linestyle='dashed')
d2l.plt.gca().set_xlabel('Groups of experiments')
d2l.plt.gca().set_ylabel('Estimated probability')
d2l.plt.legend()

每条实线对应于骰子的6个值中的一个,并给出骰子在每组实验后出现值的估计概率。当我们 通过更多的实 验获得更多的数据时,这6条实体曲线向真实概率收敛

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

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

相关文章

请简述Redis集群的工作原理。Redis集群如何保证数据的一致性?Redis集群中,当某个节点出现故障时,如何处理?

请简述Redis集群的工作原理。 Redis集群的工作原理主要依赖于数据分片和主从复制机制&#xff0c;以实现横向扩展和高可用性。以下是Redis集群工作原理的简要概述&#xff1a; 数据分片&#xff1a; Redis集群将数据划分为16384个哈希槽&#xff08;hash slot&#xff09;。 …

接口测试之文件下载

在工作中对于下载接口&#xff0c;经常会有这样的疑问&#xff1a;这类接口一般功能比较稳定&#xff0c;但是又比较重要&#xff0c;需要占用回归测试时间&#xff0c;有没有可替代的方式&#xff1f; 答案肯定是有的&#xff0c;可以从接口测试/UI自动化测试介入&#xff0c…

Postman-Installation has failed

如图&#xff1a; 解决方法&#xff1a; 打开文件夹 Postman-win64-Setup 点击Postman.exe 即可

测试开发 - 面经 - 得物青训营

面前准备&#xff1a; 自我介绍 省略具体技术栈&#xff0c;侧重数据筛选部分以及数据可视化 实习经历简单表述 反问环节 对于测试开发的岗位认知还有些模糊&#xff0c;想问下这个岗位工作中的具体内容&#xff0c;以及常用的技术或者工具 想请教下对于测试开发岗未来的…

c语言的字符串函数详解

文章目录 前言一、strlen求字符串长度的函数二、字符串拷贝函数strcpy三、链接或追加字符串函数strcat四、字符串比较函数strcmp五、长度受限制字符函数六、找字符串2在字符串1中第一次出现的位置函数strstr七、字符串切割函数strtok&#xff08;可以切割分隔符&#xff09;八、…

【C语言】分支语句(逻辑运算符与关系运算符)

文章目录 **逻辑运算符(&&、||、!)**逻辑运算符特点短路短路-逻辑与短路-逻辑或 **关系运算符&#xff08;relational expression&#xff09;**运算操作符的结合律、运算符 **选择结构/分支结构****if 语句****复合句的if语句(if...else..语句)****不良风格的程序** *…

uniapp 之 实现商品详情的锚点跳转(类似京东商品详情-点击顶部按钮跳转的对应的页面的内容区域)

类似京东商品详情-点击顶部详情跳转到页面对应的详情区域&#xff0c;点击评价跳转到页面对应的评价区域等。 照例&#xff0c;先封装方法&#xff1a; 封装方法 util.js /*** 锚点跳转&#xff08;如&#xff1a;商品详情页面跳转&#xff09;* param {string} targetId 目…

sqllab第十八关通关笔记

知识点&#xff1a; UA注入 不进行url解析&#xff0c;不能使用 %20 编码等操作出现在User-agent字段中一般为insert语句 insert 表名(字段1&#xff0c;字段2&#xff0c;。。。) values(数据1&#xff0c;数据2&#xff0c;。。。) 通过admin admin进行登录发现页面打印出了…

【中等】保研/考研408机试-二叉树相关

目录 一、基本二叉树 1.1结构 1.2前序遍历&#xff08;注意三种遍历中Visit所在的位置&#xff09; 1.2中序遍历 1.3后序遍历 二、真题实战 2.1KY11 二叉树遍历&#xff08;清华大学复试上机题&#xff09;【较难】 2.2KY212 二叉树遍历二叉树遍历&#xff08;华中科技大…

通信信号处理中的调制识别技术及其基于C++ Qt的实现

在现代通信系统中,调制技术扮演着至关重要的角色。调制是将基带信号转换为适合在信道中传输的高频信号的过程。常见的模拟调制方式有幅度调制(AM)和频率调制(FM),数字调制方式有频移键控(FSK)和相移键控(PSK)。为了实现高效、可靠的通信,接收端必须能够准确识别发送端所采用的调…

详解命令docker run -d --name container_name -e TZ=Asia/Shanghai your_image

docker run 是Docker的主要命令&#xff0c;用于从镜像启动一个新的容器。下面详细解释并举例说明 -d, --name, -e TZ 参数的用法&#xff1a; -d 或 --detach&#xff1a; 这个标志告诉Docker以守护进程&#xff08;后台&#xff09;模式运行容器。这意味着当你执行 docker ru…

前端学习笔记|JavaScript基础

JS基础 数据类型 基于动力节点视频。 Number、String、Boolean、object 强制转换 Number 强转,boolean强转(undefined、null、NaN都是转成false)&#xff0c;String强转 myAge Number("123445"); Boolean(0); String(123);parseInt、parseFloat 遇到非数字&…

Java——网络编程

网络编程基础类 InetAddress类 java.net.InetAddress类用来封装计算机的IP地址和DNS(没有端口信息),它包括一个主机名和一个ip地址,是java对IP地址的高层表示。大多数其他网络类都要用到这个类&#xff0c;包括Sorket、ServerSocker、URL、DatagramSorket、DatagramPacket等常…

15.7k stars一个实用型OCR,支持80多种语言

一个实用型 OCR,支持 80 多种语言和所有流行的书写脚本&#xff0c;包括&#xff1a;拉丁文、中文、阿拉伯文、梵文、西里尔文等。 特点 支持本地或云/API部署 准确度提高到 99% 以上 完全可定制,支持 80 多种语言 支持表格识别 二维码/条码提取识别 GitHub数据 15.7k s…

LAMP下Moodle平台安装

目录 一、虚拟机安装 二、Linux使用ubuntu 三、设置管理员root的密码: 四、注销登录 五、用root账号重新登录 六、安装vmware tools 七、更新系统 八、允许SSH客户端登录 九、实体机中安装远程管理客户端 十、实体机安装文件传输工具 十一、使用Putty登录,安装插件…

学习总结2

第二周总结 一、总结贪吃蛇制作思路 1.绘制API&#xff0c;所以需要引入graphics.h这个图形界面库。 2.游戏规则 蛇是一节一节的&#xff0c;每吃掉一个事物都会长一节蛇吃食物需要移动&#xff0c;如果需要移动那么就会有坐标的变化。蛇没吃掉一个事物都会随机产生一个食物…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Column)

沿垂直方向布局的容器。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 接口 Column(value?: {space?: string | number}) 从API version 9开始&#xff0c;该接口…

MySQL 中的自增ID及其应用场景

在MySQL中&#xff0c;自增ID主要体现在几种不同的场景下&#xff0c;每种自增ID都有其特定用途和行为特征&#xff1a; 1. Auto-Increment ID (PRIMARY KEY AUTO_INCREMENT) 场景&#xff1a;在创建表时&#xff0c;可以为某个整数字段设置AUTO_INCREMENT属性&#xff0c;生成…

LeetCode--58

58. 最后一个单词的长度 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大 子字符串 。 示例 1&#xff1a; 输入&#xff1a;s "Hello W…

unity学习(57)——选择角色界面--删除角色2

1.客户端添加点击按钮所触发的事件&#xff0c;在selectMenu界面中增加myDelete函数&#xff0c;当点击“删除角色”按钮时触发该函数的内容。 public void myDelete() {string message nowPlayer.id;//string m Coding<StringDTO>.encode(message);NetWorkScript.get…