标量 向量 矩阵 张量
标量(scalar),也可以叫做常量,例如 x = 5 向量(vector), 它是一个一维数组,例如 x = [1,3,4] 矩阵(matrix), 它是一个二维数组,例如
1 2 3
4 5 6
7 8 9
张量(tensor)是一个多维数组,张量涵盖向量,矩阵,3D空间(例如正方体), 4维等等
标量是张量的最小组成,类似于一个点 向量是一个 1阶张量, 是一条线 矩阵是一个 2阶张量, 是一个平面 依次类推 故而张量是机器学习的基础数据存储单位
求导,梯度
高等数学中一个函数
y
=
f
(
x
)
y = f(x)
y = f ( x ) 假设这个函数表示求出速度 ,
y
(
速度
k
m
/
h
)
=
1000
(
m
)
x
(
小时
h
)
y(速度km/h) = \frac{1000(m)}{x(小时 h)}
y ( 速度 km / h ) = x ( 小时 h ) 1000 ( m ) 那么这里的求导就是一个求出加速度
p
p
p
p
=
f
′
(
x
)
=
(
1000
x
)
′
=
−
1000
x
2
p = f^{'}(x) = (\frac{1000}{x})^{'} = -\frac{1000}{x^2}
p = f ′ ( x ) = ( x 1000 ) ′ = − x 2 1000 这里的求导直接使用了 牛顿莱布尼茨公式
而代码的办法是逼近求导
代码实现(导数计算)
设
y
=
f
(
x
)
y = f(x)
y = f ( x ) 根据最基础的求导理解,逼近
p
=
lim
n
−
>
0
f
(
x
+
n
)
−
f
(
x
)
n
p = \lim_{n->0}\frac{f(x+n)-f(x)}{n}
p = lim n − > 0 n f ( x + n ) − f ( x ) 那么求导代码如下
def func(x):
return 1000 / x
# 求导数
def get_p(x, batch=5, init=0.1, step=0.1):
for i in range(batch):
result = (func(x + init) - func(x)) / init
init = init * step
print(f"result == {result} batch = {i} init = {init}")
return result
# 根据极限逼近公式计算
print(get_p(1)) # -999.99
# 根据莱布尼茨公式计算
print(-1000 / (1**2)) # -1000
pytorch实现(导数计算)
需要创建一个能够记录梯度的张量 requires_grad 表示需要记录梯度(导数) 梯度(gradience), 可以被解释为多维空间中的导数(2D平面空间)
import torch
x = torch.tensor([1], dtype=torch.float, requires_grad=True)
y = 1000 / x
y.backward()
print(x.grad) # -1000
二维空间、三维空间,n维,梯度,导数(特殊的梯度)
导数是二维空间的 梯度,形式为 (x,) 如果是三维空间,函数表示为
z
=
a
x
n
+
b
y
m
+
c
z = ax^n + by^m + c
z = a x n + b y m + c 的形式
例如球可以表示为
z
=
x
2
+
y
2
z = x^2 + y^2
z = x 2 + y 2 在二维空间中,导数对应的是一个切线,而三维中,梯度对应的是一个切面,切线和切面的倾斜度表示了导数和梯度的大小 在数学中 两点可以求出一条线,或者 一个点的坐标 加上线的斜率也可以求出这个线, 在三维中也类似,梯度近似于求出这个切面,而面需要三个点,或者,一个点的坐标和在另外两位维度的倾斜度,所以梯度表示为(x, y),数学表达是偏导数,就是z 在x 这个方向的变化程序,表示为
d
z
d
x
=
l
i
m
i
−
>
0
f
(
x
+
i
,
y
)
−
f
(
x
,
y
)
i
\frac{dz}{dx} = lim_{i->0}\frac{f(x + i, y) - f(x, y)}{i}
d x d z = l i m i − > 0 i f ( x + i , y ) − f ( x , y ) 然后依次类推数学规律,n维张量的梯度表示为
(
p
1
,
p
2
,
.
.
.
p
n
−
1
)
(p_1, p_2, ... p_{n-1})
( p 1 , p 2 , ... p n − 1 ) , 也就是共有
n
−
1
n-1
n − 1 个数值 请注意,需要一个实际的点位值(坐标),才可以求出实际的梯度(导数)值
代码实现(梯度计算)
def func(x, y):
# 球方程
return y**2 + x **2
# 求导数
def get_p(x, y, batch=5, init=0.1, step=0.1):
for i in range(batch):
result_x = (func(x + init, y) - func(x, y)) / init
init = init * step
print(f"result == {result_x} batch = {i} init = {init}")
for i in range(batch):
result_y = (func(x, y + init) - func(x, y)) / init
init = init * step
print(f"result == {result_y} batch = {i} init = {init}")
return (result_x, result_y)
# 根据极限逼近公式计算
print(get_p(1, 1)) # (2.000001, 2.000001)
# 根据莱布尼茨公式计算
# z = (2x, 2y)
print((2 * 1, 2 * 1)) # (2, 2)
pytorch 实现(梯度计算)
import torch
x = torch.tensor([1, ], dtype=torch.float, requires_grad=True)
y = torch.tensor([1, ], dtype=torch.float, requires_grad=True)
z = x ** 2 + y ** 2
z.backward()
print(x.grad, y.grad) # (2, 2)