网站首页 > 技术文章 正文
医工荟萃,不是萝卜开会,融合创新才是硬道理!
预计阅读时间: 6 分钟
上一讲荟荟讲了一下张量切片、逐元素运算、广播,这一讲再说说张量点积和张量变形,集齐这五种装备,基本可以开始愉快地玩耍了。
张量点积
前面我们说过逐元素运算,要将两个张量进行逐元素相乘,我们使用“*“运算符,比如将两个矩阵A和B进行逐元素相乘
而在神经网络中,经常需要类似图1的乘法方式,我们将输入向量和权值向量的对应元素进行相乘后再求和,这种方式我们称之为张量点积。
如图2所示,如果有多个神经元需要输出,则可以把输入X写成一个列向量,它的转置为
输入权值矩阵可写为
该矩阵的每一列,代表输入到中间层某一个神经元的权值向量,如下图中输入到z2的权值正是上述矩阵的第二列。从图中可以看出,我们得到的中间层神经元的输出(这里为了简单起见省略了非线性激活函数,如ReLU)也是一个列向量,如下:
其中的第n个元素正是输入的每个元素和W的第n列对应元素一一相乘并相加的结果。如果向更高维度扩展,输入不是一个向量,而是一个矩阵,比如我们将100个输入样本向量输入刚才讨论的神经网络,那么XT的形状就是(100,3),ZT的形状就是(100,4)。
看到这里,学过线性代数的童鞋可能已经看出,这不就是我们学过的矩阵乘法嘛,没错,这里说的张量点积,如果是2d张量(矩阵),就是我们最常见的矩阵乘法,语法如下。
只不过它还可以继续拓展,比如要在神经网络里处理视频数据,形状通常是(帧,长,宽,颜色),如果需要进行点积(对应元素相乘相加),这时候如果有一个底层优化过的张量点积运算,我们就可以保持其他维度不变,直接用一次dot把所有帧和颜色的张量都进行相同的点积运算,而按照传统方法我们则需要进行多重循环。
在Numpy中,如果A为M维张量,B为N为张量,两个张量的点积就是将A张量的最后一个轴中的所有元素,与B张量中倒数第二个轴的所有元素对应相乘后相加的结果,也就是dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])。有点晕菜对不对,下面用矩阵来解释一下,如图3所示,矩阵x的第一个轴是行,第二个轴是列,矩阵一共就两个轴,所以x的最后一个轴就是列,同理y的倒数第二个轴是行。可见矩阵x和y的点积就是将x第i行中的所有列(x的最后一个轴)和y第j列中的所有行(y的倒数第二个轴)对应相乘并相加的结果返回给z(i,j)。从这个例子中也可以发现,这就要求x的列数必须等于y的行数,也就是A张量最后一个轴的元素数量必须等于B张量倒数第二个轴中的元素数量。
那么张量点积后的形状和输入张量形状的关系又是什么呢,以一个例子来说明一下,如果A的形状为(a,b,c,d),B的形状为(d,e),那么numpy.dot(A,B)的形状为(a,b,c,e)。如果A的形状为(a,b,c,d), B的形状为(c,d),那么就呵呵了,因为A的最后一个轴元素数量为d,而B的倒数第二个轴元素数量为c,不匹配,会报错。
下面给出了一个矩阵乘法的实际案例,小伙伴们去仔细研究一下吧。
此外,Numpy还提供了一种更为灵活的张量点乘函数numpy.tensordot(a,b,axes),可以指定需要和并的轴,但是不太容易理解,这里就不写出来混淆试听了,有兴趣的朋友们可以看看Chenxiao Ma的博客,写的还挺清楚的https://www.machenxiao.com/blog/tensordot
对于初学者来说知道numpy.dot就是求矩阵乘法也基本够用了。
张量变形
- reshape
张量变形其实咱们在第二讲中已经见过,当时我们需要把一个形状为(60000,28,28)的手写字符图像张量输入一个中间层为784个神经元的密集连接型神经网络。所以需要将这个张量变形为(60000,28*28)的形状,才好和后面的全连接神经网络进行加权点乘。当时我们的预处理代码是:
train_images =train_images.reshape((60000, 28 * 28))
reshape函数很简单,输入参数就是你想要的新形状,只要新张量中的元素个数和原始张量中的元素个数是一样的即可。元素的安排顺序默认和c语言是一致的,即依次进行排列。下面两个例子可以让你清楚地理解这一操作。
- 转置Transpose
另一种常见的张量变形就是转置了,即把矩阵的行换成列,列换成行,也就是x[i,:]变为x[:,i],语法为np.transpose(x)。
到这里,张量最常见的几种常见的操作和运算算是告一段落,总结一下本讲的内容:1. 张量点积(相乘相加,2D张量就是矩阵乘法);2. 张量变形(张量在神经网络逐层传播,每一层的输入和输出形状有可能发生变化,需要变形加以适应)。下一讲我们会从卷积神经网络开始正式进入深度学习的实际操作,过程中我们会反复操练这些张量操作方法。
更多精彩内容,搜索并关注微信公众号"医工荟"。
猜你喜欢
- 2024-09-26 人工智能数学基础----矩阵(人工智能a算法)
- 2024-09-26 机器学习之线性代数速查表(线性代数快速入门)
- 2024-09-26 谈谈矩阵的运算(矩阵及其运算的性质)
- 2024-09-26 巧用python的矩阵运算来进行电路的计算和分析
- 2024-09-26 计算机图形中的矩阵(计算机的矩阵怎么用)
- 2024-09-26 形象直观的“2X2矩阵”乘法运算的本质原理
- 2024-09-26 深度学习:所有矩阵尺寸和计算的深层指南!
- 2024-09-26 python与线性代数 矩阵的运算(python做线性代数)
- 2024-09-26 矩阵加法与数乘的应用——灰度矩阵的凸组合对应灰度图的合成
- 2024-09-26 NumPy最生动形象的教程(numpy技巧)
- 1515℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 573℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 513℃MySQL service启动脚本浅析(r12笔记第59天)
- 487℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 486℃启用MySQL查询缓存(mysql8.0查询缓存)
- 469℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 449℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 447℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (83)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)