MXNet NumPy 数组创建例程(Array Creation Routines)完全指南:从零、全一、数值区间到矩阵构建
【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址: https://gitcode.com/gh_mirrors/mxne/mxnet
导读
mxnet.numpy(np)是 MXNet 深度学习中面向 NumPy 兼容风格的编程入口,而数组创建例程(Array Creation Routines)是所有后续张量运算的起点。本文以官方 API 文档 routines.array-creation.rst 为主线,完整覆盖零/一/填充/单位数组、从既有数据构造、数值区间、矩阵构建四大类共 30 余个函数,并结合 python/mxnet/numpy/multiarray.py 的源码实现,讲清每个函数的参数语义、默认值与 MXNet 特有的device支持。读完本文,你将能像使用 NumPy 一样熟练地创建任意形状、任意设备(CPU/GPU)上的 MXNet 张量,并准确理解其与官方 NumPy 在默认 dtype、内存布局上的差异。
一、为什么需要一套“数组创建例程”
在 MXNet 2.x 中,mxnet.numpy以模块别名np提供与 NumPy 高度一致的 API(例如import mxnet.numpy as np),让熟悉 NumPy 的开发者可以零成本迁移,同时又针对深度学习做了三点关键调整:
- 默认 dtype 面向深度学习:官方 NumPy 默认浮点类型是
float64,而 MXNet 默认是float32(深度学习的主流精度); - 新增
device参数:几乎每个创建函数都支持device,可直接把张量分配在 GPU 上; - 内存布局仅支持 C 序:
order参数目前只接受'C'(行主序)。
文档按用途把创建例程划分为五个大类(见 routines.array-creation.rst):
| 分类 | 已实现(autosummary) | 参考 NumPy(code块) |
|---|---|---|
| Ones and zeros(全零全一) | eyeemptyfullidentityonesones_likezeroszeros_like | full_likeempty_like |
| From existing data(从既有数据) | arraycopy | frombufferfromfunctionfromiterfromstringloadtxt |
| Numerical ranges(数值区间) | arangelinspacelogspacemeshgrid | geomspacemgridogrid |
| Building matrices(构建矩阵) | tril | diagdiagflattritriuvander |
| 记录数组 / 字符数组 | np.rec、np.char子模块 | core.records.*core.defchararray.* |
需要特别说明的是文档的排版约定:.. autosummary::块中的函数会在文档站点自动生成独立 API 页面,属于 MXNet 已实现并正式导出的接口;而.. code::块中列出的(如frombuffer、geomspace、vander、mgrid、ogrid等)是对应 NumPy 同名函数、用于标注 API 对齐进度的参考项,其中相当一部分在当前仓库的 python/mxnet/numpy 中尚未实现或未作为正式接口导出,使用时需以mxnet.numpy实际可用 API 为准。
二、全零、全一与填充数组(Ones and Zeros)
这一类是模型初始化、掩码构造、权重分配时最高频的创建函数,全部实现在 python/mxnet/numpy/multiarray.py。
2.1zeros与ones:最常用的定值初始化
import mxnet.numpy as np import mxnet as mx np.zeros(5) # array([0., 0., 0., 0., 0.]) np.zeros((5,), dtype=int) # array([0, 0, 0, 0, 0], dtype=int64) np.zeros((2, 1)) # 二维全零 np.ones(5) # array([1., 1., 1., 1., 1.]) np.ones((5,), dtype=int) # array([1, 1, 1, 1, 1], dtype=int64) np.ones((2, 2)) # 全一方阵源码实现(multiarray.py)将zeros/ones直接委托给底层算子_mx_nd_np.zeros(shape, dtype, order, device),二者签名完全一致:
shape:int或int元组,如(2, 3)或2;dtype:可选,不传时由“默认 dtype”决定(见下文 2.4);order:仅支持'C'(行主序);device:内存分配设备,默认mxnet.device.current_device(),可传mx.gpu(0)直接把数组建在 GPU 上。
2.2empty与full:不初始化与按值填充
np.empty([2, 2]) # 未初始化,内容为任意值 np.empty([2, 2], dtype=int) # dtype 决定元素宽度 np.full((2, 2), 10) # array([[10., 10.], [10., 10.]]) np.full((2, 2), 2, dtype=np.int32, device=mx.cpu(0))empty(multiarray.py)只分配内存、不写值,速度最快;order非'C'时直接抛出NotImplementedError。文档示例中的随机“垃圾值”正是未初始化内存的表现,因此只在后续会立即整体覆写的场景下使用。full(multiarray.py)多一个fill_value参数,同时支持out输出参数:若传入out,结果写入既有数组而不新分配。dtype缺省时由fill_value类型推断(int → 默认整型、float → 默认浮点、bool → 布尔)。注意:full比 NumPy 多出device与out两个参数,且暂不支持order选择。
2.3*_like一族:沿用既有数组的形状与类型
a = np.array([[1, 2, 3], [4, 5, 6]]) np.zeros_like(a) # 与 a 同形状同 dtype 的全零数组 np.ones_like(a) # 与 a 同形状同 dtype 的全一数组 np.full_like(a, 7) # 与 a 同形状同 dtype、填充 7 的数组 np.empty_like(a) # 与 a 同形状同 dtype、不初始化的数组zeros_like(multiarray.py)、ones_like(multiarray.py)、full_like(multiarray.py)、empty_like(multiarray.py)均支持用dtype覆盖结果类型、用shape覆盖结果形状。empty_like的subok参数当前仅支持False,shape参数暂不支持(源码 docstring 明确标注 "Not supported at this moment"),使用时需留意。
2.4 默认 dtype 机制:float32还是float64?
这是 MXNet NumPy API 与官方 NumPy 最核心的行为差异。所有创建函数的 docstring 都写了同一段规则:
- 当
npx.is_np_default_dtype()返回False(默认),默认浮点 dtype 为float32; - 当
npx.is_np_default_dtype()返回True(即执行过npx.set_np(dtype=True)),默认浮点 dtype 为float64,与官方 NumPy 完全对齐。
np.array([1, 2, 3]).dtype # dtype('float32'),深度学习默认精度 npx.set_np(dtype=True) np.array([1, 2, 3]).dtype # dtype('float64'),对齐官方 NumPyarange的默认 dtype 规则略有不同:默认 dtype 模式下为float32,set_np(dtype=True)后为int64(见 multiarray.py 的 docstring 与示例)。这条机制在 empty、array 的源码中直接体现:dtype = _np.float64 if is_np_default_dtype() else _np.float32。
2.5eye与identity:单位矩阵
np.eye(2, dtype=int) # array([[1, 0], [0, 1]], dtype=int64) np.eye(3, k=1) # 上对角线为 1 np.identity(3) # 3×3 单位阵eye(multiarray.py):N为行数、M为列数(默认等于N),k为对角线偏移(0 主对角线、正值上对角、负值下对角),返回 2-D 数组;identity(multiarray.py):等价于eye(n)的方形特例,仅接受n、dtype、device三个参数。
三、从既有数据创建(From Existing Data)
3.1array:从 Python 序列/嵌套序列构造张量
array(multiarray.py)接受array_like、numpy.ndarray、mxnet.numpy.ndarray或任意嵌套序列:
np.array([1, 2, 3]) # array([1., 2., 3.]) np.array([[1, 2], [3, 4]]) # 二维数组 np.array([[1, 0], [0, 1]], dtype=bool) # 布尔数组实现细节上值得注意的三点:
- 类型推断规则:若输入是
ndarray,dtype缺省时沿用输入 dtype;否则按默认 dtype(float32/float64)推断; - 禁止隐式转换
mx.nd.NDArray:若传入旧式mx.nd.NDArray,源码会抛出ValueError,提示改用零拷贝的as_np_ndarray函数——这是新老两套 NDArray 体系之间的刻意隔离; - 错误透明:内部先调用官方 NumPy 的
np.array完成转换,失败时把 NumPy 的原始异常信息原样透出(raise TypeError(str(e))),便于用户对照 NumPy 排查。
3.2copy:显式复制以隔离视图
x = np.array([1, 2, 3]) y = x # 视图/引用,共享内存 z = np.copy(x) # 独立副本 x[0] = 10 x[0] == y[0] # True(y 跟着变) x[0] == z[0] # False(z 是独立副本)copy(multiarray.py)返回输入数组的完整副本,适用于需要“写时复制”语义、防止原地修改污染上游变量的场景。
3.3 尚未在 MXNet 中实现的参考 API
文档code块列出的frombuffer、fromfunction、fromiter、fromstring、loadtxt在 python/mxnet/numpy 源码中不存在对应实现(笔者在全部模块中未检索到这些函数定义)。它们属于 NumPy 兼容路线图上的待办项,当前若需从字节流、迭代器或文本文件加载数据,应改用 MXNet 现有的数据加载设施(如 python/mxnet/io 模块的 DataLoader/ImageRecordIter)或先用官方 NumPy 构造再通过np.array转换。
四、数值区间(Numerical Ranges)
4.1arange:按步长生成等差数列
arange(multiarray.py)在半开区间[start, stop)上按固定步长生成序列,与 Python 内置range语义一致,但返回ndarray:
np.arange(3) # array([0., 1., 2.]) np.arange(3.0) # array([0., 1., 2.]) np.arange(3, 7) # array([3., 4., 5., 6.]) np.arange(3, 7, 2) # array([3., 5.])要点:
start缺省为 0,step缺省为 1;若step以位置参数形式给出,start必须同时显式给出;- 浮点参数下结果长度由
ceil((stop - start)/step)决定,受浮点舍入影响,末尾元素可能略大于stop; - 默认 dtype 规则与整型/浮点参数相关:默认模式(
is_np_default_dtype()为False)下返回float32,npx.set_np(dtype=True)后返回int64。
4.2linspace:按样本数生成等间距序列
linspace(multiarray.py)用“样本个数”而非“步长”控制序列,默认在闭区间[start, stop]上生成 50 个点:
np.linspace(2.0, 3.0, num=5) # array([2. , 2.25, 2.5 , 2.75, 3. ]) np.linspace(2.0, 3.0, num=5, endpoint=False) # array([2. , 2.2, 2.4, 2.6, 2.8]) np.linspace(2.0, 3.0, num=5, retstep=True) # (array([...]), 0.25),同时返回步长参数速查:endpoint=True时stop是最后一个样本(否则排除);retstep=True时返回(samples, step)元组;num必须非负。文档同时标注了与 NumPy 的两处差异:start/stop暂不支持 list/ndarray 输入,axis目前仅支持 0。
4.3logspace:对数刻度等间距
logspace(multiarray.py)在线性空间等分[start, stop]后取base的幂,等价于base ** np.linspace(start, stop, num, endpoint):
np.logspace(2.0, 3.0, num=4) # array([100., 215.44347, 464.15887, 1000.]) np.logspace(2.0, 3.0, num=4, endpoint=False) np.logspace(2.0, 3.0, num=4, base=2.0) # 以 2 为底 np.logspace(2.0, 3.0, num=4, base=2.0, dtype=np.int32) np.logspace(2.0, 3.0, num=4, device=npx.gpu(0)) # 直接在 GPU 上创建base缺省为 10.0,axis目前仅支持 0。该函数常用于生成学习率衰减、频响分析等对数尺度下的采样点。
4.4meshgrid:由坐标向量生成网格坐标矩阵
meshgrid实现在 python/mxnet/numpy/function_base.py,接收一组一维坐标向量,返回 N 维网格坐标数组,是可视化、网格采样、插值的常用基础件:
x = np.arange(3) y = np.arange(2) X, Y = np.meshgrid(x, y) # 默认 indexing='xy'(笛卡尔) X2, Y2 = np.meshgrid(x, y, indexing='ij') # 矩阵索引参数说明:indexing支持'xy'(默认,笛卡尔)与'ij'(矩阵)两种约定;文档明确标注sparse=True与copy=False当前均不支持,即只能返回稠密、复制的网格。indexing='xy'时输出形状为(N2, N1, ...)(x1沿第二维展开),'ij'时为(N1, N2, ...)。
4.5 参考项geomspace、mgrid、ogrid
geomspace(几何刻度等间距)、mgrid、ogrid(网格切片对象)在文档code块中列为参考,但在当前仓库的mxnet.numpy源码中未检索到实现,属于尚未落地的 NumPy 对齐项。需要几何序列时可用logspace+ 自定义base组合替代。
五、构建矩阵(Building Matrices)
5.1tril/triu:提取下/上三角
tril(multiarray.py)把k对角线以上的元素置零,返回同形状、同 dtype 的副本;triu(multiarray.py)做相反操作:
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) np.tril(a, -1) # array([[ 0., 0., 0.], # [ 4., 0., 0.], # [ 7., 8., 0.], # [10., 11., 12.]])k = 0(默认)为主对角线,k < 0向下偏移,k > 0向上偏移。两者常配合用于注意力掩码、三角矩阵求逆等场景。
5.2tri:构造下三角 0/1 矩阵
tri(multiarray.py)直接生成一个下三角填充 1、其余为 0 的数组,规则为T[i,j] == 1当且仅当i <= j + k:
np.tri(3, 5, 2, dtype=int) # array([[1, 1, 1, 0, 0], # [1, 1, 1, 1, 0], # [1, 1, 1, 1, 1]]) np.tri(3, 5, -1) # k=-1,对角线以下才为 15.3diag/diagflat:对角提取与对角构造
diag(multiarray.py)是“双向”函数:输入 1-D 数组时构造以之为对角线的 2-D 矩阵;输入 2-D 数组时提取第k条对角线:
x = np.arange(9).reshape((3, 3)) np.diag(x) # array([0, 4, 8]) —— 提取主对角线 np.diag(x, k=1) # array([1, 5]) np.diag(x, k=-1) # array([3, 7]) np.diag(np.diag(x)) # 把提取的对角线还原成对角矩阵diagflat(multiarray.py)先展平输入,再以其为第k条对角线构造 2-D 矩阵,适合快速生成对角权重矩阵。
5.4 参考项vander
vander(范德蒙德矩阵)在文档code块中列为参考,当前仓库的mxnet.numpy中未检索到实现,属于待对齐项。
六、记录数组与字符数组(np.rec/np.char)
文档专门用两个小节说明结构化数据的创建入口:
- 记录数组:
np.rec是np.core.records的首选别名(np.core.records仍可用),相关创建例程包括core.records.array、core.records.fromarrays、core.records.fromrecords、core.records.fromstring、core.records.fromfile,用于构造带字段名的结构化/记录数组; - 字符数组:
np.char是np.core.defchararray的首选别名,创建例程包括core.defchararray.array、core.defchararray.asarray,用于字符串数组的批量操作。
这两组接口沿用 NumPy 的模块层级命名,在mxnet.numpy中对应子模块(mxnet.numpy.rec、mxnet.numpy.char)内可用。
七、与官方 NumPy 的关键差异速查
结合文档与源码(multiarray.py 各函数 docstring 中的 "differs from the original numpy" 说明),汇总如下:
| 差异点 | 官方 NumPy | MXNetmxnet.numpy |
|---|---|---|
| 默认浮点 dtype | float64 | float32(npx.set_np(dtype=True)后为float64) |
arange默认 dtype | int64 | float32(set_np后为int64) |
device参数 | 无 | 几乎所有创建函数均支持,如device=mx.gpu(0) |
order参数 | 'C'/'F'/'A'/'K' | 仅支持'C',其余抛NotImplementedError |
out参数 | 部分函数支持 | full/full_like等已支持 |
| 输入类型 | 任意array_like | mx.nd.NDArray需先经as_np_ndarray零拷贝转换 |
八、实战组合示例
import mxnet.numpy as np import mxnet.numpy as npx import mxnet as mx # 1) 在 GPU 上直接创建 3×4 全一矩阵用于权重初始化 w = np.ones((3, 4), device=mx.gpu(0)) # 2) 注意力掩码:下三角为 1 mask = np.tril(np.ones((5, 5))) # 3) 学习率序列:对数刻度采样 lrs = np.logspace(-3, -1, num=5) # 4) 坐标网格(可视化 / 采样) x = np.arange(4); y = np.arange(3) X, Y = np.meshgrid(x, y, indexing='xy') # 5) 拷贝隔离 params = np.array([1.0, 2.0, 3.0]) safe = np.copy(params)九、继续深入阅读
- API 文档总览:docs/python_docs/python/api/np/routines.rst(数组创建、操作、数学、统计、线性代数等例程导航)
- 核心实现:python/mxnet/numpy/multiarray.py(
eye见 L6204、linspace见 L6249、arange见 L6976) meshgrid实现:python/mxnet/numpy/function_base.pymxnet.numpy模块入口:python/mxnet/numpy/init.py- 旧式 NDArray 与 NumPy 风格数组的转换约定:可参考 python/mxnet/numpy/_op.py 及
as_np_ndarray相关文档
掌握这五类数组创建例程,即可在 MXNet 中以 NumPy 心智模型完成从标量到批量张量的全部构造需求,为后续的广播运算、自动微分与模型构建打下基础。
【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址: https://gitcode.com/gh_mirrors/mxne/mxnet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考