深度学习:探究Tensor和Numpy

news2024/11/16 15:38:36

目录

引言

1 pytorch中Tensor

1.1 什么是Tensor

1.2 为什么需要Tensor

1.3 如何创建Tensor

1.3.1 从已有其他数据结构转化创建为Tensor

1.3.2 随机初始化一个Tensor

1.3.3 从已保存文件加载一个Tensor

1.4 Tensor的特性

1.4.1 丰富的常用函数操作

1.4.2 灵活的dtype和CPU/GPU自由切换

1.4.3 自动梯度求解

2 Numpy

2.1 什么是Numpy

2.2 NumPy有哪些优势

2.2.1 ndarray支持并行化运算(向量化运算)

2.2.2 效率远高于纯Python代码

2.2.3 存储数据地址连续

2.3 如何创建Numpy对象

2.3.1 使用Numpy创建ndarray数组

2.3.2 查看数组维数并改变维度

2.3.3 通过ndarray的属性也可以操作数组

 2.3.4 创建元素均为 0 的数组

2.3.4 创建1填充的指定形状大小与数据类型的新数组

2.3.5 将一个 Python 序列转化为 ndarray 对象

 2.3.6 使用指定的缓冲区创建数组

 2.3.7 迭代对象转换为 ndarray 数组

2.3.8 创建给定数值范围的数组

 2.3.9 创建指定的数值区间内的数组

 2.3.10 创建等比数组

2.4 Numpy运算

2.4.1 平铺数组元素

2.4.2 以一维数组的形式返回一份数组副本

2.4.2 转化成连续的扁平数组

2.4.3 Numpy 的位运算

2.4.4 算术运算

2.4.5 Numpy矩阵操作

2.4.5 两个矩阵的逐元素乘法

 2.4.6 两个数组的矩阵乘积

2.4.7 两个矩阵的点积

2.4.8 两个矩阵内积

2.4.9 解线性矩阵方程

2.4.10 计算矩阵的逆矩阵

3 Tensor和Numpy的相互转换

3.1 Tensor转Numpy

3.2 Numpy转Tensor

3.2.1 使用torch.tensor

3.2.2 使用torch.from_numpy

4 Tensor转其他

4.1 Tensor转数值

4.2 Tensor转List

4.3 Tensor转List Tensor


引言

在我们构建深度学习模型的过程中,Tensor和Numpy必不可少,而且经常会面临两种数据结构的相互转换。

  • 这两个数据结构到底有什么区别?
  • 什么时候选择哪种数据结构使用?
  • 两种数据结构之间如何转换?

本文通过定义、应用场景、转换方式等多个维度,给出问题的答案。

1 pytorch中Tensor

1.1 什么是Tensor

Tensor是深度学习中最为基础也最为关键的数据结构:

  • Tensor之于PyTorch就好比是array之于Numpy或者DataFrame之于Pandas,都是构建了整个框架中最为底层的数据结构;
  • Tensor与普通的数据结构不同,具有一个极为关键的特性——自动求导。

 定义:Tensor英文原义是张量,在Pytorch官网中对其有如下介绍:

 一个Tensor是一个包含单一数据类型的高维矩阵,一般而言,描述Tensor的高维特性通常用三维及以上的矩阵来描述,例如下图所示:单个元素叫标量(scalar),一个序列叫向量(vector),多个序列组成的平面叫矩阵(matrix),多个平面组成的立方体叫张量(tensor)。当然,就像矩阵有一维矩阵和二维矩阵乃至多维矩阵一样,张量也无需严格限制在三维以上才叫张量,在深度学习的范畴内,标量、向量和矩阵都统称为张量。

Tensor也不是PyTorch特有的定义,而是众多深度学习框架广泛使用的数据结构,如TensorFlow。

1.2 为什么需要Tensor

PyTorch中的Tensor是深度学习中广泛使用的数据结构,本质上就是一个高维的矩阵,甚至将其理解为NumPy中array的推广和升级也不为过。但由于其支持的一些特殊特性,Tensor在用于支撑深度学习模型和训练时更为便利。

1.3 如何创建Tensor

一般而言,创建一个Tensor大体有三种方式:

  • 从已有其他数据结构转化创建为Tensor
  • 随机初始化一个Tensor
  • 从已保存文件加载一个Tensor

1.3.1 从已有其他数据结构转化创建为Tensor

这可能是实际应用中最常用的一种形式,常用于数据集的加载,比如从一个列表、从一个NumPy的array中读取数据,而后生成一个新的Tensor。为了实现这一目的,常用的有两种方式:

  •     torch.tensor
  •     torch.Tensor

二者的区别就是前者用的是tensor函数(t是小写),后者用的是Tensor类(T是大写)。二者在创建Tensor的默认数据类型、支持传参以及个别细节的处理方面。

  • 首先是创建的Tensor默认数据类型不同:
import torch

t1 = torch.tensor([1,2,3])
t2 = torch.Tensor([1,2,3])
print(t1, t2)
print(t1.dtype, t2.dtype)

运行显示如下:

