tensor基本运算

tensor基本运算


考虑如下代码:

mask_score_f = mask_score[:, 0, :, :].unsqueeze(1) #tensor:(N,2,W,H)  水平集函数 \phi
mask_score_b = mask_score[:, 1, :, :].unsqueeze(1) #tensor:(N,C,W,H)  待分割图像
interior_ = torch.sum(mask_score_f * lst_target, (2, 3)) / torch.sum(mask_score_f, (2, 3)).clamp(min=0.00001) # 内部常值 c_1
exterior_ = torch.sum(mask_score_b * lst_target, (2, 3)) / torch.sum(mask_score_b, (2, 3)).clamp(min=0.00001) # 外部常值 c_2
interior_region_level = torch.pow(lst_target - interior_.unsqueeze(-1).unsqueeze(-1), 2)
exterior_region_level = torch.pow(lst_target - exterior_.unsqueeze(-1).unsqueeze(-1), 2)
region_level_loss = interior_region_level*mask_score_f + exterior_region_level*mask_score_b
level_set_loss = torch.sum(region_level_loss, (1, 2, 3))/lst_target.shape[1]  # 通道平均; 

初次见到它很不清楚含义,经过一下午print各种中间量才知道一些含义。不妨设

mask_score = torch.ones(3,2,4,5)
lst_target = torch.ones(3,3,4,5)

(必须创建tensor才能用unsqueeze函数,否则建立数组后要先转成tensor。)
第一行: mask_score[:, 0, :, :]是取第1维的第0个元素,现在tensor大小为3∗4∗53*4*5345;unsqueeze(1)在第1维前加一个维度,现在tensor大小为3∗1∗4∗53*1*4*53145
第二行: 同上,得tensor大小为3∗1∗4∗53*1*4*53145
第三行: mask_score_f大小为3∗1∗4∗53*1*4*53145,而lst_target大小为3∗3∗4∗53*3*4*53345由于torch的broadcast机制,mask_score_f可以和lst_target相乘,相当于mask_score_f和每一个第一维的let_target都逐元素乘了一遍,进行了3遍。 相乘的结果是大小为3∗3∗4∗53*3*4*53345的张量,然后得interior_是大小为3∗33*333的全1张量。clamp函数在这里是保证最小值的,即tensor里小于0.00001的值全改成0.00001。注意:若mask_score_f大小为3∗2∗4∗53*2*4*53245,即便是仍用2,3维相乘再相加仍会报错(想想也是合理的,如果是3∗1∗4∗53*1*4*53145的话可以把第1维复制三份)。
第四行: 同上,得大小为3∗33*333的全1张量exterior_。
第五行: lst_target大小为3∗3∗4∗53*3*4*53345,interior_大小为3∗33*333。unsqueeze(-1)是在最后一维再拓展一维,作用两次变成3∗3∗1∗13*3*1*13311大小。张量大小不一样不影响,只不过是最后两维分别复制四份和五份再做减法。再例如:a = torch.ones(3,3,2,2) ; b = torch.ones(3,3,1,1) * 2 ; c = b - a。则c为大小为3∗3∗2∗23*3*2*23322的全1张量。pow(a,2)是求a的平方操作(逐分量求,跟矩阵乘法什么的无关)。
第六行: 同上,得大小为3∗3∗4∗53*3*4*53345的张量。
第七行: 张量interior_region_level大小为3∗3∗4∗53*3*4*53345,mask_score_f大小为3∗1∗4∗53*1*4*53145,mask_score_f第1维复制三份,逐分量相乘即可。再例如:a = torch.ones(3,3,2,2) * 2 ; b = torch.ones(3,3,1,1) * 3 ; h= a * b。则h为大小为3∗3∗2∗23*3*2*23322的全6张量。后面同理。
第八行: 现在region_level_loss大小为3∗3∗4∗53*3*4*53345,把1-3维的数字都加起来(即后面三维,因为最前面是第0维)。lst_target.shape[1]表示lst_target第1维大小,它等于3(即3∗3∗4∗53*3*4*53345的第二个3)。这个3代表通道数,所以意义是求通道平均。level_set_loss是一维张量,它仅有的一个维度(即第0维)有3个元素,这个3代表数据量大小N。理解一下的话就是level_set_loss代表每一批数据每一个通道平均水平集loss,也就是把空间上(x,y)逐点的loss相加。
注:如果是矩阵乘法,使用torch.matmul。
总结一下的话就是:如果一个维度只有1个元素,那么它做运算时可以复制,这点比较好,这样重点关注tensor的维度就可以了。
这八行代码结合原文,上午看了一小时看似明白了,实际完全没看明白,下午还是决定一点一点试,因为生成tensor数据比较方便,才算把代码的含义搞清楚。编程真不是一件容易的事情,自己水平有限,还是应该笨鸟先飞,多看多写。

