torch的一些函数

0. 长期更新,看到奇怪的弄懂了就写

ref:
https://www.bilibili.com/video/BV1wQ4y1q7Bm/?spm_id_from=333.788
https://blog.youkuaiyun.com/m0_46384757/article/details/120509481

1.torch.gather

这个的效果是切片

https://www.jianshu.com/p/b7d8d3c26f2d
上面的文章告诉我举例子的时候不要用1m或m1
也不要用n*n这种,不然歧义很多

这里是按我的理解写一遍,为了我能看懂

在这里插入图片描述
在这里插入图片描述
补充,如果你出现了**Dimension out of range (expected to be in range of [-2, 1], but got 2)**之类的报错,这是你的index的维度和gather源的维度不同,下面是正确的index,注意index的括号数

在这里插入图片描述

1.1 模糊的官方文档的解释

https://pytorch-cn.readthedocs.io/zh/latest/package_references/torch/#math-operations
在这里插入图片描述
敲过之后感觉还是能看的就是对初学者不太友好

#假设输入的是一个三维的张量
#比如 对 
# index=[
#   [[0,1],[2,3]],
#   [[4,5],[6,7]]
# ]
#其中5对应的坐标就是(101--(i.j.k)
#下面说的i,j,k都指的是index中某一数字在index中的坐标
#记 z=index(i,j,k)
# output   <-- (z, j,k) if dim=0
# output   <-- (i, z, k) if dim=1
# output   <-- (i, j, z) if dim=2

2.torch.transpose

这个的效果真的是坐标对换
比如说, 敲了个 torch.transpose(x,0,1), 第一维与第三维调换,原本(2,3,4)的数值出现在了(4,3,2)的位置上
在这里插入图片描述

3. torch.unbind(x,dim=0)

这个的效果是沿着某一维度得到原张量x的切片

在这里插入图片描述

4.torch.autograd.Function

推荐直接看这个
https://zhuanlan.zhihu.com/p/344802526

4.1 实战例子

首先记录一下这里想说的是apply()里面不是传入function的情况,function的话可以看下这个https://blog.youkuaiyun.com/qq_37025073/article/details/106739513

class Exp(Function):

    @staticmethod
    def forward(ctx, i):
        result = i.exp()
        ctx.save_for_backward(result)
        return result

    @staticmethod
    def backward(ctx, grad_output):
        result, = ctx.saved_tensors
        return grad_output * result

#Use it by calling the apply method:
output = Exp.apply(input)

# forward()和backward()都应该是staticmethod。
# forward()的输入只有2个(ctx, i),ctx必须有,i是input。
# ctx.save_for_backward(result)表示forward()的结果要存起来,以后给backward()。
# backward()的输入只有2个(ctx, grad_output),ctx必须有,grad_output是最终object对的forward()输出的导数。
# result, = ctx.saved_tensors得到之前forward()存的结果。
# 因为 exp(x) 的导数还是 exp(x) ,所以return grad_output (上一层求导结果)* result(exp(x))。
# 调用时,直接 Exp.apply(input)即可。

在这里插入图片描述
实验结果如上,functiion.apply(input)会自动调用forward,但不会子弟哦那个调用backward

上面这部分代码来自于【2】,你可以去【1】看BNN的实战例子

4.2 ref

[1]http://giantpandacv.com/project/%E9%83%A8%E7%BD%B2%E4%BC%98%E5%8C%96/AI%20%E9%83%A8%E7%BD%B2%E5%8F%8A%E5%85%B6%E5%AE%83%E4%BC%98%E5%8C%96%E7%AE%97%E6%B3%95/%E5%9F%BA%E4%BA%8EPytorch%E6%9E%84%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%8F%AF%E8%AE%AD%E7%BB%83%E7%9A%84BNN/#23
[2]https://zhuanlan.zhihu.com/p/344802526

5. le 与 ge

暂时认为是比大小

input=torch.arange(15)*0.2
print(input)
>>tensor([0.0000, 0.2000, 0.4000, 0.6000, 0.8000, 1.0000, 1.2000, 1.4000, 1.6000,
        1.8000, 2.0000, 2.2000, 2.4000, 2.6000, 2.8000])
print(input.ge(1))
>>tensor([False, False, False, False, False,  True,  True,  True,  True,  True,
         True,  True,  True,  True,  True])
print(input.le(1))
>>tensor([ True,  True,  True,  True,  True,  True, False, False, False, False,
        False, False, False, False, False])

6.torch.min

这里主要讲的是它的维度问题

# 一般是输入像这种torch.min(input, dim=3, keepdim=True)
# 这里想说的是第二个位置的数字
# 比如你输入的是一个size为[2,3,4,4] 
#  dim=0--2,dim=1--3

# 但是其实我想讲的重点是channel-wise,layer-wise那些该怎么处理
# layer-wise--->
# torch.min(input)

# channel-wise-->
# size(input)=[2,3,4,4]
# torch.min(torch.min(torch.min(input, 3, keepdim=True)[0], 2, keepdim=True)[0], 1, keepdim=True)[0]
# [0]是结果,[1]是对应的位置
# 此处dim=从内到外为321 表示层层选择,从size(input)=[2,3,4,4]最右的43
# 最里面的dim=3表示对每行
# dim=2表示对每一个4*4的平面
# dim=1 表示对于每一个由三个平面搭成的filter

在这里插入图片描述

7.register_buffer

这个是用来生成一个缓存器的,我在定义一个model类的时候看到这个,
在model中,我们需要更新其中的参数,训练结束将参数保存下来。但在某些时候,我们可能希望模型中的某些参数参数不更新(从开始到结束均保持不变),但又希望参数保存下来,就用这个

# 用法
class ...
	def....
		self.register_buffer('my_buffer', self.tensor)
# 表明将 创建一个叫my_buffer的缓存器(通过self.mybuffer调用),里面复制粘贴了#self.tensor

7.1 register_buffer.add_()

对这个buffer中的每一个元素都进行+1的操作

import torch
import torch.nn as nn
class my_model(nn.Module):
    def __init__(self,out_channels):
        super(my_model, self).__init__()
        self.register_buffer('mybuff', torch.zeros(out_channels, 1, 1, 1))

    def a(self):
        self.mybuff.add_(1)


A=my_model(5)
A.a()
print((A.mybuff))

效果:
在这里插入图片描述

8.torch.nn.embedding

作用:构建一个词向量库,认为每一行为对应编号的单词

#测试代码
mport torch
import torch.nn as nn
from torch.autograd import Variable

# 10个size为3的tensor
# 嵌入字典的大小为10(即有10个词),每个词向量的维度为3
embedding = nn.Embedding(10, 3)
# a batch of 2 samples of 4 indices each
# 该LongTensor的数字范围只能在0~9(因为设置了10)
print(embedding.weight)
print('-' * 60)
input1 = torch.LongTensor([[1, 2, 4, 5], 
                           [4, 3, 2, 9]])
emb1 = embedding(input1) # tensor([[1, 0, 2, 2, 3]])
print(emb1)
print(emb1.shape)
# torch.Size([2, 4, 3]) # 即每个词都被映射为一个3维向量
print('-' * 60)

在这里插入图片描述

### PyTorch 损失函数的使用方法与实现方式 #### 一、PyTorch 中常见的损失函数及其用途 PyTorch 提供了多种内置的损失函数,用于解决不同的机器学习问题。以下是几种常用的损失函数: 1. **NLLLoss**: `torch.nn.NLLLoss` 是一种负对数似然损失函数,适用于分类任务中的概率分布计算。为了配合该函数,模型输出通常会经过 `LogSoftmax` 转换为对数概率后再传入此函数[^1]。 2. **CrossEntropyLoss**: 这是一种集成化的损失函数,内部实现了 Softmax 和 NLLLoss 的功能,因此可以直接接受未经处理的原始分数作为输入[^4]。其定义如下: ```python import torch import torch.nn as nn # 定义 CrossEntropyLoss 函数 cross_entropy_loss = nn.CrossEntropyLoss() # 假设预测值和真实标签分别为 predictions 和 labels predictions = torch.randn(3, 4) # 批量大小为3,类别数为4 labels = torch.tensor([1, 2, 3]) # 对应的真实标签 # 计算交叉熵损失 loss = cross_entropy_loss(predictions, labels) print(loss) ``` 3. **MSELoss**: 平方误差损失函数 (`Mean Squared Error Loss`) 主要应用于回归问题中。可以通过调整参数 `reduction` 来控制返回的是均值还是逐项损失[^3]: ```python import torch import torch.nn as nn # 定义 MSE 损失函数 mse_loss_fn = nn.MSELoss(reduction='mean') # 输入张量和目标张量 input_tensor = torch.tensor([2.0, 4.0, 6.0]) target_tensor = torch.tensor([1.0, 3.0, 5.0]) # 计算 MSE 损失 loss = mse_loss_fn(input_tensor, target_tensor) print(loss) ``` 4. **自定义损失函数**: 如果现有的损失函数无法满足需求,可以手动编写新的损失函数。例如,在某些特定场景下可能需要设计特殊的对比损失或排序损失[^5]。 #### 二、具体实现细节分析 - **关于 NLLLoss 的实现**: 当前版本支持通过指定维度来执行 LogSoftmax 变换,并随后利用 NLLLoss 计算最终的结果。需要注意的是,默认情况下会对所有样本求平均;如果希望保留每条记录单独的损失值,则需设置参数 `reduction='none'`[^2]。 - **针对多类别的交叉熵优化**: 在实际项目里推荐优先选用 `nn.CrossEntropyLoss()` 替代组合形式(即分别调用 softmax 和 nllloss),因为前者不仅简化了代码逻辑而且性能更优[^4]。 - **灵活运用 reduction 参数**: 不同的任务背景决定了是否应该采用整体评估指标或者局部反馈机制。比如在训练初期阶段可能会倾向于观察个体表现以便及时发现问题所在;而后期则更加关注全局效果提升效率。 #### 三、总结说明 综上所述,合理选择并正确配置适合当前应用场景下的损失函数至关重要。无论是标准库提供的通用解决方案亦或是定制开发专属方案都需要充分理解各自特点以及适用范围才能达到最佳实践目的。 ```python import torch import torch.nn as nn # 自定义一个简单的线性网络结构 class SimpleNet(nn.Module): def __init__(self): super(SimpleNet, self).__init__() self.fc = nn.Linear(10, 3) def forward(self, x): return self.fc(x) model = SimpleNet() criterion = nn.CrossEntropyLoss() # 或者其他类型的损失函数 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) inputs = torch.randn(5, 10) # 构造一批次随机数据 targets = torch.randint(0, 3, (5,)) # 随机生成对应的目标值 outputs = model(inputs) loss = criterion(outputs, targets) print(f"初始损失: {loss.item()}") optimizer.zero_grad() loss.backward() optimizer.step() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值