深度学习:张量 介绍

news2024/12/21 20:31:40

张量[1]是向量和矩阵到 n 维的推广。了解它们如何相互作用是机器学习的基础。

简介

虽然张量看起来是复杂的对象,但它们可以理解为向量和矩阵的集合。理解向量和矩阵对于理解张量至关重要。

向量是元素的一维列表:

alt

矩阵是向量的二维列表:

alt

下标表示(行,列)。考虑矩阵的另一种方式是用向量作为元素的向量。请注意,它们通常用大写字母表示。

3D 张量可以被视为三维矩阵列表:

alt

考虑 3D 张量的另一种方式是使用矩阵作为元素的向量。请注意,在本文中它们是用书法大写字母标注的。

4D 张量可以被认为是 3D 张量的四维列表:

alt

考虑 4D 张量的另一种方式是使用 3D 张量作为其元素的向量。这些可能会变得越来越复杂,但这是继续使用张量进行运算所必需的程度。

向量运算

alt

假设这些是相同长度的向量,i。接下来的操作主要是按元素进行的。这意味着每个向量中的相应元素被一起操作。

加法

alt
import torch

x = torch.tensor([135])
y = torch.tensor([374])

x + y

# tensor([ 4, 10,  9])

减法

alt
x = torch.tensor([135])
y = torch.tensor([374])

x - y

# tensor([-2, -4,  1])

点乘

alt

这也可以用求和来表示:

alt
x = torch.tensor([135])
y = torch.tensor([374])

torch.dot(x, y) # 1*3 + 3*7 + 5*4 = 3 + 21 + 20 = 44

# tensor(44)

这也可以用 x @ y 来执行。点积的输出是一个标量。它不返回向量。

Hadamard(乘法)

alt

Hadamard 乘积用于执行逐元素乘法并返回一个向量。

x = torch.tensor([135])
y = torch.tensor([374])

x * y

# tensor([ 3, 21, 20])

标量乘法

alt

k 是标量,在大多数情况下是实数。

k = 5
x = torch.tensor([135])

k * x

# tensor([ 5, 15, 25])

由于 k 可以是分数,因此这也可以被视为标量除法。

矩阵乘法

请记住,矩阵是向量的集合。相同的操作适用于向量,但在涉及行和列时还有一些规则需要注意。

假设如下,其中 X 和 Y 的形状为 (4,3):

alt

加法

alt
X = torch.tensor([[135],
                  [361],
                  [685],
                  [732]])

Y = torch.tensor([[632],
                  [854],
                  [317],
                  [183]])

X + Y

# tensor([[ 7,  6,  7],
        [1111,  5],
        [ 9,  912],
        [ 811,  5]])

减法

alt
X = torch.tensor([[135],
                  [361],
                  [685],
                  [732]])

Y = torch.tensor([[632],
                  [854],
                  [317],
                  [183]])

X - Y

# tensor([[-5,  0,  3],
        [-5,  1-3],
        [ 3,  7-2],
        [ 6-5-1]])

点积

alt

在执行矩阵乘法时,重要的是要将矩阵视为由向量组成。通过这个视图,就可以清楚如何在矩阵上执行点积。发生乘法的唯一方法是第一个矩阵中的行数与第二个矩阵中的列数匹配。这导致:

  • (m, n) x (n, r) = (m, r)

如果情况并非如此,则必须转置其中一个矩阵以适应该顺序;这会切换行和列,但保留点积的向量。

在上图中,很明显,左侧矩阵中的每个向量(或行)都乘以第二个矩阵中的每个向量(或列)。因此,在此示例中,A 中的每个向量必须与 B 中的每个向量相乘,从而产生 16 个点积。

X = torch.tensor([[135],
                  [361],
                  [685],
                  [732]])

Y = torch.tensor([[632],
                  [854],
                  [317],
                  [183]])

X.matmul(Y.T) # X @ Y.T

# tensor([[ 25,  43,  41,  40],
        [ 38,  58,  22,  54],
        [ 70108,  61,  85],
        [ 55,  79,  38,  37]])

Hadamard 积

alt

Hadamard 乘积是逐元素乘法,因此其执行方式与加法和减法相同。

