torch.log 功能与语法
torch.log()
是 PyTorch 中用于计算自然对数(以 e 为底)的函数,对输入张量中的每个元素执行逐元素对数运算。其核心作用是将数据转换到对数空间,常用于概率模型、损失函数设计和数据预处理等场景。
语法:
torch.log(input, out=None) → Tensor
参数:
input
(Tensor):输入的张量,要求所有元素必须为正数(否则会返回nan
)。out
(Tensor, 可选):输出结果的目标张量,需与输入张量形状一致。
应用案例
案例 1:概率分布转换
在机器学习中,常将概率值转换为对数概率以避免数值下溢。
import torch
# 原始概率值(接近 0 时直接计算易导致下溢)
probabilities = torch.tensor([0.999, 0.001, 0.5])
log_probs = torch.log(probabilities)
print(log_probs) # 输出: tensor([-0.0010, -6.9078, -0.6931])
案例 2:对数损失函数实现
在二分类问题中,常用对数损失函数(如 BCE Loss)。
def binary_cross_entropy(y_pred, y_true):
# 假设 y_pred 是预测概率,y_true 是真实标签
return -torch.mean(y_true * torch.log(y_pred) + (1 - y_true) * torch.log(1 - y_pred))
# 使用示例
y_pred = torch.tensor([0.8, 0.3, 0.9], requires_grad=True)
y_true = torch.tensor([1.0, 0.0, 1.0])
loss = binary_cross_entropy(y_pred, y_true)
loss.backward() # 计算梯度
案例 3:数据预处理(压缩动态范围)
对具有较大动态范围的数据(如图像像素值或金融时间序列)进行对数变换。
# 假设 x 是像素值或价格数据(非负且范围大)
x = torch.tensor([1, 10, 100, 1000])
log_x = torch.log(x)
print(log_x) # 输出: tensor([0.0000, 2.3026, 4.6052, 6.9078])
案例 4:计算信息熵
在信息论中,熵的计算依赖于对数运算。
def entropy(prob_dist):
# 假设 prob_dist 是归一化的概率分布
return -torch.sum(prob_dist * torch.log(prob_dist))
# 使用示例
p = torch.tensor([0.25, 0.25, 0.25, 0.25]) # 均匀分布
print(entropy(p)) # 输出: tensor(1.3863),即 ln(4)
案例 5:物理模拟中的指数衰减
在模拟放射性衰变或信号衰减时,对数可用于反向计算时间。
# 衰减公式: N = N₀ * e^(-λt) → t = -ln(N/N₀) / λ
def calculate_decay_time(N, N0, decay_constant):
return -torch.log(N / N0) / decay_constant
# 使用示例
current_amount = torch.tensor([0.5]) # 剩余量
initial_amount = 1.0 # 初始量
lambda_val = 0.1 # 衰减常数
time = calculate_decay_time(current_amount, initial_amount, lambda_val)
print(time) # 输出: tensor([6.9315]),即 ln(2)/0.1
案例 6:优化算法中的对数障碍法
在约束优化中,对数障碍法通过添加对数项惩罚违反约束的解。
# 目标函数: minimize f(x) subject to x > 0
def logarithmic_barrier(x, f, mu=1.0):
# 添加对数障碍项 -μ * log(x) 防止 x 接近 0
return f(x) - mu * torch.sum(torch.log(x))
# 示例目标函数
f = lambda x: torch.sum((x - 5) ** 2) # 二次函数
x = torch.tensor([2.0, 3.0], requires_grad=True)
loss = logarithmic_barrier(x, f)
loss.backward() # 计算包含障碍项的梯度
常见错误与注意事项
1. 输入值为负数或零
- 错误表现:输入包含非正数时,输出对应位置为
nan
。 - 解决方法:预处理数据确保所有元素为正,或使用
torch.log1p()
处理接近零的值。
x = torch.tensor([-1.0, 0.0, 1.0])
print(torch.log(x)) # 输出: tensor([nan, -inf, 0.0000])
2. 数值稳定性问题
- 问题场景:当输入值非常接近 0 时,直接计算
log(x)
可能导致数值不稳定。 - 解决方法:使用
torch.log1p(x)
替代torch.log(1 + x)
,避免精度损失。
x = torch.tensor(1e-10)
print(torch.log(1 + x)) # 输出: tensor(0.),精度丢失
print(torch.log1p(x)) # 输出: tensor(1.0000e-10),更精确
3. 梯度爆炸/消失
- 问题表现:在深度学习中,当输入接近 0 时,
log
的梯度趋近于无穷大(-∞
),导致训练不稳定。 - 解决方法:
- 避免输入接近 0 的情况(如添加小常数
ε
)。 - 使用平滑的近似函数替代严格的对数。
- 避免输入接近 0 的情况(如添加小常数
4. 输出类型与输入类型一致
torch.log()
的输出张量类型与输入保持一致(如float32
或float64
)。若需更高精度,需先转换输入类型。
x = torch.tensor([1.0], dtype=torch.float16)
print(torch.log(x).dtype) # 输出: torch.float16
5. 与 numpy.log 的差异
- PyTorch 的
log
支持自动求导(Autograd),而 NumPy 的log
不支持。在深度学习中优先使用 PyTorch 版本。
总结
torch.log()
是科学计算和深度学习中常用的数学函数,核心用途包括:
- 概率模型:处理对数概率,避免数值下溢。
- 数据变换:压缩动态范围,使数据分布更均匀。
- 信息论:计算熵、交叉熵等信息度量。
- 优化算法:设计对数障碍函数处理约束条件。
使用时需特别注意输入值的范围和数值稳定性,合理预处理数据以避免 nan
或梯度异常。
《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。全书共11章,前6章涵盖深度学习基础,包括张量运算、神经网络原理、数据预处理及卷积神经网络等;后5章进阶探讨图像、文本、音频建模技术,并结合Transformer架构解析大语言模型的开发实践。书中通过房价预测、图像分类等案例讲解模型构建方法,每章附有动手练习题,帮助读者巩固实战能力。内容兼顾数学原理与工程实现,适配PyTorch框架最新技术发展趋势。