SHAOXIAOJ正在加载中...

2713: 2025AHCPC - 反向传播

金币值:10 定数:16 时间限制:1.000 s 内存限制:128 M
解决:0 提交:0 正确率:0.00% 命题人:
点赞量:0 收藏量:0 题目类型:程序 来源/分类: 程序设计大赛

题目描述

         正向传播与反向传播是现代神经网络的基础,   小 $M$ 在机器学习课程中成绩很不好,   想利用这次安徽省机器人大赛的机会实践一下机器学习的基础理论,   从零开始实现一个机器学习框架.   他手动定义了一个神经元间的结构,   定义了损失函数和优化器,   并初始化了参数,   他想让你帮忙模拟神经网络的正向传播与反向传播过程,   将正确的值告诉他.

         由于担心你的机器学习基础比小 $M$ 更不好,   小 $M$ 贴心地为你准备了一些基础概念,   以供参考:

         神经元 $(Neuron):$   神经网络的基本计算单元,模拟生物神经元的工作方式,   负责接收输入,   进行加权计算并产生输出.   接受来自前一层神经元的输入 $x_1,x_2,x_3,...,x_n$ 并与对应的权重 $w_1,w_2,w_3,...,w_n$ 分别相乘后求和,   并与偏置 $b$ 相加.   形式化地,   可以表示为:


$z = \sum_{i = 1}^{n} w_ix_i + b$


         正向传播 $(Forward \ Propagation)$:   神经网络中进行预测的核心过程,   输入数据从输入层进入网络,   依次经过各隐藏层,   每一层的神经元通过加权求和   (输入与权重的线性结合)   并施加激活函数,   将结果传递到下一层,   最终在输出层生成预测值,   对于第 $l$ 层,   形式化地表示为:


$z^{(l)} = \sigma (W ^ {(l)}a ^ {(l - 1)} + b ^ {(l)})$


         反向传播 $(Backward \ Propagation):$   神经网络中基于链式法则计算损失函数对输入的梯度   (偏导数)   的过程,   其核心是通过输出层向输入层逐层回传误差.

         由于小 $M$ 的编程能力很弱,   他设计的神经网络比较简单,   与真实的神经网络有很大差别,   小 $Y$ 将这些特点总结给你:

         小 $M$ 的神经网络中,   对于任意神经元,   偏置 $b$ 皆为 $0$,   且每个神经元恰好有两个输入,   每一层的激活函数皆为 $ReLU$ 函数,   $ReLU$ 函数定义如下:


         $ReLU(x)=\left\{\begin{matrix} x 如果x \ge 0, \\ 0 如果x \lt 0.\end{matrix}\right.$


         特别地,我们将 $ReLU$ 函数在 $x = 0$ 处的导数值作为 $0$ 来处理.


         小 $M$ 的神经网络固定有 $N = 2^p - 1$ 个节点,   结构固定是一个满二叉树.   输出层只有一个节点,   即为根节点,   根节点编号固定为 $1$.   对于编号为 $k$ 的神经元,   与神经元输入端相连的节点编号固定为 $2k$ 和 $2k + 1$.


         在针对某一个目的标签为 $0$ 的任务的训练中,   小 $W$ 将损失函数定义为输出本身,   即反向传播的目的便是计算输入层各分量对最终输出值的偏导数.

         依据计算公式,   我们可以发现,   在这个任务中,   对于一个神经元,   其正向传播过程中,   输出 $z$ 关于输入 $x$ 和 $w$ 的函数为:


         $z = ReLU(x_{inid1} \times W_{inid1} + x_{inid2} \times w_{inid2})$


         小 $M$ 首先会告诉你一个神经网络的结构和权重,   在网络初始化完成后,   小 $M$ 给你一个向量维度和输入端口数相同的输入向量 $v$.

         在网络训练中,   会让你完成三种操作,   它们分别是:

         修改输入:   对于输入向量的某一维度 $v_i$ 进行修改,   你需要给出神经网络新的输出结果 $res$,   结果保留一位小数.

         反向传播:   求损失函数对于输入向量的第 $i$ 维度 $v_i$ 的偏导数,    结果保留一位小数.

         优化:   小 $M$ 的肉眼优化器发挥作用,   对神经网络第 $k$ 个神经元的所有输入对应的权重都乘以一个系数,   将其更新.

         注意:   优化操作是对真实网络数据完成的更改,   对后续查询有后效性.

输入

         第一行输入一个整数 $N$,   代表神经元节点个数.

         接下来 $N$ 行,   每行 $2$ 个实数,   描述每一个节点两个输入的权重,   分别代表从 $2k$ 号节点和 $2k + 1$ 号节点输入的权重.   如果神经元位于输入层,   则权重均为 $0.0$.   该输入向量的某一维度直接作为输入层结点的输出.

         接下来 $\frac {N + 1}{2}$ 个实数,   分别为初始状态下各维度输入.

         接下来输入一个整数 $Q$,   代表操作次数.

         接下来 $Q$ 行,    有如下几种操作

         $1 \ x \ y:$   代表将第 $x$ 个维度的输入的值 $v_x$ 改为 $y$,   其中 $y$ 为实数.

         $2 \ x:$   代表求输出 $z$ 关于第 $x$ 维度输入 $v_x$ 的偏导数 $\frac {\partial z}{\partial v_x}$.

         $3 \ x \ k:$   代表将编号为 $x$ 的神经元所有权重都乘 $k$,   其中 $k$ 为实数,   特别地,   该操作保证不对输入层节点进行操作.

输出

         针对每一次 $1$ 或 $2$ 操作,   输出操作的结果.

样例输入    复制

3
1.0 1.0
0.0 0.0
0.0 0.0
1.0 2.0
4
1 1 3.0
2 1
3 1 -2.0
2 2

样例输出    复制

5.0
1.0
0.0

提示

样例解释


         对于初始情况,   该网络结构和输入情况如下,   初始输出为 $3.0$,   此时对于 $v1$ 为 $1.0$,   $v2$ 为 $2.0$.   此时 $z = 1.0 \times v1 + 1.0 \times v2,$   输出结果为 $3.0,$   输出对于 $v1$ 和 $v2$ 的偏导数均为 $1.0$.



数据规模与约定


         对于 $100\%$ 的数据, $1 \le N \le 10^6, \ 1 \le Q \le 5 \times 10^5, \ \left | w \right | ,\left | k \right | , \left | y \right | , \left | v_i \right | \le 10^3$.