当前位置:网站首页>3.张量运算
3.张量运算
2022-08-03 04:05:00 【好名字能更容易让朋友记住】
张量运算
深度神经网络学到的所有变换也都可以简化为数值数据张量上的一些张量运算(tensor operation)
对于叠加Dense层来构建网络。Keras层的示例如下所示。
keras.layers.Dense(512, activation=‘relu’)
这个层可以理解为一个函数,输入一个2D张量,返回另一个2D张量,即输入张量的新表示。具体而言,如以下这个函数表示
output = relu(dot(W, input) + b)
其中W是一个2D张量,b是一个向量,二者都是该层的属性。拆开来看,这里有三个张量运算:
- 输入张量和张量W之间的点积运算(dot)
- 得到的2D张量与向量b之间的加法运算(+)
- 最后的relu运算。relu(x)是max(x,0)
逐元素运算
relu 运算和加分都是逐元素(element-wise)的运算,即运算独立地应用于张量中的每个元素,也就是说,这些运算非常适合大规模并行实现(向量化实现)
以下代码是对逐元素 relu 运算的简单实现
def navie_relu(x): assert len(x.shape) == 2 # assert 断言 以上语句的意思为如果 len(x.shape)==2即表示True,则正常运行,反之会报错。 x = x.copy() # 避免覆盖输入张量 for i in range(x.shape[0]): for j in range(x.shape[1]): x[i, j] = max(x[o, j], 0) return x对于加法采用同样的实现方法。
def navie_add(x, y): assert len(x.shape) == 2 assert x.shape == y.shape # 保证 x 和 y 是Numpy的2D张量 x = x.copy() for i in range(x.shape[0]): for j in range(x.shape[1]): x[i, j] += y[i, j] return在Numpy中可以直接进行下列逐元素运算,速度非常快
import numpy as np # 逐元素相加 z = x + y # 逐元素的relu z = np.maxinum(z, 0.)
广播
对于以上的 navie_add 的简单实现仅支持两个形状相同的2D张量相加。如果将两个形状不同的张量相加。较小的张量会被广播,以匹配较大张量的形状。广播包括以下两步:
- 将较小的张量添加轴(叫做广播轴),使其ndim与较大的张量相同。
- 将较小的张量沿着新轴重复,使其形状与较大的张量相同。
举例:
假设X的形状是(32,10),y的形状是(10,)。首先,我们给y添加一个空的第一个轴,这样y的形状变为(1,10)。然后,我们将y沿着新轴重复32次,这样得到张量Y的形状为(32,10),并且Y[i, :] == y for i in range(0,32)。此时二者可以相加。def navie_add_matrix_and_vector(x, y): assert len(x.shape) == 2 assert len(y.shape) == 1 assert x.shape[1] == y.shape[0] x = x.copy() for i in range(x.shape[0]): for j in range(x.shape[1]): x[i, j] += y[j] return x 如果一个张量的形状是(a,b,… n,n+1, … ,m),另一个张量为(n,n+1,… m),那么你可以利用广播对他们做两个张量之间的逐元素运算。广播操作会自动应用于a到n-1的轴。
# 利用广播将逐元素的maximum运算应用于两个形状不同的张量 import numpy as np # 形状为(64,3,32,10)的随机张量、 x = np.random.random((64, 3, 32, 10)) # 形状为(64,10)的随机张量。 y = np.random.random((32, 10)) # 输出z的形状是(64,3,32,10),与x相同。 z = np.maximum(x, y)
张量点积
点积运算,也叫做张量积(tensor product,不要与逐元素的乘积弄混)
在Numpy、Keras、Theano和TensorFlow中,都是用 * 实现逐元素乘积。TensorFlow中的点积使用了不同的语法,但在Numpy和Keras中,都是用标准的dot运算符来实现点积。
import numpy as np z = np.dot(x, y) # 数学符号中的点( . )表示点击运算。 z=x.y从数学的角度来看,两个向量 x 和 y 的点积。其运算结果如下:
def navie_vector_dot(x, y): # 表示二者为向量 assert len(x.shape) == 1 assert len(y.shape) == 1 # 表示长度相同 assert x.shape[0] == y.shape[0] z = 0. for i in range(x.shape[0]): z += x[i] * y[i] # 返回值为一个标量 return z矩阵x和一个向量y做点积:
import numpy as np def naive_matrix_vector_dot(x, y): # x 是一个Numpy矩阵 # y 是一个Numpy向量 assert len(x.shape) == 2 assert len(y.shape) == 1 # x的第1维和y的第0维大小必须相同 assert x.shape[1] == y.shape[0] z = np.zeros(x.shape[0]) for i in range(x.shape[0]): for j in range(x.shape[1]): z[i] += x[i, j] * y[j] return z举例:
import numpy as np x = np.array([[1,2,3],[4,5,6]]) y = np.array([1,2,3]) z = navie_matrix_vector_dot(x,y) z # z = array([14., 32.]) # 即 z = [1×1 + 2×2 + 3×3 , 4×1 + 5×2 + 6×3]通过以上两个函数进行结合
def mavie_matrix_vector_dot(x,y): z = np.zeros(x.shape[0]) for i in range(x.shape[0]): z[i] = naive_vector_dot(x[i, :], y) # x[i, :]表示x的第i个轴的所有元素 return z进行推广,若两个矩阵进行点积,若矩阵x和y,当且仅当 x.shape[1] == y.shape[0] 时,二者可以进行点积。得到的结果为一个形状为**(x.shape[0],y.shape[1])**的矩阵。
def navie_matrix_dot(x, y): assert len(x.shape) == 2 assert len(y.shape) == 2 # x的第1维与y的第0维大小必须相同 # 即x的列数与y的行数相等 assert x.shape[1] == y.shape[0] z = np.zeros((x.shape[0], y.shape[1])) for i in range(x.shape[0]): for j in range(y.shape[1]): # 遍历x的所有行 row_x = x[i, :] # 遍历y的所有列 column_y = y[:, j] # x的行依次与y的列相乘 z[i, j] = navie_vector_dot(row_x, column_y) return z综上所述:
两个矩阵相乘需要的要求为矩阵x的列于矩阵y的行相等,再将矩阵x的行依次与矩阵y的列想称再相加。得到一个以矩阵x的行为行,矩阵y的列为列的新矩阵。 一般来说,可以对更高维的张量做点积,只要其形状匹配遵循与前面2D张量相同的原则:
(a, b , c ,d) . (d,) -> (a, b, c)
(a, b , c ,d) . (d, e) -> (a, b, c, e)
以此类推。
张量变形
改变张量的行和列,以得到想要的形状,变形后的张量的元素总个数与初始张量相同。
举例:
x = np.array([[0., 1.], [2., 3.], [4., 5.]]) print(x.shape) # (3, 2) x = reshape((6, 1)) x # array([[ 0.], # 1.], # 2.], # 3.], # 4.], # 5.]]) x = x.reshape((2, 3)) x # array([[ 0., 1., 2.],[ 3., 4., 5.]])最经常遇到的一种特殊的张量变形是转置。对矩阵做转置是指将行和列互换,使x[i, :]变为x[:, i]。
x = np.zeros((300,20)) x = np.transpose(x) print(x.shape)
边栏推荐
猜你喜欢

