本节将介绍深度学习领域涉及的后端知识,包括深度学习中的JavaScript数据类型和JavaScript异步编程。
2.6.1JavaScript数据类型
深度学习中的基本数据结构是张量,高效的数据结构对于任何深度学习项目都非常重要。 在C/C++中,我们可以使用形式参数来高效存储一些集合数据并实现快速访问; 在Python中,我们可以通过NumPy中的NDArray对象来实现这个功能。 NDArray对象是一系列相同类型数据的集合,用于存储相同类型元素的多维字段。
深度学习中支持的 JavaScript 数据类型是 TypedArray,它是一种介于原始字段和 NDArray 之间的数据结构。 现代浏览器中的 TypedArray 有 11 种类型,如表 2-8 所示。
表 2-8 类型化数组
类型
整型8数组
Uint8Array
Uint8ClampedArray
8位无符号整数(超出范围后的边界值)
Int16数组
16 位二进制有符号整数
Uint16数组
16 位无符号整数
Int32数组
32 位二进制有符号整数
Uint32Array
32 位无符号整数
浮点32数组
Float64数组
64 位 IEEE 浮点数(16 位有效数字)
BigInt64Array
64 位二进制有符号整数
BigUint64Array
64 位无符号整数
接下来我们介绍ArrayBuffer以及访问ArrayBuffer的两种方式——TypedArray和DataView。
1. 数组缓冲区
ArrayBuffer 对象表示通用的、固定宽度的原始二进制数据缓冲区,它是一个字节字段。 由于ArrayBuffer只是显存上的一个二进制缓冲区,它并没有提供任何操作数据的方式(读数据、写数据),也就是说我们不能直接操作ArrayBuffer的内容,而必须通过TypedArray或者DataView对象来操作。 。 它们将缓冲区中的数据表示为特定的格式,并通过这种格式读写缓冲区的内容,如代码清单2-22所示。
代码清单2-22
const buffer = new ArrayBuffer(4)
console.log(buffer.byteLength) //4
2. 类型化数组
TypedArray 对象描述了底层二进制数据缓冲区的类似字段的视图。 TypedArray 定义了如何访问底层的 ArrayBuffer。 事实上,用于存储数据的数据结构就是ArrayBuffer。 没有名为 TypedArray 的全局属性,也没有名为 TypedArray 的构造函数。 示例代码如代码清单2-23所示。
代码清单2-23
const typedArray1 = new Int8Array(8);
typedArray1[0] = 128;
const typedArray2 = new Int8Array(typedArray1);
typedArray2[1] = 20;
console.log(typedArray1);
// 期望输出: Int8Array [-128, 0, 0, 0, 0, 0, 0, 0]
console.log(typedArray2);
// 期望输出: Int8Array [-128, 20, 0, 0, 0, 0, 0, 0]
由于Int8Array上单个元素值的范围是128到127,当指定typedArray1字段的第一个元素是128时,该值超出范围,循环将从另一个边界,即该值重新开始是 128。
3. 数据视图
DataView 是一个低级套接字,可以从二进制 ArrayBuffer 对象中读取和写入多种数字类型。 使用时无需考虑不同平台的字节顺序问题,如代码清单2-24所示。
代码清单2-24
var buffer = new ArrayBuffer(4)
new DataView(buffer).setInt16(0,42,true)
console.log(new Uint8Array(buffer))
我们首先在代码清单2-24中创建了一个4字节的ArrayBufferhtml5多线程,然后使用已经创建的ArrayBuffer作为数据源并创建了一个DataView对象,并通过setInt16()创建了起始位置为0、值为42的16方法。 位整数。 我们还指定setInt16()方法的参数littleEndian为true,即采用little-endian字节序(低位字节放在显存低地址端,高位字节放在显存低地址端)位于视频存储器的高地址端)。 该参数的默认值为 false,表示默认使用 big-endian 字节顺序。 上述代码运行结果如下。
Uint8Array [42, 0, 0, 0]
2.6.2 JavaScript异步编程
在Web浏览器或Momo小程序中部署机器学习应用程序时html5多线程,经常使用两种方法:从服务器加载现成的JavaScript模型或转换TensorFlow模型。 JavaScript 语言使用单线程模型,因此网络 I/O 请求等持久任务通常通过设置回调函数、使用 Promise 对象以及使用 async/await 函数来处理。 本节将介绍JavaScript中的风暴循环机制以及如何处理异步任务。
JavaScript语言最大的特点就是单线程。 这意味着所有任务必须同步执行,即前一个任务完成后,才能开始下一个任务。 但如果前一个任务耗时较长,则前一个任务仍会处于等待状态,导致主线程阻塞。 ,进而影响页面的呈现。
为了解决这个问题,我们通常将JavaScript中可以处理的任务分为同步任务和异步任务。 同步任务是指在 JavaScript 主线程上排队等待执行的任务; 异步任务是指在任务队列中执行的任务。 异步执行的运行机制如下。
图2-29 异步编程运行流程