tensor([1, 2, 3]) tensor([1., 2., 3.])
torch.int64 torch.float32
  • 其次,应用Tensor类初始化输入一个整数将返回一个以此为长度的全零一维张量,而tensor函数则返回一个只有该元素的零维张量:
import torch

t1 = torch.tensor(3)
t2 = torch.Tensor(3)
print(t1, t2)

运行结果显示:

tensor(3) tensor([0., 0., 0.])

有一个细节需要优先提及:应用Tensor类接收一个序列创建Tensor时,返回的数据类型为float型,这是因为Tensor是FloatTensor的等价形式,即除此之外还有ByteTensor,IntTensor,LongTensor以及DoubleTensor等不同的默认数据类型。

基于已有数据创建Tensor另外两个常用函数:

  •     from_numpy
  •     as_tensor

二者与上述方法最大的不同在于它们返回的Tensor与原有数据是共享内存的,而前述的tensor函数和Tensor类则是copy后创建一个新的对象。

import torch
import numpy as np

n1 = np.array([1,2,3])
n2 = np.array([1,2,3])
n3 = np.array([1,2,3])
t1 = torch.tensor(n1)
t2 = torch.from_numpy(n2)
t3 = torch.as_tensor(n3)
print('t1:', t1)
print('t2:', t2)
print('t3:', t3)

n1[0] = 100
n2[0] = 100
n3[0] = 100

print('t1:', t1)
print('t2:', t2)
print('t2:', t3)

运行结果显示:

t1: tensor([1, 2, 3])
t2: tensor([1, 2, 3])
t3: tensor([1, 2, 3])
t1: tensor([1, 2, 3])
t2: tensor([100,   2,   3])
t2: tensor([100,   2,   3])

1.3.2 随机初始化一个Tensor

随机初始化是一种常用的形式,在搭建一个神经网络模型中,在添加了一个模块的背后也自动随机初始化了该模块的权重。这类方法分为两种形式:

  •  创建一个特定类型的tensor,例如torch.ones,torch.randn等等
  •  根据一个已有Tensor创建一个与其形状一致的特定类型tensor,例如torch.ones_like,torch.randn_like等等
import torch

func_name = [x for x in dir(torch) if x.endswith('like')]
print(func_name)

运行结果显示:

['empty_like', 'full_like', 'ones_like', 'rand_like', 'randint_like', 'randn_like', 'zeros_like']

随机构建一个PyTorch中的全连接单元Linear,其会默认创建相应的权重系数和偏置(由于网络参数一般是需要参与待后续的模型训练,所以默认requires_grad=True):

import torch

linear = torch.nn.Linear(2,3)
print('weight:', linear.weight)
print('bias:', linear.bias)

运行结果显示:

weight: Parameter containing:
tensor([[-0.5380, -0.6481],
        [ 0.0144,  0.0627],
        [-0.6560,  0.0382]], requires_grad=True)
bias: Parameter containing:
tensor([-0.2800,  0.0235, -0.6940], requires_grad=True)

1.3.3 从已保存文件加载一个Tensor

PyTorch不会刻意区分要保存和加载的对象是何种形式,可以是训练好的网络,也可以是数据,这在Python中就是pickle,通过torch.save和torch.load两个函数实现。保存后的文件没有后缀格式要求,常用的后缀格式有 .pkl、.pth、.pt三种,此方法常用于模型以及大规模数据集的保存。

import torch

t1 = torch.tensor([1,2,3,4,5])
torch.save(t1, 'tensor.pkl')

ret_t = torch.load('tensor.pkl')
print('ret_t', ret_t)

 运行结果如下:

ret_t tensor([1, 2, 3, 4, 5])

1.4 Tensor的特性

PyTorch之所以定义了Tensor来支持深度学习,而没有直接使用Python中的一个list或者NumPy中的array,是因为Tensor被赋予了一些独有的特性。Tensor的主要特性为以下三个方面:

  •     丰富的常用操作函数
  •     灵活的dtype和CPU/GPU自由切换存储
  •     自动梯度求解

1.4.1 丰富的常用函数操作

Tensor本质上是一个由数值型元素组成的高维矩阵,深度学习的过程就是各种矩阵运算的过程,Tensor作为其基础数据结构支持丰富的函数操作。

  • Tensor自身进行操作函数,例如tensor.max(), tensor.abs()等等,
  • Tensor其他tensor进行相关操作,例如tensor.add()用于与另一个tensor相加,tensor.mm()用于与另一个tensor进行矩阵乘法等等。这里的相加和相乘对操作的两个tensor尺寸有所要求。

除了支持的函数操作足够丰富外,tensor的API函数还有另一个重要的便利特性:绝大多数函数都支持两个版本:带下划线版和不带下划线版,例如tensor.abs()和tensor.abs_(),二者均返回操作后的Tensor,但同时带下划线版本属于inplace操作,即调用后自身数据也随之改变。

1.4.2 灵活的dtype和CPU/GPU自由切换

