环境介绍
硬件:Jetson Orin Nano 8G
pytorch版本:2.1.0a0+41361538.nv23.06
python版本:3.8.10
torch常用操作
import torch
print("输出torch的版本")
print(torch.__version__)
print("创建行向量,由0开始,12个整数 ")
x = torch.arange(12)
print(x)
print("改变形状,变成3行4列的矩阵,不改变数量和值")
x1 = x.reshape(3,4)
print(x1)
print("创建3行4列的张量,元素从均值为0,标准差为1的标准高斯分布中随机采样")
x2 = torch.randn(3,4)
print(x2)
print("根据形状,遍历所有元素求和,直接使用求和函数")
sum1 = 0
dim0, dim1 = x2.shape
for i in range(dim0):
for j in range(dim1):
element = x2[i][j]
sum1 = sum1 + element
sum2 = x2.sum()
print(sum1, sum2)
print("浮点数")
x3 = torch.arange(12, dtype=torch.float32).reshape(3,4)
print(x3)
print("索引, 最后一个;第一个到第二个;全部")
x4 = torch.tensor([1.0 ,2 ,4 ,8])
x5 = torch.tensor([2, 2, 2, 2])
print(x4[-1], x4[1:2], x4[:])
print("节省内存, 变量不出现两次相同, id函数可以打印内存地址")
print(id(x4))
x4 += x5
print(id(x4))
print(x4)
对应输出结果
输出torch的版本
2.1.0a0+41361538.nv23.06
创建行向量,由0开始,12个整数
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
改变形状,变成3行4列的矩阵,不改变数量和值
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
创建3行4列的张量,元素从均值为0,标准差为1的标准高斯分布中随机采样
tensor([[-0.3059, 1.4878, 0.2026, -0.7363],
[-1.2357, 0.8356, 1.3819, -1.3026],
[ 1.4943, -0.8299, 1.2947, 1.3532]])
根据形状,遍历所有元素求和,直接使用求和函数
tensor(3.6397) tensor(3.6397)
浮点数
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
矩阵点乘
tensor([ 2., 4., 8., 16.])
索引, 最后一个;第一个到第二个;全部
tensor(8.) tensor([2.]) tensor([1., 2., 4., 8.])
节省内存, 变量不出现两次相同, id函数可以打印内存地址
281470915534336
281470915534336
tensor([ 3., 4., 6., 10.])
数学基础
线性代数
import torch
print("矩阵的转置(transpose)")
A = torch.arange(16).reshape(4,4)
print(A)
print(A.T)
print("对称矩阵(symmetric matrix)和其转置矩阵相等")
B = torch.tensor([[1, 2, 3],
[2, 0, 4],
[3, 4, 5]])
print(B == B.T)
print("矩阵乘以一个标量,不会改变形状")
C = 3 * A
print(C, "\n", ((C / 3) == A))
print("哈达玛积,相同shape矩阵各元素相乘,输出仍为矩阵,用于信号、图像处理等")
D = A * C
print(D)
print("点积(矩阵乘法),行列对应相同,表示相似度")
E = torch.matmul(A, C)
print(E)
print("叉积,用于确定法向量和确定平面")
tmp_v1 = torch.tensor([1, 2, 3])
tmp_v2 = torch.tensor([3, 4, 5])
F = torch.cross(tmp_v1, tmp_v2)
print(F)
print("降维,求和、平均都可以指定轴进行")
tmp_v1 = torch.tensor([[1.,2.,3.],
[4.,5.,6.]
])
print(tmp_v1.sum(axis=0),"\n", tmp_v1.sum(axis=1))
print(tmp_v1.mean(axis=0),"\n", tmp_v1.mean(axis=1))
print("范数,表示分量的大小,L₂范数表示向量元素平方和的平方根(欧几里得距离),L₁范数表示向量元素的绝对值之合")
tmp_v1 = torch.tensor([1.2,3.4])
print(torch.norm(tmp_v1), "\n", torch.abs(tmp_v1).sum())
对应输出结果
矩阵的转置(transpose)
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
tensor([[ 0, 4, 8, 12],
[ 1, 5, 9, 13],
[ 2, 6, 10, 14],
[ 3, 7, 11, 15]])
对称矩阵(symmetric matrix)和其转置矩阵相等
tensor([[True, True, True],
[True, True, True],
[True, True, True]])
矩阵乘以一个标量,不会改变形状
tensor([[ 0, 3, 6, 9],
[12, 15, 18, 21],
[24, 27, 30, 33],
[36, 39, 42, 45]])
tensor([[True, True, True, True],
[True, True, True, True],
[True, True, True, True],
[True, True, True, True]])
哈达玛积,相同shape矩阵各元素相乘,输出仍为矩阵,用于信号、图像处理等
tensor([[ 0, 3, 12, 27],
[ 48, 75, 108, 147],
[192, 243, 300, 363],
[432, 507, 588, 675]])
点积(矩阵乘法),行列对应相同,表示相似度
tensor([[ 168, 186, 204, 222],
[ 456, 522, 588, 654],
[ 744, 858, 972, 1086],
[1032, 1194, 1356, 1518]])
叉积,用于确定法向量和确定平面
tensor([-2, 4, -2])
降维,求和、平均都可以指定轴进行
tensor([5., 7., 9.])
tensor([ 6., 15.])
tensor([2.5000, 3.5000, 4.5000])
tensor([2., 5.])
范数,表示分量的大小,L₂范数表示向量元素平方和的平方根(欧几里得距离),L₁范数表示向量元素的绝对值之合
tensor(3.6056)
tensor(4.6000)
微积分
求导,切线函数
import numpy as np
import matplotlib.pyplot as plt
# 定义函数
def func(x):
return 0.01 * x**2 + 0.1 * x
# 数值求导函数
def numerical_diff(f, x):
h = 1e-4
return (f(x + h) - f(x - h)) / (2 * h)
# 切线函数
def tangent_line(f, x):
d = numerical_diff(f, x)
y = f(x) - d * x
return lambda t: d * t + y
# 定义x范围
x = np.arange(0.0, 20.0, 0.1)
y = func(x)
# 计算切线
x_tangent = 10
tangent = tangent_line(func, x_tangent)
y_tangent = tangent(x)
# 绘制图像
plt.plot(x, y, label='Function')
plt.plot(x, y_tangent, label='Tangent at x=10', linestyle='--')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
偏导数,多元函数(mulivaritae function)、梯度
-> y关于每一个参数(元)都有偏导数,梯度就是所有偏导数组成的向量
链式法则
-> 复杂的多元函数,可以使用链式法则进行求d,将符合函数拆分成单变量函数,对于每一个函数都是可d的
自动微分
-> 深度学习框架帮你做这件事,根据模型构建一个计算图(跟踪计算哪些数据通过哪些组合产生的输出),然后通过反向传播(backpropagate)来填充每个参数的偏导数
import torch
x = torch.arange(8.0)
# 表示是否记录该变量的操作以便自动微分
x.requires_grad_(True)
# 进行一些操作
y = x * 2
z = y.mean()
# 反向传播
z.backward()
# 查看梯度
print(x.grad)
-> tensor([0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500])
-> 这里可以看到z函数反向传播,实际上关于x的导数即z = (1/8)* (x*2) = (1/4)x,这个导数就是1/4,和上面的梯度张量相同
-> 如果requires_grad设置为False,则会报错:RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn