写点什么

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

  • 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:251880

评论

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

Go语言学习查缺补漏ing Day2

恒生LIGHT云社区

Go 编程语言

火山引擎+焱融 YRCloudFile,驱动数据存储新增长

焱融科技

云计算 分布式 云原生 高性能 文件存储

模运算和与运算的一点儿简单思考

LSJ

位运算 二进制

JVM中的对象及引用

Ayue、

技术专题合集

前端避坑指南丨辛辛苦苦开发的APP竟然被判定为简单网页打包?

YonBuilder低代码开发平台

大前端 APP开发 APICloud 跨端开发

详解工作流框架Activiti的服务架构和组件

华为云开发者联盟

工作流 工作流引擎 BPM Activiti BPMN

软件工程师年满 40 岁,下一步怎么走?|本周话题

InfoQ写作社区官方

生涯规划 个人成长 职业规划 话题讨论

开始读 Go 源码了

AlwaysBeta

golang 源码 源码阅读 源码剖析 Go web

百度智能客服斩获 “金音奖—中国最佳客户联络中心技术与解决方案奖”

百度大脑

人工智能 智能客服

模仿UP主,用Python实现一个弹幕控制的直播间!

Zhendong

Python

做一款互联网内容平台,到底要懂多少AI?

百度开发者中心

AI

【AI最前线】精准优质-资讯|分享|热议第42期

百度大脑

同态加密实现数据隐私计算,能让你的小秘密更加秘密

华为云开发者联盟

数据 加密 同态加密 联邦计算 数据隐私计算

清空数组的几个方式

编程江湖

大前端

如何在 Flutter 中设置背景图像【Flutter专题15】

坚果

flutter 28天写作 签约计划第二季 12月日更

什么是云计算?云计算特点是什么?

行云管家

云计算 公有云 混合云 云资源

Redis架构实战:高并发情况下并发扣减库存

编程江湖

java编程

CIO如何制定低代码/无代码战略

BeeWorks

mPaaS 月度小报|魔方卡片(Cube)公测,十个卡片模板任意使用

蚂蚁集团移动开发平台 mPaaS

小程序 消息推送 移动开发 API网关 cube

青藤解密:72%客户容器规模>100个,[镜像安全]谁来保护?

青藤云安全

镜像安全

HBase 和 Hive 的差别是什么,各自适用在什么场景中

编程江湖

大数据

大数据开发技术应该怎么学习入门才好

@零度

大数据

复杂场景,从OpenTSDB迁移到TDengine的最佳实践

TDengine

数据库 tdengine

MySQL「 Every derived table must have its own alias」1248 错误修复法

蒋川

数据库 MySQL 运维 MySQL 数据库

滚雪球学Python系列,真能学会Python!

梦想橡皮擦

内容合集 签约计划第二季

等保工作五大误区汇总,让你更懂等保!

行云管家

网络安全 等保 等级保护

打造基于 PostgreSQL/openGauss 的分布式数据库解决方案

SphereEx

数据库 开源 分布式数据库 ShardingSphere SphereEx

面对行业难题,华为云邀请物联网全行业拿出“亮剑”精神

华为云开发者联盟

IoT 华为云 LiteOS HarmonyOS IoT边缘

【Java】代码重构时,为什么禁止在方法内对对象类型的入参赋值

恒生LIGHT云社区

Java 代码规范 java代码规范

架构实战营 模块七作业

felix

「架构实战营」

莫要寻找可能不存在的答案

FunTester

学习 解决方案 自学 FunTester 思路

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