【深度学习 | 第一篇】- Pytorch与张量

张开发
2026/4/4 1:53:09 15 分钟阅读
【深度学习 | 第一篇】- Pytorch与张量
前言深度学习作为机器学习的一个子集也是现在的最火的方向它以神经网络为基础通过一个一个神经元结点来提取数据之间的特征具有不可解释性所以也被大家称为“黑盒模型”被广泛应用于NLPCV推荐系统之中。PyTorch框架简介PyTorch一个基于Python语言的深度学习框架它将数据封装成张量Tensor来进行处理。PyTorch提供了灵活且高效的工具用于构建、训练和部署机器学习和深度学习模型。PyTorch广泛应用于学术研究和工业界特别是在计算机视觉、自然语言处理、强化学习等领域。下载链接pip install torch torchvision -i https://pypi.tuna.tsinghua.edu.cn/simple张量基础1. 什么是张量TensorPyTorch 中的张量就是元素为同一种数据类型的多维矩阵。类似于 NumPy 数组但支持 GPU 加速。0维标量1维向量2维矩阵多维高维张量2. 张量的创建importtorch# 1. torch.tensor() - 根据指定数据创建张量datatorch.tensor(10)# 标量datatorch.tensor([[10.,20.],[40.,50.]])# 列表# 2. torch.Tensor() - 根据形状创建张量未初始化datatorch.Tensor(2,3)# 2行3列默认float32# 3. 创建指定类型的张量datatorch.IntTensor(2,3)# int32datatorch.FloatTensor(2,3)# float32datatorch.LongTensor(2,3)# int643. 线性与随机张量# 线性张量datatorch.arange(0,10,2)# [0, 2, 4, 6, 8]步长为2datatorch.linspace(0,11,10)# 均匀分布包含首尾# 随机张量datatorch.rand(2,3)# 0~1均匀分布datatorch.randn(2,3)# 标准正态分布 N(0,1)datatorch.randint(0,10,(2,3))# 整数随机张量# 随机种子torch.manual_seed(100)# 设置随机种子print(torch.initial_seed())# 查看随机种子4. 0、1、指定值张量# 全0 / 全1张量datatorch.zeros(2,3)datatorch.ones(2,3)datatorch.zeros_like(data)# 根据形状创建datatorch.ones_like(data)# 全指定值张量datatorch.full((2,3),10)# 全部填充10datatorch.full_like(data,20)张量类型转换# 方式1使用 .type()datatorch.full([2,3],10)datadata.type(torch.FloatTensor)# 转float32datadata.type(torch.DoubleTensor)# 转float64datadata.type(torch.IntTensor)# 转int32# 方式2使用转换方法datadata.float()# float32datadata.double()# float64datadata.int()# int32datadata.long()# int64datadata.half()# float16张量与 NumPy 互转importnumpyasnp# 张量 → NumPydata_tensortorch.tensor([2,3,4])data_numpydata_tensor.numpy()# 共享内存data_numpydata_tensor.numpy().copy()# 不共享内存# NumPy → 张量data_numpynp.array([2,3,4])data_tensortorch.from_numpy(data_numpy)# 共享内存data_tensortorch.tensor(data_numpy)# 不共享内存# 标量张量提取值datatorch.tensor(30)print(data.item())# 30张量基本运算1. 四则运算datatorch.randint(0,10,[2,3])# 不修改原数据new_datadata.add(10)# data 10new_datadata.sub(10)# data - 10new_datadata.mul(10)# data * 10new_datadata.div(10)# data / 10new_datadata.neg()# -data# 就地修改带下划线data.add_(10)# data 10直接修改原数据2. 逐点乘法Hadamard积data1torch.tensor([[1,2],[3,4]])data2torch.tensor([[5,6],[7,8]])datatorch.mul(data1,data2)# 方式1datadata1*data2# 方式2# 结果: tensor([[ 5, 12], [21, 32]])3. 矩阵乘法data1torch.tensor([[1,2],[3,4],[5,6]])# (3, 2)data2torch.tensor([[5,6],[7,8]])# (2, 2)datadata1 data2# 运算符datatorch.matmul(data1,data2)# 函数# 结果: (3, 2) (2, 2) (3, 2)# tensor([[19, 22], [43, 50], [67, 78]])4. 常见数学函数datatorch.randint(0,10,[2,3],dtypetorch.float64)data.mean()# 均值data.mean(dim0)# 按列求均值data.mean(dim1)# 按行求均值data.sum()# 求和data.sqrt()# 平方根torch.pow(data,2)# 幂运算data.exp()# 指数运算 e^ndata.log()# 对数运算自然对数data.log2()data.log10()张量索引操作datatorch.randint(0,10,[4,5])# 简单行列索引data[0]# 第1行所有元素data[:,0]# 第1列所有元素# 列表索引data[[0,1],[1,2]]# (0,1)和(1,2)位置元素data[[[0],[1]],[1,2]]# 广播机制# 范围索引data[:3,:2]# 前3行前2列data[2:,:2]# 第3行到最后的前2列# 布尔索引data[data[:,2]5,:]# 第3列5的整行data[:,data[1,:]5]# 第2行5的整列# 多维索引以3D张量为例datatorch.randint(0,10,[3,4,5])data[0,:,:]# 0轴第1个数据data[:,0,:]# 1轴第1个数据data[:,:,0]# 2轴第1个数据张量形状操作1. reshape 与 flattendatatorch.tensor([[10,20,30],[40,50,60]])new_datadata.reshape(1,6)# 改变形状new_datadata.reshape(-1,1)# -1自动推断data.flatten()# 展平为1维2. squeeze 与 unsqueezemydatatorch.tensor([1,2,3,4,5])# (5,)mydata2mydata.unsqueeze(dim0)# (1, 5)mydata3mydata.unsqueeze(dim1)# (5, 1)mydata4mydata.unsqueeze(dim-1)# (5, 1)mydata5mydata4.squeeze()# (5,)压缩维度3. transpose 与 permutedatatorch.randint(0,10,[3,4,5])# 交换维度mydatatorch.transpose(data,1,2)# (3, 5, 4)# 一次交换多个维度mydatatorch.permute(data,[1,2,0])# (4, 5, 3)mydatadata.permute(1,2,0)4. view 与 contiguousdatatorch.tensor([[10,20,30],[40,50,60]])# view要求张量必须连续mydatadata.view(3,2)# (3, 2)mydatadata.view(-1,1)# 自动推断# 非连续张量需先转连续mydata3torch.transpose(data,0,1)mydata4mydata3.contiguous().view(2,3)张量拼接操作1. torch.cat()data1torch.randint(0,10,[1,2,3])data2torch.randint(0,10,[1,2,3])# 按维度拼接不增加新维度new_datatorch.cat([data1,data2],dim0)# (2, 2, 3)new_datatorch.cat([data1,data2],dim1)# (1, 4, 3)new_datatorch.cat([data1,data2],dim2)# (1, 2, 6)2. torch.stack()data1torch.randint(0,10,[2,3])data2torch.randint(0,10,[2,3])# 在新维度上拼接增加新维度new_datatorch.stack([data1,data2],dim0)# (2, 2, 3)new_datatorch.stack([data1,data2],dim1)# (2, 2, 3)new_datatorch.stack([data1,data2],dim2)# (2, 3, 2)3. torch.flip()4. torch.chunk()自动微分模块1. 梯度基本计算importtorch# 定义需要求梯度的张量必须为浮点型wtorch.tensor(10.,requires_gradTrue,dtypetorch.float32)# 定义计算图y2*w**2print(y)# tensor(200., grad_fnMulBackward0)# 反向传播求梯度y.sum().backward()# 向量需转标量# 获取梯度print(w.grad)# tensor(40.)2. 梯度下降法示例# 求 y x^2 20 的极小值点xtorch.tensor(10.,requires_gradTrue,dtypetorch.float32)lr0.01foriinrange(1000):yx**220# 梯度清零防止累加ifx.gradisnotNone:x.grad.zero_()# 反向传播y.backward()# 梯度更新x.datax.data-lr*x.gradprint(f最优解: x {x.item():.6f}, y {y.item():.6f})# 输出: 最优解: x ≈ 0, y ≈ 203. 梯度计算注意点# 不能对requires_grad的张量直接调用.numpy()x1torch.tensor([10.,20.],requires_gradTrue)# 报错RuntimeError# print(x1.numpy())# 使用detach()分离计算图x2x1.detach()# 新张量不追踪梯度print(x2.numpy())# [10. 20.]线性回归实战1. PyTorch 模型训练四步骤准备训练集数据 → 构建模型 → 设置损失函数和优化器 → 模型训练2. 完整代码importtorchfromtorch.utils.dataimportTensorDataset,DataLoaderfromtorchimportnn,optimfromsklearn.datasetsimportmake_regressionimportmatplotlib.pyplotasplt# 1. 准备数据集 defcreate_dataset():x,y,coefmake_regression(n_samples100,# 100个样本n_features1,# 1个特征noise10,# 噪声标准差coefTrue,# 返回系数bias14.5,# 截距random_state0)# 转张量注意类型匹配xtorch.tensor(x,dtypetorch.float32)ytorch.tensor(y,dtypetorch.float32)returnx,y,coef x,y,coefcreate_dataset()# 2. 构建模型 # 构造数据集对象datasetTensorDataset(x,y)# 构造数据加载器dataloaderDataLoader(datasetdataset,batch_size16,# 每批样本数shuffleTrue,# 打乱顺序drop_lastFalse# 是否丢弃多余样本)# 构造模型线性回归y wx bmodelnn.Linear(in_features1,out_features1)# 3. 设置损失函数和优化器 criterionnn.MSELoss()# 均方误差损失optimizeroptim.SGD(model.parameters(),lr1e-2)# 随机梯度下降# 4. 模型训练 epochs100epoch_loss[]forepochinrange(epochs):total_loss0.0train_sample0fortrain_x,train_yindataloader:# 正向传播y_predmodel(train_x.reshape(-1,1))# 计算损失losscriterion(y_pred,train_y.reshape(-1,1))# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()total_lossloss.item()train_sample1epoch_loss.append(total_loss/train_sample)if(epoch1)%200:print(fEpoch{epoch1}/{epochs}, Loss:{epoch_loss[-1]:.4f})# 绘制结果 # 损失曲线plt.plot(range(epochs),epoch_loss)plt.title(Loss Curve)plt.grid()plt.show()# 拟合效果plt.scatter(x,y,labelData)x_linetorch.linspace(x.min(),x.max(),1000)y_linemodel(x_line.reshape(-1,1)).detach()plt.plot(x_line,y_line,labelFitted,colorred)plt.legend()plt.grid()plt.show()3. 训练流程口诀2244第一个2定义数据集对象 定义数据加载器 第一个4定义模型 定义损失函数 定义学习率 定义优化器 第二个2外层循环轮数 内层循环批次数 第二个4梯度清零 计算loss 反向传播 参数更新2244口诀第一个2定义数据集对象 定义数据加载器 dataloader第二个2 :两个循环 训练多少轮 对轮数进行循环 每轮有几个数据批次对每轮的批次循环第一个4定义模型、loss函数、优化器 、设定学习率第二个4训练4个步骤 在每一批次的训练时 梯度清零如果不需要累加的话 计算loss并反向传播求梯度自动微分 模型的参数更新 当一个轮次训练完之后判断学习率是否要调整。零碎每隔多少轮次后进行模型保存 或 者跑一次验证集样本 以及更新 loss 曲线下降的图 等等GPU 加速# 判断GPU是否可用devicetorch.device(cudaiftorch.cuda.is_available()elsecpu)# 创建张量到GPUtensortorch.tensor([1,2,3]).to(device)# 模型移动到GPUmodelmodel.to(device)PyTorch 特点总结特点说明类NumPy操作语法与NumPy相似易上手GPU加速支持CUDA训练速度更快动态计算图网络结构可变调试方便自动微分内置autograd模块自动求导广泛应用CV、NLP、强化学习等安装命令pip install torch torchvision -i https://pypi.tuna.tsinghua.edu.cn/simple

更多文章