基础内容:创建、转换、拷贝、空间、切片、合并、数据、索引
张量-创建:4种维度、4种特殊(全值、序列、矩阵、分布)、多种相似。
-1- 零维张量:单个数
t = torch.tensor(1)
-2- 一维张量:单个序列(元组、列表、数组)
t2 = torch.tensor([1, 2])
t2 = torch.tensor((1, 2))
t2 = torch.tensor(np.array((1, 2)))
-3- 二维张量:序列的序列(元组、列表、数组)
t3 = torch.tensor(([1, 2], [3, 4]))
-4- 三维张量:二维数组或矩阵的集合
a4 = np.array([[1, 2, 2], [3, 4, 4]])
b4 = np.array([[5, 6, 6], [7, 8, 8]])
t4 = torch.tensor([a4, b4])
-5- 特殊张量:
- 全值:3种参数形式(2,3)、[2,3]
torch.empty([2, 3]) # 全空矩阵:2行3列(默认0)
torch.zeros([2, 3]) # 全0矩阵:2行3列
torch.ones([2, 3]) # 全1矩阵:2行3列
torch.full([2, 3], n) # 全n矩阵:2行3列
- 序列:
torch.arange(5) # 数列:tensor([0, 1, 2, 3, 4])
torch.randperm(5) # 打乱:(随机卷发)取5个数并打乱
torch.arange(1, 5, 0.5) # 数列:[1,5)区间,隔0.5取一个数
torch.linspace(1, 5, 3) # 数列:[1,5)区间,等距取三个数
- 矩阵:
torch.eye(5) # 单位矩阵:5行5列
torch.diag(torch.tensor([1, 2, 3])) # 对角矩阵:3行3列(参数:一维张量)
torch.diag(t, 1/-1) # 对角矩阵:对角线向上/下偏移一位
- 分布:
torch.manual_seed(8) # 随机种子(手工的种子)
torch.rand([2,3]) # 均匀分布:2行3列(0-1)
torch.randint(1, 10, [2,3]) # 随机分布:2行3列(1-10)
torch.randn([2,3]) # 标准正态:2行3列(均值0,标准差1)
torch.normal(1, 2, [2,3]) # 正态分布:2行3列(均值1,标准差2)
-6- 相似张量:特殊张量创建方法名 + _like(张量)
torch.zeros_like(t1) # 全0矩阵:维度同t
张量-判断:判定、返回
-1- 判定: torch.is_tensor(a) # true 或 false isinstance(a, torch.Tensor) # true 或 false -2- 返回: tensor([[1, 0],[0, 2]])
张量-转换:方法、参数
-1- 方法
t1.item() # 2(t1必须0维张量)
t2.numpy() # [0 1 2]
t2.tolist() # [0, 1, 2]
-2- 参数
np.array(t) # [0 1 2]
list(t) # [tensor(0), tensor(1), tensor(2)]
tuple(t) # (tensor(0), tensor(1), tensor(2))
张量-拷贝:深拷贝、浅拷贝
-1- 浅拷贝:
a = torch.tensor((1, 2, 3))
b = a # 改1变2,地址相同
-2- 深拷贝:
b = a.clone() # 改谁变谁,新建张量
张量-空间:维度、形状、元素个数
-1- 张量维度:
- 查看:
torch.tensor([[1,2], [3,4]]).ndim # 2
- 降维: 删除包含单个元素的维度
torch.squeeze(a) # squeeze:挤压
- 升维: 第n个括号中元素添加括号
torch.unsqueeze(a, n)
-2- 张量形状:
- 查看:
a.shape # torch.Size([2, 3])
a.size() # torch.Size([2, 3])
- 拉平:
a = torch.tensor([[1, 2], [3, 4]])
torch.flatten(a) # tensor([1, 2, 3, 4])
- 变形:
a = torch.tensor([1, 2])
torch.reshape(a, [2,1])
torch.reshape(a, [-1,1]) # 自动推导该维的长度
-3- 元素个数:
a.numel() # 4
张量-切片:视图、分块、拆分
-1- 视图: a.view(3, 2) # 浅拷贝 -2- 分块: torch.chunk(a, 4, 0) # 在0维度上(按行)四等分,返回视图 -3- 拆分: torch.split(a, 2, 0) # 在0维度上(按行)二等分,返回视图 torch.split(a, [1, 3], 0) # 在0维度上(按行)1/3划分,返回视图
张量-合并:多个张量的拼接、堆叠
-1- 拼接: 添加内容,维度不变
torch.cat([a, b]) # 按第0维拼接,默认0
-2- 堆叠: 添加括号,维度升高
torch.stack([a, b])
张量-数据:查看、创建、转换
-1- 类型查看:
torch.tensor([True, False]).dtype # 查看类型:torch.bool
-2- 类型创建:
torch.tensor([1.1, 2.7], dtype = torch.int16) # 创建制定类型的张量
-3- 类型转化:
- 隐式转换:
torch.tensor([1.1, 2]) # 浮点型+整型 to 浮点型
torch.tensor([2.0, True]) # 浮点型+布尔型 to 浮点型
torch.tensor([True, 2]) # 布尔型+整型 to 整型
- 显式转换:
torch.tensor([1, 2]).double()
torch.tensor([1, 2.2]).int()
张量-索引:符号、函数
-1- 符号索引
- 一维索引: [start: end: step]
t1 = torch.arange(1, 11)
t1[0] # tensor(1)
t1[1: 8] # tensor([2, 3, 4, 5, 6, 7, 8])
t1[1: 8: 2] # tensor([2, 4, 6, 8]),每个2个数
- 二维索引:
t2 = torch.arange(1, 10).reshape(3, 3)
t2[0, 1] # 第一行、第二个(第二列的)元素
t2[0, ::2] # 第一行、每隔两个元素取一个
t2[[0, 2], 1] # 第一行、第三行、第二列的元素
t2[1][2] # 双括号
- 三维索引: 矩阵索引、矩阵行、矩阵列
t3 = torch.arange(1, 28).reshape(3, 3, 3)
t3[1, 1, 1] # 索引第二个矩阵;第二行;第二列
t3[::2,::2,::2] # 矩阵隔2取1;行隔2取1;列隔2取1
t3[1][2][3] # 三括号
-2- 函数索引:
t2 = torch.arange(12).reshape(4, 3)
indices = torch.tensor([1, 2])
torch.index_select(t2, 0, indices) # indices必须是tensor类型
2.2 张量科学运算
广播运算、逐点运算、规约运算、比较运算
广播运算:将异形异维的张量通过广播特性转换成同形同维的张量进而实现计算
-1- 同维&同形:
t1 = torch.arange(3)
t1 + t1
-2- 同维&异形: 同维度取值不同存在取值为1
t24 = torch.arange(3).reshape(3, 1)
t25 = torch.arange(3).reshape(1, 3)
t24 + t25 # 第1/2维:3和1✔️
-3- 异维&异形: 低维张量升维后,进行同维异形的广播计算
t2 = torch.arange(4).reshape(2, 2)
t3 = torch.zeros(3, 2, 2)
t3 + t2.reshape(1, 2, 2)
-4- 标量&任意维:
t4 = torch.zeros((3, 4))
t4 + 1 # 标量和每一个元素相加
逐点运算:每个元素都进行运算
-1- 基本数学运算: 加、减、乘、除
t1 + t2 # torch.add(t1, t2)
t1 - t2 # torch.subtract(t1, t2)
t1 * t2 # torch.multiple(t1, t2)
t1 / t2 # torch.divide(t1, t2)
-2- 数值调整运算: 绝对值、取整、取反
touch.abs(t2) # 绝对值(absolute, 绝对的)
touch.ceil(t2) # 向上取整(ceil, 天花板)
touch.floor(t2) # 向下取整(floor, 地板)
touch.round(t2) # 四舍五入
touch.negative(t2) # 相反数(negative, 负面的)
-3- 常用科学运算: 幂运算、指数运算、对数运算、三角函数运算
- 幂运算:
torch.exp(t3) # e为底,t3中元素为幂
torch.exp2(t3) # 2为底,t3中元素为幂
torch.square(t3) # t3中元素的平方
touch.pow(t3, n) # t3中元素为底,n为指数(可以是张量)
touch.sqrt(t3) # t3中元素为底,1/2为指数(square root)
- 对数运算:
torch.log(t3) # e为底,t3中元素的对数
torch.log2(t3) # 2为底,t3中元素的对数
- 三角函数运算:
torch.sin(t3) # 正弦
torch.cos(t3) # 余弦
torch.tan(t3) # 正切
规约运算:对张量进行总结
-1- 分布:
touch.mean(t)
touch.median(t) # 中位数
touch.var(t) # 方差 variance
touch.std(t) # 标准差 standard deviation
-2- 最值:
touch.max(a) # 最大值
touch.argmax(a) # 最大值索引
touch.min(a) # 最小值
touch.argmin(a) # 最小值索引
-3- 运算:
touch.sum(a, 1) # 求和(第1维)
touch.prod(a, 1) # 求积(第1维)
touch.dist(a, b, n) # 求距离(n=2欧式距离)
torch.sort(a, 1) # 按照第1维数据升序排序
torch.sort(a, 0, descending=True) # 按照第0维数据降序排序
a = a[torch.randperm(a.size(0))] # 随机打乱
比较运算:个体、整体
-1- 个体比较: 返回张量
t1 > t2 # 大于 touch.gt(t1, t2)
t1 >= t2 # 大于 touch.ge(t1, t2)
t1 < t2 # 小于 touch.lt(t1, t2)
t1 <= t2 # 小于 touch.le(t1, t2)
t1 == t2 # 等于 touch.eq(t1, t2)
t1 != t2 # 不等于 touch.ne(t1, t2)
-2- 整体比较: 返回 true/false
touch.equal(t1, t2) # True / False
2.3 张量矩阵运算
基本运算:
-1- 单个矩阵:
torch.t(t1) # t1的转置矩阵
t1.t() # 同上
-2- 两个矩阵:
torch.dot(t1, t2) # 张量内积,只能作用于一维张量
torch.mv(t1, t2) # 矩阵*向量,矩阵列数和向量元素个数相同
torch.mm(t1, t2) # 矩阵乘法
torch.bmm(t1, t2) # 三维矩阵,各对应位置的矩阵相乘
# 矩阵相乘后相加 == beta * input + alpha * (mat1 * mat2)
torch.addmm(input, mat1, mat2, beta=1, alpha=1)
torch.addbmm(t, t1, t2) # 矩阵t + 各对应位置的矩阵相乘&结果再相加
线性代数运算:
torch.trace(A) # 迹:对角线元素之和,不一定是方阵 torch.matrix_rank(A) # 秩:行或列的极大线性无关数,唯一存在 torch.det(A) # 行列式:必须是方阵 torch.inverse(A) # 求逆:퐴∗퐵=퐸(单位矩阵),则我们称퐴、퐵互为逆矩阵 torch.lstsq(A, B) # 最小二乘法
矩阵分解:将矩阵拆分成几种特殊矩阵的乘积퐴=푉푈퐷。
特征分解(方阵):方阵分解为 A = Q Λ Q − 1 A = QLambda Q^{-1} A=QΛQ−1。 Q Q Q和 Q − 1 Q^{-1} Q−1互为逆矩阵。 Λ Lambda Λ是矩阵A的特征值按照降序排列组成的对角矩阵。 Q Q Q的列是矩阵A的特征值所对应的特征向量。
torch.eig(A, eigenvectors=True) # 参数为True才会返回矩阵的特征向量
torch.return_types.eig(
# 特征值:对应列(特征)在矩阵中的重要程度
eigenvalues=tensor([[ 1.6117e+01, 0.0000e+00],
[-1.1168e+00, 0.0000e+00],
[ 2.9486e-07, 0.0000e+00]]),
eigenvectors=tensor([[-0.2320, -0.7858, 0.4082],
[-0.5253, -0.0868, -0.8165],
[-0.8187, 0.6123, 0.4082]])
)
SVD奇异值分解(奇异矩阵):将一个维度为m×n的奇异矩阵A分解成三个部分
A
=
U
∑
V
T
A = Usum V^{T}
A=U∑VT 。
U
和
V
U和V
U和V是两个正交矩阵,其中的每一行(每一列)分别被称为左奇异向量和右奇异向量,和
∑
∑
∑中对角线上的奇异值相对应A = torch.arange(1, 10).reshape(3, 3).float()
U, S, V = torch.svd(A)
torch.return_types.svd(
U=tensor([[-0.2148, 0.8872, 0.4082],
[-0.5206, 0.2496, -0.8165],
[-0.8263, -0.3879, 0.4082]]),
S=tensor([1.6848e+01, 1.0684e+00, 1.0313e-07]),
V=tensor([[-0.4797, -0.7767, -0.4082],
[-0.5724, -0.0757, 0.8165],
[-0.6651, 0.6253, -0.4082]]))



