原理与实战解析)
人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载延后初始化是深度学习框架中一项看不见但离不开的底层机制它允许开发者先定义网络架构、暂不指定输入维度直到第一批数据真正流过模型时才自动推断并完成所有参数形状的确定与初始化。本文基于《动手学深度学习》d2l-zh深度学习计算章节中的《延后初始化》一节展开结合本仓库 d2l 工具库中训练循环的真实调用从框架如何推迟初始化、如何验证与触发初始化到在 CNN/RNN 等场景中的工程价值逐层拆解读完即可掌握在多层感知机、卷积网络与循环网络中使用延后初始化写出更灵活模型代码的方法。为什么需要延后初始化回顾此前章节的建模过程你会发现我们其实做了几件看起来不该成立的事情定义了网络架构却没有指定输入维度添加层时没有显式指定前一层的输出维度甚至在信息不足以确定模型参数总数时就已经调用了参数初始化。直觉上这些代码应该报错——因为框架无法预知网络的输入维度。但代码偏偏能跑通秘密就在于框架采用了延后初始化defers initialization策略它把真正分配参数内存的动作推迟到第一次向模型传递数据时届时再根据实际数据形状动态推断每一层的大小。这一机制在后续章节会变得尤其重要使用卷积神经网络时输入维度即图像分辨率会逐层影响后续各层的维度。如果编写代码时无需提前知道维度就能设置参数那么定义和修改模型的任务都会被大大简化。要理解这一点需要先深入初始化机制的内部工作方式。实例化一个尚未初始化的网络首先实例化一个两层多层感知机。在 MXNet 中我们用nn.Sequential依次添加两个全连接层隐藏层 256 个单元、ReLU 激活输出层 10 个单元from mxnet import init, np, npx from mxnet.gluon import nn npx.set_np() def get_net(): net nn.Sequential() net.add(nn.Dense(256, activationrelu)) net.add(nn.Dense(10)) return net net get_net()在 TensorFlowKeras中对应的写法是#tab tensorflow import tensorflow as tf net tf.keras.models.Sequential([ tf.keras.layers.Dense(256, activationtf.nn.relu), tf.keras.layers.Dense(10), ])此刻输入维数未知网络不可能知道输入层权重的形状因此框架尚未初始化任何参数。我们可以通过访问参数来确认这一点print(net.collect_params) print(net.collect_params())#tab tensorflow [net.layers[i].get_weights() for i in range(len(net.layers))]MXNet 视角-1占位与延迟的真实含义在 MXNet 中尽管参数对象已经存在但每一层的输入维度被记录为-1——这是 MXNet 用来表示参数维度仍然未知的特殊值。此时如果强行访问net[0].weight.data()会触发运行时错误提示必须先初始化网络才能访问参数。当我们调用initialize时发生了什么net.initialize() net.collect_params()结果是一切照旧、没有任何改变。这说明在输入维度未知时initialize并不会真正初始化参数它只是在 MXNet 内部登记了我们希望初始化参数这一意图并可选地声明使用哪种分布。真正的分配动作被挂起等待数据到来。TensorFlow 视角权重对象存在但为空TensorFlow 侧的现象对称每一层的层对象都存在但权重张量为空。此时调用net.get_weights()会抛出异常因为权重尚未完成初始化。传递数据触发真正的初始化接下来让第一批数据通过网络迫使框架完成参数初始化X np.random.uniform(size(2, 20)) net(X) net.collect_params()#tab tensorflow X tf.random.uniform((2, 20)) net(X) [w.shape for w in net.get_weights()]一旦输入维度本例为 20已知框架就能把这个值代入识别出第一层权重矩阵的形状256×20。识别出第一层形状后框架继续处理第二层依此类推沿着计算图一路向后直到所有层的形状都确定。需要特别说明的是本例中只有第一层真正需要延后初始化但框架依然采用顺序初始化的方式处理所有层。等到全部参数形状已知框架才真正初始化参数并分配内存。参数对象、值与梯度的关系结合同一章节的参数管理一节可以更完整地理解这一过程在 MXNet 中参数是包含值、梯度与额外信息的复合对象。延后初始化之所以能拖则拖正是因为它需要weight.data()指向一块真实存在的内存在维度未知时参数对象虽有名称和结构例如dense0_weight、dense0_bias却没有可用的数据缓冲区。参数管理章节中展示的net.collect_params()[dense1_bias].data()、net[0].weight.grad()等访问方式都要求初始化已经完成才能拿到有效数据。从源码看延后初始化在真实训练循环中的位置延后初始化不只是理论机制它在本仓库的工具库 d2l/mxnet.py 的训练函数中被反复使用。以卷积网络训练函数train_ch6为例d2l/mxnet.pydef train_ch6(net, train_iter, test_iter, num_epochs, lr, device): 用GPU训练模型(在第六章定义) net.initialize(force_reinitTrue, ctxdevice, initinit.Xavier()) loss gluon.loss.SoftmaxCrossEntropyLoss() ...这里net.initialize(force_reinitTrue, ctxdevice, initinit.Xavier())在数据到达之前被调用init.Xavier()声明了初始化分布Xavier 初始化ctxdevice指定参数将被分配到的设备force_reinitTrue则保证即使参数此前已被初始化过也会强制重新初始化。而train_ch6的调用方如 LeNet 训练传入的net只定义了层结构、并未显式给出输入尺寸所以这正是一次典型的延后初始化声明意图在前实际分配参数要等到训练循环里第一次执行y_hat net(X)d2l/mxnet.py时才完成。同理在循环神经网络训练函数train_ch8d2l/mxnet.py中if isinstance(net, gluon.Block): net.initialize(ctxdevice, force_reinitTrue, initinit.Normal(0.01))RNNModel的forward里先执行X npx.one_hot(inputs.T, self.vocab_size)把形状为(时间步数, 批量大小)的输入转成 one-hot 表示d2l/mxnet.py此时dense层的输入维度时间步数 × 批量大小才第一次成为已知量——这正是延后初始化在动态序列长度场景下的典型应用。从源码结构看可以提炼出延后初始化在工程中的三个关键配合参数参数作用典型取值init声明初始化分布在数据到达后生效init.Xavier()、init.Normal(sigma0.01)、init.Constant(1)ctx声明参数分配到的设备CPU/GPUdevice如mx.gpu(0)force_reinit是否强制覆盖已有初始化结果训练脚本中通常设为True延后初始化为什么越用越方便延后初始化带来的核心便利有三点架构定义与数据维度解耦定义模型时无须关心输入形状代码可以写得更通用。尤其对卷积网络图像分辨率一旦变化后续每一层的维数都会连锁改变延后初始化让这类修改不再需要同步更新层定义。消除一类常见错误手工推算每一层的输入/输出维度极易出错漏算批量维度、忘记展平等把形状推断交给框架在首次前向时自动完成从机制上减少维度不匹配问题。支持动态输入在自然语言处理中句子长度往往可变。只要在首次前向时框架能推断出形状延后初始化就允许同一模型接受不同尺寸的输入。小结延后初始化让框架能够自动推断参数形状从而简化模型架构的定义与修改并消除一类常见的维度错误。在 MXNet 中维度未知时参数被标记为 -1initialize仅登记初始化意图在 TensorFlow 中权重对象存在但内容为空。通过向模型传递数据执行一次前向可以触发框架最终完成参数初始化。实际训练循环如本仓库 d2l/mxnet.py 的train_ch6普遍采用先声明初始化意图、数据到来时再真正初始化的模式init、ctx、force_reinit三个参数共同决定了初始化如何执行。练习如果指定了第一层的输入尺寸但没有指定后续层的尺寸会发生什么是否立即进行初始化如果指定了不匹配的维度会发生什么如果输入具有不同的维度需要做什么提示查看参数管理一节中的参数绑定相关内容在 MXNet 中可通过paramsshared.params让多个层共享同一份参数从而支持变长输入时的权重复用。赞分享人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载相关推荐《动手学深度学习》延后初始化Deferred Initialization深度解析框架如何动态推断网络参数形状《动手学深度学习》延后初始化Deferred Initialization深度解析框架如何动态推断网络参数形状 延后初始化Deferred Initia人工智能深度学习机器学习教程D2L 延迟初始化Lazy Initialization深入解析深度学习框架如何自动推断参数形状D2L 延迟初始化Lazy Initialization深入解析深度学习框架如何自动推断参数形状 延迟初始化Lazy Initialization是《文档教程人工智能深度学习NLP计算机视觉强化学习《动手学深度学习》参数管理实战模型参数的访问、初始化与共享《动手学深度学习》参数管理实战模型参数的访问、初始化与共享 选择好网络架构、设置完超参数之后训练的本质就是不断调整模型参数以最小化损失函数训练结束后我们人工智能深度学习机器学习教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考