赞
踩
主要内容
PyTorch
的自动求导功能计算梯度,并演示梯度清除和分离计算图的操作。import torch import pandas as pd import os # 创建和操作张量 # 张量表示一个数值组成的数组,这个数组可能有多个维度 x = torch.arange(12) # 创建一个包含从0到11的向量 print("x:", x) # 打印张量x print("x的形状:", x.shape) # 打印张量的形状 print("x中的元素总数:", x.numel()) # 打印张量中元素的总数 # 改变一个张量的形状而不改变元素数量和元素值,采用reshape X = x.reshape(3, 4) # 将x重塑为一个3行4列的矩阵 print("重塑后的X:", X) # 打印重塑后的X # 创建全0,全1张量 print("全零张量:", torch.zeros((2, 3, 4))) # 创建一个形状为(2,3,4)的全0张量 print("全一张量:", torch.ones((2, 3, 4))) # 创建一个形状为(2,3,4)的全1张量 # 使用包含数值的Python列表创建张量 t = torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]]) # 创建张量t print("从列表创建的张量:", t) # 打印张量t print("张量t的形状:", t.shape) # 打印张量t的形状 # 张量操作 X = torch.arange(12, dtype=torch.float32).reshape((3, 4)) # 创建并重塑张量X Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]]) # 创建张量Y Z = torch.zeros_like(X) # 创建一个形状和X相同的全零张量 Z[:] = X + Y # 计算X和Y的逐元素加法 print("Z (X + Y):", Z) # 打印Z print("Z的转置:", Z.T) # 打印Z的转置 # 使用pandas创建和处理数据集 # 创建一个人工数据集,并存储在CSV(逗号分隔值)文件中 os.makedirs(os.path.join('..', 'data'), exist_ok=True) # 创建数据目录 data_file = os.path.join('..', 'data', 'house_tiny.csv') # 定义文件路径 with open(data_file, 'w') as f: f.write('NumRooms,Alley,Price\n') # 列名 f.write('NA,Pave,127500\n') # 每行表示一个数据样本 f.write('2,NA,106000\n') f.write('4,NA,178100\n') f.write('NA,NA,140000\n') data = pd.read_csv(data_file) # 读取CSV文件 print("从CSV加载的数据:", data) # 打印加载的数据 inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2] # 分离输入和输出 inputs['NumRooms'] = inputs['NumRooms'].fillna(inputs['NumRooms'].mean()) # 用均值填充缺失值 print("处理后的输入数据:", inputs) # 打印处理后的输入数据 inputs = pd.get_dummies(inputs, dummy_na=True).astype('float') # 转换类别变量并将其转换为浮点型 print("独热编码后的输入数据:", inputs) # 打印独热编码后的输入数据 X = torch.tensor(inputs.values) # 将输入数据转换为张量 Y = torch.tensor(outputs.values) # 将输出数据转换为张量 print("输入数据的张量X:", X) # 打印输入数据的张量X print("输出数据的张量Y:", Y) # 打印输出数据的张量Y # 线性代数操作 A = torch.arange(20, dtype=torch.float32).reshape(5, 4) # 创建并重塑张量A B = A.clone() # 通过分配新内存,将A的副本分配给B print("矩阵A:", A) # 打印矩阵A print("矩阵A + B:", A + B) # 矩阵加法 print("矩阵A * B:", A * B) # 矩阵逐元素乘法 a = 2 X = torch.arange(24).reshape(2, 3, 4) # 创建并重塑张量X print("张量X:", X) # 打印张量X print("a + X:", a + X) # 标量和张量相加 print("a * X的形状:", (a * X).shape) # 打印标量和张量相乘后的形状 # 求和与均值 A_sum_axis0 = A.sum(axis=0) # 沿着第0维度求和 print("沿第0维度求和:", A_sum_axis0, "形状:", A_sum_axis0.shape) # 打印求和结果及其形状 print("A中的元素总数:", A.numel()) # 打印A中的元素总数 print("A的均值:", A.mean()) # 打印A的均值 print("A的和除以元素总数:", A.sum() / A.numel()) # 打印A的和除以元素总数 sum_A = A.sum(axis=1, keepdims=True) # 沿第1维度求和,并保持维度 print("沿第1维度求均值,保持维度:", A.mean(axis=1, keepdim=True)) # 打印沿第1维度的均值,并保持维度 print("沿第1维度求和,保持维度:", sum_A) # 打印沿第1维度的求和,并保持维度 print("A的归一化 (A / sum_A):", A / sum_A) # 打印归一化的A print("沿第0维度的累积和:", A.cumsum(axis=0)) # 打印沿第0维度的累积和 # 点积 x = torch.arange(4, dtype=torch.float32) # 创建张量x y = torch.ones(4, dtype=torch.float32) # 创建全1张量y print("x和y的点积:", torch.dot(x, y)) # 打印x和y的点积 print("逐元素乘积的和:", torch.sum(x * y)) # 打印逐元素乘积的和 print("矩阵A和向量x的乘积:", torch.mv(A, x)) # 打印矩阵和向量的乘积 # 矩阵乘法 B = torch.ones(4, 3) # 创建全1矩阵B print("矩阵A:", A) # 打印矩阵A print("矩阵B:", B) # 打印矩阵B print("矩阵A和B的矩阵乘法:", torch.mm(A, B)) # 打印矩阵A和B的矩阵乘法 # 各种范数 u = torch.tensor([3.0, -4.0]) # 创建张量u print("u的L2范数:", torch.norm(u)) # 打印u的L2范数 print("u的L1范数:", torch.abs(u).sum()) # 打印u的L1范数 print("一个全1矩阵(4x9)的弗罗贝尼乌斯范数:", torch.norm(torch.ones((4, 9)))) # 打印全1矩阵的弗罗贝尼乌斯范数 print("张量元素的和:", sum(torch.arange(20, dtype=torch.float32))) # 打印张量元素的和 A = torch.arange(40, dtype=torch.float32).reshape(2, 5, 4) # 创建并重塑张量A print("3D张量A:", A) # 打印3D张量A print("沿轴[1,2]求和:", A.sum(axis=[1, 2])) # 打印沿轴[1,2]求和结果 print("沿轴[1,2]求和,保持维度:", A.sum(axis=[1, 2], keepdims=True)) # 打印沿轴[1,2]求和结果,并保持维度 A = torch.ones(2, 5, 4) # 创建全1张量A print("3D张量A,全为1:", A) # 打印全1张量A print("沿轴[0,1]求和,保持维度:", A.sum(axis=[0, 1], keepdim=True)) # 打印沿轴[0,1]求和结果,并保持维度 # 自动求导 x = torch.arange(4.0) # 创建张量x print("张量x:", x) # 打印张量x x.requires_grad_(True) # 开启自动求导 print("x的梯度 (初始为None):", x.grad) # 打印x的梯度 (初始为None) y = 2 * torch.dot(x, x) # 2 * (x · x) 求导为 4x print("y = 2 * (x · x):", y) # 打印y y.backward() # 计算导数 print("backward之后x的梯度:", x.grad) # 打印x的梯度 print("x的梯度是否等于4 * x:", x.grad == 4 * x) # 打印x的梯度是否等于4 * x # 清除梯度 x.grad.zero_() # 清除x的梯度 y = x.sum() y.backward() print("求和y并backward之后的x梯度:", x.grad) # 打印求和y并backward之后的x梯度 # 对非标量调用backward需要传入一个gradient参数 x.grad.zero_() # 清除x的梯度 y = x * x y.sum().backward() # 等价于 y.backward(torch.ones(len(x))) print("平方并求和y之后的x梯度:", x.grad) # 打印平方并求和y之后的x梯度 # 分离计算图 x.grad.zero_() # 清除x的梯度 y = x * x u = y.detach() # 从计算图中分离y print("张量y:", y) # 打印张量y print("从y分离的张量u:", u) # 打印从y分离的张量u z = u * x z.sum().backward() print("分离u乘以x的梯度:", x.grad == u) # 打印分离u乘以x的梯度 x.grad.zero_() # 清除x的梯度 y.sum().backward() print("再次求和y之后的x梯度:", x.grad == 2 * x) # 打印再次求和y之后的x梯度
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。