核心区别对比
先通过表格直观对比三者的关键差异:
| 特性 | torch.empty() | torch.zeros() | torch.ones() |
|---|---|---|---|
| 数据初始化 | 未初始化,值为内存随机垃圾值 | 初始化,所有元素填充为 0 | 初始化,所有元素填充为 1 |
| 创建速度 | 最快(仅分配内存,不填值) | 较慢(分配内存 + 填充 0) | 较慢(分配内存 + 填充 1) |
| 数值可用性 | 不可直接使用,需手动赋值 | 可直接使用(值为 0) | 可直接使用(值为 1) |
| 内存占用 | 同形状下三者一致 | 同形状下三者一致 | 同形状下三者一致 |
适用场景
torch.empty()
- 你需要先分配内存,后续会通过赋值(如
tensor.fill_(5))、运算(如tensor = x + y)等方式完全覆盖张量所有值; - 追求极致的创建速度,且能确保使用前填充有效数据。
torch.zeros()/ones()
- 你需要直接使用初始化好的全 0/全 1 张量(比如作为初始值、掩码、偏置项等);
- 对创建速度要求不高,且需要张量有明确的初始值,避免随机值导致的错误。
例子
import torch
# 1. torch.empty():未初始化,随机值
empty_tensor = torch.empty(2, 2)
print("torch.empty(2,2) 结果(随机值):")
print(empty_tensor)
# 输出示例(每次运行值不同):
# tensor([[1.4013e-45, 0.0000e+00],
# [0.0000e+00, 0.0000e+00]])
# 2. torch.zeros():初始化,全 0
zeros_tensor = torch.zeros(2, 2)
print("\ntorch.zeros(2,2) 结果(全 0):")
print(zeros_tensor)
# 输出:
# tensor([[0., 0.],
# [0., 0.]])
# 3. torch.ones():初始化,全 1
ones_tensor = torch.ones(2, 2)
print("\ntorch.ones(2,2) 结果(全 1):")
print(ones_tensor)
# 输出:
# tensor([[1., 1.],
# [1., 1.]])
性能对比(创建大张量)
torch.empty() 因为跳过了“填充数据”步骤,创建大张量时速度优势明显,我们可以用代码验证:
import time
# 创建 10000x10000 的大张量,测试耗时
start = time.time()
torch.empty(10000, 10000)
empty_time = time.time() - start
start = time.time()
torch.zeros(10000, 10000)
zeros_time = time.time() - start
start = time.time()
torch.ones(10000, 10000)
ones_time = time.time() - start
print(f"torch.empty() 耗时:{empty_time:.4f} 秒")
print(f"torch.zeros() 耗时:{zeros_time:.4f} 秒")
print(f"torch.ones() 耗时:{ones_time:.4f} 秒")
# 输出示例(仅供参考,取决于硬件):
# torch.empty() 耗时:0.0010 秒
# torch.zeros() 耗时:0.0820 秒
# torch.ones() 耗时:0.0815 秒
总结
- 核心差异:
empty()是“只分配内存不初始化”,zeros()/ones()是“分配内存 + 填充固定值”; - 速度差异:
empty()创建速度远快于后两者,尤其创建大张量时差距明显; - 使用选择:需要直接用有意义值选
zeros()/ones(),需要先占内存后填值选empty()。