X = torch.tensor([[135],
                  [361],
                  [685],
                  [732]])

Y = torch.tensor([[632],
                  [854],
                  [317],
                  [183]])

X * Y

# tensor([[ 6,  9, 10],
        [2430,  4],
        [18,  835],
        [ 724,  6]])

标量乘法

alt
k = 5
X = torch.tensor([[135],
                  [361],
                  [685],
                  [732]])

k * X

# tensor([[ 5, 15, 25],
        [1530,  5],
        [304025],
        [351510]])

三维张量运算

张量运算要求两个张量具有相同的大小,除非正在执行点积。

对于本节中的逐元素运算,假设两个张量的形状为 (3, 3, 2)。这意味着两个张量都包含三个 (3,2) 矩阵。如下所示:

import torch

gen = torch.Generator().manual_seed(2147483647)

X = torch.randint(010, (332), generator=gen)
Y = torch.randint(010, (332), generator=gen)

X = tensor([[[14],
             [92],
             [30]],

            [[46],
             [77],
             [15]],

            [[68],
             [14],
             [49]]])

Y = tensor([[[80],
             [36],
             [60]],

            [[91],
             [00],
             [22]],

            [[71],
             [81],
             [90]]])

加法

加法是按元素进行的,并且按预期执行。每个张量中对应的元素相互相加。

X + Y

tensor([[[ 9,  4],
         [12,  8],
         [ 9,  0]],

        [[13,  7],
         [ 7,  7],
         [ 3,  7]],

        [[13,  9],
         [ 9,  5],
         [13,  9]]])

减法

减法也是按元素进行的并且按预期执行。

X - Y

tensor([[[-7,  4],
         [ 6-4],
         [-3,  0]],

        [[-5,  5],
         [ 7,  7],
         [-1,  3]],

        [[-1,  7],
         [-7,  3],
         [-5,  9]]])

点积

alt

张量乘法比二维中的张量乘法稍微复杂一些。之前,矩阵乘法只有满足以下条件才能发生:

  • (m, n) x (n, r) = (m, r)

在三个维度上,这仍然是一个要求。但是,第一个轴必须相同:

  • (z, m, n) x (z, n, r) = (z, m, r)

为什么是这样?嗯,如前所述,二维的点积主要是将向量彼此相乘。在三维中,重点是按矩阵相乘,然后对这些矩阵中的每个向量执行点积。

上图应该有助于解释这一点。将两个 3D 张量视为矩阵向量可能会有所帮助。由于点积是通过按元素相乘然后求和来执行的,因此首先发生的事情是每个矩阵与其相应的矩阵相乘。当这种情况发生时,矩阵乘法会导致矩阵中的每个向量与其他向量执行点积。从某种意义上说,它就像一个嵌套的点积。

为了使 和 彼此相乘,必须调换 的第二轴和第三轴。并且两者的大小均为 (3, 3, 2)。这意味着必须变成(3,2,3)。这可以使用 Y.permute(0, 2, 1) 来完成,它转置第二和第三轴。或者,可以使用 Y.transpose(1,2)。

print(Y.transpose(1,2))
print(Y.transpose(1,2).shape) # Y.permute(0, 2, 1)

tensor([[[836],
         [060]],

        [[902],
         [102]],

        [[789],
         [110]]])

torch.Size([323])

通过适当的调整大小,现在可以使用 matmul 或 @ 执行张量乘法。输出的形状应为 (3, 3, 2) x (3, 2, 3) = (3, 3, 3)。

X.matmul(Y.transpose(1,2)) # X @ Y.transpose(1,2)

tensor([[[ 827,  6],
         [723954],
         [24,  918]],

        [[42,  020],
         [70,  028],
         [14,  012]],

        [[505654],
         [1112,  9],
         [374136]]])

Hadamard 积

Hadamard 积的性能符合预期,并在 3D 张量的矩阵中按元素相乘。

X * Y

tensor([[[ 8,  0],
         [2712],
         [18,  0]],

        [[36,  6],
         [ 0,  0],
         [ 210]],

        [[42,  8],
         [ 8,  4],
         [36,  0]]])