Tensor中dtype的概念类似于NumPy和Pandas中的用法,用于指定待创建Tensor的数据结构。PyTorch中定义了10种不同的数据结构,包括不同长度的整型、不同长度的浮点型,整个Tesor的所有元素必须数据类型相同,且必须是数值类型(NumPy中的array也要求数组中的元素是同质的,但支持字符串类型的):

除了支持不同的数值数据类型外,Tensor的另一大特色是其支持不同的计算单元:CPU或GPU,支持GPU加速也是深度学习得以大规模应用的一大关键。为了切换CPU计算(数据存储于内存)或GPU计算(数据存储于显存),Tensor支持灵活的设置存储设备,包括如下两种方式:

  •     创建tensor时,通过device参数直接指定
  •     通过tensor.to()函数切换,to()既可用于切换存储设备,也可切换数据类型

此外,除了dtype和device这两大特性之外,其实Tensor还有第三个特性,即layout,布局。主要包括strided和sparse_coo两种,该特性一般不需要额外考虑。

1.4.3 自动梯度求解

Tensor自动梯度求解是支撑深度学习的基石,深度学习模型的核心是在于神经元的连接,而神经元之间连接的关键在于网络权重,也就是各个模块的参数。正因为网络参数的不同,所以才使得相同的网络结构能实现不同的模型应用价值。那么,如何学习最优网络参数呢?这就是深度学习中的的优化利器:梯度下降法,而梯度下降法的一大前提就是支持自动梯度求解。

Tensor为了支持自动梯度求解,大体流程如下:

  • Tensor支持grad求解,即requires_grad=True
  • 根据Tensor参与计算的流程,将Tensor及相应的操作函数记录为一个树结构(或称之为有向无环图:DAG),计算的方向为从叶节点流向根节点
  • 根据根节点Tensor与目标值计算相应的差值(loss),然后利用链式求导法则反向逐步计算梯度(也即梯度的反向传播)

2 Numpy

2.1 什么是Numpy

Numpy 是 Numerical Python 的缩写,它是一个由多维数组对象(ndarray)和处理这些数组的函数(function)集合组成的库。使用 Numpy 库,可以对数组执行数学运算和相关逻辑运算。Numpy 不仅作为 Python 的扩展包,它同样也是 Python 科学计算的基础包。Numpy 提供了大量的数学函数,主要用来计算、处理一维或多维数组,支持常见的数组和矩阵操作。NumPy 的底层主要用 C语言编写,因此它能够高速地执行数值计算。Numpy 还提供了多种数据结构,这些数据结构能够非常契合的应用在数组和矩阵的运算上。
Numpy 作为一个开源项目,它由许多协作者共同开发维护,随着数据科学(Data Science,简称 DS,包括大数据分析与处理、大数据存储、数据抓取等分支)的蓬勃发展,像 Numpy、SciPy(Python科学计算库)、Pandas(基于NumPy的数据处理库) 等数据分析库都有了大量的增长,它们都具有较简单的语法格式。Numpy 通常会和Matplotlib等搭配一块使用。

2.2 NumPy有哪些优势

2.2.1 ndarray支持并行化运算(向量化运算)

numpy内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy会自动做并行计算。

2.2.2 效率远高于纯Python代码

Numpy底层使用C语言编写,内部解除了GIL(全局解释器锁),其对数组的操作速度不受Python解释器的限制,所以,其效率远高于纯Python代码。

2.2.3 存储数据地址连续

ndarray在存储数据的时候,数据与数据的地址都是连续的,这样就使得批量操作数组元素时速度更快。

ndarray中的所有元素的类型都是相同的,而Python列表中的元素类型是任意的,所以ndarray在存储元素时内存可以连续,而python原生list就只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面Numpy的ndarray不及Python原生list,但在科学计算中,Numpy的ndarray就可以省掉很多循环语句,代码使用方面比Python原生list简单的多。
 

2.3 如何创建Numpy对象

Numpy 定义了一个 n 维数组对象,简称 ndarray 对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块,使用索引或切片的方式可以获取数组中的每个元素。ndarray 对象有一个 dtype 属性,该属性用来描述元素的数据类型。ndarray 对象采用了数组的索引机制,将数组中的每个元素映射到内存块上,并且按照一定的布局对内存块进行排列,常用的布局方式有两种,即按行或者按列。

通过 Numpy 的内置函数 array() 可以创建 ndarray 对象,其语法格式如下:

numpy.array(object, dtype = None, copy = True, order = None,ndmin = 0)

2.3.1 使用Numpy创建ndarray数组

import numpy as np

a = np.array([1,2,3])
b = np.array([[1,2,3], [4,5,6]])

print(f'a:{a}')
print(f'type(a):{type(a)}')

print('b:{b}')

运行结果显示:

a:[1 2 3]
type(a):<class 'numpy.ndarray'>
b:{b}

2.3.2 查看数组维数并改变维度

import numpy as np

a = np.array([[1,2], [3,4], [5,6]])

print(a.ndim)
print("old array:", a)

a = a.reshape(2,3)
print("new array:", a.ndim, a)

运行结果显示:

