HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

深度学习入门(三):多维数组的运算

  • 2020-03-29
  • 本文字数:4023 字

    阅读完需:约 13 分钟

深度学习入门(三):多维数组的运算

编者按:本文节选自图灵程序设计丛书 《深度学习入门》一书中的部分章节。


如果掌握了 NumPy 多维数组的运算,就可以高效地实现神经网络。因此,本节将介绍 NumPy 多维数组的运算,然后再进行神经网络的实现。

多维数组

简单地讲,多维数组就是“数字的集合”,数字排成一列的集合、排成长方形的集合、排成三维状或者(更加一般化的) 维状的集合都称为多维数组。下面我们就用 NumPy 来生成多维数组,先从前面介绍过的一维数组开始。


>>> <b>import numpy as np</b>>>> <b>A = np.array([1, 2, 3, 4])</b>>>> <b>print(A)</b>[1 2 3 4]>>> <b>np.ndim(A)</b>1>>> <b>A.shape</b>## 4,>>> <b>A.shape[0]</b>4
复制代码


如上所示,数组的维数可以通过 np.dim() 函数获得。此外,数组的形状可以通过实例变量 shape 获得。在上面的例子中,A 是一维数组,由 4 个元素构成。注意,这里的 A.shape 的结果是个元组(tuple)。这是因为一维数组的情况下也要返回和多维数组的情况下一致的结果。例如,二维数组时返回的是元组 (4,3),三维数组时返回的是元组 (4,3,2),因此一维数组时也同样以元组的形式返回结果。下面我们来生成一个二维数组。



>>> <b>B = np.array([[1,2], [3,4], [5,6]])</b>>>> <b>print(B)</b>[[1 2] [3 4] [5 6]]>>> <b>np.ndim(B)</b>2>>> <b>B.shape</b>## 3, 2
复制代码


这里生成了一个 3 × 2 的数组 B。3 × 2 的数组表示第一个维度有 3 个元素,第二个维度有 2 个元素。另外,第一个维度对应第 0 维,第二个维度对应第 1 维(Python 的索引从 0 开始)。二维数组也称为 矩阵 (matrix)。如图 1 所示,数组的横向排列称为 (row),纵向排列称为 (column)。



图 1 横向排列称为行,纵向排列称为列

矩阵乘法

下面,我们来介绍矩阵(二维数组)的乘积。比如 2 × 2 的矩阵,其乘积可以像图 2 这样进行计算(按图中顺序进行计算是规定好了的)。



图 2 矩阵的乘积的计算方法


如本例所示,矩阵的乘积是通过左边矩阵的行(横向)和右边矩阵的列(纵向)以对应元素的方式相乘后再求和而得到的。并且,运算的结果保存为新的多维数组的元素。比如, 的第 1 行和 的第 1 列的乘积结果是新数组的第 1 行第 1 列的元素, 的第 2 行和 的第 1 列的结果是新数组的第 2 行第 1 列的元素。另外,在本书的数学标记中,矩阵将用黑斜体表示(比如,矩阵 ),以区别于单个元素的标量(比如,)。这个运算在 Python 中可以用如下代码实现。



>>> <b>A = np.array([[1,2], [3,4]])</b>>>> <b>A.shape</b>## 2, 2>>> <b>B = np.array([[5,6], [7,8]])</b>>>> <b>B.shape</b>## 2, 2>>> <b>np.dot(A, B)</b>array([[19, 22], [43, 50]])
复制代码


这里, 都是 2 × 2 的矩阵,它们的乘积可以通过 NumPy 的 np.dot() 函数计算(乘积也称为点积)。np.dot() 接收两个 NumPy 数组作为参数,并返回数组的乘积。这里要注意的是,np.dot(A, B)np.dot(B, A) 的值可能不一样。和一般的运算(+* 等)不同,矩阵的乘积运算中,操作数(AB)的顺序不同,结果也会不同。


这里介绍的是计算 2 × 2 形状的矩阵的乘积的例子,其他形状的矩阵的乘积也可以用相同的方法来计算。比如,2 × 3 的矩阵和 3 × 2 的矩阵的乘积可按如下形式用 Python 来实现。



>>> <b>A = np.array([[1,2,3], [4,5,6]])</b>>>> <b>A.shape</b>## 2, 3>>> <b>B = np.array([[1,2], [3,4], [5,6]])</b>>>> <b>B.shape</b>## 3, 2>>> <b>np.dot(A, B)</b>array([[22, 28], [49, 64]])
复制代码


2 × 3 的矩阵 和 3 × 2 的矩阵 的乘积可按以上方式实现。这里需要注意的是矩阵的形状(shape)。具体地讲,矩阵 的第 1 维的元素个数(列数)必须和矩阵 的第 0 维的元素个数(行数)相等。在上面的例子中,矩阵 的形状是 2 × 3,矩阵 的形状是 3 × 2,矩阵 的第 1 维的元素个数(3)和矩阵 的第 0 维的元素个数(3)相等。如果这两个值不相等,则无法计算矩阵的乘积。比如,如果用 Python 计算 2 × 3 的矩阵 和 2 × 2 的矩阵 的乘积,则会输出如下错误。



>>> <b>C = np.array([[1,2], [3,4]])</b>>>> <b>C.shape</b>## 2, 2>>> <b>A.shape</b>## 2, 3>>> <b>np.dot(A, C)</b>Traceback (most recent call last): File "<stdin>", line 1, in <module>ValueError: shapes (2,3) and (2,2) not aligned: 3 (dim 1) != 2 (dim 0)
复制代码


