导入
向量
了解如何使用 JAX 执行各种向量操作。
鉴于你对 NumPy 已有一定了解,本章并非对该主题的全面讲解,仅作为快速复习。我们将通过练习使用 JAX,来探索普通 NumPy 与 JAX 版本 NumPy 语法之间的对应关系。
注意:在代码中,我们将分别使用
np和jnp表示默认的 NumPy 和 JAX 的 NumPy 版本。
内积
两个向量的内积可以通过三种语法(dot()、inner() 和 @)计算,如下所示:
1a = jnp.arange(1,10) 2b = jnp.arange(11,20) 3 4print(jnp.dot(a,b)) 5print(jnp.inner(a,b)) 6print(a@b) 7print(b@a)
线性函数
线性函数可以表示为:
我们也可以将其写成 lambda 函数的形式:
1a= 1.2 2b = 2.4 3 4FuncA = lambda x : a*x[0]+b*x[1] 5 6x = jnp.arange(1,3) 7print(FuncA(x))
泰勒近似
泰勒近似是机器学习中许多优化算法的核心。我们可以用一阶近似来估计函数在某点 z 附近的函数值:
前面已经见识过 grad() 的高效性,因此我们可以轻松实现泰勒近似。例如,在 处,我们想近似以下函数的值:
1FuncA = lambda x : x[0]**2 - x[1]**3 2Gradient = lambda x : grad(FuncA)(x) 3TaylorApprox = lambda x:FuncA(z) + Gradient(z)@(x-z) 4 5z = jnp.array([2,3.2]) 6 7z1 = jnp.array([2.1, 3.25]) 8 9z2 = jnp.array([2.7, 3.2]) 10 11# 相同的点——无特殊之处。 12print("z 处的真实函数值:",FuncA(z)) 13print("z 处的泰勒近似值:",TaylorApprox(z)) 14 15# z1 接近 z。 16print("z1 处的真实函数值:",FuncA(z1)) 17print("z1 处的泰勒近似值:",TaylorApprox(z1)) 18 19# z2 距离 z 更远。 20print("z2 处的真实函数值:",FuncA(z2)) 21print("z2 处的泰勒近似值:",TaylorApprox(z2))
范数
任意向量的欧几里得范数定义为:
可以使用 linalg 模块计算范数。我们也可以利用范数来求两个向量之间的欧氏距离:
1x = jnp.arange(1,100) 2y = jnp.arange(11,110) 3x_norm = jnp.linalg.norm(x) 4 5print("x 的范数为: ",x_norm) 6print("x 与 y 向量之间的距离为:",jnp.linalg.norm(x-y))
余弦相似度
在机器学习中,尤其是 NLP 应用 中,衡量两个向量相似性的常用方法是计算余弦相似度。根据点积的定义:
可得余弦相似度为:
1x = jnp.arange(1,100) 2y = jnp.arange(11,110) 3 4cosine = lambda x,y: (x@y)/(jnp.linalg.norm(x)*jnp.linalg.norm(y)) 5print("x 与 y 的余弦相似度为:",cosine(x,y))
标准差
向量的标准差定义为(其中 是向量的长度):
我们可以直接使用 jnp.std() 计算该值。以下示例展示了直接使用 std() 和基于上述公式实现的两种方式:
1x = jnp.arange(20,61) 2y = jnp.arange(1,101) 3 4stdv = lambda x: jnp.linalg.norm(x-jnp.average(x))/(jnp.sqrt(x.size)) 5 6print("使用自定义函数计算 x 的标准差: ",stdv(x)) 7print("使用自定义函数计算 y 的标准差:",stdv(y)) 8# 结果应相同 9print("x 的实际标准差: ",jnp.std(x)) 10print("y 的实际标准差:",jnp.std(y))