Torch入门小知识点--总结性语言
一,torch.tensor()
torch.tensor()
主要是用来存数值的,只能放能够转成数值的类型(int、float、bool 等)。
1. 可以放的类型
数值型
int
、float
、bool
例子:
torch.tensor(1) # int torch.tensor(1.5) # float torch.tensor(True) # bool torch.tensor([1, 2, 3]) # list of int
嵌套序列(list / tuple / numpy array)
里面的元素必须能统一转换成一种数值类型(int/float)。
例子:
torch.tensor([[1, 2], [3, 4]]) # 2D int tensor torch.tensor((1.0, 2.5, 3.3)) # tuple 转 float tensor
标量张量或 numpy 标量
PyTorch 和 NumPy 都能相互转换。
例子:
import numpy as np torch.tensor(np.array([1, 2, 3]))
2.不能直接放的类型
字符串
torch.tensor(["a", "b", "c"]) # ❌ 报错: ValueError: too many dimensions 'str'
Python 的复杂对象(dict、类实例 等)
torch.tensor([{"x": 1}, {"y": 2}]) # ❌ 报错: can't convert dict to tensor
🔑 总结
torch.tensor()
只能存储数值(int、float、bool)。如果要处理字符串、类别等数据,需要先 编码成数值(比如
OneHotEncoder
、LabelEncoder
,或者自己映射成整数)。
二,torch.size()
torch.Size([1])
里的数字,其实就是 张量在各个维度上的长度。
例子解析
标量 (scalar)
a = torch.tensor(1) print(a.shape) # torch.Size([])
没有维度 → shape 为空
[]
。
一维张量 (vector)
a = torch.tensor([1]) print(a.shape) # torch.Size([1])
说明这是 1 维张量,长度为 1。
里面就 1 个元素。
再看一个:
b = torch.tensor([1, 2, 3, 4]) print(b.shape) # torch.Size([4])
这是 1 维张量,长度为 4。
二维张量 (matrix)
c = torch.tensor([[1, 2, 3],[4, 5, 6]]) print(c.shape) # torch.Size([2, 3])
第一维大小是 2 → 有 2 行
第二维大小是 3 → 每行有 3 个元素
三维张量 (batch of matrices)
d = torch.randn(10, 3, 28, 28) print(d.shape) # torch.Size([10, 3, 28, 28])
10 → batch_size = 10
3 → 通道数 (比如 RGB 图像的 3 个通道)
28, 28 → 每张图像的宽和高
🔑 总结
torch.Size
就是张量的形状(shape)。里面的数字表示 每个维度的长度。
例子:
torch.Size([])
→ 标量torch.Size([1])
→ 一维张量,长度 1torch.Size([2, 3])
→ 二维张量,2 行 3 列
三,数据类型
在 PyTorch 里,目前(到 2025)支持的数据类型(dtype
)主要是:
1.整数类型(int)
torch.int8
(8 位有符号整数)torch.uint8
(8 位无符号整数)torch.int16
(16 位有符号整数)torch.int32
(32 位有符号整数)torch.int64
(64 位有符号整数,常用作索引)
2.浮点数类型(float)
torch.float16
(半精度,FP16)torch.bfloat16
(brain float,Google TPU 常用格式)torch.float32
(单精度,FP32,最常用)torch.float64
(双精度,FP64,也叫double
)
⚠️ 注意:PyTorch 里 没有 float8(至少到 2025 还没有正式支持)。 只有
float16 / bfloat16 / float32 / float64
这几种浮点类型。
3.布尔类型
torch.bool
(只有 True / False)
✅ 小结
所以,严格来说 PyTorch 的基本数值类型有:
浮点数:
float16
、bfloat16
、float32
、float64
(4 种)整数:
int8
、uint8
、int16
、int32
、int64
(5 种)布尔:
bool
(1 种)
四,数据转换涉及的内存问题
在处理张量(如 PyTorch 的Tensor
或 TensorFlow 的tensor
)与 NumPy 数组的转换时,n_later = n.numpy().copy()
的写法涉及到两者的内存关联特性,需要从数据转换机制和内存所有权的角度理解:
numpy()
返回的数组可能与原张量共享内存
当我们对张量调用.numpy()
时,得到的 NumPy 数组可能与原张量共享底层内存(这取决于框架的实现,例如 PyTorch 在多数情况下会共享内存,尤其是 CPU 上的张量)。 这意味着:如果后续修改原张量或这个 NumPy 数组,另一方可能会被意外改变,导致不可预期的结果。
为什么是先numpy()再copy()
?
n.numpy().copy()
的逻辑是:
先通过
.numpy()
将张量转换为 NumPy 数组(可能共享内存);再通过
.copy()
对这个 NumPy 数组进行深拷贝,生成一个完全独立的新数组,与原张量彻底脱离内存关联。
这样可以确保n_later
是一个独立的数据,后续操作不会影响原张量,也不会被原张量影响。
为什么不先copy()再numpy()
?
如果写成n.copy().numpy()
,逻辑上是:
先对张量
n
进行拷贝(得到一个新的张量,与原张量脱离关联);再将这个新张量转换为 NumPy 数组(此时转换得到的数组可能仍与新张量共享内存,但由于新张量本身已经独立,这种共享不会影响原张量)。
这种写法也能达到独立的效果,但相比之下:
先numpy()再copy()
更直接:转换后立即拷贝数组,明确确保 NumPy 数组的独立性;先copy()再numpy()
多了一步张量拷贝,在内存和效率上可能稍逊(尤其是大张量时)。
总结
两种写法都能实现数据独立,但n.numpy().copy()
更简洁高效,且直接针对 NumPy 数组进行操作,更符合 “确保最终数组独立” 的目标。其核心是利用.copy()
切断与原张量的内存关联,而.numpy()
只是转换数据格式的第一步。
五,项目运用
import torch
import numpy as np
# 判断cuda:0 是否可用
device = torch.device('cuda'if torch.cuda.is_available() else 'cpu') # 检测GPU是否可用否则选择CPU
torch.set_printoptions(sci_mode=False) # 取消科学计数法
'''
使用不同方法创建tensor张量
'''
def create_tensor():# tensor方法def tensor():a = torch.tensor(1) # tensor根据数值自动选择dtype 这里为int64print(a, a.dtype, a.shape)a_list_float = torch.tensor([1,2,3],dtype=torch.float64,device=device) # 使用列表创建张量并指定设备和数值类型print(a_list_float,a_list_float.dtype,a_list_float.shape)a_numpy = torch.tensor(np.array([[1,2,3],[2,3,3]])) # 使用数组来创建张量print(a_numpy,a_numpy.dtype,a_numpy.shape)# tensor()# Tensor 方法 根据形状创建张量def Tensor():# 根据形状b_tensor = torch.Tensor(2,3) # 张量中的元素值是未定义的垃圾值(取决于内存中当前的随机数据)print(b_tensor)b = torch.Tensor(1) # 不支持显式指定设备,数值类型print(b,b.dtype,b.shape) # Tensor创建的数值类型默认为float32# Tensor()# torch.IntTensor 创建指定类型的张量def tensor_dtype():# 建指定形状的张量tt6 = torch.ByteTensor(3,3)print(tt6.dtype)tt5 = torch.ShortTensor(3, 3)print(tt5.dtype)tt1 = torch.IntTensor(2, 3)print(tt1.dtype)tt4 = torch.LongTensor(3, 3)print(tt4.dtype)tt8 = torch.BFloat16Tensor(3, 3)print(tt8.dtype)tt7 = torch.HalfTensor(3, 3)print(tt7.dtype)tt2 = torch.FloatTensor(3, 3)print(tt2.dtype)tt3 = torch.DoubleTensor(3, 3)print(tt3.dtype)tt9 = torch.BoolTensor(3, 3)print(tt9.dtype)tt11 = tt1.float() # 数值类型转换print(tt11.dtype)# tensor_dtype()# 生成随机张量def tensor_random():# 生成随机数种子torch.manual_seed(42)# 获取随机数种子print(torch.initial_seed())c_01 = torch.rand(3,3) # 生成随机张量,均匀分布(范围 [0, 1))print(c_01)c_gaussian = torch.randn(3,3) # 生成随机张量:标准正态分布(均值 0,标准差 1)print(c_gaussian)c_normal = torch.normal(mean=2,std=3,size=(3,3))print(c_normal)# tensor_random()# 生成线性张量def tensor_lines():d = torch.linspace(1,10,9)print(d,d.shape,d.dtype)# tensor_lines()'''
张量的属性
'''
def tensor_attribute():# 切换设备def switch_devices():a = torch.tensor([1,2,3])print(a,a.device)# a = a.to(device) # cpu --> gpua = a.cuda() # cpu --> gpuprint(a)a = a.cpu() # gpu --> cpuprint(a,a.device)# switch_devices()# 数据转换# numpy to tensordef numpy_to_tensor():# 浅拷贝m = np.array([[7,8,9],[9,8,7]])# numpy --> tensorm_later = torch.from_numpy(m)print(m_later)m_later[0,0]=111print(f"m:{m}") # m改变print(f"m_later:{m_later}")# 深拷贝n = np.array([[1,2,3],[3,2,1]])print(n)# numpy --> tensorn_later = torch.tensor(n,device=device)n_later[0,0]=111print(f"n:{n}")print(f"n_later:{n_later}")# tensor to numpydef tensor_to_numpy():# 浅拷贝m = torch.tensor([[7,8,9],[9,8,7]])print(m)# tensor --> numpym_later = m.numpy()m_later[0, 0] = 111print(f"m:{m}") # m改变print(f"m_later:{m_later}")# 深拷贝n = torch.tensor([[7,8,9],[9,8,7]])print(n)# tensor --> numpyn_later = n.numpy().copy()n_later[0,0]=111print(f"n:{n}")print(f"n_later:{n_later}")tensor_to_numpy()'''
tensor常见操作
'''
def tensor_common_operations():# 获取单个元素def get_single_element():tensor = torch.tensor(1) # 只能单个元素1 [1] (1)a = tensor.item()print(a)# get_single_element()# 元素值运算 add() sub() mul() div() pow()def element_value_operation ():# 生成范围 [0, 10) 的 2x3 随机整数张量data = torch.randint(0, 10, (2, 3))print(data)# 元素级别的加减乘除:不修改原始值print(data.add(1))print(data.sub(1))print(data.mul(2))print(data.div(3))print(data.pow(2))# 元素级别的加减乘除:修改原始值data = data.float()data.add_(1)data.sub_(1)data.mul_(2)data.div_(3.0)data.pow_(2)print(data)# element_value_operation()# 点积和相乘def point_product_and_multiply():# 阿达玛点积tensor1 = torch.tensor([[1,2,3],[4,5,6]])tensor2 = torch.tensor([[7,8,9],[9,8,7]])tensor3 = (tensor1*tensor2)tensor3 = tensor1.mul(tensor2)print(tensor3)# 相乘tensor5 = torch.tensor([[1, 2, 3], [4, 5, 6]])tensor6 = torch.tensor([[7, 8], [9, 8], [7, 8]])tensor4 = (tensor5 @ tensor6)tensor4 = tensor5.matmul(tensor6)print(tensor4)point_product_and_multiply()
if __name__ == '__main__':# create_tensor()# tensor_attribute()tensor_common_operations()