标量乘法

标量乘法也按预期执行。

k = 5
k*X

tensor([[[ 520],
         [4510],
         [15,  0]],

        [[2030],
         [3535],
         [ 525]],

        [[3040],
         [ 520],
         [2045]]])

四维张量运算

四维张量运算仍然要求两个张量具有相同的大小。

对于本部分,假设形状为 (2, 3, 3, 2)。这意味着两个 4D 张量都包含两个 3D 张量,并且每个张量都包含三个 (3,2) 矩阵。如下所示:

import torch

gen = torch.Generator().manual_seed(2147483647)

X = torch.randint(010, (2332), generator=gen)
Y = torch.randint(010, (2332), generator=gen)

X
# 4d tensor
tensor([
# 3d tensor
        [
         # matrix 1
         [[14],
          [92],
          [30]],
         # matrix 2
         [[46],
          [77],
          [15]],
         # matrix 3
         [[68],
          [14],
          [49]]],

# 3d tensor
        [
         # matrix 1
         [[80],
          [36],
          [60]],
         # matrix 2
         [[91],
          [00],
          [22]],
         # matrix 3
         [[71],
          [81],
          [90]]]])

Y
# 4d tensor
tensor([
# 3d tensor
        [
         # matrix 1 
         [[63],
          [64],
          [57]],
         # matrix 2
         [[37],
          [20],
          [51]],
         # matrix 3
         [[04],
          [08],
          [06]]],

# 3d tensor
        [
         # matrix 1
         [[05],
          [86],
          [10]],
         # matrix 2
         [[51],
          [16],
          [12]],
         # matrix 3
         [[60],
          [26],
          [15]]]])

加法

加法、减法和哈达玛积仍然按预期按元素执行。

X + Y

tensor([[[[ 7,  7],
          [15,  6],
          [ 8,  7]],

         [[ 713],
          [ 9,  7],
          [ 6,  6]],

         [[ 612],
          [ 112],
          [ 415]]],


        [[[ 8,  5],
          [1112],
          [ 7,  0]],

         [[14,  2],
          [ 1,  6],
          [ 3,  4]],

         [[13,  1],
          [10,  7],
          [10,  5]]]])

减法

X - Y

tensor([[[[-5,  1],
          [ 3-2],
          [-2-7]],

         [[ 1-1],
          [ 5,  7],
          [-4,  4]],

         [[ 6,  4],
          [ 1-4],
          [ 4,  3]]],


        [[[ 8-5],
          [-5,  0],
          [ 5,  0]],

         [[ 4,  0],
          [-1-6],
          [ 1,  0]],

         [[ 1,  1],
          [ 6-5],
          [ 8-5]]]])

点积

alt

在四维中,张量乘法将具有与三维和二维中相同的要求。它还需要第一轴和第二轴与两个张量匹配:

  • (c、z、m、n) x (c、z、n、r) = (c、z、m、r)

在三维空间中,进行矩阵乘法,然后进行向量之间的点积。相同的步骤将在四个维度中发生,但首先将每个 3D 张量与其相应的 3D 张量相乘。然后,它们的每个矩阵将相互相乘。最后,它们的向量将相互执行点积。这可以在上图中看到。

对于本例, 和 的大小为 (2, 3, 3, 2)。为了进行乘法运算,必须调换 的第三轴和第四轴。这可以按照与之前使用 Y.permute(0, 1, 3, 2) 或 Y.transpose(2,3) 相同的方式完成。转置后的形状为 (2, 3, 2, 3)。

结果的形状应为 (2, 3, 3, 2) x (2, 3, 2, 3) = (2,3,3,3)。这意味着将有两个 3D 张量,每个张量将包含三个 (3,3) 矩阵。这个结果可以使用 matmul 或 @ 获得。

X.matmul(Y.transpose(2,3)) # X @ Y.transpose(2,3)

tensor([[[[182233],
          [606259],
          [181815]],

         [[54,  826],
          [701442],
          [38,  210]],

         [[326448],
          [163224],
          [367254]]],


        [[[ 064,  8],
          [3060,  3],
          [ 048,  6]],

         [[461511],
          [ 0,  0,  0],
          [1214,  6]],

         [[422012],
          [482213],
          [5418,  9]]]])

