十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

numpy-ml 神经网络层库(layers)深度指南:从全连接到 LSTM 的可组合层实现

numpy-ml 神经网络层库(layers)深度指南:从全连接到 LSTM 的可组合层实现 机器学习人工智能【免费下载链接】numpy-mlMachine learning, in numpy项目地址https://gitcode.com/gh_mirrors/nu/numpy-ml点击查看免费下载numpy_ml/neural_nets/layers/README.md定义的 layers 模块是 numpy-ml 神经网络子库的核心积木它以 NumPy 实现了 19 种常用网络层与逐层操作可自由组合成任意规模的神经网络。本指南以该模块为主体结合 layers.py 源码与 test_nn.py 测试用例逐层讲解其数学原理、构造参数、前向/反向接口并展示它们在 VAE、word2vec、WGAN-GP 等仓库内置模型中的真实用法帮助读者彻底掌握这套零依赖、纯 NumPy的层系统。模块定位与设计哲学numpy_ml/neural_nets/layers/README.md开篇即点明本模块的定位实现常见的层layer与逐层layer-wise操作使其可以被组合composed以构建更大的神经网络。它既不是一个完整的深度学习框架也不是针对某个特定任务的专用实现而是一套教科书式的层积木。在 numpy_ml/neural_nets/README.md 中对整个神经网络子库有更宏观的说明该子库以 Keras 风格构建更大神经网络模型的积木并且刻意不实现通用的自动微分autograd系统以强调概念理解而非灵活性。这意味着每个层必须显式实现forward前向与backward反向两个方法梯度的传播路径对读者完全透明层的组合方式是手写网络拓扑而非声明式的计算图所有数值计算基于纯 NumPy不依赖任何深度学习后端方便单步调试与数学推导。所有层都继承自抽象基类LayerBaselayers.py其构造方法统一接收可选的optimizer参数并通过OptimizerInitializer解析同时维护parameters可学习参数、gradients梯度缓存与derived_variables前向/反向过程中间量三个字典。基类还提供了freeze/unfreeze冻结/解冻参数、flush_gradients清空梯度、update用优化器更新参数、set_params/summary参数读写与序列化等通用能力这些是每个具体层都共享的骨架。层全景19 类层的一览表根据 README 与源码layers.py共 4433 行实现了以下层每个类的定义位置如下表所示层类别类名源码行号核心作用主要论文出处注意力DotProductAttentionL139单头点积注意力Luong et al., 2015Vaswani et al., 2017Transformer生成模型RBML365受限玻尔兹曼机CD-n训练Smolensky, 1986Carreira-Perpiñán Hinton, 2005逐元素操作AddL633输入求和残差连接—逐元素操作MultiplyL745输入逐元素相乘—形状操作FlattenL859展平多维输入—归一化BatchNorm2DL9692D 批归一化Ioffe Szegedy, 2015归一化BatchNorm1DL12181D 批归一化Ioffe Szegedy, 2015归一化LayerNorm2DL14442D 层归一化Ba, Kiros Hinton, 2016归一化LayerNorm1DL16341D 层归一化Ba, Kiros Hinton, 2016嵌入EmbeddingL1811词/离散索引嵌入—全连接FullyConnectedL2010稠密全连接层—分类输出SoftmaxL2192Softmax 归一化—稀疏进化SparseEvolutionL2352SET 稀疏进化层Mocanu et al., 2018卷积Conv1DL26031D 卷积stride/pad/dilationvan den Oord et al., 2016卷积Conv2DL28952D 卷积stride/pad/dilationYu Koltun, 2016池化Pool2DL31812D 最大/平均池化—反卷积Deconv2DL33532D 转置卷积deconvolutionZeiler et al., 2010循环单元RNNCellL3576单步 Elman RNN 单元Elman, 1990循环单元LSTMCellL3782单步 LSTM 单元Hochreiter Schmidhuber, 1997循环层RNNL4088多时间步 RNN 层Elman, 1990循环层LSTML4257多时间步 LSTM 层Hochreiter Schmidhuber, 1997从源码结构看RNN/LSTM是外层封装它们在_init_params中构造内部RNNCell/LSTMCell实例将时间步循环与单步单元解耦而set_params、flush_gradients、update等生命周期方法则委托给内部的cell对象处理参见 layers.py。公共基类 LayerBase所有层的统一契约在深入具体层之前必须先理解LayerBase提供的行为契约因为所有层都复用它来管理参数、梯度与优化器。# 摘自 numpy_ml/neural_nets/layers/layers.py L27-L86节选 class LayerBase(ABC): def __init__(self, optimizerNone): self.X [] # 前向输入缓存供反向使用 self.act_fn None # 激活函数对象 self.trainable True self.optimizer OptimizerInitializer(optimizer)() self.gradients {} self.parameters {} self.derived_variables {} super().__init__() abstractmethod def forward(self, z, **kwargs): ... abstractmethod def backward(self, out, **kwargs): ... def freeze(self): self.trainable False # 冻结参数 def unfreeze(self): self.trainable True # 解冻参数 def update(self, cur_lossNone): assert self.trainable, Layer is frozen self.optimizer.step() for k, v in self.gradients.items(): if k in self.parameters: self.parameters[k] self.optimizer(self.parameters[k], v, k, cur_loss) self.flush_gradients()关键约定如下参数初始化惰性化多数层如FullyConnected、Conv2D、RNN在构造时并不知道输入维度n_in因此is_initialized False直到第一次forward时根据输入X.shape[1]才调用_init_params完成权重分配。这带来一个实用便利搭建网络时无需预先计算上游维度层与层之间自动适配。权重初始化策略所有带权重的层都接受init参数取值限定为glorot_normal、glorot_uniform、he_normal、he_uniform四种默认glorot_uniform由WeightInitializer依据激活函数类型自动挑选合适的初始化方案。优化器注入optimizer参数可以是字符串、优化器对象或None为None时默认使用带默认参数的 SGD 优化器由OptimizerInitializer解析。梯度累计与刷新backward把参数梯度累加到self.gradientsupdate调用优化器按梯度更新self.parameters随后flush_gradients将梯度归零、清空输入缓存为下一个 minibatch 做准备。冻结机制freeze()之后forward/backward/update都会因assert self.trainable而拒绝执行用于迁移学习或固定底层特征。全连接层 FullyConnected一切网络的地基FullyConnected是使用频率最高的层计算Y f(WX b)其中W、b为可学习参数f为激活函数layers.py。FullyConnected(n_out, act_fnNone, initglorot_uniform, optimizerNone)参数说明n_out输出维度必填act_fn输出非线性可为激活函数名字符串、激活对象或NoneNone时退化为线性映射Y WX b默认Noneinit权重初始化策略默认glorot_uniformoptimizer优化策略默认None即默认 SGD。其前向与反向的核心实现如下def _fwd(self, X): W self.parameters[W]; b self.parameters[b] Z X W b Y self.act_fn(Z) return Y, Z def _bwd(self, dLdy, X): W self.parameters[W] dX (dLdy W.T) * self.act_fn.grad(X) # 对输入的梯度继续回传 dW X.T dLdy # 对权重的梯度 db np.sum(dLdy, axis0, keepdimsTrue) # 对偏置的梯度 return dX, dW, db注意backward中的一个小技巧self.act_fn.grad(X)使用的是**层输入X**而非线性输出Z作为激活梯度自变量。这是因为仓库中的激活函数对象如Tanh、ReLU在forward时缓存了自身输入grad直接读取缓存值即可——这是该库由激活对象自管中间量的设计细节。在仓库测试 test_nn.py 中test_FullyConnected将本层与 PyTorch 对应模块对比随机抽取Tanh、Sigmoid、ReLU、Affine四种激活函数、随机维度n_ex × n_in逐一校验前向输出与反向梯度。这也印证了 README 中强调概念理解的定位每一层的数值正确性都经由与主流框架的逐元素对照来保障。实战中FullyConnected被大量用于仓库内置模型VAE 的编码器/解码器vae.py、WGAN-GP 的生成器与判别器wgan_gp.py均由多层FullyConnected堆叠而成。卷积族Conv1D / Conv2D / Pool2D / Deconv2D2D 卷积 Conv2DConv2D对输入体积施加二维卷积核支持stride步长、padding填充、dilation膨胀三个关键超参数这也是 README 特别强调的能力Conv2D(out_ch, kernel_shape, pad0, stride1, dilation0, act_fnNone, optimizerNone, initglorot_uniform)输出尺寸的解析公式在源码注释中给出layers.pyout act_fn(pad(X) * W b) n_rows_out floor(1 (n_rows_in pad_left pad_right - filter_rows) / stride) n_cols_out floor(1 (n_cols_in pad_top pad_bottom - filter_cols) / stride)参数细节out_ch本层滤波器卷积核个数即输出通道数kernel_shape单个 2D 核的尺寸2 元组pad可为int、元组或same默认0不填充same时自动计算填充使输出与输入空间尺寸一致stride卷积核移动步长默认1dilation核元素之间插入的空洞数膨胀后的有效核尺寸为[kernel_rows * (d 1) - d, kernel_cols * (d 1) - d]默认0即普通卷积dilation 0即空洞卷积dilated convolution常用于扩大感受野而不增参数量。底层计算依赖numpy_ml.neural_nets.utils中的im2col/col2im/conv2D/dilate/calc_pad_dims_2D等工具函数在 layers.py 中导入将卷积转化为矩阵乘法从而直接复用 NumPy 的高效矩阵运算。测试 test_nn.py 对随机 pad/stride/dilation 组合与 PyTorchConv2d逐项对比了输出与梯度。1D 卷积 Conv1DConv1D的签名与Conv2D一一对应kernel_width代替kernel_shape面向序列输入是 WaveNet 式因果/膨胀卷积的基础组件layers.py。numpy_ml.neural_nets.modules中的 WaveNet 风格残差块即建立在带空洞的Conv1D之上。2D 池化 Pool2DPool2D(kernel_shape, stride1, pad0, modemax, optimizerNone)mode取值max或average默认max对应最大池化与平均池化其余参数kernel_shape、stride、pad与卷积保持一致且同样支持padsame。2D 反卷积 Deconv2DDeconv2D(out_ch, kernel_shape, pad0, stride1, act_fnNone, optimizerNone, initglorot_uniform)源码注释明确提醒此处的 deconvolution 并非数学意义上的反卷积更准确的叫法是转置卷积/梯度卷积layers.py用于上采样特征图如生成模型的解码器。它与Conv2D的差异仅在于不支持 dilation底层使用deconv2D_naive朴素实现以保持数值可读性。注意力与稀疏进化面向 Transformer 与 SET 的先进层点积注意力 DotProductAttentionDotProductAttention是一个独立的注意力头层采用点积作为打分函数layers.pyZ K Q^T scaleFalse 时 Z K Q^T / sqrt(d_k)scaleTrue 时 Y dropout(softmax(Z)) V构造参数scale是否在 softmax 前将点积除以sqrt(d_k)键/查询向量维度默认True。源码注释解释了必要性当查询/键维度增大时点积的量级会随之变大使 softmax 落入饱和区缩放后梯度更稳定——这正是 Transformer 论文中的标准做法dropout_psoftmax 输出上的 dropout 概率取值[0, 1)默认0表示不施加_init_params中通过Dropout(Softmax(), self.dropout_p)组合包装实现init、optimizer源码标注为 Unused保留以维持接口一致性因为该层不含可学习参数parameters与gradients均为空字典。forward(Q, K, V)支持在Q/K/V中携带中间维度如并行注意力头数形状为(n_ex, *, d_k)/(n_ex, *, d_v)backward(dLdy)返回对Q、K、V三个输入的梯度。numpy_ml.neural_nets.modules中的 Transformer 风格多头注意力即在此层基础上叠加多头投影实现。稀疏进化层 SparseEvolutionSparseEvolution实现 Mocanu et al. (2018) 的**稀疏进化训练SET**算法以一个 Erdos-Renyi 随机稀疏掩码约束全连接层并在训练中进化式地重连权重layers.pyY f( (W ⊙ W_mask) X b )关键参数zeta每次更新后正、负权重中最接近 0 的那一部分比例被剪除并随机重连默认0.3epsilon层稀疏度参数默认20。初始化时按p epsilon * (n_in n_out) / (n_in * n_out)的概率对每个权重做伯努利采样生成二元掩码W_masklayers.py网络规模越大稀疏度越高从而在保持容量的同时显著减少有效参数。归一化家族BatchNorm 与 LayerNorm2D/1D 批归一化BatchNorm2D面向带通道维的 2D 输入BatchNorm1D面向 1D 输入两者签名一致BatchNorm2D(momentum0.9, epsilon1e-5, optimizerNone) BatchNorm1D(momentum0.9, epsilon1e-5, optimizerNone)momentumrunning mean / running std 的动量系数默认0.9。源码注释说明越接近 1当前 batch 的均值/方差权重越低平滑越强epsilon归一化分母中的平滑常数防止除零默认1e-5。训练与测试阶段使用两套公式layers.py训练Y scaler * norm(X) interceptnorm(X) (X - mean(X)) / sqrt(var(X) epsilon) 测试Y scaler * running_norm(X) interceptrunning_norm(X) (X - running_mean) / sqrt(running_var epsilon)源码文档还特别对比了 BatchNorm 与 LayerNorm 的差异BatchNorm 沿 batch 维统计均值/方差因此对小 batch 敏感且难以直接应用于 RNN每个时间步需独立的 BatchNorm这是选择归一化层时的重要工程考量。2D/1D 层归一化LayerNorm2D(epsilon1e-5, optimizerNone) LayerNorm1D(epsilon1e-5, optimizerNone)LayerNorm 沿输出特征维而非 batch 维做归一化摆脱了对 batch size 的依赖是 Transformer 与 RNN 场景下的首选与 [Ba, Kiros Hinton, 2016] 论文一致。嵌入与 Softmax词向量与分类输出的两端嵌入层 EmbeddingEmbedding通过查表Y W[x]将离散索引映射为稠密向量layers.pyEmbedding(n_out, vocab_size, poolNone, initglorot_uniform, optimizerNone)n_out嵌入向量的维度vocab_size词表大小合法索引范围为0到vocab_size - 1poolsum、mean或None默认对每条样本内的多个索引编码做池化得到单一嵌入向量。源码中的两个重要约束构造时校验pool只能取sum、mean、None三者之一layers.py文档明确要求该层必须作为网络的第一个层因为梯度不会回传到其输入。实际应用可见 w2v.pyword2vec 模型的 skip-gram 模式使用poolNone每个上下文词独立取嵌入CBOW 模式使用poolmean上下文词取平均后预测中心词与论文设定完全吻合。Softmax 层Softmax将任意实数向量归一化为概率分布支持通过dim指定归一化轴默认最后一维通常作为分类网络的输出层测试 test_nn.py 中将其与 PyTorchnn.Softmax对照验证。形状与逐元素操作Add / Multiply / Flatten这三个无参层是搭建残差网络、门控机制与维度转换的胶水AddL633返回多个输入的逐元素和可接可选非线性是实现残差连接F(x) x的直接工具MultiplyL745逐元素相乘用于门控、注意力加权等场景FlattenL859将多维输入展平是卷积骨干到全连接头部之间的标准过渡层。keep_dim参数默认first决定保留哪个维度不展平。VAE 模型即使用Flatten衔接卷积编码器与全连接层vae.py。循环神经网络RNNCell / LSTMCell / RNN / LSTM单步单元RNNCell(n_out, act_fnTanh, initglorot_uniform, optimizerNone)Elman 式简单循环单元默认 tanh 激活layers.pyLSTMCell(n_out, initglorot_uniform, optimizerNone)含输入门、遗忘门、输出门与记忆细胞的 LSTM 单元layers.py。多时间步封装RNN(n_out, act_fnTanh, initglorot_uniform, optimizerNone) LSTM(n_out, initglorot_uniform, optimizerNone)RNN/LSTM在_init_params中实例化对应 Cell 并在多个时间步上循环展开。n_out是单时间步隐藏状态/输出的维度。它们与BidirectionalLSTM见 modules.py配合可构建双向循环网络test_nn.py 的test_BidirectionalLSTM将仓库实现与 PyTorch 双向 LSTM 的参数和输出逐项比对。快速上手如何用这些层搭建一个网络将各层组合成网络的通用模式如下与 VAE、WGAN-GP 等内置模型的结构一致from numpy_ml.neural_nets.layers import ( FullyConnected, Flatten, Conv2D, Embedding, Softmax, ) from numpy_ml.neural_nets.activations import Tanh from numpy_ml.neural_nets.optimizers import Adam # 1. 实例化层设置输出维与激活函数 fc1 FullyConnected(n_out64, act_fnTanh) fc2 FullyConnected(n_out10, act_fnNone) # 输出层线性 sm Softmax() # 2. 自定义 forward / backward 链式调用库不提供自动微分 def forward(x): h fc1.forward(x) # (n_ex, 64) z fc2.forward(h) # (n_ex, 10) return sm.forward(z) def backward(dLdy): dz sm.backward(dLdy) # 梯度逐层回传 dh fc2.backward(dz) fc1.backward(dh) # 3. 每完成一个 minibatch 后统一更新参数 fc1.update(); fc2.update() # 内部使用各自优化器完成参数更新并清空梯度要点回顾每层forward需传retain_derivedTrue默认以缓存中间量供反向使用backward返回对输入的梯度须按前向相反顺序传递update()依赖构造时注入的优化器默认 SGD可传Adam、RMSProp等字符串或优化器对象可通过freeze()/unfreeze()控制哪些层参与训练。结语一套可读性优先的层实现回顾 numpy_ml/neural_nets/layers/README.md 的核心承诺这 19 类层覆盖了现代深度学习的主干——从最朴素的全连接、卷积/池化/反卷积到注意力、稀疏进化、批/层归一化再到 RNN 与 LSTM 家族。与生产级框架不同本模块刻意放弃自动微分以换取每一行前向/反向代码的可读性与可推导性而 test_nn.py 中与 PyTorch 的逐元素对照测试又保证了这套教学实现的数值正确性。对于想要深入理解神经网络底层原理的读者建议的进阶路径是先用FullyConnectedSoftmax搭一个分类器跑通流程再对照 vae.py、w2v.py、wgan_gp.py 三个内置模型观察卷积、展平、嵌入、全连接如何协同最后回到layers.py逐行推演Conv2D的 im2col 实现与LSTM的时间步展开即可完整掌握从积木到模型的组装艺术。赞分享机器学习人工智能【免费下载链接】numpy-mlMachine learning, in numpy项目地址https://gitcode.com/gh_mirrors/nu/numpy-ml点击查看免费下载相关推荐5步掌握ZMK分体键盘无线化改造从零构建个性化输入系统5步掌握ZMK分体键盘无线化改造从零构建个性化输入系统 ZMK是一款基于Zephyr RTOS的开源键盘固件专为分体键盘和可定制化键盘设计。它允许开发者通过固件嵌入式智能硬件蓝牙OpenR社区贡献指南如何参与开源项目开发并做出有意义的贡献OpenR社区贡献指南如何参与开源项目开发并做出有意义的贡献 OpenR作为一个开源的大型语言模型高级推理框架Open Source Framework fMLX Layers 完全指南mlx.nn 的 69 个神经网络层组件详解MLX Layers 完全指南mlx.nn 的 69 个神经网络层组件详解 本文面向 MLX 框架使用者系统梳理 mlx.nn 模块提供的全部神经网络层组件人工智能机器学习深度学习本地部署上一篇为什么选择sass-resources-loader10个提升前端开发效率的核心优势下一篇KnowStreaming终极路线图2025年云原生Kafka平台的完整发展规划创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表