一、张量的索引与切片
张量的索引方法基本与Numpy相同
my_data1 = torch.tensor([0,7,8,3])
my_data1[1] = 7
my_data1[2] = 8
my_data2 = torch.arange(0,6).reshape([2,3])
my_data2 :
tensor([[0, 1, 2],
[3, 4, 5]])
print(my_data2[1,1]): 4
print(my_data2[1]): [3,4,5]
print(my_data2([:,1]) [1,4]
张量的切片: [start:end:step],从start 开始,以step为步长开始读取张量,到end终止(不包含end)。 start、end、step均可以缺省,start缺省为0,end缺省,为该维度最后一个元素,step缺省为1。
start可以为负数,step不能为负数
my_data3 = torch.arange(0,27).reshape([3,9])
my_data3[-2:] :tensor([[ 9, 10, 11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24, 25, 26]])
张量的切片索引
例: 张量为 2* 3 * 2 * 2
my_data5 = torch.arange(0,24).view([2,3,2,2])
#读取 读取两个第一维的,第二维数为0、1,第三维序号为1的像素。
print(my_data5[:,0:2,1,:])
tensor([[[ 2, 3],
[ 6, 7],
[10, 11]],
[[14, 15],
[18, 19],
[22, 23]]])
二、张量的维度压缩、扩展
torch.squeeze(input,dim): 如果没有指定dim ,将张量中所有值为1的维度移除。如果指定dim,
则input 只会在给定维度挤压。
x = torch.zeros(2,1,2,1,2) # 维度序号从左至右从0算起,依次为0,1,2,3,4
x.size() : (2L, 1L, 2L, 1L, 2L)
y = torch.squeeze(x) # 没指定维度,将张量中所有值为1的维度移除
y.size() : (2L, 2L, 2L)
y = torch.squeeze(x, 0) # 指定0维,将0维有值为1的维度移除
y.size() : (2L, 1L, 2L, 1L, 2L)
y = torch.squeeze(x, 1) # 指定1维,将0维有值为1的维度移除
y.size() :(2L, 2L, 1L, 2L)
torch.unsqueeze(input,dim):在第dim维上插入值为1的维度 ,
my_data1 = torch.tensor([1,2,3,4])
my_data2 = torch.unsqueeze(my_data1,0)---> [[1,2,3,4]]
my_data2 = torch.unsqueeze(my_data1,1) --->[[1],[2],[3],[4]]
三、张量的自动求导
Pytorch支持自动求导,用户定义好操作的前向计算和反向梯度计算规则(可自定义),Pytorch能够自动调用计算图算子,完成整个网络的自动求导。
使用requires_grad参数来设置张量是否需要自动求导,默认为false。
对于一个计算操作来说,如果所有输入中有一个输入需要求导,则输出就需要求导,如果所有输入都不需要求导,则输出也不需要求导。
在PyTorch中,用户可以通过自定义torch.autograd.Function的子类来定义反向梯度计算规则。
import torch
class MyCustomFunction(torch.autograd.Function):
@staticmethod
def forward(ctx, input):
# 前向传播:计算输出
ctx.save_for_backward(input) # 保存输入供反向传播使用
output = input.clamp(min=0) # 示例操作(ReLU)
return output
@staticmethod
def backward(ctx, grad_output):
# 反向传播:计算梯度
input, = ctx.saved_tensors # 获取前向传播保存的张量
grad_input = grad_output.clone()
grad_input[input < 0] = 0 # ReLU的导数规则
return grad_input
说明:
forward(ctx, *args):
ctx:上下文对象,用于保存张量(save_for_backward)或其他信息(mark_non_differentiable)。
返回前向传播的结果。
backward(ctx, grad_output):
grad_output:来自后续层的梯度。
返回对每个输入的梯度(与forward的参数一一对应),非张量输入可返回None。
使用方法:
x = torch.tensor([-1.0, 2.0], requires_grad=True)
y = MyCustomFunction.apply(x) # 使用.apply()触发自定义逻辑
y.sum().backward() # 反向传播
print(x.grad) # 输出梯度: tensor([0., 1.])
四、张量的操作
可以采用torch.operation、tensor.operation、tensor.operation_等实现张量的计算操作。
my_data1 = torch.tensor([1,2,3,4,5])
my_data2 = torch.add(my_data1, 100)
my_data3 = my_data1.add(100)
原位操作:指在存储原张量的内存上直接计算更新张量值,而不是先复制张量再计算更新。其标志是在原操作语句后添加“_”.
原位操作能够节省内存占用,在进行深度学习算法推理时,使用原为操作能够有效减少模型占用的内存。 原位操作会破坏模型的训练过程;如果张量被引用,会对影响引用张量。
五、张量的广播机制
允许形状不相同的张量进行数学运算,而无需显式地复制数据。通过广播机制,可以自动扩展较小形状的张量,使其与较大张量的形状兼容,从而能够执行逐元素操作。
从右到左匹配维度:广播是从最后一个维度(即最右边的维度)开始逐个比较的。
维度匹配规则:
-
如果两个张量在某个维度的大小相同,或者其中一个张量的该维度大小为 1,则视为匹配,可以进行广播。
-
如果维度大小不相同且不为 1,则广播失败,会引发错误。
-
自动扩展:对于维度大小为 1 的张量,广播机制会将其沿着该维度扩展,使其行为上像是与另一个张量具有相同的维度。
import torch
# 创建两个不同形状的张量
a = torch.tensor([[1, 2, 3], [4, 5, 6]]) # 形状 (2, 3)
c = torch.tensor([1, 2, 3]) # 形状 (3,)
# 进行逐元素加法操作,c 会自动广播到与 a 的形状一致,
c----->tensor([[1, 2, 3], [1, 2, 3]])
result = a + b
print(result)
# 输出:
# tensor([[2, 4, 6],
# [5, 7, 9]])
my_data1 = torch.ones(2,3,3)
my_data2 = torch.tensor([[1],[2],[3]])
my_data3 = torch.add(my_data1, my_data2)
my_data3 =
tensor([[[2., 2., 2.],
[3., 3., 3.],
[4., 4., 4.]],
[[2., 2., 2.],
[3., 3., 3.],
[4., 4., 4.]]])
六、 常用计算操作
new_tensor 返回一个新张量
new_zeros/new_ones 返回尺寸与原张量相同,元素值全为0/1的新张量
grad 训练时得到的张量梯度
add/subtract/multiply/divide 加/减/乘/除计算
bitwise_and/bitwise_or/bitw 按位与/或/非操作
ise_not
sin/cos/tanh 正弦/余弦/正切计算
where(condition,x,y) 按条件输出不同张量
to 张量数据类型、设备类型转换
sort 按指定维度将张量元素升序/降序排列
round/ceil/floor 四舍五入/向上取整/向下取整操作
transpose 转置计算
七、计算图
编程框架中使用有向图来描述计算过程。有向图中包含一组节点和边。支持通过多种高级语言来构建计算图。计算图对应了神经网络的结构。
计算图实例:

计算图分 静态图和动态图,两者的区别:
静态图: 先定义整张图,再运行,可以对图进行全局优化,获得更快的运算速度,调试不方便。(错误往往体现在图的结构中,而不是在具体的执行时。开发者可能需要使用特定的工具或命令来查看和分析图的结构,在静态图中,不能像动态图那样逐步执行和检查中间结果,调试起来相对较为复杂)
动态图: 即时运行,网络模型可在运行时修改; 代码编写灵活,可立即获得运行结果,调试方便,优化不方便(图时在运行中动态生成的,图复杂时较难追踪。)
学习资料: http://novel.ict.ac.cn/aics

&spm=1001.2101.3001.5002&articleId=154400781&d=1&t=3&u=4a5fd108ce6842de82e2dc41e5c389c2)
1277

被折叠的 条评论
为什么被折叠?



