网站设计规划,建设银行朝阳支行网站,百科网站推广,法库综合网站建设方案一. 张量的创建
张量简介 张量是pytorch的基本数据结构 张量#xff0c;英文为Tensor#xff0c;是机器学习的基本构建模块#xff0c;是以数字方式表示数据的形式。
例如#xff0c;图像可以表示为形状为 [3, 224, 224] 的张量#xff0c;这意味着 [colour_channels, h…一. 张量的创建
张量简介 张量是pytorch的基本数据结构 张量英文为Tensor是机器学习的基本构建模块是以数字方式表示数据的形式。
例如图像可以表示为形状为 [3, 224, 224] 的张量这意味着 [colour_channels, height, width] 因为图像具有 3 颜色通道红色、绿色、蓝色高度为 224 像素宽度为 224 像素。
在张量语言用于描述张量的语言中张量将具有三个维度一个维度表示 colour_channels 、 height 和 width 。 张量的基本创建
根据数据创建tensor
默认64
# 1. 使用torch.tensor根据数据创建张量
# 1.1. 创建标量
data torch.tensor(10)
print(data)
# 1.2. 创建numpy数组
data np.random.randn(3, 4)
data torch.tensor(data)
print(data)
# 1.3. 创建张量
data torch.tensor([[1, 2], [3, 4]])
print(data)
根据形状/数据创建Tensor
默认32
# 2.使用torch.Tensor根据形状/数据创建张量
# 2.1. 创建两行三列张量, 默认dtype为float32
data torch.Tensor(2, 3)
print(data)
# 2.2. 如果传递列表, 则创建包含指定元素的张量
data torch.Tensor([10])
print(data)
data torch.Tensor([1, 4])
print(data)
指定类型张量
# 3. torch.IntTensor(), torch.FloatTensor(), torch.DoubleTensor()创建指定类型的张量
# 3.1. 创建2行3列, dtype 为 int32 的张量
data torch.IntTensor(2, 3)
print(data)
# 3.2. 注意: 如果传递的元素类型不正确, 则会进行类型转换
data torch.IntTensor([2.5, 3.3])
print(data)
# 3.3. 其他的类型
data torch.ShortTensor() # int16
print(data)
data torch.LongTensor() # int64
print(data)
data torch.FloatTensor() # float32
print(data)
data torch.DoubleTensor() # float64
print(data) 线性张量与随机张量 torch.arange 和 torch.linspace 创建线性张量 torch.random.init_seed 和 torch.random.manual_seed 随机种子设置 torch.randn 创建随机张量 线性张量
torch.arange()
# 1.1 arange() 左闭右开
data torch.arange(0, 11, 2)
print(data)
torch.linspace()
# 1.2 linspace() 左闭右闭
data torch.linspace(0, 10, 5)
print(data)
区别
arange(start, end, step): 起始, 截至, 步长(每步走多少, 左闭右开)
linspace(start, end, steps): 起始, 截止, 步数(走几步, 左闭右闭)
随机张量 torch.random.initial_seed()查看随机种子 torch.random.manual_seed() 设置随机数种子 torch.randn() 创建随机张量 创建随机张量
# 2.1 创建随机张量
data torch.randn(2, 3) # 2行3列
print(data)
# 2.2 查看随机种子
print(torch.random.initial_seed()) # 查看默认种子, 机器码
# 2.3 创建随机种子
torch.random.manual_seed(1) # 设置随机种子
data torch.randn(2, 3) # 随机张量
print(data)
print(torch.random.initial_seed()) 创建指定值张量 torch.ones 和 torch.ones_like(像什么形状) 创建全1张量 torch.zeros 和 torch.zeros_like 创建全0张量 torch.full([行数, 列数], 指定值) 和 torch.full_like 创建指定值张量 创建全0张量
创建结果为浮点型, zeros_like(data) 创建形状和data一样的张量
# 3.1 创建全0张量
data_zeros torch.zeros(2, 3)
print(0张量, data_zeros)
data_zeros torch.zeros_like(data_zeros)
print(0张量, data_zeros)
创建全1张量
# 3.2 创建全1张量
data_ons torch.ones(2, 3)
print(1张量, data_ons)
data_ons torch.tensor(data_ons)
print(1张量, data_ons)
创建全指定值张量
# 3.3 创建指定值张量
data_full torch.full((2, 3), 5)
print(指定值张量, data_full)
data_full torch.full_like(data_full, 10)
print(指定值张量, data_full) 张量元素类型转换 data.type(torch.DoubleTensor) data.double(), data.float()......小写 data.dtype: 查看数据类型 间接转换
data torch.full([2, 3], 10)
print(data.dtype)torch.int64
# 将 data 元素类型转换为 float64 类型
data data.type(torch.DoubleTensor)
print(data.dtype)torch.float64
# 转换为其他类型
# data data.type(torch.ShortTensor) # int16
# data data.type(torch.IntTensor) # int32
# data data.type(torch.LongTensor) # int64
# data data.type(torch.FloatTensor) # float32
直接转换
data torch.full([2, 3], 10)
print(data.dtype)torch.int64
# 将 data 元素类型转换为 float64 类型
data data.double()
print(data.dtype)torch.float64
# 转换为其他类型
# data data.short()
# data data.int()
# data data.long()
# data data.float()
张量创建总结
创建张量的方式 torch.tensor() 根据指定数据创建张量 torch.Tensor() 根据形状创建张量, 其也可用来创建指定数据的张量 torch.IntTensor()、torch.FloatTensor()、torch.DoubleTensor() 创建指定类型的张量
创建线性和随机张量 torch.arrange() 和 torch.linspace() 创建线性张量 torch.random.initial_seed() 和 torch.random.manual_seed() 随机种子设置 torch.randn() 创建随机张量
创建01张量 torch.ones() 和 torch.ones_like() 创建全1张量 torch.zeros() 和 torch.zeros_like() 创建全0张量 torch.full() 和 torch.full_like() 创建全为指定值张量
张量元素类型转换 data.type(torch.DoubleTensor) data.double()
二. 张量相关操作
张量的类型转换 张量转Numpy数组 使用 Tensor.numpy 函数可以将张量转换为 ndarray 数组但是共享内存可以使用 copy 函数避免共享。 import torch
torch.manual_seed(21)
data torch.randn(2, 3)
print(type(data))
data_numpy data.numpy().copy() # 设置不共享内存
print(type(data_numpy))
data[0][0] 100
print(data)
print(data_numpy) Numpy数组转张量 from_numpy(data_numpy):默认共享内存, 可以使用data_numpy.copy()复制一份, 避免内存共享 torch.tensor()/torch.Tensor ()此方法不共享内存 # numpy转张量
import numpy as np
data_numpy np.random.randn(2, 3)
print(type(data_numpy))
print(data_numpy)
# data_tensor torch.from_numpy(data_numpy) # 此方法共享内存
# data_tensor torch.from_numpy(data_numpy.copy()) # 此方法不共享内存
# data_tensor torch.tensor(data_numpy) # 此方法不共享内存
data_tensor torch.Tensor(data_numpy) # 此方法不共享内存
print(type(data_tensor))
print(data_tensor)
data_tensor[0][0] 100
print(data_numpy)
print(data_tensor) 标量张量和数字转换 当只有一个元素的张量时, 可以使用data.item()函数将该值从张量中取出 # 标量张量和数字转换
data torch.tensor(1)
print(data.item())
data torch.tensor([1, 2])
print(data.item()) # 报错 张量类型转换总结
张量转换为 numpy 数组 data_tensor.numpy() data_tensor.numpy().copy()
numpy 转换为张量 torch.from_numpy(data_numpy) torch.tensor(data_numpy)
标量张量和数字转换 data.item() 张量的数值计算 基本运算 1. 加减乘除取负号
2. add、sub-、mul*、div/、neg负号 不修改原数据
3. add_、sub_、mul_、div_、neg_ 修改原数据 import torch
torch.manual_seed(21)
data1 torch.randint(0, 10, [2, 3])
torch.manual_seed(22)
data2 torch.randint(10, 20, [3, 4])
torch.manual_seed(23)
data3 torch.randint(10, 20, [2, 3])
print(data1)
print(data2)
print(data3)
# 不修改原数据
print(data1.add(2))
print(data1.sub(2))
print(data1.mul(2))
print(data1.div(2))
print(data1.neg())
print(data1)
# # 修改原数据
print(data1.add_(2))
print(data1.sub_(2))
print(data1.mul_(2))
print(data1.neg_())
print(data1)
点乘运算 对应位置元素相乘 mul或者* # 点乘
print(data1.mul(data3))
print(data1 * data3)
矩阵运算 点积 (n, m) * (m, p) (n, p) matmul或者 # 点积
print(data1.matmul(data2))
print(data1 data2)
张量运算总结
张量基本运算函数 add、sub、mul、div、neg等函数 add、sub、mul、div、neg_等函数
张量的点乘运算 mul 和运算符 *
点积运算 运算符用于进行两个矩阵的点乘运算 torch.matmul 对进行点乘运算的两矩阵形状没有限定对数输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则 张量函数运算 PyTorch 为每个张量封装很多实用的计算函数 import torch
torch.manual_seed(21)
data torch.randint(1, 10, (2, 3), dtypetorch.float64)
print(data)
# 均值
print(data.mean())
print(data.mean(dim0)) # 按列求和
print(data.mean(dim1)) # 按行求和
# 平方
print(torch.pow(data, 2))
# 平方根
print(data.sqrt())
# 求和
print(data.sum())
print(data.sum(dim0))
print(data.sum(dim1))
# 指数计算(以e为底的指数)
print(data.exp())
# 对数计算
print(data.log()) # 以e为底
print(data.log2())
print(data.log10()) 张量索引操作
import torch
# 随机生成数据
data torch.randint(0, 10, [4, 5])
print(data)tensor([[0, 7, 6, 5, 9],[6, 8, 3, 1, 0],[6, 3, 8, 7, 3],[4, 9, 5, 3, 1]])
简单行列索引
print(data[0]) # 第0行数据tensor([0, 7, 6, 5, 9])
print(data[:, 0]) # 所有行第0列数据tensor([0, 6, 6, 4])
列表索引
# 返回 (0, 2)、(1, 3) 两个位置的元素
print(data[[0, 1], [2, 3]]) # 第0行第2列和第1行第3列tensor([7, 3])
# 返回 0、1 行的 1、2 列共4个元素
print(data[[[0], [1]], [1, 2]])tensor([[7, 6],[8, 3]])
范围索引
# 前3行的前2列数据
print(data[:3, :2])tensor([[0, 7],[6, 8],[6, 3]])
# 第2行到最后的前2列数据
print(data[2:, :2])tensor([[6, 3],[4, 9]])
# 第0行、第2行的第0、1两列数据
print(data[0:3:2, :2])# data[行(start, end, step), 列(start, end, step)]
tensor([[0, 7],[6, 3]])
布尔索引
# 第三列大于5的行数据
print(data[data[:, 2] 5])tensor([[0, 7, 6, 5, 9],[6, 3, 8, 7, 3]])
# 第二行大于5的列数据
# 所有数据第1列数据大于5的所有行数据
print(data[:, data[1] 5]) # data[行, 列] 第2行大于5的列tensor([[0, 7],[6, 8],[6, 3],[4, 9]])
# 所有行中第4列小于10的行数据
print(data[data[:, 3] 10]) 多维索引
# 范围索引
torch.random.manual_seed(21)
data torch.randint(0, 10, [3, 4, 5]) # 三通道、四行、五列
print(data)
tensor([[[3, 3, 6, 8, 6],[4, 0, 9, 8, 8],[3, 7, 2, 2, 6],[7, 8, 5, 9, 9]],
[[9, 4, 4, 4, 2],[2, 0, 8, 1, 2],[9, 8, 8, 3, 1],[4, 1, 6, 8, 8]],
[[4, 8, 2, 6, 3],[5, 8, 2, 9, 4],[6, 9, 5, 8, 6],[8, 5, 2, 0, 8]]])
print(data[:, 1:3, 2]) # 所有通道的第1行和第2行第2列的数据
tensor([[0, 8],[4, 0],[0, 7]])
print(data[1, :, :]) # 第二通道的所有行所有列的数据
tensor([[9, 4, 4, 4, 2],[2, 0, 8, 1, 2],[9, 8, 8, 3, 1],[4, 1, 6, 8, 8]]) 张量形状操作
有重塑、堆叠、挤压和解压
方法单行描述torch.reshape(input, shape)重塑 input 到 shape 如果兼容也可以使用 torch.Tensor.reshape()。tensor.view(shape)返回不同 shape 中的原始张量视图但与原始张量共享相同的数据。tensor.contiguous()将张量转换到整块内存上torch.stack(tensors, dim0)堆叠:沿着新的维度dim连接 tensors 的序列所有 tensors 必须具有相同的大小。torch.squeeze(input)降维:挤压 input 以移除值为 1 的所有尺寸。torch.unsqueeze(input, dim)升维:返回在 dim 处添加了维度值 1 的 input。torch.transpose(input,dim1,dim2)维度交换:实现交换张量形状的指定维度torch.permute(input, dims)返回原始 input 的视图其尺寸被置换重新排列为 dims。
深度学习模型神经网络都是以某种方式操纵张量。由于矩阵乘法的规则如果形状不匹配就会遇到错误。这些方法可帮助您确保张量的正确元素与其他张量的正确元素混合。 重塑维度形状 reshape reshape 函数可以在保证张量数据不变的前提下改变数据的维度将其转换成指定的形状。 使用 torch.reshape() 增加一个维度。 import torch
torch.random.manual_seed(21)
data torch.randint(0, 10, [4, 5, 6])
print(data)
print(data.shape)
print(data.size())
# 1. reshape
# 1.1 降维
data1 torch.reshape(data, [2, -1]) # -1表示自动计算
print(data1.shape) # torch.Size([2, 60])
# 1.2 改变形状
data2 torch.reshape(data, [2, 5, -1])
print(data2.shape) # torch.Size([2, 5, 12]) view/contiguous view 函数也可以用于修改张量的形状只能用于存储在整块内存中的张量。 在 PyTorch 中有些张量是由不同的数据块组成的它们并没有存储在整块的内存中view 函数无法对这样的张量进行变形处理。例如: 一个张量经过了 transpose 或者 permute 函数的处理之后就无法使用 view 函数进行形状操作。 此时需要先使用 contiguous 函数转换为整块内存的张量再使用 view 函数。 # 2. view(): 存储在一块内存上才可以操作
# 查看data是否在一块内存上
print(data.is_contiguous()) # True
# 2.1 在一块内存上, 改变形状
data3 data.view(3, 8, -1)
print(data3.shape) # torch.Size([3, 8, 5])
# 2.2 不在一块内存上, 改变形状
# 2.2.1 交换数据维度, 使数据在不同的内存上
# data4 data.permute(2, 0, 1) # 一次交换多个维度
data4 torch.transpose(data, 1, 2) # 交换两个维度
print(data4.is_contiguous()) # False
# 2.2.2 转换为同一内存
print(data4.contiguous().is_contiguous()) # True
# 改变形状
data5 data4.contiguous().view(3, 8, -1)
print(data5.shape) # torch.Size([3, 8, 5]) stack 将新张量堆叠五次使用 torch.stack() 来实现。 x torch.arange(1, 9)
x_stack torch.stack([x, x, x, x], dim0) # 按0维堆叠
print(x_stack) 升维降维 squeeze 函数删除形状为 1 的维度降维unsqueeze 函数添加形状为1的维度升维。 unsqueeze升维
# 4. unsqueeze(): 增加维度
data torch.tensor([1, 2, 3, 4, 5])
print(data.shape) # torch.Size([5])
data1 data.unsqueeze(dim0)
print(data1.shape) # torch.Size([1, 5])
data2 data.unsqueeze(dim1)
print(data2.shape) # torch.Size([5, 1])
data3 data.unsqueeze(dim-1)
print(data3.shape) # torch.Size([5, 1])
squeeze降维
只可以将维度1的维度删除
# 5. squeeze(): 删除维度
data4 data3.squeeze()
print(data4.shape) # torch.Size([5])
data5 data1.squeeze(dim0)
print(data5.shape) # torch.Size([5]) 维度交换 transpose 函数可以实现交换张量形状的指定维度, 例如: 一个张量的形状为 (2, 3, 4) 可以通过 transpose 函数把 3 和 4 进行交换, 将张量的形状变为 (2, 4, 3) 。 permute 函数可以一次交换更多的维度。 # 6. 交换维度
data torch.randint(0, 10, [4, 5, 6])
print(data.shape) # torch.Size([4, 5, 6])
# 交换1和2维度
data1 torch.transpose(data, 1, 2)
print(data1.shape) # torch.Size([4, 6, 5])
data2 data.permute(0, 2, 1)
print(data2.shape) # torch.Size([4, 6, 5]) 张量形状总结 reshape 函数可以在保证张量数据不变的前提下改变数据的维度 squeeze 和 unsqueeze 函数可以用来增加或者减少维度 transpose 函数可以实现交换张量形状的指定维度, permute 可以一次交换更多的维度 view 函数也可以用于修改张量的形状, 但是它要求被转换的张量内存必须连续所以一般配合 contiguous 函数使用 张量拼接 将多个张量按指定维度(根据维度索引)拼接成一个张量 torch.cat([data1, data2...], dim维度索引) import torch
data1 torch.randint(1, 11, [1, 3, 4])
data2 torch.randint(1, 11, [1, 3, 4])
# print(data1)
# print(data2)
# 按0维拼接
data3 torch.cat([data1, data2], dim0)
print(data3)
print(data3.shape)
# 按1维拼接
data4 torch.cat([data1, data2], dim1)
print(data4)
print(data4.shape)
# 按2维拼接
data5 torch.cat([data1, data2], dim2)
print(data5)
print(data5.shape) 自动微分模块 再反向传播中, 用于计算梯度 正向传播: 由x得到z
反向传播: 由损失更新权重参数
一维 多维
import torch
def test02():# 输入张量 2*5x torch.ones(2,5)# 目标值是 2*3y torch.zeros(2,3)# 设置要更新的权重和偏置的初始值w torch.randn(5, 3,requires_gradTrue)b torch.randn(3, requires_gradTrue)# 设置网络的输出值z torch.matmul(x, w) b # 矩阵乘法# 设置损失函数并进行损失的计算loss torch.nn.MSELoss()loss loss(z, y)# 自动微分loss.backward()# 打印 w,b 变量的梯度# backward 函数计算的梯度值会存储在张量的 grad 变量中print(W的梯度:, w.grad)print(b的梯度, b.grad)
案例-线性回归 pytorch模型构建流程: 准备训练集数据 使用 PyTorch 的 data.DataLoader 代替自定义的数据加载器 打乱数据顺序, 数据分批次 构建要使用的模型 使用 PyTorch 的 nn.Linear 代替自定义的假设函数 设置损失函数和优化器 使用 PyTorch 的 nn.MSELoss() 代替自定义的平方损失函数 使用 PyTorch 的 optim.SGD 代替自定义的优化器 模型训练 225原则: 2: 2个初始化参数(损失函数, 优化器) 2: 2个遍历(epoch: 轮次, 数据: 批次大小) 5: 前向传播, 损失函数, 梯度清零, 反向传播, 参数更新 构建数据集
# 导入相关模块
import torch
from torch.utils.data import TensorDataset # 构造数据集对象
from torch.utils.data import DataLoader # 数据加载器
from torch import nn # nn模块中有平方损失函数和假设函数
from torch import optim # optim模块中有优化器函数
from sklearn.datasets import make_regression # 创建线性回归模型数据集
import matplotlib.pyplot as plt
plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签
plt.rcParams[axes.unicode_minus] False # 用来正常显示负号
# 定义函数创建数据集: 线性回归: y kx b
def creat_datasets():x, y, coef make_regression(n_samples100,n_features1,noise10,coefTrue,bias1.5,random_state21)x torch.tensor(x)y torch.tensor(y)
return x, y, coef
if __name__ __main__:x, y, coef creat_datasets()plt.scatter(x, y)x torch.linspace(x.min(), x.max(), 1000)# y1 torch.tensor([coef * i 1.5 for i in x]) # 报错y1 torch.tensor([i * coef 1.5 for i in x]) # i为张量, 只可以张量 * 标量plt.plot(x, y1, labelpredict)plt.legend()plt.grid()plt.xlabel(x)plt.ylabel(y)plt.show()
构建数据加载器和模型构建
# 构建数据加载器和模型
def data_loader(x, y):# 构造数据集对象dataset TensorDataset(x, y)# 构造数据加载器# batch_size: 批次大小# batch: 批次数量# shuffle: 是否打乱顺序dataloader DataLoader(dataset, batch_size10, shuffleTrue)# 构造模型model nn.Linear(1, 1)return dataloader, model
训练参数设置
# 设置损失函数和优化器
def loss_optimizer(model):# 设置损失函数: 均方损失函数loss_fn nn.MSELoss()# 设置优化器: 随机梯度下降, 学习率0.01optimizer optim.SGD(model.parameters(), lr0.01)return loss_fn, optimizer
模型训练
# 训练模型
def train_model(dataloader, model, loss_fn, optimizer):# 训练100轮epoch 100# 存储每轮损失loss_epoch []total_loss 0train_sample 0# 训练轮次for i in range(epoch):# 遍历批次for train_x, train_y in dataloader:# 预测值, 正向传播y_pred model(train_x.type(torch.float32))# 计算损失loss loss_fn(y_pred, train_y.reshape(-1, 1).type(torch.float32))# 累加损失total_loss loss.item()# 累加样本数量train_sample len(train_y)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 优化器更新参数optimizer.step()# 存储批次损失loss_epoch.append(total_loss / train_sample)return loss_epoch, epoch
轮次损失可视化
if __name__ __main__:x, y, coef creat_datasets()dataloader, model data_loader(x, y)loss_fn, optimizer loss_optimizer(model)loss_epoch, epochs train_model(dataloader, model, loss_fn, optimizer)print(loss_epoch)# 绘制损失变化曲线plt.plot(range(epochs), loss_epoch)plt.title(损失变化曲线)plt.grid()plt.show()# 绘制拟合直线plt.scatter(x, y)x torch.linspace(x.min(), x.max(), 1000)y1 torch.tensor([v * model.weight model.bias for v in x])y2 torch.tensor([v * coef 1.5 for v in x])plt.plot(x, y1, label训练)plt.plot(x, y2, label真实)plt.grid()plt.legend()plt.show() 案例总结