Hadamard 积

X * Y

tensor([[[[ 612],
          [54,  8],
          [15,  0]],

         [[1242],
          [14,  0],
          [ 5,  5]],

         [[ 032],
          [ 032],
          [ 054]]],


        [[[ 0,  0],
          [2436],
          [ 6,  0]],

         [[45,  1],
          [ 0,  0],
          [ 2,  4]],

         [[42,  0],
          [16,  6],
          [ 9,  0]]]])

标量乘法

k = 5
k * X

tensor([[[[ 520],
          [4510],
          [15,  0]],

         [[2030],
          [3535],
          [ 525]],

         [[3040],
          [ 520],
          [2045]]],


        [[[40,  0],
          [1530],
          [30,  0]],

         [[45,  5],
          [ 0,  0],
          [1010]],

         [[35,  5],
          [40,  5],
          [45,  0]]]])

Reference

[1]

Source: https://medium.com/@hunter-j-phillips/a-simple-introduction-to-tensors-c4a8321efffc

本文由 mdnice 多平台发布

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

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

相关文章

JAVA面试题简单整理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、重载和重写的区别一、&和&&的区别一、get和post请求的区别 delete、put一、cookie和session的区别一、Autowired和Resource区别一、”和equals…

wait 和 notify 这个为什么要在 synchronized 代码块中?

wait 和 notify wait 和 notify 用来实现多线程之间的协调,wait 表示让线程进入到阻塞状态,notify 表示让阻塞的线程唤醒。 wait 和 notify 必然是成对出现的,如果一个线程被 wait()方法阻塞,那么必然需要另外一个线程通过 noti…

C语言_文件_进程_进程间通讯 常用函数/命令 + 实例

文件相关命令: ps -aux|grep init? //搜索包含init名称的进程 top //linux下的资源管理器(动态)//open 返回的int 是给后面的读/写/光标移动 用的fd,没有open就不能进行后面的操作; int op…

大数据Flink(一百零三):SQL 表值聚合函数(Table Aggregate Function)

文章目录 SQL 表值聚合函数(Table Aggregate Function) SQL 表值聚合函数(Table Aggregate Function) Python UDTAF,即 Python TableAggregateFunction。Python UDTAF 用来针对一组数据进行聚合运算,比如同一个 window 下的多条数据、或者同一个 key 下的多条数据等,与…

【micro ros】快速上手:在 RT-Thread上运行 micro ros

文章目录 快速上手micro ros && RT-Thread(serial和udp方式)1.背景介绍2.工程准备工作2.1 克隆 RT-Thread主仓2.2 克隆 env-windows 3.编译准备工作3.1 python & cmake安装3.2 scons工具安装3.3 GNU make安装3.4 Fastgithub安装 4.工程配置4…

[SQL开发笔记]LIKE操作符:在 WHERE 子句中搜索列中的指定模式

一、功能描述: LIKE操作符:用于在 WHERE 子句中搜索列中的指定模式。 二、LIKE操作符语法详解: LIKE 语法 SELECT column1, column2,…FROM table_nameWHERE column LIKE pattern; 参数说明: (1)colum…

全球生物气候产品2.5m和30s分辨率

简介 生物气候是指生物和气候相互作用的结果,包括植物和动物对气候的影响,以及气候对生物的影响。生物气候研究的是生物、气候、土地和水等自然要素之间相互作用的过程,旨在探讨它们是如何互动并导致生态系统的变化的。生物气候对于理解全球…

C#,数值计算——分类与推理,基座向量机(SVM,Support Vector Machines)的计算方法与源程序

把 Support Vector Machines 翻译成 支持向量机 是书呆子翻译。基座向量机 不好吗。 1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Support Vector Machines /// </summary> public class Svm { priv…

上海亚商投顾:沪指震荡反弹 华为汽车、卫星通信板块再度爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一、市场情绪 三大指数早盘低开低走&#xff0c;深成指、创业板指一度跌超1%&#xff0c;午后集体拉升翻红。 华为汽车概念…

