torch.div()——数组的‘点除‘运算

本文介绍了PyTorch中torch.div()函数的基本用法,包括元素级除法运算,支持广播和不同类型的输入,以及rounding_mode参数的三种舍入选项:默认、四舍五入和向下取整。通过实例演示了这些特性在实际应用中的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

torch.div()——数组的’点除’运算

torch.div(input, other, *, rounding_mode=None, out=None) → Tensor

功能:将数组input与数组other对应元素做除法,具体计算公式如下:
o u t i = i n p u t i o t h e r i out_i=\frac{input_i}{other_i} outi=otheriinputi
输入:

  • input:元素用于被除数的数组
  • other:元素用于除数的数组或者数
  • rounding_mode:输入为字符串类型,用于判断结果的舍入类型,有以下三种情况:
    • None:默认行为,不执行舍入操作。
    • trunc:将除法结果向零四舍五入,相当于C语言风格的除法。
    • floor:将除法结果向下取整,等同于np.floor_divide

注意:

  • 该运算支持广播机制,并且还支持整数、浮点数和复杂输入,始终将整数类型提升为默认标量类型
  • torch.div可以通过a.div实现,后者默认a当做被除数

代码案例

一般用法

import torch
a=torch.arange(20).reshape(5,4)
b=torch.arange(21,41).reshape(5,4)
c=torch.div(a,b)
print(a)
print(b)
print(c)

输出

# 被除数
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [12, 13, 14, 15],
        [16, 17, 18, 19]])
# 除数
tensor([[21, 22, 23, 24],
        [25, 26, 27, 28],
        [29, 30, 31, 32],
        [33, 34, 35, 36],
        [37, 38, 39, 40]])
# div结果(不进行舍入操作)
tensor([[0.0000, 0.0455, 0.0870, 0.1250],
        [0.1600, 0.1923, 0.2222, 0.2500],
        [0.2759, 0.3000, 0.3226, 0.3438],
        [0.3636, 0.3824, 0.4000, 0.4167],
        [0.4324, 0.4474, 0.4615, 0.4750]])

rounding_mode三种方式的区别

import torch
import numpy as np
a=torch.from_numpy(np.random.randn(2,5))
b=torch.from_numpy(np.random.randn(2,5))
c=torch.div(a,b)
d=torch.div(a,b,rounding_mode='trunc')
e=torch.div(a,b,rounding_mode='floor')
print(a)
print(b)
print(c)
print(d)
print(e)

输出

# 被除数
tensor([[-0.1634,  1.6856, -0.0897, -0.7464,  1.3927],
        [-0.9697,  0.2859,  0.2458,  0.3014,  0.0339]], dtype=torch.float64)
# 除数
tensor([[ 0.2383,  0.8596, -0.0589, -1.5333,  0.6570],
        [-0.3662,  0.1371, -0.1085, -0.0345,  0.2491]], dtype=torch.float64)
# 默认情况下,不进行舍入操作
tensor([[-0.6858,  1.9609,  1.5221,  0.4868,  2.1197],
        [ 2.6481,  2.0850, -2.2658, -8.7355,  0.1361]], dtype=torch.float64)
# trunc方式的舍入
tensor([[-0.,  1.,  1.,  0.,  2.],
        [ 2.,  2., -2., -8.,  0.]], dtype=torch.float64)
# floor方式的舍入
tensor([[-1.,  1.,  1.,  0.,  2.],
        [ 2.,  2., -3., -9.,  0.]], dtype=torch.float64)

trunc与floor最主要的差别就是负数的四舍五入方法,trunc向零四舍舍入,floor普通的四舍五入,trunc得到的负数结果始终比floor得到的负数结果大1。

官方文档

torch.div():https://pytorch.org/docs/stable/generated/torch.div.html?highlight=div#torch.div

### Transformer模型代码详解及实现原理 #### 1. 导入必要的库 为了构建和训练Transformer模型,需要导入一系列Python库。这些库提供了创建神经网络所需的功能。 ```python import torch import torch.nn as nn import numpy as np ``` 这部分准备工作中,`torch`及其子模块用于定义张量操作以及搭建深度学习框架;`numpy`则主要用于处理数组运算[^1]。 #### 2. 定义位置编码函数 由于Transformers不包含循环结构来捕捉序列中的顺序信息,因此引入了位置编码(Positional Encoding),使得模型能够区分不同位置上的输入特征。 ```python def positional_encoding(max_len, d_model): pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2) * -(np.log(10000.0) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) return pe.unsqueeze(0) ``` 此方法通过正弦波的形式给定了每个token的位置向量表示。 #### 3. 构建多头自注意力机制(Multi-head Self Attention) 这是整个架构的核心部分之一,它允许查询(Query)、键(Key) 和 值(Value)之间相互作用,从而捕获更复杂的依赖关系。 ```python class MultiHeadAttention(nn.Module): def __init__(self, embed_size, num_heads): super().__init__() self.embed_size = embed_size self.num_heads = num_heads assert embed_size % num_heads == 0, "Embedding size needs to be divisible by heads" self.depth = embed_size // self.num_heads self.wq = nn.Linear(embed_size, embed_size) self.wk = nn.Linear(embed_size, embed_size) self.wv = nn.Linear(embed_size, embed_size) self.dense = nn.Linear(embed_size, embed_size) def split_into_heads(self, x, batch_size): ... def forward(self, v, k, q, mask=None): ... ``` 上述类实现了多头注意层的设计理念,其中包含了线性变换权重矩阵WQ,WK,WV 的初始化过程。 #### 4. 创建前馈神经网络(Feed Forward Network) 了自注意力外,每一层还含有一个简单的全连接前馈网络FFN,其内部采用ReLU激活函数作为非线性单元。 ```python class FeedForward(nn.Module): def __init__(self, d_model, d_ff=2048, dropout=.1): super().__init__() self.linear_1 = nn.Linear(d_model, d_ff) self.dropout = nn.Dropout(dropout) self.linear_2 = nn.Linear(d_ff, d_model) def forward(self, x): x = F.relu(self.linear_1(x)) x = self.dropout(x) x = self.linear_2(x) return x ``` 这里定义了一个两层感知机形式的前馈网络,负责进一步加工来自上一层的信息流。 #### 5. 组合各组件形成完整的Transformer Layer 最后一步就是把之前提到过的各个部件组合起来构成单个变压器层——即由一个多头自关注力模块加上两个残差链接与标准化后的前馈网络组成。 ```python class EncoderLayer(nn.Module): def __init__(self, embed_size, num_heads, ff_dim, rate=0.1): super().__init__() self.mha = MultiHeadAttention(embed_size, num_heads) self.ffn = FeedForward(embed_size, ff_dim) self.layernorm1 = nn.LayerNorm(normalized_shape=embed_size, eps=1e-6) self.layernorm2 = nn.LayerNorm(normalized_shape=embed_size, eps=1e-6) self.dropout1 = nn.Dropout(rate) self.dropout2 = nn.Dropout(rate) def forward(self, x, training=True, mask=None): attn_output = self.mha(v=x, k=x, q=x, mask=mask) out1 = self.layernorm1(x + self.dropout1(attn_output)) ffn_output = self.ffn(out1) out2 = self.layernorm2(out1 + self.dropout2(ffn_output)) return out2 ``` 至此已经完成了对于单一编码器层的具体实现逻辑说明。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

视觉萌新、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值