old array: [[1 2]
 [3 4]
 [5 6]]
new array: 2 [[1 2 3]
 [4 5 6]]

2.3.3 通过ndarray的属性也可以操作数组

ndarray的属性

import numpy as np

a = np.array([[1,2], [3,4], [5,6]])
print('a.shape:', a.shape)
print('a:', a)
a.shape = (2, 3)
print('a[2,3]:', a)
print('a[3,2]:', a.reshape(3, 2))

print('a.ndim:', a.ndim)
print('a.itemsize:', a.itemsize)
print('a.flags:', a.flags)

 dd

a.shape: (3, 2)
a: [[1 2]
 [3 4]
 [5 6]]
a[2,3]: [[1 2 3]
 [4 5 6]]
a[3,2]: [[1 2]
 [3 4]
 [5 6]]
a.ndim: 2
a.itemsize: 4
a.flags:   C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False

ndarray的类型

Numpy中的数据类型标识码,Numpy 中每种数据类型都有一个唯一标识的字符码,如下所示:

  • i - 整数
  • b - 布尔
  • u - 无符号整数
  • f - 浮点
  • c - 复合浮点数
  • m - timedelta
  • M - datetime
  • O - 对象
  • S - 字符串
  • U - unicode 字符串
  • V - 固定的其他类型的内存块 ( void )

通常,Numpy 与 SciPy 程序包一起使用,SciPy 可以看做对 Numpy 库的扩展,它在 Numpy 的基础上又增加了许多工程计算函数。

2.3.4 创建未初始化的数组

numpy.empty(shape, dtype = float, order = 'C')

numpy.empty() 创建未初始化的数组,可以指定创建数组的形状(shape)和数据类型(dtype)。 

参数:

    shape:指定数组的形状;
    dtype:数组元素的数据类型,默认值是值 float;
    order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(“C”代表以行顺序存储,“F”则表示以列顺序存储)。
import numpy as np
n1 = np.empty([2, 2])
print(n1)

运行结果显示:

[[0.0e+000 5.4e-323]
 [9.9e-324 9.9e-324]]

 2.3.4 创建元素均为 0 的数组

numpy.zeros(shape,dtype=float,order="C")

该函数用来创建元素均为 0 的数组,同时还可以指定被数组的形状。 

参数:

    shape:指定数组的形状;
    dtype:数组元素的数据类型,默认值是值 float;
    order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(“C”代表以行顺序存储,“F”则表示以列顺序存储)。
import numpy as np
n1 = np.zeros([2, 2])
print(n1)

运行结果显示:

[[0. 0.]
 [0. 0.]]

2.3.4 创建1填充的指定形状大小与数据类型的新数组

numpy.ones(shape, dtype = None, order = 'C')

返回指定形状大小与数据类型的新数组,并且新数组中每项元素均用 1 填充。 

import numpy as np
n1 = np.ones([2, 2])
print(n1)

运行结果显示

[[1. 1.]
 [1. 1.]]

2.3.5 将一个 Python 序列转化为 ndarray 对象

numpy.asarray(sequence,dtype = None ,order = None )

asarray() 能够将一个 Python 序列转化为 ndarray 对象。 

参数:

    sequence:接受一个 Python 序列,可以是列表或者元组;
    dtype:可选参数,数组的数据类型,默认值是值 float;
    order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(“C”代表以行顺序存储,“F”则表示以列顺序存储)。
import numpy as np


array = [1, 2, 3, 4, 5]
n1 = np.asarray(array)
print(n1)
print(type(n1))

运行结果显示

[1 2 3 4 5]
<class 'numpy.ndarray'>

 2.3.6 使用指定的缓冲区创建数组

numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)

表示使用指定的缓冲区创建数组。 

参数:

    buffer:将任意对象转换为流的形式读入缓冲区;
    dtype:返回数组的数据类型,默认是 float32;
    count:要读取的数据数量,默认为 -1 表示读取所有数据;
    offset:读取数据的起始位置,默认为 0。
import numpy as np

data =b'hello world!'
res = np.frombuffer(data,dtype='S3',offset=0)
print(res)

 运行结果显示:

[b'hel' b'lo ' b'wor' b'ld!']

 2.3.7 迭代对象转换为 ndarray 数组

numpy.fromiter(iterable, dtype, count = -1)

把迭代对象转换为 ndarray 数组,其返回值是一个一维数组。 

参数:

    iterable:可迭代对象;
    dtype:数组元素的数据类型,默认值是值 float;
    count:读取的数据数量,默认为 -1,读取所有数据。
import numpy as np

iterable = (x * x*x for x in range(4))
n1 = np.fromiter(iterable, int)

print (n1)

 运行结果显示

[ 0  1  8 27]

2.3.8 创建给定数值范围的数组

numpy.arange(start, stop, step, dtype)
参数:

    start: 起始值,默认是 0。
    stop: 终止值,注意生成的数组元素值不包含终止值。
    step: 步长,默认为 1。
    dtype: 可选参数,指定 ndarray 数组的数据类型。
import numpy as np