KMS在腾讯云的微服务实践助力其降本50%

背景介绍 KMS 是一家日本的游戏公司&#xff0c;主要经营游戏业务、数字漫画业务、广告业务、云解决方案业务等&#xff0c;出品了多款在日本畅销的漫画风游戏&#xff0c;同时有网络漫画专业厂牌&#xff0c;以内容创作为目标&#xff0c;拥有原创 IP 创作、游戏开发等多元化发…

WSL2Linux 子系统(六)

WSL 连接USB WSL (Windows Subsystem for Linux) 是一种在 Windows 操作系统上运行 Linux 应用程序的兼容层。它的主要作用是提供了一个类似于虚拟机的环境&#xff0c;使得在 Windows 上开发和运行基于 Linux 的应用变得更加方便。然而&#xff0c;WSL 目前还不支持直接通过 …

spring6-提前编译:AOT

提前编译&#xff1a;AOT 1、AOT概述1.1、JIT与AOT的区别1.2、Graalvm1.3、Native Image 2、演示Native Image构建过程2.1、GraalVM安装&#xff08;1&#xff09;下载GraalVM&#xff08;2&#xff09;配置环境变量&#xff08;3&#xff09;安装native-image插件 2.2、安装C的…

【Unity程序技巧】事件管理器

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

TIA博途_Profinet通信故障诊断及常见错误解决方法汇总

TIA博途_Profinet通信故障诊断及常见错误解决方法汇总 1. 在线诊断报硬件组件的用户数据错误,设备组态不支持 解决方法: (1)检查模块终端盖板; (2)检查组态模块与实际组装模块顺序型号是否一致。 2. 网络视图,设备视图界面显示黑色感叹号 解决方法: PLC转离线,下载硬…

疫情物资管理系统-基于SSM实现

包括-源码参考文档 下载地址: https://juzhendongli.store/commodity/details/5

Spark UI中Shuffle dataSize 和shuffle bytes written 指标区别

背景 本文基于Spark 3.1.1 目前在做一些知识回顾的时候&#xff0c;发现了一些很有意思的事情&#xff0c;就是Spark UI中ShuffleExchangeExec 的dataSize和shuffle bytes written指标是不一样的&#xff0c; 那么在AQE阶段的时候&#xff0c;是以哪个指标来作为每个Task分区大…

【计网 CDN】计算机网络 CDN(Content Delivery Network)分布式网络架构详解:中科大郑烇老师笔记 (八)

目录 0 引言1 为什么需要分布式的网络架构&#xff1f;2 视频流化服务2.1 多媒体&#xff1a;视频2.2 存储视频的流化&#xff08;Streaming&#xff09;服务2.3 流媒体传输协议&#xff1a;DASH2.4 面临挑战&#xff1a;服务器如何向上百万用户同时提供视频流化内容&#xff1…

buuctf_练[GYCTF2020]FlaskApp

[GYCTF2020]FlaskApp 文章目录 [GYCTF2020]FlaskApp常用绕过方法掌握知识解题思路解题一 -- 计算pin码解题二 -- 拼接绕过 执行命令 关键paylaod 常用绕过方法 ssti详解与例题以及绕过payload大全_ssti绕过空格_HoAd’s blog的博客-CSDN博客 CTF 对SSTI的一些总结 - FreeBuf网…

Java中会出现内存泄漏吗

这是一个老生常谈的面试题&#xff0c;本文就系统讲解一下吧 虽然Java有GC垃圾⾃动回收功能&#xff0c;但并不是说Java程序就不会内存泄漏。如果一个对象没有地⽅会使⽤到&#xff0c;但是却仍然有引用指向他&#xff0c;那么垃圾回收器就无法回收他&#xff0c;这种情况就属于…

重复性管理--抽象的重要性(下)

接着 上一篇的谈论, 继续谈论抽象在重复性管理中的重要作用. 好的抽象与糟糕的抽象? 通过前面的一些例子, 你可能形成了一个印象: 所谓抽象很多时候就是把一些代码封装到一个方法中. 不过事实上并不是这么简单的. 抽象的结果确实很多时候产生了一个方法, 但不是说我把一堆代…