张量(点)积
张量积(tensor product)或 点积(dot product)是最常见且最有用的张量运算之一。需要注意的是不要将其与逐元素乘积(运算符为:*)混淆。
在numpy中,使用np.dot来实现张量积,例如:
import numpy as np
x=np.ranodm.random((32,))
y=np.random.random((32,))
z=np.dot(x,y) ##两个向量点积
在数学运算中,点积是接受在实数R上的两个向量并返回一个实数值标量的二元运算,而且只有元素相同的向量才能进行点积运算,下面通过一串简单的代码展现其中的数学运算过程:
def naive_vector_dot(x,y):
assert len(x.shape)==1 ##x为向量
assert len(y.shape)==1 ##y为向量
assert x.shape[0]==y.shape[0]
for i in range(x.shape[0]):
z+=x[i]*y[i]
return z
还可以对一个矩阵x和一个向量y做点积运算,其返回值是一个向量,其中每个元素是y与x每一行的点积,也就是说点积可以推广到具有任意轴数的张量,但是其根本都是基于向量点积结果的集合。我们通过下面一段代码展现其运算过程:
def naive_matrix_vector_dot(x,y):
assert len(x.shape)==2 ##x为一个矩阵
assert len(y.shape)==1 ##y为一个向量
assert x.shape[1]==y.shape[0] ##dot(x,y)中x的列数必须等于y的行数
z=np.zeros(x.shape[0])
for i in range(x.shape[0]):
for j in range(y.shape[0]):
z+=x[i,j]*y[j]
return z
需要注意的是,只要两个张量中有一个维度(ndim)大于1,其点积运算就不再对称,例如上述代码中dot(x,y)不等于dot(y,x),原因很简单,点积运算是前面的行乘后面的列,这也是代码中x的列数必须等于x的行数的原因。
而我们最常见的应用就是两个矩阵的点积,对于矩阵x和矩阵y,当且仅当x.shape[1]==y.shape[0]时才可以进行点积运算,点积结果是一个形状为(x.shape[0],y.shape[1])的矩阵。
张量变形
另一个需要了解的张量运算是张量变形(tensor reshaping)。在将数据输入神经网络之前预处理数据常常需要用到这种运算。
张量变形是指重新排列张量的行和列,以得到想要的形状。变形后张量的元素个数与初始张量相同,常见的一中张量变形是转置(transpose)。矩阵转置是指将矩阵的行和列互换,即把x[i,j]变为x[j,i]。
import numpy as np
x=np.zeros((300,20)) ##创建一个形状为(300,20)的矩阵
x=np.transpose(x)
x.shape ##(20,300)