A = np.arange(5)
print(A)
print(type(A))

A = np.arange(1, 5)
print(A)

A = np.arange(1, 5, 2)
print(A)

A = np.arange(1, 5.2, 0.6)
print(A)

运行结果显示

[0 1 2 3 4]
<class 'numpy.ndarray'>
[1 2 3 4]
[1 3]
[1.  1.6 2.2 2.8 3.4 4.  4.6 5.2]

 2.3.9 创建指定的数值区间内的数组

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数:

    start:代表数值区间的起始值;
    stop:代表数值区间的终止值;
    num:表示数值区间内要生成多少个均匀的样本。默认值为 50;
    endpoint:默认为 True,表示数列包含 stop 终止值,反之不包含;
    retstep:默认为 True,表示生成的数组中会显示公差项,反之不显示;
    dtype:代表数组元素值的数据类型。
import numpy as np

n1 = np.linspace(start = 0, stop = 1, num = 11)
n2 = np.linspace(start = 0, stop = 100, num = 11)
n3 = np.linspace(start = 1, stop = 5, num = 4, endpoint = False)
n4 = np.linspace(start = 0, stop = 100, num = 5, dtype = int)
print(n1)
print(n2)
print(n3)
print(n4)

 运行结果显示:

[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
[  0.  10.  20.  30.  40.  50.  60.  70.  80.  90. 100.]
[1. 2. 3. 4.]
[  0  25  50  75 100]

 2.3.10 创建等比数组

numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数:

    start: 序列的起始值:base**start。
    stop: 序列的终止值:base**stop。
    num: 数值范围区间内样本数量,默认为 50。
    endpoint: 默认为 True 包含终止值,反之不包含。
    base: 对数函数的 log 底数,默认为10。
    dtype: 可选参数,指定 ndarray 数组的数据类型。

logspace中,开始点和结束点是10的幂

import numpy as np

n1 = np.logspace(0,0,10)
n2 = np.logspace(0,9,10)
n3 = np.logspace(0,9,10,base=2)

print(n1)
print(n2)
print(n3)

 运行结果显示:

[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1.e+00 1.e+01 1.e+02 1.e+03 1.e+04 1.e+05 1.e+06 1.e+07 1.e+08 1.e+09]
[  1.   2.   4.   8.  16.  32.  64. 128. 256. 512.]

2.4 Numpy运算

2.4.1 平铺数组元素

numpy.ndarray.flat()

返回一个数组迭代器,可以用 for 循环遍历其中的每一个元素。

import numpy as np

a = np.arange(8).reshape(2, 4)
print ('a:', a)

for e in a.flat:
    print (e, end=" ")

运行结果显示:

a: [[0 1 2 3]
 [4 5 6 7]]
0 1 2 3 4 5 6 7 

2.4.2 以一维数组的形式返回一份数组副本

numpy.ndarray.flatten()

以一维数组的形式返回一份数组副本,对副本修改不会影响原始数组。

import numpy as np

a = np.arange(8).reshape(2, 4)
print(a)
print(a.flatten())

运行结果显示:

[[0 1 2 3]
 [4 5 6 7]]
[0 1 2 3 4 5 6 7]

2.4.2 转化成连续的扁平数组

numpy.ravel()

返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)。

import numpy as np

a1, a2 = np.mgrid[1:4:1, 2:3:1]
print("a1:\n", a1, "\n", "a2:\n", a2)

n1 = a1.ravel() 
n2 = a2.ravel()

print("n1:", n1)
print("n2:", n2)
sum = n1 + n2
print(sum)

运行结果显示:

a1:
 [[1]
 [2]
 [3]] 
 a2:
 [[2]
 [2]
 [2]]
n1: [1 2 3]
n2: [2 2 2]
[3 4 5]

2.4.3 Numpy 的位运算

import numpy as np

n1 = np.bitwise_and([11,7], [4,25])
n2 = np.bitwise_and(np.array([2,5,255]), np.array([3,14,16]))
n3 = np.bitwise_and([True, True], [False, True])


n4 = np.bitwise_or([11,7], [4,25])
n5 = np.bitwise_or(np.array([2,5,255]), np.array([3,14,16]))
n6 = np.bitwise_or([True, True], [False, True])

print(n1)
print(n2)
print(n3)
print(n4)
print(n5)
print(n6)

运行结果显示:

[0 1]
[ 2  4 16]
[False  True]
[15 31]
[  3  15 255]
[ True  True]

2.4.4 算术运算

NumPy 数组的“加减乘除”算术运算,分别对应 add()、subtract()、multiple() 以及 divide() 函数。

  • numpy.reciprocal()函数对数组中的每个元素取倒数,并以数组的形式将它们返回。
  • numpy.power()将 a 数组中的元素作为底数,把 b 数组中与 a 相对应的元素作幂 ,最后以数组形式返回两者的计算结果。
  • numpy.mod()返回两个数组相对应位置上元素相除后的余数
import numpy as np

