文章目录
- [1 张量的创建](#1 张量的创建)
-
- [1.1 根据已有的数据创建张量](#1.1 根据已有的数据创建张量)
- [1.2 创建指定形状的张量](#1.2 创建指定形状的张量)
- [1.3 创建指定类型的张量](#1.3 创建指定类型的张量)
- [1.4 创建线性张量](#1.4 创建线性张量)
- [1.5 创建随机张量](#1.5 创建随机张量)
- [1.6 创建全为0的张量](#1.6 创建全为0的张量)
- [1,7 创建全为1的张量](#1,7 创建全为1的张量)
- [1.8 创建全为指定值的张量](#1.8 创建全为指定值的张量)
- [1.9 张量元素类型转换](#1.9 张量元素类型转换)
- [2 张量运算](#2 张量运算)
-
- [2.1 张量的基本运算](#2.1 张量的基本运算)
- [2.2 阿达玛积](#2.2 阿达玛积)
- [2.3 点积运算](#2.3 点积运算)
- [2.4 指定设备进行运算](#2.4 指定设备进行运算)
- [3 张量与numpy数组转换](#3 张量与numpy数组转换)
-
- [3.1 张量转换为numpy数组](#3.1 张量转换为numpy数组)
- [3.2 numpy数组转换为张量](#3.2 numpy数组转换为张量)
- [3.3 提取单值张量](#3.3 提取单值张量)
- [4 张量的拼接](#4 张量的拼接)
-
- [4.1 cat函数使用](#4.1 cat函数使用)
- [4.2 stack函数使用](#4.2 stack函数使用)
1 张量的创建
python
import torch
import numpy as np
1.1 根据已有的数据创建张量
- 使用torch.tensor()方法,根据已有数据创建张量
- 创建张量的时候,默认使用原有数据的数据类型
python
def test01():
# 1.1 创建标量
data = torch.tensor(10)
print(data)
# 1.2 使用numpy数组来创建张量
# 传入numpy数组,张量默认的类型是float64
data = np.random.randn(2, 3) # float64
data = torch.tensor(data)
print(data)
# 1.3 使用list列表创建张量
# 传入列表,张量的默认的类型是float32
data = [[10., 20., 30.], [40., 50., 60.]]
data = torch.tensor(data)
print(data)
1.2 创建指定形状的张量
- torch.Tensor(),可以根据指定的形状创建张量
python
def test02():
# 2.1 创建2行3列的张量
data = torch.Tensor(2, 3)
print(data)
# 2.2 可以创建指定值的张量
# 注意: 传递列表
data = torch.Tensor([2, 3])
print(data)
data = torch.Tensor([10])
print(data)
1.3 创建指定类型的张量
- tensor.IntTensor()
- tensor.DoubleTensor()
python
def test03():
# 前面创建的张量都是使用默认类型或者元素类型
# 创建一个 int32 类型的张量
data = torch.IntTensor(2, 3)
print(data)
# torch.ShortTensor(2, 3) # 表示创建的是 int16 张量
# torch.LongTensor(2, 3) # 表示创建的是 int32 张量
# torch.FloatTensor(2, 3) # 表示创建的是 float32 张量
# 注意: 如果创建指定类型的张量,但是传递的数据不匹配,会发生类型转换
data = torch.IntTensor([2.5, 3.5])
print(data)
import torch
1.4 创建线性张量
python
def test01():
# 1.1 创建指定步长的张量
# 第一参数: 开始值
# 第二参数: 结束值
# 第三参数: 步长
data = torch.arange(0, 10, 2) # tensor([0, 2, 4, 6, 8])
print(data)
# 1.2 在指定区间指定元素个数
# 第一个参数: 开始值
# 第二个参数: 结束值
# 第三个参数: 创建元素的个数
data = torch.linspace(0, 11, 10) # tensor([ 0.0000, 1.2222, 2.4444, 3.6667, 4.8889, 6.1111, 7.3333, 8.5556,
# 9.7778, 11.0000])
print(data)
1.5 创建随机张量
python
def test02():
# 固定随机数种子
# 设置随机种子之后,就可以固定随机数
# 下面的代码,每次执行,产生的随机数都是一样的
torch.random.manual_seed(0)
# 2.1 创建随机张量
# torch.randn - 创建0-1之间的随机张量
# torch.randint(start,end,(shape)) - 创建整型随机张量
data = torch.randn(2, 3)
print(data)
# 2.2 希望能够固定随机数
print('随机数种子:', torch.random.initial_seed())
1.6 创建全为0的张量
python
def test01():
# 1.1 创建指定形状全为0的张量
data = torch.zeros(2, 3)
print(data)
# 1.2 根据其他张量的形状去创建全0张量
data = torch.zeros_like(data)
print(data)
1,7 创建全为1的张量
python
def test02():
# 2.1 创建指定形状全为1的张量
data = torch.ones(2, 3)
print(data)
# 2.2 根据其他张量的形状去创建全1张量
data = torch.ones_like(data)
print(data)
1.8 创建全为指定值的张量
python
def test03():
# 3.1 创建形状为2行3列,值全部为10的张量
data = torch.full([2, 3], 100)
print(data)
# 3.2 创建一个形状和data一样,但是值全部为200的张量
data = torch.full_like(data, 200)
print(data)
1.9 张量元素类型转换
python
import torch
# 1. type 函数进行转换
def test01():
data = torch.full([2, 3], 10)
print(data.dtype)
# 注意: 返回一个新的类型转换过的张量
# 不会修改原来的类型,使用type函数的时候通常使用一个新的变量承接新创建的变量
data = data.type(torch.DoubleTensor)
print(data.dtype)
# 2. 使用具体类型函数进行转换
def test02():
data = torch.full([2, 3], 10)
print(data.dtype)
# 转换成 float64 类型
data = data.double()
print(data.dtype)
data = data.short() # 将张量元素转换为 int16 类型
data = data.int() # 将张量转换为 int32 类型
data = data.long() # 将张量转换为 int64 类型
data = data.float() # 将张量转换为 float32
2 张量运算
2.1 张量的基本运算
python
# 1. 不修改原数据的计算
# 函数不带下划线,计算完成之后会返回一个新的张量
def test01():
# 产生指定形状的整型随机张量
# 第一个参数: 开始值
# 第二个参数: 结束值
# 第三个参数: 形状
data = torch.randint(0, 10, [2, 3])
print(data)
# 计算完成之后,会返回一个新的张量
# 与标量数值进行计算
data = data.add(10)
print(data)
# data.sub() # 减法
# data.mul() # 乘法
# data.div() # 除法
# data.neg() # 取相反数
# 2. 修改原数据的计算(inplace方式的计算)
def test02():
data = torch.randint(0, 10, [2, 3])
print(data)
# 带下划线的版本的函数直接修改原数据,不需要用新的变量保存
data.add_(10)
print(data)
# data.sub_() # 减法
# data.mul_() # 乘法
# data.div_() # 除法
# data.neg_() # 取相反数
2.2 阿达玛积
- 对应位置的元素进行相乘
python
import torch
# 1. 使用 mul 函数
# 阿达玛积计算:矩阵对应位置相乘
def test01():
data1 = torch.tensor([[1, 2], [3, 4]])
data2 = torch.tensor([[5, 6], [7, 8]])
data = data1.mul(data2)
print(data)
# 2. 使用 * 号运算符
def test02():
data1 = torch.tensor([[1, 2], [3, 4]])
data2 = torch.tensor([[5, 6], [7, 8]])
data = data1 * data2
print(data)
2.3 点积运算
- 按照矩阵的运算规则进行运算
- mm() - 必须传入两个二维张量
- bmm() - 必须传入两个三维张量
python
import torch
# 1. 使用 @ 运算符
# 按照矩阵运算的规则进行运算 - 点积运算
def test01():
# 形状为: 3行2列
data1 = torch.tensor([[1, 2],
[3, 4],
[5, 6]])
# 形状为: 2行2列
data2 = torch.tensor([[5, 6],
[7, 8]])
data = data1 @ data2
print(data)
# 2. 使用 mm 函数
# 两个运算的矩阵是必须是二维的
def test02():
# 要求输入的张量形状都是二维
# 形状为: 3行2列
data1 = torch.tensor([[1, 2],
[3, 4],
[5, 6]])
# 形状为: 2行2列
data2 = torch.tensor([[5, 6],
[7, 8]])
data = torch.mm(data1, data2)
print(data)
# 3. 使用 bmm 函数
# 传入的两个矩阵必须是三维的
def test03():
# 第一个维度: 表示批次
# 第二个维度: 多少行
# 第三个维度: 多少列
data1 = torch.randn(3, 4, 5)
data2 = torch.randn(3, 5, 8)
data = torch.bmm(data1, data2)
print(data.shape)
# 4. 使用 matmul 函数
def test04():
# 对二维进行计算
data1 = torch.randn(4, 5)
data2 = torch.randn(5, 8)
print(torch.matmul(data1, data2).shape)
# 对三维进行计算
data1 = torch.randn(3, 4, 5)
data2 = torch.randn(3, 5, 8)
print(torch.matmul(data1, data2).shape)
# 也可以进行计算
data1 = torch.randn(3, 4, 5)
data2 = torch.randn(5, 8)
print(torch.matmul(data1, data2).shape)
2.4 指定设备进行运算
- 张量运算可以运行在CPU中,也可以运算在GPU当中
- 创建张量的时候,可以通过device参数指定设备
- 使用data.cuda()方法,指定GPU作为运算设备
- 使用data.to(设备名称),指定运算设备
- 在不同设备上的张量是不能进行运算的
python
import torch
# 默认创建在CPU中的内存中
# 1. 使用 cuda 方法
def test01():
data = torch.tensor([10, 20, 30])
print('存储设备:', data.device)
# 将张量移动到 GPU 设备上
# cuda就表示GPU
data = data.cuda()
print('存储设备:', data.device)
# 将张量从GPU再移动到CPU
data = data.cpu()
print('存储设备:', data.device)
# 2. 直接将张量创建在指定设备上
# 创建张量的时候,通过device参数指定张量创建的位置
def test02():
data = torch.tensor([10, 20, 30], device='cuda:0')
print('存储设备:', data.device)
# 把张量移动到cpu设备上
data = data.cpu()
print('存储设备:', data.device)
# 3. 使用 to 方法
def test03():
data = torch.tensor([10, 20, 30])
print('存储设备:', data.device)
# 使用 to 方法移动张量到指定设备
data = data.to('cuda:0')
print('存储设备:', data.device)
# 4. 注意: 存储在不同设备上的张量不能够直接运算
def test04():
data1 = torch.tensor([10, 20, 30])
data2 = torch.tensor([10, 20, 30], device='cuda:0')
# RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
# 下面代码会报错
# 如果你的电脑上安装 pytorch 不是 gpu 版本的,或者电脑本身没有 gpu (nvidia)设备环境
# 否则下面的调用 cuda 函数的代码会报错
data1 = data1.cuda()
data = data1 + data2
print(data)
3 张量与numpy数组转换
3.1 张量转换为numpy数组
- 使用data.numpy()函数,可以将张量转化为numpy数组,但是两者共享内存,一个变化,另外一个也发生变化
- 如果不想让两者共享内存,可以使用copy()进行拷贝
python
import torch
# 1. 张量转换为numpy数组
def test01():
data_tensor = torch.tensor([2, 3, 4])
# 将张量转换为numpy数组
# 转化为numpy之后的得到的ndarray对象和原tensor对象共享内存
# 如果修改了其中一个值,另外一个也会改变
data_numpy = data_tensor.numpy()
print(type(data_tensor))
print(type(data_numpy))
print(data_tensor)
print(data_numpy)
# 2. 张量和numpy数组共享内存
def test02():
data_tensor = torch.tensor([2, 3, 4])
data_numpy = data_tensor.numpy()
# 修改张量元素的值,看看numpy数组是否会发生变化?会发生变化
# data_tensor[0] = 100
# print(data_tensor)
# print(data_numpy)
# 修改numpy数组元素的值,看看张量是否会发生变化?会发生变化
data_numpy[0] = 100
print(data_tensor)
print(data_numpy)
# 3. 使用copy函数实现不共享内存
def test03():
data_tensor = torch.tensor([2, 3, 4])
# 此处, 发生了类型转换,可以使用拷贝函数产生新的数据,避免共享内存
data_numpy = data_tensor.numpy().copy()
# 修改张量元素的值,看看numpy数组是否会发生变化?没有发生变化
# data_tensor[0] = 100
# print(data_tensor)
# print(data_numpy)
# 修改numpy数组元素的值,看看张量是否会发生变化?没有发生变化
data_numpy[0] = 100
print(data_tensor)
print(data_numpy)
3.2 numpy数组转换为张量
- 采用torch.from_numpy(ndarray)函数,共享内存
- 使用torch.tensor(ndarray) - 不共享内存
python
import torch
import numpy as np
# 1. from_numpy 函数的用法
# 默认进行的是前拷贝
def test01():
data_numpy = np.array([2, 3, 4])
# 张量是没有copy()函数的
# 先将ndarray进行拷贝,转换为张量
data_tensor = torch.from_numpy(data_numpy.copy())
print(type(data_numpy))
print(type(data_tensor))
# 默认共享内存
data_numpy[0] = 100
# data_tensor[0] = 100
print(data_numpy)
print(data_tensor)
# 2. torch.tensor 函数的用法
# 默认情况下是不进行共享内存的
# 默认情况下进行深拷贝
def test02():
data_numpy = np.array([2, 3, 4])
data_tensor = torch.tensor(data_numpy)
# 默认不共享内存
# data_numpy[0] = 100
data_tensor[0] = 100
print(data_numpy)
print(data_tensor)
3.3 提取单值张量
- 单值张量虽然只有一个值,但是仍然为张量类型
python
import torch
def test():
t1 = torch.tensor(30)
t2 = torch.tensor([30])
t3 = torch.tensor([[30]])
print(t1.shape)
print(t2.shape)
print(t3.shape)
print(t1.item())
print(t2.item())
print(t3.item())
# 注意: 张量中只有一个元素,如果有多个元素的话,使用 item 函数可能就会报错
# ValueError: only one element tensors can be converted to Python scalars
# t4 = torch.tensor([30, 40])
# print(t4.item())
4 张量的拼接
4.1 cat函数使用
python
import torch
def test():
# 固定随机数种子
torch.manual_seed(0)
data1 = torch.randint(0, 10, [3, 4, 5])
data2 = torch.randint(0, 10, [3, 4, 5])
print(data1.shape)
print(data2.shape)
# 1. 按照0维度进行拼接
new_data = torch.cat([data1, data2], dim=0)
print(new_data.shape) # [6,4,5]
# 2. 按照1维度进行拼接
new_data = torch.cat([data1, data2], dim=1)
print(new_data.shape) # [3,8,5]
# 3. 按照2维度进行拼接
new_data = torch.cat([data1, data2], dim=2)
print(new_data.shape) # [3,4,10]
# 注意: dim 必须保证是有效的
# new_data = torch.cat([data1, data2], dim=3)
# print(new_data.shape)
4.2 stack函数使用
- 按照一定维度,从两个张量中各自取一个元素,组合成新的元素,形成新的张量,会改变原有张量的维度
python
import torch
def test():
# stack()
# 按照一定维度,从两个张量中各自取一个元素,组合成新的元素,形成新的张量
# 会改变原有张量的维度
torch.manual_seed(0)
data1 = torch.randint(0, 10, [2, 3])
data2 = torch.randint(0, 10, [2, 3])
print(data1)
print(data2)
print('-' * 30)
# 将两个张量 stack 起来,像 cat 一样指定维度
# 1. 按照0维度进行叠加
# 将两个二维张量作为元素进行堆叠,变为一个三维,变为两个两行三列 (2,2,3)
new_data = torch.stack([data1, data2], dim=0)
print(new_data.shape)
print(new_data)
print('-' * 30)
# 2. 按照1维度进行叠加
# 将二维张量中的第一层中的元素进行拼接
# 这里是两个一维向量进行拼接
new_data = torch.stack([data1, data2], dim=1)
print(new_data.shape)
print(new_data)
print('-' * 30)
# 3. 按照2维度进行叠加
# 将二维张量中,按照元素进行拼接
new_data = torch.stack([data1, data2], dim=2)
print(new_data.shape)
print(new_data)
print('-' * 30)