这个错误的意思是,矩阵 的第 1 维和矩阵 的第 0 维的元素个数不一致(维度的索引从 0 开始)。也就是说,在多维数组的乘积运算中,必须使两个矩阵中的对应维度的元素个数一致,这一点很重要。我们通过图 3 再来确认一下。



图 3 在矩阵的乘积运算中,对应维度的元素个数要保持一致


图 3 中,3 × 2 的矩阵 和 2 × 4 的矩阵 的乘积运算生成了 3 × 4 的矩阵 。如图所示,矩阵 和矩阵 的对应维度的元素个数必须保持一致。此外,还有一点很重要,就是运算结果的矩阵 的形状是由矩阵 的行数和矩阵 的列数构成的。


另外,当 是二维矩阵、 是一维数组时,如图 4 所示,对应维度的元素个数要保持一致的原则依然成立。


可按如下方式用 Python 实现图 4 的例子。



>>> <b>A = np.array([[1,2], [3, 4], [5,6]])</b>>>> <b>A.shape</b>## 3, 2>>> <b>B = np.array([7,8])</b>>>> <b>B.shape</b>## 2,>>> np.dot(A, B)array([23, 53, 83])
复制代码



图 4  是二维矩阵、 是一维数组时,也要保持对应维度的元素个数一致

神经网络的内积

下面我们使用 NumPy 矩阵来实现神经网络。这里我们以图 5 中的简单神经网络为对象。这个神经网络省略了偏置和激活函数,只有权重。



图 5 通过矩阵的乘积进行神经网络的运算


实现该神经网络时,要注意 的形状,特别是 的对应维度的元素个数是否一致,这一点很重要。



>>> <b>X = np.array([1, 2])</b>>>> <b>X.shape</b>## 2,>>> <b>W = np.array([[1, 3, 5], [2, 4, 6]])</b>>>> <b>print(W)</b>[[1 3 5] [2 4 6]]>>> <b>W.shape</b>## 2, 3>>> <b>Y = np.dot(X, W)</b>>>> <b>print(Y)</b>[ 5 11 17]
复制代码


如上所示,使用 np.dot(多维数组的点积),可以一次性计算出 的结果。这意味着,即便 的元素个数为 1001000,也可以通过一次运算就计算出结果!如果不使用 np.dot,就必须单独计算 的每一个元素(或者说必须使用 for 语句),非常麻烦。因此,通过矩阵的乘积一次性完成计算的技巧,在实现的层面上可以说是非常重要的。


图书简介https://www.ituring.com.cn/book/1921



相关阅读


深度学习入门(一):神经网络


深度学习入门(二):激活函数


2020-03-29 19:251735

评论

发布
暂无评论
发现更多内容

iOS开发:平时做项目经常用到的快捷键归纳

三掌柜

11月日更

Activity生命周期详解,android游戏开发实践指南

android 程序员 移动开发

Android 12 行为变更:适配以Android 12为目标的应用,移动应用开发就业方向

android 程序员 移动开发

android activity Intent 传值 传对象,移动智能终端的发展趋势

android 程序员 移动开发

8年Android开发程序员教你如何写简历!看完别再问为何你只值5K

android 程序员 移动开发

Android 10 适配攻略,最新阿里Android面试题目

android 程序员 移动开发

Android D8 编译器 和 R8 工具,android零基础开发

android 程序员 移动开发

Activity Result API 使用与源码分析,移动端开发基础

android 程序员 移动开发

AdapterViewFlipper 图片_文字 轮播动画控件,【面试必会】

android 程序员 移动开发

Andorid性能优化之traceview的使用(不懂揍我),androidstudio计算器

android 程序员 移动开发

android Alarm闹钟发送广播播放音乐,【大牛疯狂教学

android 程序员 移动开发

Android Glide 3(1),撸了郭霖大神写的Framework源码笔记

android 程序员 移动开发

Android Glide 3,android编程软件

android 程序员 移动开发

8年Android开发程序员教你如何写简历!看完别再问为何你只值5K(1)

android 程序员 移动开发

8年老Android开发谈;Context都没弄明白凭什么拿高薪?

android 程序员 移动开发

9次Android面试经验总结,已收字节,阿里,2021Android开发面试解答之设计模式篇

android 程序员 移动开发

Activity页面的绘制流程,移动端跨平台开发

android 程序员 移动开发

andriod搭建自己的轮询框架,flutter开发环境

android 程序员 移动开发

Android Camera 内存问题剖析,Android屏幕适配很难嘛其实也就那么回事

android 程序员 移动开发

7年老Android收到阿里offer,跟领导提离职被怼:为年薪百万不做兄弟

android 程序员 移动开发

Android DataBinding 从入门到进阶,android路由实现

android 程序员 移动开发

Android Systrace 使用方法,互联网寒冬

android 程序员 移动开发

Android - singleTask启动模式详解,kotlin常用高阶函数

android 程序员 移动开发

Android 12 行为变更:适配以Android 12为目标的应用(1)

android 程序员 移动开发

Android Gradle 干货,android屏幕适配框架

android 移动开发

Android 9 Pie 现已面向全球正式发布!,flutter插件播放音乐

android 程序员 移动开发

Android App安装包大小优化,Android开发面试技能介绍

android 程序员 移动开发

9成Android开发者必须收藏的80个开源库,安卓rxjava获取网络时间

android 程序员 移动开发

Activity启动流程分析(android-29),Android面试题库

android 程序员 移动开发

Android 11 Settings源码入门,flutter安装

android 程序员 移动开发

Android Ashmem匿名共享内存,科学技术协会面试

android 程序员 移动开发

深度学习入门(三):多维数组的运算_AI&大模型_斋藤康毅_InfoQ精选文章