<think>嗯,用户想了解如何使用PyTorch构建模型和进行张量运算。首先,我需要确认用户的基础知识,可能他们已经了解了一些PyTorch的基本概念,比如Tensor,但需要更深入的指导。 首先,我应该从Tensor的基础操作开始,因为这是构建模型的基础。记得用户提供的引用中提到,Tensor类似于NumPy的ndarray,但支持GPU加速。所以需要强调Tensor的创建和基本运算,比如加减乘除、矩阵乘法等。还要提到如何将Tensor移动到GPU上,这点很重要,因为这是PyTorch的优势之一。 接下来,构建模型部分。用户可能需要知道如何使用PyTorch的nn.Module类来定义模型的结构。应该举例说明如何定义一个简单的神经网络,比如全连接层、激活函数的使用,以及前向传播的方法。同时,要提到模型参数的初始化和如何将模型转移到GPU上训练,这部分用户可能不太熟悉,需要详细说明。 然后,损失函数和优化器也是关键部分。需要介绍常见的损失函数,比如交叉熵损失和均方误差,以及优化器如SGD和Adam。用户可能想知道如何将这些组件整合到训练循环中,所以给出一个训练循环的示例代码会很有帮助。 在张量运算的高级操作部分,可能需要包括形状变换、自动微分机制,因为自动微分是PyTorch的核心特性。解释requires_grad和backward()方法的使用,以及如何通过优化器更新参数。这部分内容对于理解模型训练过程至关重要。 还要考虑用户可能遇到的问题,比如张量形状不匹配、梯度清零的必要性,以及设备转移的注意事项。这些常见错误应该在教程中提到,帮助用户避免踩坑。 最后,生成相关问题的时候,要确保问题覆盖用户可能进一步探索的方向,比如模型保存、自定义层、分布式训练等。这些扩展问题可以帮助用户深入学习,满足他们的后续需求。 总之,结构需要清晰,分步骤讲解,结合代码示例和实际应用场景,确保用户能够逐步掌握PyTorch的模型构建和Tensor运算。同时,引用提供的资料中的信息,比如引用[1]和[2]中关于Tensor的创建方式和重要性,来增强回答的可靠性。</think># PyTorch 模型构建与 Tensor 运算教程 ## 一、Tensor 基础操作 PyTorch Tensor 是多维数组的核心数据结构,支持自动微分和 GPU 加速计算[^1]。基础运算包含: ```python import torch # 创建张量 a = torch.tensor([[1,2],[3,4]]) # 2x2 矩阵 b = torch.randn(2,2) # 正态分布随机矩阵 # 基本运算 c = a + b # 逐元素加法 d = torch.matmul(a, b) # 矩阵乘法 e = a * b # 逐元素乘法 # GPU 加速 if torch.cuda.is_available(): a_gpu = a.to('cuda') ``` ## 二、模型构建方法 通过继承`nn.Module`类构建神经网络: ```python import torch.nn as nn class MLP(nn.Module): def __init__(self): super().__init__() self.fc1 = nn.Linear(784, 256) # 输入层到隐藏层 self.relu = nn.ReLU() self.fc2 = nn.Linear(256, 10) # 隐藏层到输出层 def forward(self, x): x = x.view(-1, 784) # 展平输入 x = self.fc1(x) x = self.relu(x) return self.fc2(x) # 初始化模型 model = MLP() print(model) # 显示网络结构 ``` ## 三、损失函数与优化器 常用组合示例: ```python # 分类任务 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 回归任务 mse_loss = nn.MSELoss() sgd_optimizer = torch.optim.SGD(model.parameters(), lr=0.01) ``` ## 四、训练循环示例 ```python for epoch in range(100): # 前向传播 outputs = model(inputs) loss = criterion(outputs, labels) # 反向传播 optimizer.zero_grad() # 梯度清零 loss.backward() # 自动微分 optimizer.step() # 参数更新 ``` ## 五、Tensor 高级操作 1. **形状变换**:`view()`, `reshape()` 2. **自动微分**: ```python x = torch.tensor(2.0, requires_grad=True) y = x**2 + 3*x y.backward() # 自动计算梯度 print(x.grad) # 输出 dy/dx = 2x+3 = 7.0 ``` 3. **广播机制**:自动扩展维度进行运算 ```python a = torch.ones(3,2) b = torch.ones(2) c = a + b # b被广播为(3,2) ``` ## 六、注意事项 1. 张量形状匹配:矩阵乘法需满足 $m \times n$ 与 $n \times p$ 的维度 2. 梯度累积:每次反向传播前需执行`optimizer.zero_grad()` 3. 设备转移:避免CPU与GPU张量的直接运算 深度学习模型的构建本质是通过组合各种张量运算形成计算图,配合自动微分实现参数优化[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值