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)) / h

ratio = 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 * 2
    while b.norm() < 1000:
        # print('b:', b)
        b = b * 2
    if b.sum() > 0:
        c = b
    else:
        c = 100 * b
    return 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条实体曲线向真实概率收敛

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

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

相关文章

HarmonyOS NEXT应用开发—折叠屏音乐播放器方案

介绍 本示例介绍使用ArkUI中的容器组件FolderStack在折叠屏设备中实现音乐播放器场景。 效果图预览 使用说明 播放器预加载了歌曲&#xff0c;支持播放、暂停、重新播放&#xff0c;在折叠屏上&#xff0c;支持横屏悬停态下的组件自适应动态变更。 实现思路 采用MVVM模式进…

【Algorithms 4】算法(第4版)学习笔记 18 - 4.4 最短路径

文章目录 前言参考目录学习笔记0&#xff1a;引入介绍1&#xff1a;APIs1.1&#xff1a;API&#xff1a;加权有向边1.2&#xff1a;Java 实现&#xff1a;加权有向边1.3&#xff1a;API&#xff1a;加权有向图1.4&#xff1a;Java 实现&#xff1a;加权有向图1.5&#xff1a;AP…

Unity类银河恶魔城学习记录10-12 p100 Improve aliments - chill源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili CharacterStats.cs using System.Collections; using System.Collections…

docker容器镜像管理

目录 一、 Docker的基本组成 二、 容器和镜像的关系 2.1 面向对象角度 2.2 从镜像容器角度 三、镜像命令 3.1 查看当前已有镜像 3.2 查看已有的全部镜像 3.3 查看镜像ID 3.4 镜像删除 四、 容器命令 4.1 下载镜像 4.2 新建和启动容器 run 4.3 交互式 4.…

探讨大世界游戏的制作流程及技术——大场景制作技术概况篇

接上文&#xff0c;我们接下来了解一下大世界场景制作技术有哪些&#xff0c;本篇旨在给大家过一遍目前业界的做法&#xff0c;能让大家有一个宏观的知识蓝图。实际上&#xff0c;针对不同的游戏类型和美术风格&#xff0c;制作技术在细节上有着非常大的不同&#xff0c;业界目…

【UE5】持枪状态站立移动的动画混合空间

项目资源文末百度网盘自取 创建角色在持枪状态站立移动的动画混合空间 在BlendSpace文件夹中单击右键选择动画(Animation)中的混合空间(Blend Space) 选择SK_Female_Skeleton 命名为BS_RifleStand 打开 水平轴表示角色的方向&#xff0c;命名为Direction&#xff0c;方…

SD-WAN技术助力跨境电商网络搭建的解决方案

随着全球贸易的蓬勃发展&#xff0c;跨境电商成为了商业领域中的一个重要组成部分。然而&#xff0c;跨境电商面临着网络搭建和管理的复杂性&#xff0c;而SD-WAN技术的引入为解决这些问题提供了一种创新的方法。本文将深入探讨SD-WAN如何有效解决跨境电商行业的网络搭建问题。…

UE5.1 iClone8 正确导入角色骨骼与动作

使用iClone8插件Auto Setup 附录下载链接 里面有两个文件夹,使用Auto Setup C:\Program Files\Reallusion\Shared Plugins 在UE内新建Plugins,把插件复制进去 在工具栏出现这三个人物的图标就安装成功了 iClone选择角色,导入动作 选择导出FBX UE内直接导入 会出现是否启动插件…

同城预约上门服务APP小程序开发 打造快捷便利生活

随着移动互联网的快速发展&#xff0c;人们的生活方式正在发生深刻的变化。特别是在城市生活中&#xff0c;人们越来越依赖移动应用来解决日常生活中的各种问题。其中&#xff0c;同城预约上门服务APP正成为一种新型的生活服务平台&#xff0c;为人们提供了更加便利和快捷的服务…

RTC的Google拥塞控制算法 rmcat-gcc-02

摘要 本文档描述了使用时的两种拥塞控制方法万维网&#xff08;RTCWEB&#xff09;上的实时通信&#xff1b;一种算法是基于延迟策略&#xff0c;一种算法是基于丢包策略。 1.简介 拥塞控制是所有共享网络的应用程序的要求互联网资源 [RFC2914]。 实时媒体的拥塞控制对于许…

2023年总结:一个普通程序员如何挑选出价值千万的职业赛道

​​​​​​​ 引言 随着2023年的序幕缓缓落下&#xff0c;我终于在岁月的流转中捕捉到了一条隐秘而又公开的真理。它悄然告诉我们&#xff0c;成功并非单纯由勤劳的双手雕琢&#xff0c;一份耕耘未必有一份收获&#xff0c;而是在于我们如何在命运的十字路口作出关键选择。那…

Linux/secret

Enumeration nmap 第一次扫描发现系统对外开放了22&#xff0c;80和3000端口&#xff0c;端口详细信息如下 可以看到22端口对应的是ssh服务&#xff0c;80和3000都是http服务&#xff0c;80端口使用nginx&#xff0c;3000使用了Node.js TCP/80 可以先从80端口开始探索&…

滑动窗口和螺旋矩阵

209. 长度最小的子数组 题目 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度**。**如果不存在符合条件的子数组&#xff0c;返回…

R统计学3 - 数据分析入门问题41-60

往期R统计学文章: R统计学1 - 基础操作入门问题1-20 R统计学2 - 数据分析入门问题21-40 41. R 语言如何做双坐标图? # 创建模拟数据 year <- 2014:2024 gdp <- data.frame(year, GDP = sort(rnorm(11, 1000, 100))) ur <- data.frame(year, UR = rnorm(11, 5, 1…

微信小程序原生<map>地图实现标记多个位置以及map 组件 callout 自定义气泡

老规矩先上效果图: 1 、在pages文件夹下新建image文件夹用来存放标记的图片。 2、代码片段 也可以参考小程序文档:https://developers.weixin.qq.com/miniprogram/dev/component/map.html index.wxml代码 <mapid="map"style="width: 100%; height:100%;&…

外包就干了2个月,技术退步明显....

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

分布式机器学习

考虑到当今大数据时代生成的数据量&#xff0c;分布式机器学习是一项重要技术。 由此引出的问题是&#xff0c;我们应该选择哪个平台来帮助构建分布式机器学习环境&#xff1f; Apache Spark 是近年来非常流行的此类平台之一。 spark Apache Spark 是一个开源集群计算框架&am…

MySQL语法分类 DDL(2)

DDL&#xff08;2&#xff09; C(Create):创建 //复制表 create table 表名 like 被复制的表名;//数据类型 1. int : 整数类型 2. double : 小数类型 //double(5,2) 最多五位且保留两位小数 3. date : 日期类型 //只包含年月日 yyyy-MM-dd 4. datetime : 日期 //包含年月日时…

php彩虹/异世界云商全解系统

系统更新与修复列表 1. 基于彩虹的二次开发 - 对彩虹系统进行了二次开发&#xff0c;增强了系统的功能和性能。2. 新增自定义输入框提示内容&#xff08;支持批量修改&#xff09; - 用户可以自定义输入框的提示内容&#xff0c;并支持批量修改&#xff0c;提升用户体验。3. 新…

DFS的一些题目

题目1&#xff1a;奶牛选美 这道题其实就是把两个连通块合成一个&#xff0c;可以用dfs、bfs和并查集。因为最近在dfs专题训练&#xff0c;这里我只写了dfs。 首先我们用dfs的方式遍历两个连通块&#xff0c;将两个连通块中点的坐标分别存入两个数组中&#xff0c;将这两个数组…