PyTorch提供了一种直观的方式来创建和操作张量,而且它还支持GPU加速,这对于深度学习任务非常重要。我们可以使用PyTorch来定义神经网络模型、进行前向传播和反向传播,以及许多其他深度学习任务,因而了解张量是了解这些任务的基础。
维度(Rank):张量的维度也称为秩(rank),表示张量中轴(或维度)的数量。标量是0维张量,向量是1维张量,矩阵是2维张量,以此类推。
我们使用**.shape** 查看形状,.ndim属性查看维度
当使用PyTorch库时,我们可以轻松地创建和操作张量。下面是使用PyTorch创建不同秩的张量的示例代码:
import torch
scalar = torch.tensor(5) # 创建一个标量
print("Scalar:", scalar)
print("Scalar的秩(Rank):", scalar.ndim) # 输出0,表示秩为0
print("Scalar的形状", scalar.shape) #输出torch.Size([]) #输出torch.Size([])此时形状向量输出为空
import torch
vector = torch.tensor([1, 2, 3, 4]) # 创建一个向量
print("Vector:", vector)
print("Vector的秩(Rank):", vector.ndim ) # 输出1,表示秩为1
print("vector的形状", vector.shape) #输出torch.Size([4])
import torch
matrix = torch.tensor([[1, 2, 3], [4, 5, 6]]) # 创建一个2x3的矩阵
print("Matrix:")
print(matrix)
print("Matrix的秩(Rank):", matrix.ndim # 输出2,表示秩为2
print("Matrix的形状:", matrix.shape # 输出torch.Size([2,3]) 2x3的矩阵
import torch
tensor_3d = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) # 创建一个2x2x2的3维张量
print("3D Tensor:")
print(tensor_3d)
print("3D Tensor的秩(Rank):", tensor_3d.ndim) # 输出3,表示秩为3
print("3D Tensor的形状:", tensor_3d.shape ) # 输出torch.Size([2,2,2]) 2x2x2的3维张量
以上我们实际上是通过torch.tensor函数把列表转换为tensor张量
除此之外,还有一些其他torch内置函数的创建方式
# 创建特定形状的全零张量
zeros_tensor = torch.zeros(3, 2) #创建形状(3,2)的全零张量
# 创建特定形状的全一张量
ones_tensor = torch.ones(2, 3)#创建形状(2,3)的全一张量
# 创建特定形状的随机均匀分布的张量 每个元素都会随机生成,取值范围是大于等于0且小于1的浮点数。
uniform_random = torch.rand(2, 2) #形状(2,2)
# 创建随机正态分布的张量
normal_random = torch.randn(3, 3) #形状(3,3)
# 创建单位矩阵
identity_matrix = torch.eye(4)
输出
tensor([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
# 创建从0到4的张量
sequence_tensor = torch.arange(5)
# 创建从2到10的张量,步长为2
sequence_with_step = torch.arange(2, 11, step=2)
张量中的每个值称为元素。根据张量的维度和形状,可以有不同数量的元素。例如,一个形状为(3, 4)
的张量将包含12个元素。
每个元素可以有不同的类型
张量可以包含不同的数据类型,如整数、浮点数、布尔值等。常见的数据类型包括int32
、float32
、bool
等
使用 .dtype
属性可以查看张量的数据类型。例如:
pythonCopy codeimport torch
# 创建一个张量
tensor = torch.tensor([1, 2, 3, 4], dtype=torch.float32)
# 查看张量的数据类型
print(tensor.dtype)
输出将显示张量的数据类型,例如 torch.float32
注意,python其他数据类型查看是通过type函数(),注意区分,距离如下
# 定义不同类型的变量
integer_variable = 42
float_variable = 3.14
string_variable = "Hello, World!"
list_variable = [1, 2, 3]
dictionary_variable = {"name": "John", "age": 30}
# 使用 type() 函数查看数据类型
print(type(integer_variable)) #
print(type(float_variable)) #
print(type(string_variable)) #
print(type(list_variable)) #
print(type(dictionary_variable)) #
通过to函数() 或者用type()函数
注意这里的type()函数是tensor张量自己带的,不是上面讲到3.1讲到的python内的type函数
import torch
# 创建一个整数类型的张量
int_tensor = torch.tensor([1, 2, 3, 4],dtype=torch.int32)
# 将整数类型的张量转换为浮点数类型 或者 float_tensor = int_tensor.type(torch.float32)
float_tensor = int_tensor.to(torch.float32)
# 查看新的张量的数据类型
print(float_tensor.dtype)
输出为 torch.float32
注意 执行to函数之后必须进行赋值操作,否则该操作就丢失了,查看下面的代码
import torch
# 创建一个整数类型的张量
int_tensor = torch.tensor([1, 2, 3, 4],dtype=torch.int32)
# 将整数类型的张量转换为浮点数类型
int_tensor.to(torch.float32)
# 查看新的张量的数据类型
print(int_tensor.dtype)
最开始我觉得会输出torch.float32 实际输出torch.int32
+
和 -
运算符执行张量的逐元素加法和减法。*
和 /
运算符执行逐元素的乘法和除法。**
运算符进行幂运算。-
运算符取张量的负值。import torch
# 创建两个示例张量
tensor1 = torch.tensor([1.0, 2.0, 3.0])
tensor2 = torch.tensor([4.0, 5.0, 6.0])
# 加法和减法
result_addition = tensor1 + tensor2 # 逐元素加法
result_subtraction = tensor1 - tensor2 # 逐元素减法
# 乘法和除法
result_multiplication = tensor1 * tensor2 # 逐元素乘法
result_division = tensor1 / tensor2 # 逐元素除法
# 幂运算
exponent = 2
result_power = tensor1 ** exponent # 每个元素求平方
# 取负值
result_negation = -tensor1 # 每个元素取负值
print("Addition:", result_addition)
print("Subtraction:", result_subtraction)
print("Multiplication:", result_multiplication)
print("Division:", result_division)
print("Power:", result_power)
print("Negation:", result_negation)
输出
矩阵相乘:
使用 torch.matmul()
函数或 @
运算符 或**torch.mm()
** 可以执行两个张量(矩阵)的矩阵相乘。矩阵相乘要求左边矩阵的列数等于右边矩阵的行数。
import torch
# 创建两个示例矩阵
matrix1 = torch.tensor([[1, 2], [3, 4]])
matrix2 = torch.tensor([[5, 6], [7, 8]])
# 矩阵相乘 matmul
result_matrix_mul_1 = torch.matmul(matrix1, matrix2)
# 或者使用 @ 运算符
result_matrix_mul_2 = matrix1 @ matrix2
# 矩阵相乘 mm
result_matrix_mul_3=torch.mm(matrix1, matrix2)
print("Matrix Multiplication:")
print(result_matrix_mul_1)
print(result_matrix_mul_2)
print(result_matrix_mul_3)
输出将是两个矩阵相乘的结果
Matrix Multiplication:
tensor([[19, 22],
[43, 50]])
tensor([[19, 22],
[43, 50]])
tensor([[19, 22],
[43, 50]])
批量矩阵相乘:
使用 torch.matmul()
函数和**@运算符可以执行两个张量的批量矩阵相乘。这对于同时处理多个矩阵非常有用,但要求最后两个维度必须是矩阵的维度**。而mm只能用于单个矩阵乘法
import torch
# 创建两个批量矩阵(3个2x2矩阵)
batch_matrix1 = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]])
batch_matrix2 = torch.tensor([[[2, 0], [1, 2]], [[-1, -2], [-3, -4]], [[0, 1], [-1, 0]]])
# 执行批量矩阵相乘
result_batch_matrix_mul_1 = batch_matrix1 @ batch_matrix2
result_batch_matrix_mul_2 =torch.matmul(batch_matrix1,batch_matrix2)
# 或者使用 @ 运算符
# result_batch_matrix_mul = batch_matrix1 @ batch_matrix2
print("Batch Matrix Multiplication:")
print(result_batch_matrix_mul_1)
print(result_batch_matrix_mul_2)
输出将是批量矩阵相乘的结果
输出
Batch Matrix Multiplication:
tensor([[[ 4, 4],
[ 10, 8]], [[-23, -34],
[-31, -46]],[[-10, 9], [-12, 11]]])
tensor([[[ 4, 4],
[ 10, 8]],[[-23, -34], [-31, -46]],
[[-10, 9],
[-12, 11]]])
点积:
点积是两个向量的内积,也可以视为两个矩阵的逐元素乘法后的和。在 PyTorch 中,可以使用 torch.dot()
函数来计算两个一维张量的点积。
import torch
# 创建两个一维示例张量
vector1 = torch.tensor([1, 2, 3])
vector2 = torch.tensor([4, 5, 6])
# 计算点积
dot_product = torch.dot(vector1, vector2)
print("Dot Product:")
print(dot_product)
输出将是两个向量的点积结果
Dot Product:
tensor(32)
tensor张量还会自带很多的运算函数,方便我们的操作
这些运算将分别应用于张量的每个元素,结果将生成一个与原始张量相同形状的新张量。
torch.abs(tensor)
:计算张量中每个元素的绝对值。torch.sqrt(tensor)
:计算张量中每个元素的平方根。torch.exp(tensor)
:计算张量中每个元素的指数值。torch.log(tensor)
:计算张量中每个元素的自然对数。这些运算将返回张量的单个标量值,通常用于统计和汇总。
torch.sum(tensor)
:计算张量中所有元素的和。torch.mean(tensor)
:计算张量中所有元素的平均值。torch.max(tensor)
和 torch.min(tensor)
:计算张量中的最大值和最小值。torch.argmax(tensor)
和 torch.argmin(tensor)
:返回张量中最大值和最小值的索引。torch.unique(tensor)
:返回张量中的唯一元素。torch.histc(tensor, bins=10, min=0, max=1)
:计算张量的直方图。PyTorch 提供了一系列用于处理和操作张量的运算,包括拼接、切片、转置、扩展和重塑等。以下是这些运算的详细介绍:
torch.cat(tensors, dim=0)
:将多个张量沿指定维度 dim
进行拼接,生成一个新的张量。这在将多个张量连接在一起时非常有用。
import torch
# 创建两个示例张量
tensor1 = torch.tensor([[1, 2,3], [4, 5,6]]) #(2×3)
tensor2 = torch.tensor([[7, 8,9], [10, 11,12]]) #(2×3)
# 沿行维度进行拼接
result_concatenation_row = torch.cat((tensor1, tensor2), dim=0) #行维度对应相加,最后拼接后的形状(4×3)
result_concatenation_column=torch.cat((tensor1, tensor2), dim=1)#列维度对应相加,最后拼接后的形状(2×6)
print("Concatenation:")
print(result_concatenation_row)
print(result_concatenation_column)
Concatenation:
tensor([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
tensor([[ 1, 2, 3, 7, 8, 9],
[ 4, 5, 6, 10, 11, 12]])
使用索引和切片运算符 []
对张量进行切片。可以指定要提取的元素的索引或范围。这对于获取部分数据非常有用。
import torch
# 创建一个示例张量
tensor = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 提取特定元素
element = tensor[0, 1] # 获取第一行第二列的元素
# 提取特定行或列
row = tensor[1, :] # 获取第二行的所有元素
column = tensor[:, 2] # 获取第三列的所有元素
print("Element:", element)
print("Row:", row)
print("Column:", column)
Element: tensor(2)
Row: tensor([4, 5, 6])
Column: tensor([3, 6, 9])
torch.transpose(tensor, dim0, dim1)
:将张量的指定维度进行转置,生成一个新的张量。这对于调整张量的维度顺序非常有用。
import torch
# 创建一个示例张量
tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
# 转置张量
transposed_tensor = torch.transpose(tensor, dim0=0, dim1=1) # 交换行和列
print("Transposed Tensor:")
print(transposed_tensor)
输出
Transposed Tensor:
tensor([[1, 4],
[2, 5],
[3, 6]])
tensor.view(new_shape)
或者函数tensor.reshape(new_shape)
将张量的形状重塑为新的形状,生成一个新的张量。这对于改变张量的形状非常有用,但要确保新形状与原始形状兼容。
pythonCopy codeimport torch
# 创建一个示例张量
tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
# 重塑张量的形状
reshaped_tensor = tensor.view(3, 2) # 将2x3矩阵重塑为3x2矩阵
print("Reshaped Tensor:")
print(reshaped_tensor)
这些张量操作非常有用,可用于处理和操作 PyTorch 张量,适应不同的任务和需求。请根据您的具体情况选择适当的操作。
广播(Broadcasting)是一种在 PyTorch 中执行元素级运算的机制,它允许在不同形状的张量之间进行运算,而无需显式地扩展(重复复制)其中一个张量。广播使得在不同形状的张量上执行操作更加方便,因为它自动调整张量的形状,以使其兼容。
import torch
# 创建示例张量
tensor = torch.tensor([[1, 2], [3, 4]])
# 使用广播将标量加到矩阵的每个元素上
scalar = 2
result_broadcasting = tensor + scalar
print("Broadcasting:")
print(result_broadcasting)
输出
Broadcasting:
tensor([[3, 4],
[5, 6]])
广播规则如下:
不要求两个张量维度数相等,但要求从右向左逐一比较张量的维度(直到维度低的向量比较完毕)满足以下两个条件之一即可
(1)两个张量该维度相等
(2)其中一个张量该维度是1
如果在某一维度的比较上两者都不满足,则会引发广播错误。
tensor_1=torch.ones(2,3,4) #2*3*4
tensor_2=torch.ones(3,1) #3*1
tensor=tensor_2+tensor_1
print(tensor)
如上,从右向左 ,第一维(4和1 )虽然不相等,但tensor_2为1 满足条件(2)
继续从右向左,第二维(3,3 )相等,满足条件(1)
此时低维向量比较完毕,所以上述两者可以广播
tensor_1=torch.ones(2,3,3)#2*3*2
tensor_2=torch.ones(2,1) #2*3
tensor=tensor_2+tensor_1
print(tensor)
而这个例子,从右向左 ,第一维(3和1 )虽然不相等,但tensor_2为1 满足条件(2)
继续从右向左,第二维(3,2 )不相等,不满足条件(1),也不满足条件(2),引发广播失败