1. 环境配置
1.1 anconda配置环境
conda create -n DL_pytorch python=3.11
conda acticvate DL_pytorch
conda deactivate
conda env list
conda remove -n DL_pytorch --all
1.2 torch CPU环境配置
pip install torch==1.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
conda install torch==1.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
1.3 torch GPU环境配置
安装或者更新nvidia显卡驱动:
https://www.nvidia.cn/Download/index.aspx?lang=cn
安装CUDA:
https://developer.nvidia.com/cuda-toolkit-archive
nvidia-smi
nvcc -V
配置cuDNN:
https://developer.nvidia.com/rdp/cudnn-archive
下载bin include 三个文件
放在cuda的安装路径:
Windows:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA
Linux:/usr/local/cuda
2. 张量的基本使用
2.1 张量的创建
import torch
import numpy as np
torch.tensor # 注意这里是小写的tensor
torch.tensor(10) # 标量
torch.tensor([1, 2, 3]) # 向量
tensor([1, 2, 3])
data = np.random.randn(2, 3) # 通过numpy数组 创建
data = torch.tensor(data)
data
tensor([[-0.5604, -1.0443, 1.1241],
[ 1.2787, 0.4894, -0.2351]], dtype=torch.float64)
data = [[10., 20., 30.], [40., 50., 60.]] # 通过列表创建tensor
data = torch.tensor(data)
data
tensor([[10., 20., 30.],
[40., 50., 60.]])
根据形状来创
torch.Tensor # 注意这里是大写的Tensor
data = torch.Tensor(2, 3) # 创建 (2, 3)的tensor
data
tensor([[1.0663e-08, 6.4833e-10, 6.6646e-10],
[2.1237e+20, 1.3226e-08, 3.4164e+21]])
data = torch.Tensor([10])
data
tensor([10.])
data = torch.Tensor([10, 20])
data
tensor([10., 20.])
创建指定类型的tensor torch.IntTensor、torch.FloatTensor、torch.DoubleTensor
torch.IntTensor(2, 3)
tensor([[ 909194802, 1664692277, 1650538552],
[1647326519, 879060020, 842555749]], dtype=torch.int32)
torch.IntTensor([2.5, 3.3]) # 截取整数部分
tensor([2, 3], dtype=torch.int32)
torch.ShortTensor(2,3)
tensor([[257, 0, 0],
[ 0, 0, 0]], dtype=torch.int16)
torch.LongTensor(2, 3)
tensor([[0, 0, 0],
[0, 0, 0]])
torch.FloatTensor(2, 3)
tensor([[4.1327e-39, 1.0102e-38, 1.0194e-38],
[9.1837e-39, 8.4490e-39, 9.6428e-39]])
torch.DoubleTensor(2, 3)
tensor([[0., 0., 0.],
[0., 0., 0.]], dtype=torch.float64)
线性张量 随机张量
torch.arange(0, 10, 2) # start end step
tensor([0, 2, 4, 6, 8])
torch.linspace(0, 1, 10) # start end steps # 总共多少steps
tensor([0.0000, 0.1111, 0.2222, 0.3333, 0.4444, 0.5556, 0.6667, 0.7778, 0.8889,
1.0000])
torch.random.initial_seed()# 查看随机种子
torch.random.manual_seed(100) # 设置随机种子
<torch._C.Generator at 0x233ac7ff1f0>
torch.randn(2, 3)
tensor([[ 0.3607, -0.2859, -0.3938],
[ 0.2429, -1.3833, -2.3134]])
# 0-1张量
torch.zeros(2, 3)
tensor([[0., 0., 0.],
[0., 0., 0.]])
torch.zeros_like(torch.Tensor([[1, 2], [3, 4]]))
tensor([[0., 0.],
[0., 0.]])
torch.ones(2,5)
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
torch.full([2,4], 33)
tensor([[33, 33, 33, 33],
[33, 33, 33, 33]])
data = torch.full([2,4], 33)
data.type(torch.FloatTensor)
tensor([[33., 33., 33., 33.],
[33., 33., 33., 33.]])
data.short()
data.int()
data.long()
data.float()
tensor([[33., 33., 33., 33.],
[33., 33., 33., 33.]])
2.2 张量类型转换
numpy数组与tensor之间的转换
data
tensor([[33, 33, 33, 33],
[33, 33, 33, 33]])
data_t = data.numpy() # tensor直接转numpy数组 # 共享内存
data_t[0][0] = 44
data_t, data
(array([[44, 33, 33, 33],
[33, 33, 33, 33]], dtype=int64),
tensor([[44, 33, 33, 33],
[33, 33, 33, 33]]))
data_t_2 = data.numpy().copy() # 不共享内存
data_t_2[0][1] = 555
data_t_2, data
(array([[ 44, 555, 33, 33],
[ 33, 33, 33, 33]], dtype=int64),
tensor([[44, 33, 33, 33],
[33, 33, 33, 33]]))
data_numpy = np.random.randn(2, 5)
print(data_numpy)
data_t = torch.from_numpy(data_numpy) # 共享内存
data_t
[[-0.25562675 0.14893395 1.23102334 0.50414347 0.55989952]
[-0.32142073 -0.4290815 0.22257028 0.31362279 0.8518773 ]]
tensor([[-0.2556, 0.1489, 1.2310, 0.5041, 0.5599],
[-0.3214, -0.4291, 0.2226, 0.3136, 0.8519]], dtype=torch.float64)
data_t_2 = torch.tensor(data_numpy) # 不共享内存
data_t_2
tensor([[-0.2556, 0.1489, 1.2310, 0.5041, 0.5599],
[-0.3214, -0.4291, 0.2226, 0.3136, 0.8519]], dtype=torch.float64)
data = torch.tensor([30, ])
data.item() # 提取标量元素
30
data = torch.tensor(30)
data.item()
30
2.3 张量的数值计算 **重点内容
# add sub mul div neg 不会改变原数据 对应位置进行操作
data = data = torch.full([2,4], 1)
print(data)
data1 = data.add(torch.full([2,4], 4)) # size需要一样
print(data1)
data2 = data.sub(1)
data3 = data.mul(torch.full([2,4], 4)) # 点乘 对应位置相乘
print(data3)
data4 = data.div(2)
data5 = data.neg()
data5
# add_ sub_ mul_ neg_ 会修改原数据 直接操作后覆盖掉原来的
tensor([[1, 1, 1, 1],
[1, 1, 1, 1]])
tensor([[5, 5, 5, 5],
[5, 5, 5, 5]])
tensor([[4, 4, 4, 4],
[4, 4, 4, 4]])
tensor([[-1, -1, -1, -1],
[-1, -1, -1, -1]])
点乘
# 两个size相同的矩阵 对应位置元素 相乘
# mul * 都可以
data1 = torch.tensor([[1, 2], [3, 4]])
data2 = torch.tensor([[5, 6], [7, 8]])
data = torch.mul(data1, data2)
print(data)
tensor([[ 5, 12],
[21, 32]])
data1 * data2
tensor([[ 5, 12],
[21, 32]])
点积 -- 线性代数里面的矩阵乘法
# 第一个矩阵shape (n, m) 第二个矩阵(m, p) 输出shape:(n, p)
# matmul 运算符@ 都可以
data1 = torch.tensor([[1, 2], [3, 4], [5, 6]]) # shape: (3, 2)
data2 = torch.tensor([[5, 6], [7,8]]) # shape:(2, 2)
data = data1 @ data2
print(data)
data = torch.matmul(data1, data2)
print(data)
tensor([[19, 22],
[43, 50],
[67, 78]])
tensor([[19, 22],
[43, 50],
[67, 78]])
2.4 张量运算函数
# 均值 mean
data = torch.randn(2, 3)
print(data)
data.mean()
data.mean(dim=0) # 列
data.mean(dim=1) # 行
# 平方 pow
torch.pow(data, 2)
# 平方根 sqrt
torch.sqrt(data)
data.sqrt()
# 求和
data.sum()
data.sum(dim=0) # 列
data.sum(dim=1) # 行
# 指数计算
data.exp() # e^x 次方
# 对数计算
data.log()
data.log2()
data.log10()
tensor([[-0.5200, -2.6718, 1.1100],
[-1.4660, 1.2769, -0.5401]])
tensor([[ nan, nan, 0.0453],
[ nan, 0.1062, nan]])
2.5 张量的索引操作
# 行 列 索引
print(data)
data[0] # 第0行
data[:, 0] # 行不管 所有第0列
tensor([[-0.5200, -2.6718, 1.1100],
[-1.4660, 1.2769, -0.5401]])
tensor([-0.5200, -1.4660])
# 列表索引
data[[0,1], [1, 2]] # 取出[0,1], [1, 2]位置的元素
tensor([-2.6718, -0.5401])
有点难
data[[[0], [1]], [1, 2]] # 返回0、1两行 1、2列 共4个元素
"""
索引 [[0], [1]] 表示选择第一行(索引 0)和第二行(索引 1),而 [1, 2] 表示选择每一行中的第二列(索引 1)和第三列(索引 2)。
索引操作 data[[[0], [1]], [1, 2]] 的工作原理如下:
[[0], [1]] 是一个形状为 (2, 1) 的索引张量,表示选取第一行和第二行。
[1, 2] 是一个形状为 (2,) 的索引张量,表示选取每行中的第二列和第三列。
"""
'\n索引 [[0], [1]] 表示选择第一行(索引 0)和第二行(索引 1),而 [1, 2] 表示选择每一行中的第二列(索引 1)和第三列(索引 2)。\n\n索引操作 data[[[0], [1]], [1, 2]] 的工作原理如下:\n\n[[0], [1]] 是一个形状为 (2, 1) 的索引张量,表示选取第一行和第二行。\n[1, 2] 是一个形状为 (2,) 的索引张量,表示选取每行中的第二列和第三列。\n'
# 范围索引 注意 : 的使用
data = torch.randn(4, 5)
data
tensor([[-1.3608, 0.1249, -0.4400, -0.3507, -0.5745],
[-0.5747, 0.7298, -0.2237, 0.0371, 0.6545],
[-0.2542, -0.7038, -0.1101, -0.6953, -2.4869],
[ 0.6016, 0.5706, 0.5814, 0.0257, 0.5501]])
data[:3, :2] # 前3行 前2列
tensor([[-1.3608, 0.1249],
[-0.5747, 0.7298],
[-0.2542, -0.7038]])
data[2:, :2] # 第二行 到最后 前两列
tensor([[-0.2542, -0.7038],
[ 0.6016, 0.5706]])
布尔索引
print(data)
data[data[:,2] > 0]
tensor([[-1.3608, 0.1249, -0.4400, -0.3507, -0.5745],
[-0.5747, 0.7298, -0.2237, 0.0371, 0.6545],
[-0.2542, -0.7038, -0.1101, -0.6953, -2.4869],
[ 0.6016, 0.5706, 0.5814, 0.0257, 0.5501]])
tensor([[0.6016, 0.5706, 0.5814, 0.0257, 0.5501]])
你正在对张量 data 执行布尔索引(boolean indexing)。这里的目标是选择 data 中所有第三列大于 0 的行。
- data[:,2]: 这个表达式选择了 data 张量中所有的第三列(索引为 2)。结果是一个一维张量,
包含了每一行的第三列的值:tensor([-0.4400, -0.2237, -0.1101, 0.5814]) - data[:,2] > 0: 这个表达式会产生一个布尔掩码,指示第三列的每个元素是否大于 0:tensor([False, False, False, True])
- data[data[:,2] > 0]: 最后,这个表达式使用上面得到的布尔掩码来选择原始张量 data 中满足条件的行。也就是说,只有当掩码中的值为 True 时,对应的行才会被选择出来
data[:, data[1] > 0] # 对列数据进行选择 条件:data[1]>0 第二行大于0的
tensor([[ 0.1249, -0.3507, -0.5745],
[ 0.7298, 0.0371, 0.6545],
[-0.7038, -0.6953, -2.4869],
[ 0.5706, 0.0257, 0.5501]])
# 多维索引
data = torch.randn(3, 4, 5)
data
tensor([[[-0.6116, 0.5543, -0.6651, -0.3359, 0.5927],
[-1.0827, 1.1656, -1.2133, -0.1537, 0.8497],
[-0.8250, -0.8993, 0.0117, -2.1280, 1.6864],
[-0.2162, 0.4295, 0.4811, 0.2097, 0.6806]],
[[-0.1514, 0.6108, 0.0778, 1.5342, 0.2500],
[ 0.9691, -0.6606, -0.1131, 1.4533, 0.7470],
[-0.9503, -0.3014, -0.8767, -0.3568, 0.7205],
[ 0.1470, -0.3025, -0.6386, 0.6149, -0.4721]],
[[-0.3975, 0.0386, -1.1172, 1.5829, 1.3345],
[-1.3295, 2.5171, 0.4138, 0.2716, -0.1553],
[-1.7482, 0.8090, 1.2613, 0.9671, 0.8621],
[ 1.2277, -0.7056, 0.7022, -0.0756, 0.2025]]])
data[0, :, : ] # batch=0的数据取出
tensor([[-0.6116, 0.5543, -0.6651, -0.3359, 0.5927],
[-1.0827, 1.1656, -1.2133, -0.1537, 0.8497],
[-0.8250, -0.8993, 0.0117, -2.1280, 1.6864],
[-0.2162, 0.4295, 0.4811, 0.2097, 0.6806]])
data[:,0,:] # 获取1轴 的第一个数据
tensor([[-0.6116, 0.5543, -0.6651, -0.3359, 0.5927],
[-0.1514, 0.6108, 0.0778, 1.5342, 0.2500],
[-0.3975, 0.0386, -1.1172, 1.5829, 1.3345]])
data[:,:,0]
tensor([[-0.6116, -1.0827, -0.8250, -0.2162],
[-0.1514, 0.9691, -0.9503, 0.1470],
[-0.3975, -1.3295, -1.7482, 1.2277]])
2.6 张量的形状操作
# reshape
data = torch.randn(2, 3)
data.reshape(1, 6)
tensor([[ 1.0803, 0.1024, -0.4122, 0.6845, 0.2331, -1.1714]])
view contigous
data.view(6)
tensor([ 1.0803, 0.1024, -0.4122, 0.6845, 0.2331, -1.1714])
只能用于存储在整块内存中的张量 一个张量经过transpose 或者permute 函数处理之后 就无法使用view函数 解决办法:先试用contiguous函数转化成整块内存的张量, 再使用view
print(data)
data = data.transpose(1, 0)
print(data)
data.contiguous().view(6)
tensor([[ 1.0803, 0.6845],
[ 0.1024, 0.2331],
[-0.4122, -1.1714]])
tensor([[ 1.0803, 0.1024, -0.4122],
[ 0.6845, 0.2331, -1.1714]])
tensor([ 1.0803, 0.1024, -0.4122, 0.6845, 0.2331, -1.1714])
stack
x = torch.tensor([1, 2, 3, 4, 5, 6, 7])
torch.stack([x, x, x], dim=0)
tensor([[1, 2, 3, 4, 5, 6, 7],
[1, 2, 3, 4, 5, 6, 7],
[1, 2, 3, 4, 5, 6, 7]])
torch.stack([x, x, x], dim=1)
tensor([[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4],
[5, 5, 5],
[6, 6, 6],
[7, 7, 7]])
squeeze 降维 unsqueeze升维度
data = torch.tensor([1, 2, 3, 4, 5])
data.size()
torch.Size([5])
data_2 = data.unsqueeze(dim=0) # 原来为[5] 在0位置 增加一维度
print(data_2)
print(data_2.size())
tensor([[1, 2, 3, 4, 5]])
torch.Size([1, 5])
data3 = data.unsqueeze(dim=1) # 原来是[5] 转换成 [5, 1]
print(data3)
print(data3.size())
tensor([[1],
[2],
[3],
[4],
[5]])
torch.Size([5, 1])
data4 = data.unsqueeze(dim=-1) # 在-1维度上 拓展维度
print(data4)
print(data4.size())
tensor([[1],
[2],
[3],
[4],
[5]])
torch.Size([5, 1])
data5 = data4.squeeze(dim=-1)# 在-1维度上 缩减维度
print(data5)
print(data5.size())
tensor([1, 2, 3, 4, 5])
torch.Size([5])
transpose permute
# transpose 只能2个维度交换
data = torch.randn(3, 4)
data
tensor([[-1.0069, 0.7304, -1.3472, 0.5965],
[ 0.4020, 1.7312, -0.3246, 1.3733],
[-0.4804, -0.0982, 0.7994, 1.2517]])
torch.transpose(data, 1, 0)
tensor([[-1.0069, 0.4020, -0.4804],
[ 0.7304, 1.7312, -0.0982],
[-1.3472, -0.3246, 0.7994],
[ 0.5965, 1.3733, 1.2517]])
data = torch.randn(3, 4, 5)
print(data)
torch.permute(data, [1, 2, 0])
tensor([[[ 1.0964, -0.8027, -0.4841, -0.6895, 1.7071],
[-1.6045, -0.5880, 1.1074, 0.4812, -1.2373],
[ 1.7160, 0.1088, -0.6017, 0.2499, -1.1512],
[-0.4349, -1.0886, 0.3174, 0.1676, 1.4173]],
[[ 0.0233, -0.8274, 1.0045, -0.4129, 0.3580],
[ 0.4398, -1.3933, -1.3686, 0.0073, 1.4153],
[-1.3518, 0.0532, 0.1976, 0.2051, -0.2813],
[-1.6588, -0.8350, 0.8495, -0.5495, -0.7754]],
[[ 0.8632, 0.6078, -0.8819, -0.5462, 0.4548],
[-0.5378, 1.0573, -0.5659, -1.2096, 0.2418],
[-0.1599, 0.8649, -1.0205, 1.1256, 0.2203],
[-1.4804, 0.2306, -1.1593, 0.5648, -0.6707]]])
tensor([[[ 1.0964, 0.0233, 0.8632],
[-0.8027, -0.8274, 0.6078],
[-0.4841, 1.0045, -0.8819],
[-0.6895, -0.4129, -0.5462],
[ 1.7071, 0.3580, 0.4548]],
[[-1.6045, 0.4398, -0.5378],
[-0.5880, -1.3933, 1.0573],
[ 1.1074, -1.3686, -0.5659],
[ 0.4812, 0.0073, -1.2096],
[-1.2373, 1.4153, 0.2418]],
[[ 1.7160, -1.3518, -0.1599],
[ 0.1088, 0.0532, 0.8649],
[-0.6017, 0.1976, -1.0205],
[ 0.2499, 0.2051, 1.1256],
[-1.1512, -0.2813, 0.2203]],
[[-0.4349, -1.6588, -1.4804],
[-1.0886, -0.8350, 0.2306],
[ 0.3174, 0.8495, -1.1593],
[ 0.1676, -0.5495, 0.5648],
[ 1.4173, -0.7754, -0.6707]]])
2.7 张量的拼接操作
维度变 3维的 还是3维的 但是‘面积’变大而已
例如:[1, 2, 3] 第一个维度代表批次 两条这样的数据cat在一次 则变成[2, 2, 3] 多了一条数据而已
data1 = torch.randint(0, 10, [1, 2, 3])
data2 = torch.randint(0, 10, [1, 2, 3])
data1, data2
(tensor([[[5, 7, 2],
[4, 9, 2]]]),
tensor([[[0, 0, 1],
[9, 8, 7]]]))
new_data = torch.cat([data1, data2], dim=0)
print(new_data)
print(new_data.size())
tensor([[[5, 7, 2],
[4, 9, 2]],
[[0, 0, 1],
[9, 8, 7]]])
torch.Size([2, 2, 3])
new_data = torch.cat([data1, data2], dim=1)
print(new_data)
print(new_data.size())
tensor([[[5, 7, 2],
[4, 9, 2],
[0, 0, 1],
[9, 8, 7]]])
torch.Size([1, 4, 3])
new_data = torch.cat([data1, data2], dim=2)
print(new_data)
print(new_data.size())
tensor([[[5, 7, 2, 0, 0, 1],
[4, 9, 2, 9, 8, 7]]])
torch.Size([1, 2, 6])
2.8 自动微分模块
标签:tensor,33,torch,张量,003,pytorch,basic,print,data
From: https://www.cnblogs.com/cavalier-chen/p/18384961