a = np.random.randint(9, size=(3, 3))
print("a =", a)
b = np.random.randint(9, size=(3, 3))
print("b =", b)
print("a + b =", np.add(a, b))
print("a - b =", np.subtract(a, b))
print("a x b =", np.multiply(a, b))
print("a / b =", np.divide(a, b))

运行结果显示:

a = [[8 0 2]
 [7 8 4]
 [3 5 1]]
b = [[2 3 5]
 [1 8 3]
 [4 1 2]]
a + b = [[10  3  7]
 [ 8 16  7]
 [ 7  6  3]]
a - b = [[ 6 -3 -3]
 [ 6  0  1]
 [-1  4 -1]]
a x b = [[16  0 10]
 [ 7 64 12]
 [12  5  2]]
a / b = [[4.         0.         0.4       ]
 [7.         1.         1.33333333]
 [0.75       5.         0.5       ]]

2.4.5 Numpy矩阵操作

NumPy 提供了一个 矩阵库模块numpy.matlib,该模块中的函数返回的是一个 matrix 对象,而非 ndarray 对象。矩阵由 m 行 n 列(m*n)元素排列而成,矩阵中的元素可以是数字、符号或数学公式等。

  • numpy.matlib.empty() 返回一个空矩阵,它的创建速度非常快。
  • numpy.matlib.zeros() 创建一个以 0 填充的矩阵。
  • numpy.matlib.ones() 创建一个以 1 填充的矩阵。
  • numpy.matlib.eye() 返回一个对角线元素为 1,而其他元素为 0 的矩阵 。
  • numpy.matlib.identity()该函数返回一个给定大小的单位矩阵,矩阵的对角线元素为 1,而其他元素均为 0。
  • numpy.matlib.rand() 创建一个以随机数填充,并给定维度的矩阵。
import numpy as np
import numpy.matlib

print(np.matlib.empty((3, 4)))
print(np.matlib.zeros((3, 4)))
print(np.matlib.ones((3, 4)))

运行结果显示:

[[0.00000000e+000             nan 1.69759663e-313 0.00000000e+000]
 [0.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000]
 [0.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000]]
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]

2.4.5 两个矩阵的逐元素乘法

multiple()

函数用于两个矩阵的逐元素乘法。

import numpy as np

a1=np.array([[1,2], [3,4]], ndmin=2)
a2=np.array([[1,2], [3,4]], ndmin=2)

print(np.multiply(a1, a2))
[[ 1  4]
 [ 9 16]]

 2.4.6 两个数组的矩阵乘积

matmul()
用于计算两个数组的矩阵乘积。

import numpy as np

a1=np.array([[1,2], [3,4]], ndmin=2)
a2=np.array([[1,2], [3,4]], ndmin=2)

print(np.matmul(a1, a2))

 运行结果显示:

[[ 7 10]
 [15 22]]

2.4.7 两个矩阵的点积

dot()
函数用于计算两个矩阵的点积。

import numpy as np

a1=np.array([[1,2], [3,4]], ndmin=2)
a2=np.array([[1,2], [3,4]], ndmin=2)

print(np.dot(a1, a2))
[[ 7 10]
 [15 22]]

2.4.8 两个矩阵内积

numpy.inner()
用于计算数组之间的内积。

import numpy as np
n1=np.inner(np.array([1,2,3,4]),np.array([1,2,3,4]))
a1=np.array(([[1,2],[3,4]]))
a2=np.array(([[11,12],[13,14]]))
n2=np.inner(a1,a2)

print(n1)
print(n2)

运行结果显示:

30
[[35 41]
 [81 95]]

2.4.9 解线性矩阵方程

numpy.linalg.solve()
该函数用于求解线性矩阵方程组,并以矩阵的形式表示线性方程的解。

解方程组x0 + 2 * x1 = 13 * x0 + 5 * x1 = 2:

import numpy as np

a = np.array([[1, 2], [3, 5]])
b = np.array([1, 2])
x = np.linalg.solve(a, b)
print(x)

运行结果显示:

[-1.  1.]

2.4.10 计算矩阵的逆矩阵

numpy.linalg.inv()
该函数用于计算矩阵的逆矩阵,逆矩阵与原矩阵相乘得到单位矩阵。 

import numpy as np

a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
n =np.linalg.inv(a)
print(a)
print(n)

运行结果显示:

[[[1. 2.]
  [3. 4.]]

 [[1. 3.]
  [3. 5.]]]
[[[-2.    1.  ]
  [ 1.5  -0.5 ]]

 [[-1.25  0.75]
  [ 0.75 -0.25]]]
[[[-2.    2.  ]
  [ 4.5  -2.  ]]

 [[-1.25  2.25]
  [ 2.25 -1.25]]]

3 Tensor和Numpy的相互转换

3.1 Tensor转Numpy

import numpy as np
import torch

t = torch.arange(1, 10).reshape(3, 3)
x = t.numpy()
print(f'a={t}')
print(f'b={x}')

运行结果显示:

a=tensor([[1, 2, 3],
          [4, 5, 6],
          [7, 8, 9]])
b=[[1 2 3]
   [4 5 6]
   [7 8 9]]

