0_Pytorch中的张量操作
[引言]张量的概念
1.基本概念
- 张量是一个通用的多维数组,可以表示标量(0 维)、向量(1 维)、矩阵(2 维)以及更高维度的数据。
- 张量是 PyTorch 中的核心数据结构,用于表示和操作数据。
0维张量:标量(scalar)
1维张量:向量(vector)
2维张量:矩阵(matrix)
多维张量: 例如三维张量==>类比魔方
1.张量的创建
张量的基本创建
-
torch.tensor() 根据指定数据创建张量
# 1.根据指定数据创建张量 - torch.tensor print('tensor 方式创建张量')# 1.1 创建张量标量 data = torch.tensor(10) print(f'张量标量:{data}')# 1.2 根据 numpy数组 创建张量 data = np.random.randn(3, 2) data = torch.tensor(data) print(f'根据numpy数组创建张量:\r\n{data}')# 1.3 根据 列表 创建张量 data = [[1, 0, 0], [0, 1, 0]] data = torch.tensor(data) print(f'根据列表创建张量:\r\n{data}')
-
torch.Tensor() 根据形状创建张量, 其也可用来创建指定数据的张量
# 2. 根据形状创建张量 - torch.Tensor print('Tensor 方式创建张量') # 2.1 创建 2 行 3 列的张量 默认的dtype为 float32 data = torch.Tensor(2, 3) print(data)# 2.2 注意!! 如果 传递列表, 则创建包含指定元素的张量 data = torch.Tensor([10]) print(data)
-
torch.IntTensor()、torch.FloatTensor()、torch.DoubleTensor() 创建指定类型的张量
# 3.创建指定类型的张量 - torch.IntTensor、torch.FloatTensor、torch.DoubleTensor print('创建指定类型的张量-> torch.IntTensor、torch.FloatTensor、torch.DoubleTensor') # 3.1 创建 2 行 3 列,dtype为 int32 的张量 data = torch.IntTensor(2, 3) print(data)# 3.2 注意!! 如果传递的类型不正确,则会进行类型转换 data = torch.IntTensor([2.5, 3.3]) print(data) """ 其他的一些类型 class DoubleTensor(Tensor): ... class FloatTensor(Tensor): ... class BFloat16Tensor(Tensor): ... class LongTensor(Tensor): ... class IntTensor(Tensor): ... class ShortTensor(Tensor): ... class HalfTensor(Tensor): ... class CharTensor(Tensor): ... class ByteTensor(Tensor): ... class BoolTensor(Tensor): ... """
1-总结
小写 t: 根据指定数据创建
大写 T: 既可以根据指定数据创建,也可以根据形状创建
Tensor: 不指定类型
(Type)Tensor: 指定类型
创建线性张量和随机张量
-
torch.arange() 和 torch.linspace() 创建线性张量
# 1. 创建线性张量 print('=' * 50 + '创建线性张量' + '=' * 50) # 1.1 在指定区间内按照步长生成元素 data = torch.arange(0, 10, 2) print(data)# 1.2 在指定区间按照元素个数生成 data = torch.linspace(0, 10, 9) print(data)
-
torch.random.init_seed() 和 torch.random.manual_seed() 随机种子设置
-
torch.randn() 创建随机张量
# 2.创建随机张量
print('=' * 50 + '创建随机张量' + '=' * 50)
# 2.1 创建一个 2 行 3列的随机张量
data = torch.randn(2, 3)
print(data)# 2.2 设置随机数种子
# - torch.random.init_seed
print(f'随机数种子: {torch.random.initial_seed()}') # 25338627685600
# - torch.random.manual_seed
torch.random.manual_seed(200)
data = torch.randn(2, 3)
print(data)
print(f'随机数种子: {torch.random.initial_seed()}') # 100
创建0-1张量
- torch.ones 和 torch.ones_like 创建全1张量
- torch.zeros 和 torch.zeros_like 创建全0张量
- torch.full 和 torch.full_like 创建全为指定值张量
import torch# - torch.ones 和 torch.ones_like 创建全1张量
data = torch.ones(2, 3)
print(f'data:\r\n{data}')
data1 = torch.ones_like(data)
print(f'data1:\r\n{data1}')# - torch.zeros 和 torch.zeros_like 创建全0张量
data = torch.zeros(2, 3)
print(f'data:\r\n{data}')
data1 = torch.zeros_like(data)
print(f'data1:\r\n{data1}')# - torch.full 和 torch.full_like 创建全为指定值张量
data = torch.full([2, 3], 10, dtype=torch.float32)
print(f'data:\r\n{data}')
data1 = torch.full_like(data, 20)
print(f'data1:\r\n{data1}')
print(f'data1.dtype:{data1.dtype}') # float32
2.张量的类型转换
张量的元素类型转换
data.type(torch.DoubleTensor)
data.double()
import torch
# 1. data.type(torch.类型)
print('===============data.type(torch.类型)================')
data = torch.full([2, 3], 10)
print(data.dtype)data = data.type(torch.DoubleTensor)
print(data.dtype)# data = data.type(torch.IntTensor)
# print(data.dtype)
# data = data.type(torch.LongTensor)
# print(data.dtype)# 2. data.double()
print('===============data.double()=================')
data = torch.full([2, 3], 20)
print(data.dtype)data = data.double()
print(data.dtype)# data = data.int()
# print(data.dtype)
张量的类型转换
- 张量转换为
Numpy
数组的方法
-
使用
Tensor.numpy
函数可以将张量转换为ndarray
数组,但是共享内存,可以使用 copy 函数避免共享。# 1. 张量转换为Numpy数组的方法 # - 使用 Tensor.numpy 函数可以将张量转换为 ndarray 数组,但是共享内存,可以使用 copy 函数避免共享. print('=' * 30 + '使用 Tensor.numpy但不进行copy' + '=' * 30) data_tensor = torch.tensor([2, 3, 4]) data_numpy = data_tensor.numpy() print(type(data_tensor)) print(type(data_numpy))data_numpy[0] = 100 print(data_tensor) print(f'ndarray:{data_numpy}')print('=' * 30 + '使用 Tensor.numpy并进行copy' + '=' * 30) data_tensor = torch.tensor([2, 3, 4]) data_numpy = data_tensor.numpy().copy() print(type(data_tensor)) print(type(data_numpy))data_numpy[0] = 100 print(data_tensor) print(f'ndarray:{data_numpy}')
Numpy
数组转换为张量的方法
-
使用
from_numpy
可以将ndarray
数组转换为Tensor
,默认共享内存,使用copy
函数避免共享。 -
使用
torch.tensor
可以将ndarray
数组转换为Tensor
,默认不共享内存。# 2. Numpy数组转换为张量的方法 """ 将numpy数组转换为张量2.1 from_numpy 默认共享内存,使用 copy 函数避免共享。2.2 torch.tensor(ndarray) 默认不共享内存。 """ # - 2.1 使用 from_numpy:会共享内存,可以使用 copy 函数避免共享。 print('=' * 30 + '使用from_numpy但不进行copy' + '=' * 30) data_numpy = np.array([2, 3, 4]) data_tensor = torch.from_numpy(data_numpy) data_tensor[0] = 100 print(data_tensor) print(f'ndarray:{data_numpy}')print('=' * 30 + '使用from_numpy且进行copy' + '=' * 30) data_numpy = np.array([2, 3, 4]) data_tensor = torch.from_numpy(data_numpy.copy()) data_tensor[0] = 100 print(data_tensor) print(f'ndarray:{data_numpy}')# - 2.2 使用 torch.tensor(ndarray) 默认不共享内存。 data_numpy = np.array([2, 3, 4]) data_tensor = torch.tensor(data_numpy)data_tensor[0] = 100 print(data_tensor) print(f'ndarray:{data_numpy}')
- 标量张量和数字转换方法
- 对于只有一个元素的张量,使用item()函数将该值从张量中提取出来
官方文档解释: Returns the value of this tensor as a standard Python number.
This only works for tensors with one element.
# 3. 标量张量和数字转换方法
# - 对于只有一个元素的张量,使用item()函数将该值从张量中提取出来
data_tensor = torch.tensor([30, ])
print(data_tensor.item())data_tensor = torch.tensor(30)
print(data_tensor.item())
3.张量数值计算
- 张量基本运算
-
不修改原数据
- add、sub、mul、div、neg
-
修改源数据
- add_、sub_、mul_、div_、neg_(带下划线的版本会修改原数据)
# 1.张量基本运算 print('=' * 30 + '基本运算' + '=' * 30) data = torch.randint(0, 10, [2, 3]) print(f'原数据data:\r\n{data}')# 1.1 不修改原数据 print('=' * 10 + 'add' + '=' * 10) new_data = data.add(10) print(f'new_data:\r\n{new_data}') print(f'data:\r\n{data}')# 1.2 直接修改原数据 print('=' * 10 + 'add_' + '=' * 10) data.add_(10) print(f'data:\r\n{data}')# print(data.sub(10)) # print(data.mul(10)) # print(data.div(10)) # print(data.neg())
-
张量点乘运算
-
点乘指(Hadamard积)的是两个 同维[同型]矩阵 对应位置的元素相乘,使用mul 和运算符 * 实现。
# 2. 张量点乘运算 print('=' * 30 + '张量点乘运算' + '=' * 30) A = torch.tensor([[1, 2], [3, 4]]) B = torch.tensor([[5, 6], [7, 8]])# - 2.1 使用 mul(A,B) print('=' * 10 + 'mul 点乘' + '=' * 10) res = torch.mul(A, B) print(f'点乘后的结果:{res}')# - 2.2 使用 * 运算符 print('=' * 10 + '* 点乘' + '=' * 10) res = A * B print(f'点乘后的结果:{res}')
-
-
张量矩阵乘法运算
矩阵乘法运算要求第一个矩阵 shape: (n, m),第二个矩阵 shape: (m, p), 两个矩阵点积运算 shape 为: (n, p)。
- 1.运算符 @ 用于进行两个矩阵的乘积运算
- 2.torch.matmul 对进行乘积运算的两矩阵形状没有限定.对数输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则
# 3. 张量矩阵乘法运算
print('=' * 30 + '张量矩阵乘法运算' + '=' * 30)
A = torch.tensor([[1, 2], [3, 4], [5, 6]])
B = torch.tensor([[5, 6], [7, 8]])# 3.1 使用 matmul(A,B)
# - torch.matmul 对进行乘积运算的两矩阵形状没有限定.对数输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则
print(f'matmul(A,B) ={torch.matmul(A, B)}')# 3.2 使用@ 运算符
print(f'A @ B = {A @ B}')
4.张量运算函数
"""
- 均值
- 平方根
- 求和
- 指数计算
- 对数计算
.......
"""
import torchdata = torch.randint(0, 10, [2, 3], dtype=torch.float64)
print(data)# 1.均值
# 注意!! tensor必须为 float 或者 Double类型
print('=' * 10 + 'mean' + '=' * 10)
print(data.mean())
print(data.mean(dim=0)) # 按列求均值
print(data.mean(dim=1)) # 按行求均值# 2.求和
print('=' * 10 + 'sum' + '=' * 10)
print(data.sum())
print(data.sum(dim=0))
print(data.sum(dim=1))# 3.计算平方
print('=' * 10 + 'pow' + '=' * 10)
print(torch.pow(data, 2))
print(data.pow(2))# 4.计算平方根
print('=' * 10 + 'sqrt' + '=' * 10)
print(data.sqrt())
print(torch.sqrt(data))# 5.指数计算 e^n 次方
print('=' * 10 + 'exp' + '=' * 10)
print(data.exp())
print(torch.exp(data))# 6.对数计算 :以 e 为底数
print('=' * 10 + 'log' + '=' * 10)
print(data.log())
print(torch.log(data))
print(data.log2())
print(data.log10())
5.张量索引操作
-
简单行列索引的使用
格式:data[row,col]
代码
data = torch.randint(0, 10, [4, 5]) print('data->\r\n', data)# 1. 简单行列索引的使用 print('=' * 20, '简单行列索引', '=' * 20) print(f'data[0, 0] -> {data[0, 0]}') print(f'data[:,0] -> {data[:, 0]}')
-
列表索引的使用
格式:rows = [a,b,...]cols = [c,d...]访问:data[rows,cols] 含义:访问 [a,c] | [b,d]....的值
代码:
data = torch.randint(0, 10, [4, 5]) print('data->\r\n', data)# 2. 列表索引的使用 print('=' * 20, '列表索引', '=' * 20) # 2.1 返回 (0, 2)、(1, 3) 两个位置的元素 rows = [0, 1] cols = [2, 3] print(f'data[rows,cols] ->', data[rows, cols]) # 2.2 返回行索引为 0 的第 1、2、3 列的值 print(f'data[[0],[1,2]] ->', data[[0], [1, 2]])# 2.3 range()方式访问元素:返回 (0, 1) 和 (1, 2) 两个位置的元素 print(f'data[rows,cols] ->', data[range(2), range(1, 3)])# 2.4 返回行索引为 0 和 1 的第 1、2、3 列的值 print(f'data[[[0], [1]], [1, 2, 3]] ->', data[[[0], [1]], [1, 2, 3]])# 2.5 返回行索引为 0、1、2 的第 0、1、2 列的值 和 行索引为 1、2、3 的第 1、2、3 列的值 print(f'data[[[0, 1, 2], [1, 2, 3]], [[0, 1, 2], [1, 2, 3]]] ->', data[[[0, 1, 2], [1, 2, 3]], [[0, 1, 2], [1, 2, 3]]])# print('data[[[0],[1,2,3]], [0,1,2]] ->',{data[0, 0]}) # 报错, 因为索引的维度不匹配
-
范围索引的使用
- 和
Numpy
大致相同,但不 支持反向索引
data = torch.randint(0, 10, [4, 5]) print('data->\r\n', data)# 3. 范围索引的使用 print('=' * 20, '范围索引', '=' * 20) # 3.1 获取前三行前两列元素的值 print('data[:3,:2]->', data[:3, :2])# 3.2 获取后两行后两列元素的值 print('data[-2:,-2:]->', data[-2:, -2:])# print('data[3:1:-1,-2:]->', data[3:1:-1, -2:]) # 报错,tensor不支持反向切片
- 和
-
布尔索引的使用
- 和`Numpy`,`Pandas`大致相同
# 4. 布尔索引的使用 print('=' * 20, '布尔索引', '=' * 20) # 4.0 理解布尔索引的原理 bool_index = [True, False, False, True, False] """ 注意它取元素时的方式!!!!第一行中满足布尔索引的拿出来,当作一行第二行中满足布尔索引的拿出来,当作一行以此类推 """ print('data[:,bool_index] ->\r\n', data[:, bool_index])# 4.1 获取第三行大于 5的元素 print(data[data[:, 2] > 5])# 4.2 获取第二行大于 5的 列 print('data[:,data[1]>5] ->\r\n', data[:, data[1] > 5])
-
多维索引的使用
- 和
Numpy
,Pandas
大致相同
- 和
data = torch.randint(0, 10, [4, 5])
print('data->\r\n', data)# 5. 多维索引的使用
print('=' * 20, '多维索引', '=' * 20)
data = torch.randint(0, 10, [3, 4, 5])
print('data->\r\n', data)
# 5.1 获取第一维元素
print(data[0, :, :])
# 5.2 获取第二维元素
print(data[:, 0, :])
# 5.3 获取第三维元素 # 注意它取元素的方式!!!
print(data[:, :, 0])
6.张量形状操作
0.形状信息获取
使用 shape 属性或者 size 方法都可以获得张量的形状
data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 1. 使用 shape 属性或者 size 方法都可以获得张量的形状
print('使用 shape 属性或者 size 方法都可以获得张量的形状')
print(data.shape, data.shape[0], data.shape[1])
print(data.size(), data.size(0), data.size(1))
print()
1.reshape方式修改形状
- reshape()
reshape 函数可以在保证张量数据不变的前提下改变数据的维度,将其转换成指定的形状
转换顺序:左右上下
data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 2. 使用 reshape() 修改张量的形状
print('使用 reshape() 修改张量的形状')
reshape_data = data.reshape(1, data.shape[0] * data.shape[1])
print(f'reshape_data:{reshape_data}')
print(f'reshape_data:{data.reshape(1, -1)}')
print()
-
升维与降维
-
squeeze()
-
unsqueeze()
- squeeze函数 删除形状为 1 的维度(降维) - unsqueeze函数 添加形状为1的维度(升维)
unsqueeze(dim=i):在索引为i的位置添加一个形状为1的维度
data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 3. squeeze()和unsqueeze()函数 print('squeeze()和unsqueeze()函数') mydata1 = torch.tensor([1, 2, 3, 4, 5, 6]) print('mydata1->', mydata1.shape, mydata1) # torch.Size([6])mydata2 = mydata1.unsqueeze(dim=0) print('在0维度上 扩展维度:', mydata2, mydata2.shape) # torch.Size([1, 6])mydata3 = mydata1.unsqueeze(dim=1) print('在1维度上 扩展维度:\r\n', mydata3, mydata3.shape) # torch.Size([6, 1])mydata4 = mydata1.unsqueeze(dim=-1) print('在-1维度上 扩展维度:\r\n', mydata3, mydata3.shape) # torch.Size([6, 1])mydata5 = mydata4.squeeze() print('压缩维度:', mydata5, mydata5.shape) # torch.Size([6]) print()
-
-
修改形状
-
transpose()
-
permute()
transpose 函数可以实现交换张量形状的指定维度, 例如: 一个张量的形状为 (2, 3, 4) 可以通过 transpose 函数把 3 和 4进行交换, 将张量的形状变为 (2, 4, 3) 。
permute 函数可以一次交换更多的维度。data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 4.transpose() 和 permute() print('transpose() 和 permute()') data = torch.tensor(np.random.randint(0, 10, [2, 3, 3])) print(f'data shape:{data.size()}') print(data) # 4.1 交换1 和 2维度 data_transpose = torch.transpose(data, 1, 2) print(f'data_transpose shape:{data_transpose.size()}')# 4.2 将data 的形状修改为 (4, 5, 3), 需要变换多次 data_transpose1 = torch.transpose(data, 0, 1) print(data_transpose1) data_transpose1 = torch.transpose(data_transpose1, 1, 2) print(f'data_transpose1 shape:{data_transpose1.size()}')# 4.3 使用 permute 函数将形状修改为 (4, 5, 3) data_transpose2 = torch.permute(data, (1, 2, 0)) print(f'data_transpose1 shape:{data_transpose2.size()}')
-
view()
view 函数也可以用于修改张量的形状,只能用于存储在整块内存中的张量。
在 PyTorch 中,有些张量是由不同的数据块组成的,它们并没有存储在整块的内存中,view 函数无法对这样的张量进行变形处理.
例如: 一个张量经过了transpose 或者 permute 函数的处理之后,就无法使用 view 函数进行形状操作。 -
contiguous()
若要使用view函数, 需要使用contiguous() 变成连续以后再使用view函数
is_contiguous() 判断是否 连续存储
-
data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 5.view()和contiguous()函数"""
1. 一个张量经过了 transpose 或者 permute 函数的处理之后,就无法使用view 函数进行形状操作若要使用view函数, 需要使用contiguous() 变成连续以后再使用view函数
2. 判断张量是否使用整块内存 is_contiguous
"""
print('view()和is_contiguous()函数')
data = torch.tensor([[10, 20, 30], [40, 50, 60]])
print('data--->', data, data.shape)# 5.1 判断是否使用整块内存
print(data.is_contiguous()) # True# 5.2 view
data_view = data.view(3, 2)
print('data_view ->', data_view, data_view.shape)# 5.3 判断是否使用整块内存
print('data_view.is_contiguous->', data_view.is_contiguous())
print()# 5.4 使用 transpose 函数修改形状
print('view()和contiguous()函数')
data_transpose = data.transpose(0, 1)
print('data_transpose->', data_transpose, data_transpose.shape)
print('data_transpose.is_contiguous->', data_transpose.is_contiguous())
print(data_transpose.contiguous().is_contiguous())
data_view = data_transpose.contiguous().view(2, 3)
print('data_view->', data_view.shape, data_view)
print('')
7.张量拼接操作
张量拼接(Concatenation)是将多个张量按指定的维度连接起来的操作。
-
torch.cat()
-
torch.cat 是按指定维度将多个张量连接起来,拼接后的维度大小会变化,但总维数保持不变。
-
使用时,所有张量在指定的拼接维度上必须形状一致。
# 1. torch.cat() print('================cat 方式拼接=====================') data1 = torch.randint(0, 10, [1, 2, 3]) data2 = torch.randint(0, 10, [1, 2, 3]) print(f'data1:{data1}') print(f'data2:{data2}') print() # 1.1 按 0维拼接 new_data = torch.cat([data1, data2], dim=0) print('按 0维 拼接->', new_data, new_data.size())# 1.2 按 1维拼接 new_data = torch.cat([data1, data2], dim=1) print('按 1维 拼接->', new_data, new_data.size())# 1.3 按 2维拼接 new_data = torch.cat([data1, data2], dim=2) print('按 2维 拼接->', new_data, new_data.size()) print()
-
-
torch.stack() [了解]
-
torch.stack 是在新维度上将多个张量连接起来,拼接后的总维数会增加 1。
-
使用时,所有张量的形状必须完全一致。
# 2.stack print('================stack 方式拼接=====================') data1 = torch.randint(0, 10, [1, 2, 3]) data2 = torch.randint(0, 10, [1, 2, 3]) print(f'data1:{data1}') print(f'data2:{data2}')# 2.1 按 0维连接 new_data = torch.stack([data1, data2], dim=0) print('按 0维 连接->', new_data, new_data.size())# 2.2 按 1维连接 new_data = torch.stack([data1, data2], dim=1) print('按 1维 连接->', new_data, new_data.size())# 2.3 按 2维连接 new_data = torch.stack([data1, data2], dim=2) print('按 2维 连接->', new_data, new_data.size()) print()
-
torch.cat
与 torch.stack
的区别
q特性 | torch.cat | torch.stack |
---|---|---|
总维数变化 | 不增加维数 | 增加 1 个维数 |
形状要求 | 指定维度一致 | 所有维度必须完全一致 |
典型应用 | 沿某个轴扩展数据 | 创建新的批量或时间步维度 |
8.自动微分模块
- 反向传播算法```properties在该算法中,参数(模型权重)会根据损失函数关于对应参数的梯度进行调整。为了计算这些梯度,PyTorch内置了名为 torch.autograd 的微分引擎。它支持任意计算图的自动梯度计算, 使用 backward 方法、grad 属性来实现梯度的计算和访问.```
示例:
# 1. 当X为标量时梯度的计算
def scaler_grad_compute():x = torch.tensor(5)# 目标值: labely = torch.tensor(0.)# 设置要更新的权重和偏置的初始值w = torch.tensor(1, requires_grad=True, dtype=torch.float32)b = torch.tensor(3, requires_grad=True, dtype=torch.float32)# 设置网络的输出值z = w * x + b # 矩阵乘法?# 设置损失函数,并进行损失的计算loss = torch.nn.MSELoss()loss = loss(z, y)# 自动微分loss.backward()# 打印 w,b 变量的梯度# backward 函数计算的梯度值会存储在张量的 grad 变量中print(f'w->{w.grad}')print(f'b->{b.grad}')
# 2.非标量下时梯度的计算
def grad_compute():# 输入张量(2,5)x = torch.ones(2, 5)# 输出张量(2,3)y = torch.zeros(2, 3)# 设置要更新的权重和偏置的初始值w = torch.randn(5, 3, requires_grad=True)b = torch.randn(3, requires_grad=True)# 设置神经网络的输出值z = torch.matmul(x, w) + b# 设置损失函数,并进行损失的计算loss = torch.nn.MSELoss()loss = loss(z, y) # 底层实现了__call__()方法print(y)# 自动微分loss.backward()# 打印 w,b 变量的梯度# backward 函数计算的梯度值会存储在张量的 grad 变量中print("W的梯度:", w.grad)print("b的梯度", b.grad)
矩阵乘法?
# 设置损失函数,并进行损失的计算
loss = torch.nn.MSELoss()
loss = loss(z, y)# 自动微分
loss.backward()
# 打印 w,b 变量的梯度
# backward 函数计算的梯度值会存储在张量的 grad 变量中
print(f'w->{w.grad}')
print(f'b->{b.grad}')
2.非标量下时梯度的计算
def grad_compute():
# 输入张量(2,5)
x = torch.ones(2, 5)
# 输出张量(2,3)
y = torch.zeros(2, 3)
# 设置要更新的权重和偏置的初始值
w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)
# 设置神经网络的输出值
z = torch.matmul(x, w) + b
# 设置损失函数,并进行损失的计算
loss = torch.nn.MSELoss()
loss = loss(z, y) # 底层实现了__call__()方法
print(y)
# 自动微分
loss.backward()
# 打印 w,b 变量的梯度
# backward 函数计算的梯度值会存储在张量的 grad 变量中
print("W的梯度:", w.grad)
print("b的梯度", b.grad)
相关文章:
0_Pytorch中的张量操作
[引言]张量的概念 1.基本概念 张量是一个通用的多维数组,可以表示标量(0 维)、向量(1 维)、矩阵(2 维)以及更高维度的数据。张量是 PyTorch 中的核心数据结构,用于表示和操作数据。…...
Java面试43-常见的限流算法有哪些?
限流算法是一种系统保护策略,主要是避免在流量高峰导致系统被压垮,造成系统不可用的问题。 常见的限流算法有五种: 计数器限流,一般用在单一维度的访问频率限制上,比如短信验证码每隔60s只能发送一次,或者…...
牛客网:树的高度 ← 根节点为 0 号节点
【题目来源】 https://www.nowcoder.com/questionTerminal/4faa2d4849fa4627aa6d32a2e50b5b25 【题目描述】 现在有一棵合法的二叉树,树的节点都是用数字表示,现在给定这棵树上所有的父子关系,求这棵树的高度。 【输入格式】 输入的第一行表…...
Linux:进程程序替换execl
目录 引言 1.单进程版程序替换 2.程序替换原理 3.6种替换函数介绍 3.1 函数返回值 3.2 命名理解 3.3 环境变量参数 引言 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),我们所创建的所有的子进程,执行的代码&#x…...
⑩数据中心M-LAG 实战
一、配置指导自己去看今天操作的是M-LAG 基础实验 二、配置代码信息回顾 ### 1、配置 M-LAG 系统 MAC 地址<H3C>system-view[H3C]m-lag system-mac ?H-H-H MAC address2a7a-53ee-0100 Bridge MAC address[H3C]m-lag system-mac### 2、配置 M-LAG 系统编号…...
delphi idtcpserver 搭建tcp ,ssl协议服务端
如果想用indy idtcpserver实现tcp ssl,那么正是你需要的 首先生成证书: 2、windows生成pem证书 - 站着说话不腰疼 - 博客园 有证书后 idtcpserver 用的三个证书, IdServerIOHandlerSSLOpenSSL1.SSLOptions.CertFile = ca.crt IdServerIOHandlerSSLOpenSSL1.SSLOptions.…...
如何实现外观模式?
一、模式理解(用快递驿站比喻) 想象你网购了5件商品,分别来自不同快递公司。 外观模式就像小区门口的快递驿站,你不需要知道中通怎么分拣、顺丰怎么运输,只要到驿站报取件码就能拿到所有包裹。 在前端开发中…...
深入解析 Linux 文件系统权限:从基础到高级实践
引言 在 Linux 系统中,文件系统权限是保障数据安全和多用户协作的核心机制。想象这样一个场景: 你的服务器上有多个团队共享项目文件 财务数据必须严格保密,仅允许指定人员访问 开发团队需要共同编辑代码,但禁止随意删除他人文…...
GZ036区块链卷一 EtherStore合约漏洞详解
题目 pragma solidity >0.8.3;contract EtherStore {mapping(address > uint) public balances;function deposit() public payable {balances[msg.sender] msg.value;emit Balance(balances[msg.sender]);}function withdraw() public {uint bal balances[msg.sender…...
医药流通行业批发公司IT运维转型:Prometheus+Grafana监控Spring Boot 3应用实践
一、引言:医药流通行业IT运维挑战与工具换代需求 在医药流通行业批发领域,业务的核心在于供应链的高效运转、订单处理的精准及时以及库存管理的动态平衡。随着互联网医疗的兴起和电商平台的渗透,传统医药批发企业正加速向数字化、智能化转型…...
编程助手fitten code使用说明(超详细)(vscode)
这两年 AI 发展迅猛,作为开发人员,我们总是追求更快、更高效的工作方式,AI 的出现可以说改变了很多人的编程方式。 AI 对我们来说就是一个可靠的编程助手,给我们提供了实时的建议和解决方,无论是快速修复错误、提升代…...
金融大模型
FinGPT 数据集:https://github.com/AI4Finance-Foundation/FinGPT/tree/master/fingpt/FinGPT-v3 FinGPT v3 系列是在新闻和微博情绪分析数据集上使用 LoRA 方法进行微调的LLM,在大多数金融情绪分析数据集上取得了最佳分数。 FinGPT v3.1 使用 chatgl…...
【Pandas】pandas DataFrame infer_objects
Pandas2.2 DataFrame Conversion 方法描述DataFrame.astype(dtype[, copy, errors])用于将 DataFrame 中的数据转换为指定的数据类型DataFrame.convert_dtypes([infer_objects, …])用于将 DataFrame 中的数据类型转换为更合适的类型DataFrame.infer_objects([copy])用于尝试…...
011_异常、泛型和集合框架
异常、泛型和集合框架 异常Java的异常体系异常的作用 自定义异常异常的处理方案异常的两种处理方式 泛型泛型类泛型接口泛型方法、通配符和上下限泛型支持的类型 集合框架集合体系结构Collection Collection集合Collection的遍历方式认识并发修改异常问题解决并发修改异常问题的…...
QTSql全解析:从连接到查询的数据库集成指南
概览 与数据库的有效集成是确保数据管理效率和应用性能的关键,Qt框架就提供了强大的QtSql模块,使得开发者能够轻松地进行数据库操作,包括连接、查询执行以及结果处理等 一、引入QtSql模块 首先,需要在项目中引入QtSql模块&…...
docker快捷打包脚本(ai版)
直接进入主题: 用这个脚本前提是你本地可以拉镜像仓库的镜像,并且在 本地有了,然后将所有的镜像tag写在一个文件中,和下面docker_tags.txt 对应,文件叫什么,脚本里对应改什么,给小白说的 #!/bi…...
分布式防护节点秒级切换:实战配置与自动化运维
摘要:针对DDoS攻击导致节点瘫痪的问题,本文基于群联AI云防护的智能调度系统,详解如何实现节点健康检查、秒级切换与自动化容灾,并提供Ansible部署脚本。 一、分布式节点的核心价值 资源分散:攻击者难以同时击溃所有节…...
TBE(TVM的扩展)
算子 张量 一个张量只有一种数据类型 在内存中只能线性存储,最终形成一个长的一维数组 晟腾AI的数据格式 AIPP是对我们常见的数据格式转化成AI core支持的数据格式 广播机制 TVM TBE的第一种开发方式:DSL TBE的第二种开发方式:TVM TBE的第…...
Jenkins配置的JDK,Maven和Git
1. 前置 在配置前,我们需要先把JDK,Maven和Git安装到Jenkins的服务器上。 (1)需要进入容器内部,执行命令:docker exec -u root -it 容器号/容器名称(2选1) bash -- 容器名称 dock…...
核心案例 | 湖南汽车工程职业大学无人机操控与编队技术实验室
核心案例 | 湖南汽车工程职业大学无人机操控与编队技术实验室 为满足当今无人机行业应用需求,推动无人机技术的教育与实践深度融合,北京卓翼智能科技有限公司旗下品牌飞思实验室与湖南汽车工程职业大学强强联手,共同建设无人机操控与编队技术…...
【阻抗匹配】
自动匹配的实现: 检测反射信号:通过传感器(如定向耦合器)监测反射功率或驻波比(SWR),判断是否失配。控制单元:利用微控制器或专用芯片(如FPGA)分析检测数据&a…...
micro常用快捷键
micro常用快捷键 以下是 micro 编辑器 的常用快捷键整理,按功能分类清晰,方便快速查阅: 1. 基础操作 快捷键功能Ctrl S保存文件Ctrl Q退出编辑器Ctrl O打开文件Ctrl E打开命令栏(输入命令)Ctr…...
DNS域名解析服务
目录 DNS系统 DNS系统的作用 DNS系统的类型(服务器分类) 1. 递归解析器(Recursive Resolver) 2. 根域名服务器(Root Name Server) 3. 顶级域服务器(TLD Name Server)…...
Linux的目录结构
倒根树状结构 【注意】 / 表示根目录,相当于Windows的C盘 进入跟目录命令: cd / /bin:存放的系统命令或二进制文件,如:cd ls cp等 /sbin /usr/bin /dev:存放的设备节点文件 , 驱动文件 /…...
【Python】Python 100题 分类入门练习题 - 新手友好
Python 100题 分类入门练习题 - 新手友好篇 - 整合篇 一、数学问题题目1:组合数字题目2:利润计算题目3:完全平方数题目4:日期天数计算题目11:兔子繁殖问题题目18:数列求和题目19:完数判断题目21…...
Three.js 系列专题 7:性能优化与最佳实践
内容概述 随着 3D 场景复杂度的增加,性能优化变得至关重要。Three.js 项目可能因几何体数量、纹理大小或渲染设置而变慢。本专题将介绍减少 draw call、优化纹理和使用调试工具的最佳实践。 学习目标 学会减少 draw call 和几何体复杂度。掌握纹理压缩与内存管理。使用 Stat…...
特权FPGA之Johnson移位
完整代码: module johnson(clk,rst_n,led,sw1_n,sw2_n,sw3_n);input clk; //时钟信号,50MHz input rst_n; //复位信号,低电平有效 output[3:0] led; //LED控制,1--灭…...
聊聊 CSS
先补充一些概念 C/S(客户端/服务器):要下载到本地才能用 需要安装、偶尔更新、不跨平台 B/S(浏览器/服务器):在浏览器输入网址就可以使用 无需安装、无需更新、可跨平台 [!NOTE] B/S 架构优点如此之多&am…...
域名系统DNS
一 概述 域名系统DNS是互联网使用的命名系统,用来把便于人们使用的机器名称转换为IP地址,比如我们熟知的www.baidu.com,www.sina.com,这些域名的背后都对应着一个又一个的IP地址。由域名转换为IP的过程我们称为解析,解析的过程大…...
大模型ui设计SVG输出
你是一位资深 SVG 绘画设计师,现需根据以下产品需求创建SVG方案: 产品需求 约拍app 画板尺寸: 宽度:375px(基于提供的HTML移动设计)高度:812px(iPhone X/XS 尺寸) 配…...
利用securecrt的tftp服务器功能传递文件
日常经常能用到需要调测一些openwrt设备,要互相拷贝文件,没有开启ftp功能时,这时可以用到crt的tftp内置服务器功能,利用tftp功能传递文件。 配置方法: 打开设置→全局配置→终端→tftp配置设置c上内置tftp服务器时&a…...
基于STM32、HAL库的IP2736U快充协议芯片简介及驱动程序设计
一、简介: IP2736U是一款高性能的USB Type-C和Power Delivery(PD)控制器芯片,支持最新的USB PD 3.0规范。它具有以下特点: 支持USB Type-C和PD 3.0协议 内置MCU,可编程配置 支持多种供电角色(Source/Sink/DRP) 支持PPS可编程电源 支持多种快充协议(PD/QC/AFC/FCP/SCP等) I…...
SQL学习笔记七
第九章用正则表达式进行搜索 9.1正则表达式介绍 正则表达式是用来匹配文本的特殊的串(字符集合)。如果你想从一个文本文件中提取电话号码,可以使用正则表达式。如果你需要查找名字中间有数字的所有文件,可以 使用一个正则表达式…...
MicroPython 开发ESP32应用教程 之 Timer、GPIO中断
随着我们课程的递进,大家会发现,我们之前课程中的例子,虽然功能都能实现,但总觉得体验感不够好,比如按键控制GRB灯珠的时候,很容易出现按键后,灯珠没有反应,还有蓝牙发送指令控制灯珠…...
【区块链安全 | 第三十七篇】合约审计之获取私有数据(一)
文章目录 私有数据访问私有数据实例存储槽Solidity 中的数据存储方式1. storage(持久化存储)定长数组变长数组 2. memory(临时内存)3. calldata 可见性关键字私有数据存储风险安全措施 私有数据 私有数据(Private Dat…...
20250408在荣品的PRO-RK3566开发板使用Rockchip原厂的buildroot系统时拿掉经常出现的list-iodomain.sh警告信息
rootrk3566-buildroot:/usr/bin# vi list-iodomain.sh rootrk3566-buildroot:/usr/bin# sync 【最后】 #chk_env #get_chip_id $1 #echo_msg "Get CHIP ID: $CHIP_ID" #get_iodomain_val 20250408在荣品的PRO-RK3566开发板使用Rockchip原厂的buildroot系统时拿掉经常…...
上下拉电阻详解
一、基本定义 上拉电阻:连接信号线与电源(VCC),确保信号在无驱动时保持高电平。 下拉电阻:连接信号线与地(GND),确保信号在无驱动时保持低电平。 二、核心作用 电平稳定 防止悬空引…...
特权FPGA之数码管
case语句的用法: 计数器不断的计数,每一个num对应数码管一种数据的输出。实例通俗易懂,一目了然。 timescale 1ns / 1ps// Company: // Engineer: // // Create Date: // Design Name: // Module Name: // Project Name: //…...
PyTorch 学习笔记
环境:python3.8 PyTorch2.4.1cpu PyCharm 参考链接: 快速入门 — PyTorch 教程 2.6.0cu124 文档 PyTorch 文档 — PyTorch 2.4 文档 快速入门 导入库 import torch from torch import nn from torch.utils.data import DataLoader from torchvision …...
MCP基础学习计划:从MCP入门到项目构建的全面指南
文章简介 ai生成的学计划有的连接是无效的,想着边学习边找输出文章,后续会继续链接更新 在人工智能和大语言模型(LLM)的快速发展下,掌握Model Context Protocol(MCP)成为提升AI应用能力的关键。…...
NO.77十六届蓝桥杯备战|数据结构-单调队列|质量检测(C++)
什么是单调队列? 单调队列,顾名思义,就是存储的元素要么单调递增要么单调递减的队列。注意,这⾥的队列和普通的队列不⼀样,是⼀个双端队列。单调队列解决的问题 ⼀般⽤于解决滑动窗⼝内最⼤值最⼩值问题,以…...
【有啥问啥】深入浅出讲解 Teacher Forcing 技术
深入浅出讲解 Teacher Forcing 技术 在序列生成任务(例如机器翻译、文本摘要、图像字幕生成等)中,循环神经网络(RNN)以及基于 Transformer 的模型通常采用自回归(autoregressive)的方式生成输出…...
redis数据迁移之通过redis-dump镜像
这里写目录标题 一、redis-dump 镜像打包1.1 安装windows docker1.2 idea项目创建1.3 idea镜像打包 二、redis数据迁移2.1 数据导出2.2 数据导入 一、redis-dump 镜像打包 没有找到可用的redis-dump镜像,需要自己打包一下,这里我是在idea直接打包的 1.…...
Redis哨兵模式下执行sentinel failover mymaster命令可能导致什么风险,如何避免
在 Redis 哨兵模式下执行 SENTINEL FAILOVER mymaster 命令会强制触发主节点切换(手动故障转移),虽然这是合法的管理操作,但可能带来以下风险及规避方法: 一、潜在风险 数据丢失风险 原因:主节点可能在故障…...
软考案例分析实例答题模板
案例分析(全部为主观问答题, 总 5 大题, 第一题必选, 剩下 4 选 2, 每题 25 分, 共75分) 第一题: 案例分析——某企业信息架构优化项目 案例材料: 某企业是一家从事电子商务的大型企业, 随着业务规模的不断扩大, 现有的信息架 构已无法满足企业快速发展的需求。 企业…...
Docker+Jenkins+Gitee自动化项目部署
前置条件 docker安装成功 按照下面配置加速 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://register.librax.org"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker一、…...
olib开源图书
8.olib开源图书 该软件作者已开源,开源地址:开源地址:https://github.com/shiyi-0x7f/o-lib 点击该软件,使用管理员权限打开,进入界面可以搜索图书并下载pdf文件。 蓝奏云下载:https://wwph.lanzout.com/…...
react: styled-components实现原理 标签模版
styled-components是针对react中一个前端广泛使用的css-in-js样式库B站 利用标签模版 利用ES6中的 标签模版文档标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数。 let a 5; let b 10;…...
AI大模型从0到1记录学习 day15
14.3.5 互斥锁 1)线程安全问题 线程之间共享数据会存在线程安全的问题。 比如下面这段代码,3个线程,每个线程都将g_num 1 十次: import time import threading def func(): global g_num for _ in range(10): tmp g_num 1 # ti…...
macbook pro查询并修改命令提示符的格式
环境 MacBook Pro 描述 我的命令提示符总是: # 前面总是多了(base) (base) yutaoyutaodeMacBook-Pro ~ % vim .zshrc (base) yutaoyutaodeMacBook-Pro ~ % source .zshrc # 期望改成下面这样: yutaoyutaodeMacBook-Pro ~ % 找…...