直播|StarRocks 技术内幕 :低基数全局字典优化

解析,强势供应商的管理方法

Oracle EMCC可以独立安装吗?还是必须安装到数据库服务器上?

StarRocks 7 月社区动态

中断系统需要解决的问题

【STM32】入门(四):外部中断-按键通过中断动作

ClickHouse - Getting Started

银微转债,洁特转债上市价格预测

Shenzhen Offline Registration|StarRocks on AWS: How to conduct rapid and unified analysis of real-time data warehouses

Can Oracle EMCC be installed independently?Or does it have to be installed on the database server?
随机推荐
Test drive: project management module - curd development project
OpenFOAM extracts equivalency and calculates area
DC-6靶场下载及渗透实战详细过程(DC靶场系列)
HI3521D 烧录128M nand flash文件系统过程-一定要注意flash的容量
Mysql如何建立索引实现语句优化
SMP 需要考虑的事情
path development介绍
Chapter 8 Character Input Output and Input Validation
log4j设置日志的时区
AF-DNAT
肖sir__简历
数商云供应链集成系统开发方案:多行业集成平台管理自动化
DOM破环和两个实验的复现
Oracle EMCC可以独立安装吗?还是必须安装到数据库服务器上?
DC-5靶场下载及渗透实战详细过程(DC靶场系列)
移植RT-Thread编译报错thumb conditional instruction should be in IT block
基于 jetpack compose,使用MVI架构+自定义布局实现的康威生命游戏
电子设备行业智能供应链系统:打破传统供应链壁垒,提升电子设备企业管理效能
ESP8266-Arduino编程实例-MCP3008-ADC转换器驱动
t条件判断语句与if循环