3.2 Numpy转Tensor

3.2.1 使用torch.tensor

import numpy as np
import torch
a = np.random.normal(0, 1, (2, 3))
b = torch.tensor(a)
print(f'a={a}, b={b}')

   运行结果显示:

a=[[ 1.77128009  2.02509013  0.38144148]
   [ 1.14920329 -0.30733646 -1.20198951]]
b=tensor([[ 1.7713,  2.0251,  0.3814],
          [ 1.1492, -0.3073, -1.2020]], dtype=torch.float64)

3.2.2 使用torch.from_numpy

import numpy as np
import torch

a = np.random.normal(0, 1, (4, 5))
b = torch.from_numpy(a)
print(f'a={a}')
print(f'b={b}')

 运行结果显示:

a=[[ 1.27357033  0.43722359 -0.74243293 -0.19531152  0.95053336]
   [-0.52235811  0.95262418 -0.11157708  0.65592213  0.04188334]
   [ 0.14932165 -0.40966126  0.09067062  0.3212764  -2.41411188]
   [ 0.63391603  0.29742247 -0.43064322  1.08767221 -0.95699876]]
b=tensor([[ 1.2736,  0.4372, -0.7424, -0.1953,  0.9505],
          [-0.5224,  0.9526, -0.1116,  0.6559,  0.0419],
          [ 0.1493, -0.4097,  0.0907,  0.3213, -2.4141],
          [ 0.6339,  0.2974, -0.4306,  1.0877, -0.9570]], dtype=torch.float64)

4 Tensor转其他

4.1 Tensor转数值

import torch

a = torch.tensor([1])
b = a.item()

print(f'a={a}')
print(f'b={b}')

运行结果显示:

a=tensor([1])
b=1

4.2 Tensor转List

import torch

t1 = torch.arange(10)
t2 = t1.tolist() 

print(f't1={t1}')
print(f't2={t2}')

运行结果显示:

t1=tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
t2=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

4.3 Tensor转List Tensor

import torch

t1 = torch.arange(10)
t3 = list(t1)

print(f't1={t1}')
print(f't3={t3}')

运行结果显示

t1=tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
t3=[tensor(0), tensor(1), tensor(2), tensor(3), tensor(4), tensor(5), tensor(6), tensor(7), tensor(8), tensor(9)]

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

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

相关文章

使用TensorBoard进行可视化

1. TensorBoard介绍 TensorBoard是TensorFlow推出的可视化工具&#xff0c;可以可视化模型结构、跟踪并以表格形式显示模型指标。 TensorBoard的使用包括两个步骤&#xff1a; 在代码中设置TensorBoard&#xff0c;在训练的过程中将会根据设置产生日志文件在浏览器中可视化该…

启动RocketMQ报错

说明&#xff1a;启动RocketMQ消费者时&#xff0c;报以下错误&#xff1a;java.lang.IllegalStateException&#xff1a;Failed to start RocketMQ push consumer. 解决&#xff1a;看下所有的监听器类&#xff0c;检查是不是有相同的消费者组名&#xff0c;注释掉其中一个即可…

文心一言 VS 讯飞星火 VS chatgpt (71)-- 算法导论7.1 1题

参照图 7-1的方法&#xff0c;说明 PARTITION在数组 A(13&#xff0c;19&#xff0c;9&#xff0c;5&#xff0c;12&#xff0c;8&#xff0c;7&#xff0c;4&#xff0c;21&#xff0c;2&#xff0c;6&#xff0c;11)上的操作过程。 文心一言&#xff1a; PARTITION 是一种常…

C++笔记之while循环的帧率监测与控制

C笔记之while循环的帧率监测与控制 code review! 文章目录 C笔记之while循环的帧率监测与控制1.两个时间相关的类2.例程3.运行4.代码 1.两个时间相关的类 2.例程 3.运行 4.代码 // 帧率监测与控制程序 #include <chrono> #include <iostream> #include <thre…

python 连接oracle pandas以简化excel的编写和数据操作

python代码 Author: liukai 2810248865qq.com Date: 2022-08-18 04:28:52 LastEditors: liukai 2810248865qq.com LastEditTime: 2023-07-06 22:12:56 FilePath: \PythonProject02\pandas以简化excel的编写和数据操作.py Description: 这是默认设置,请设置customMade, 打开koro…

Python爬虫的学习day02 requests 模块post 函数, lmxl 模块的 etree 模块

1. requests 模块post 函数 1.1 post 函数的参数 &#xff08;简单版&#xff09; 参数1&#xff1a; url 网络地址 参数2&#xff1a; data 请求数据 &#xff08;一般数据是 账号&#xff0c;密码&#xff09; 参数3&#xff1a; headers 头请求 &#xff08…

概念解析 | 虚拟镜面:超越三次反射的非视线成像

虚拟镜面:超越三次反射的非视线成像 注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:虚拟镜面在非视线成像中的应用。 参考文献:Royo D, Sultan T, Muoz A, et al. Virtual Mirrors: Non-Line-of-Sight Imaging Beyond the Th…

MyBatis关联查询

文章目录 前言多对一关联 association一对多关联 collection 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 关联查询是指在一个查询中同时获取多个表中的数据&#xff0c;将它们结合在一起进行展示。 关联表需要两个及以上的表 数据库代码&#xff1…

初阶C语言——特别详细地介绍函数

系列文章目录 第一章 “C“浒传——初识C语言&#xff08;更适合初学者体质哦&#xff01;&#xff09; 第二章 详细认识分支语句和循环语句以及他们的易错点 第三章 初阶C语言——特别详细地介绍函数 目录 系列文章目录 前言 一、函数是个什么鬼东西&#xff1f; 二、C语…

springboot基于vue的高校迎新系统的设计与实现8jf9e

随着时代的发展&#xff0c;人们的生活方式得到巨大的改变&#xff0c;从而慢慢地产生了大量高校迎新信息&#xff0c;高校迎新信息需要一个现代化的管理系统&#xff0c;进行高校迎新信息的管理。 高校迎新系统的开发就是为了解决高校迎新管理的问题&#xff0c;系统开发是基于…

JavaScript |(六)DOM事件 | 尚硅谷JavaScript基础实战

学习来源&#xff1a;尚硅谷JavaScript基础&实战丨JS入门到精通全套完整版 文章目录 &#x1f4da;事件对象&#x1f4da;事件的冒泡&#x1f4da;事件的委派&#x1f4da;事件的绑定&#x1f407;赋值绑定&#x1f407;addEventListener()&#x1f407;attachEvent()&…

认识FFMPEG框架

FFMPEG全称: Fast Forward Moving Picture Experts Group (MPEG:动态图像专家组) ffmpeg相关网站: git://source.ffmpeg.org/ffmpeg.git http://git.videolan.org/?pffmpeg.git https://github.com/FFmpeg/FFmpeg FFMPEG框架基本组件: AVFormat , AVCodec, AVDevice, AVFil…

【多线程学习6】synchronized关键字

【多线程学习6】synchronized关键字 一、synchronized关键字是什么&#xff1f;有什么作用&#xff1f; synchronized关键字是Java线程同步的关键字&#xff0c;其可以修饰方法或代码块&#xff0c;并可以保证其修饰的方法或代码块在任意时刻只能有一个线程执行。 synchroni…

关于HIVE的分区与分桶

1.分区 1.概念 Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区&#xff0c;这样的查询效率会提高很多 个人理解白话:按表中或者自定义的一个列,对数据进…

筛选给定范围内的日志

目录 1.时间戳 2.实例 1.首先创建ubuntu.log日志 2.写dem.awk创建规则 3.筛选 1.时间戳 一个能表示一份数据在某个特定时间之前已经存在的、 完整的、 可验证的数据,通常是一个字符序列&#xff0c;唯一地标识某一刻的时间。 awk提供了mktime()函数&#xff0c;它可以将时间…

macbook怎么卸载软件?2023年最新全新解析macbook电脑怎样删除软件

macbook怎么卸载软件&#xff1f;2023年最新全新解析macbook电脑怎样删除软件。关于Mac笔记本如何卸载软件_Mac笔记本卸载软件的四种方法的知识大家了解吗&#xff1f;以下就是小编整理的关于Mac笔记本如何卸载软件_Mac笔记本卸载软件的四种方法的介绍&#xff0c;希望可以给到…

像素画教程:立体感与“84渐变法“

像素画本身没有什么困难&#xff0c;是矢量图简笔画之外最简单、而又最容易产生美术效果的画风。 然而&#xff0c;细节难以描绘、立体感难表现、画面易单调成了像素画绘制过程中的常见困难。 这篇文章或许不能保证每个人都能熟练掌握、运用像素画&#xff0c;但至少可以抛砖引…

任务14、无缝衔接,MidJourney瓷砖(Tile)参数制作精良贴图

14.1 任务概述 在这个实验任务中,我们将深入探索《Midjourney Ai绘画》中的Tile技术和其在艺术创作中的具有挑战性的应用。此任务将通过理论学习与实践操作相结合的方式,让参与者更好地理解Tile的核心概念,熟练掌握如何在Midjourney平台上使用Tile参数,并实际运用到AI绘画…

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台

吃完快餐粥&#xff0c;除了粥的味道不错之外&#xff0c;我对个快餐盒的圆盖子产生了兴趣&#xff0c;能否做个极低成本的简易机器人呢&#xff1f;也许只需要二十元左右 知识点&#xff1a;轮子&#xff08;wheel&#xff09; 中国词语。是用不同材料制成的圆形滚动物体。简…

Dockerfile定制Tomcat镜像

Dockerfile中的打包命令 FROM &#xff1a; 以某个基础镜像作为此镜像的基础 RUN &#xff1a; RUN后面跟着linux常用命令&#xff0c;如RUN echo xxx >> xxx,注意&#xff0c;RUN 不能用于执行命令&#xff0c;因为每个RUN都是独立运行的&#xff0c;RUN 的cd对镜像中的…