From cfc666641aa289a42267565e3247894ead8b3def Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Tue, 29 Apr 2025 18:12:50 +0800 Subject: [PATCH] =?UTF-8?q?Commit=20on=202025/04/29=20=E5=91=A8=E4=BA=8C?= =?UTF-8?q?=2018:12:50.83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 科研/zy.md | 6 + 科研/卡尔曼滤波.md | 8 ++ 科研/图神经网络.md | 248 +++++++++++++++++++++++++++--------------- 科研/草稿.md | 158 +++++++++++---------------- 科研/陈茂森论文.md | 8 +- 科研/颜佳佳论文.md | 85 +++++++++++++++ 自学/Java笔记本.md | 33 +++++- 自学/力扣Hot 100题.md | 42 +++++++ 自学/草稿.md | 105 +++++++++--------- 9 files changed, 459 insertions(+), 234 deletions(-) diff --git a/科研/zy.md b/科研/zy.md index 23b0b97..8b6e637 100644 --- a/科研/zy.md +++ b/科研/zy.md @@ -1,3 +1,9 @@ 如何确定kmeans的簇数?节点之间的流量,空间转为时间的图。 压缩感知 函数拟合 采样定理 傅里叶变换 + + + + + +gat有没有问题 比如初始训练好的w和a 后面新加入节点 这个w和a不变会不会导致问题? 我现在能实时重构出邻接矩阵a和特征矩阵 是否有帮助? 是否也能替换与邻居节点的通信 因为卡尔曼能重构,知道邻居节点的特征? diff --git a/科研/卡尔曼滤波.md b/科研/卡尔曼滤波.md index ff965ac..b039f1a 100644 --- a/科研/卡尔曼滤波.md +++ b/科研/卡尔曼滤波.md @@ -302,6 +302,14 @@ $$ | $ W^{(c)} $ | 协方差权重 | $ 1 \times (2n+1) $ | | $ \alpha, \beta, \kappa $ | UKF调参参数(控制Sigma点分布) | 标量 | +建模: + +$$x_k = f(x_{k-1}) + w_k$$ + +$$y_k = h\left(x_k\right) + v_k$$ + + + **Step 1: 生成Sigma点(确定性采样)** **目的**:根据当前状态均值和协方差,生成一组代表状态分布的采样点。 diff --git a/科研/图神经网络.md b/科研/图神经网络.md index b41c5a4..4f0fe9f 100644 --- a/科研/图神经网络.md +++ b/科研/图神经网络.md @@ -276,109 +276,117 @@ $$ 4. **聚合**:最后利用注意力系数加权邻居节点的特征向量,并经过激活函数得到新的节点表示 $\mathbf{h}_i'$。 5. **多头注意力**:为增强表示能力,可并行地执行多个独立的注意力头(multi-head attention),再将它们的结果进行拼接(或在最后一层进行平均),从而得到最终的节点表示。 -### 注意力系数 -1. **注意力系数(未归一化)** -$$ -e_{ij} = a\bigl(W\mathbf{h}_i,\; W\mathbf{h}_j\bigr) -$$ +**输入:** -2. **注意力系数的 softmax 归一化** +1. **节点特征矩阵(Node Features)** -$$ -\alpha_{ij} = \text{softmax}_j\bigl(e_{ij}\bigr) -= \frac{\exp\bigl(e_{ij}\bigr)}{\sum_{k \in \mathcal{N}_i} \exp\bigl(e_{ik}\bigr)} -$$ + - 形状:`[num_nodes, num_features]` + - 每个节点的初始特征向量,例如社交网络中用户的属性或分子图中原子的特征。 -3. **具体的注意力计算形式(以单层前馈网络 + LeakyReLU 为例)** +2. **图的边结构(Edge Index)** -$$ -\alpha_{ij} -= \frac{\exp\Bigl(\text{LeakyReLU}\bigl(\mathbf{a}^\top \bigl[\;W\mathbf{h}_i \,\|\, W\mathbf{h}_j\bigr]\bigr)\Bigr)} -{\sum_{k\in \mathcal{N}_i} \exp\Bigl(\text{LeakyReLU}\bigl(\mathbf{a}^\top \bigl[\;W\mathbf{h}_i \,\|\, W\mathbf{h}_k\bigr]\bigr)\Bigr)} -$$ + - 形状:**`[2, num_edges]`(稀疏邻接表格式)**或稠密邻接矩阵 `[num_nodes, num_nodes]`(最好是将邻接矩阵转为邻接表) - - 其中,$\mathbf{a}$ 为可学习的参数向量,$\|$ 表示向量拼接(concatenation)。 + - 定义图中节点的连接关系(有向/无向边)。 -**示例假设:** + -- **节点特征**: - 假设每个节点的特征向量维度为 $F=2$。 +3. **预训练的GAT模型参数** + + - 包括注意力层的权重矩阵、注意力机制参数等(通过`model.load_state_dict()`加载) + + + +### 线性变换(特征投影) + +- **目的**:将原始特征映射到更高维/更有表达力的空间。 + +- **操作**:对每个节点的特征向量 $\mathbf{h}_i$ 左乘可学习权重矩阵 $W$(维度为 $d' \times d$,$d$ 是输入特征维度,$d'$ 是输出维度): $$ - \mathbf{h}_i = \begin{bmatrix}1 \\ 0\end{bmatrix},\quad - \mathbf{h}_j = \begin{bmatrix}0 \\ 1\end{bmatrix},\quad - \mathbf{h}_k = \begin{bmatrix}1 \\ 1\end{bmatrix}. - $$ - -- **线性变换矩阵 $W$**: - 为了简化,我们令 $W$ 为单位矩阵(即 $W\mathbf{h} = \mathbf{h}$)。 - $$ - W = \begin{bmatrix}1 & 0 \\ 0 & 1\end{bmatrix}. + \mathbf{z}_i = W \mathbf{h}_i, \quad \mathbf{z}_j = W \mathbf{h}_j $$ -- **可学习向量 $\mathbf{a}$**: - 假设 $\mathbf{a}$ 为 4 维向量,设 +### 自注意力系数计算(关键步骤) + +- **目标**:计算节点 $i$ 和邻居 $j$ 之间的未归一化注意力得分 $e_{ij}$。 + +- **实现方式**: + + - **步骤1**:将两个节点的投影特征 $\mathbf{z}_i$ 和 $\mathbf{z}_j$ **拼接**($\|$),得到一个联合表示。 + + - **步骤2**:通过一个可学习的参数向量 $\mathbf{a}$(维度 $2d'$)和激活函数(如LeakyReLU)计算得分: + $$ + e_{ij} = \text{LeakyReLU}\Bigl(\mathbf{a}^\top [\mathbf{z}_i \| \mathbf{z}_j]\Bigr) + $$ + + - **直观理解**:$\mathbf{a}$ 像一个"问题",询问两个节点的联合特征有多匹配。 + - **公式拆分**: + 1. 拼接:$[\mathbf{z}_i \| \mathbf{z}_j]$(长度 $2d'$) + 2. 点积:$\mathbf{a}^\top [\mathbf{z}_i \| \mathbf{z}_j]$(标量) + 3. 非线性激活:LeakyReLU(引入稀疏性,避免负值被完全抑制) + +### 归一化注意力权重 + +- **目的**:让注意力系数在邻居间具有可比性(总和为1)。 + +- **方法**:对 $e_{ij}$ 应用 softmax,仅对节点 $i$ 的邻居 $\mathcal{N}_i$ 归一化: $$ - \mathbf{a} = \begin{bmatrix}1 \\ 1 \\ 1 \\ 1\end{bmatrix}. + \alpha_{ij} = \text{softmax}_j(e_{ij}) = \frac{\exp(e_{ij})}{\sum_{k \in \mathcal{N}_i} \exp(e_{ik})} $$ -- 激活函数使用 LeakyReLU(负数斜率设为0.2,但本例中结果为正数,所以不变)。 + - **关键点**:分母只包含节点 $i$ 的直接邻居(包括自己,如果图含自环)。 ---- -**计算步骤:** -1. **计算 $W\mathbf{h}_i$、$W\mathbf{h}_j$ 和 $W\mathbf{h}_k$:** +### 注意力系数计算示例(带数值模拟) + +假设: + +- 输入特征 $\mathbf{h}_i = [1.0, 2.0]$, $\mathbf{h}_j = [0.5, 1.5]$(维度 $d=2$) +- 权重矩阵 $W = \begin{bmatrix}0.1 & 0.2 \\ 0.3 & 0.4\end{bmatrix}$($d'=2$) +- 参数向量 $\mathbf{a} = [0.5, -0.1, 0.3, 0.2]$(长度 $2d'=4$) + +**计算步骤**: + +1. **线性变换**: $$ - W\mathbf{h}_i = \begin{bmatrix}1 \\ 0\end{bmatrix},\quad - W\mathbf{h}_j = \begin{bmatrix}0 \\ 1\end{bmatrix}, \quad - W\mathbf{h}_k = \begin{bmatrix}1 \\ 1\end{bmatrix} + \mathbf{z}_i = W \mathbf{h}_i = [0.1 \times 1.0 + 0.2 \times 2.0,\ 0.3 \times 1.0 + 0.4 \times 2.0] = [0.5, 1.1] + $$ + + $$ + \mathbf{z}_j = W \mathbf{h}_j = [0.1 \times 0.5 + 0.2 \times 1.5,\ 0.3 \times 0.5 + 0.4 \times 1.5] = [0.35, 0.75] + $$ + +2. **拼接特征**: + $$ + [\mathbf{z}_i \| \mathbf{z}_j] = [0.5, 1.1, 0.35, 0.75]\\ + [\mathbf{z}_i \| \mathbf{z}_i] = [0.5, 1.1, 0.5, 1.1] + $$ + +3. **计算未归一化得分**: + $$ + e_{ij} = \text{LeakyReLU}(0.5 \times 0.5 + (-0.1) \times 1.1 + 0.3 \times 0.35 + 0.2 \times 0.75) = \text{LeakyReLU}(0.25 - 0.11 + 0.105 + 0.15) = \text{LeakyReLU}(0.395) = 0.395 + $$ + + $$ + e_{ii} = \text{LeakyReLU}(0.5 \times 0.5 + (-0.1) \times 1.1 + 0.3 \times 0.5 + 0.2 \times 1.1)=0.51 + $$ + + (假设LeakyReLU斜率为0.2,正输入不变) + +4. **归一化**(假设邻居只有 $j$ 和自身 $i$): + $$ + \alpha_{ij} = \frac{\exp(0.395)}{\exp(0.395) + \exp(0.51)}\approx 0.529 $$ -2. **构造拼接向量并计算未归一化的注意力系数 $e_{ij}$ 和 $e_{ik}$:** - - - 对于邻居 $j$: - $$ - \bigl[W\mathbf{h}_i \,\|\, W\mathbf{h}_j\bigr] = - \begin{bmatrix}1 \\ 0 \\ 0 \\ 1\end{bmatrix}. - $$ - - 内积计算: - $$ - \mathbf{a}^\top \begin{bmatrix}1 \\ 0 \\ 0 \\ 1\end{bmatrix} = 1+0+0+1 = 2. - $$ - - 经过 LeakyReLU(正数保持不变): - $$ - e_{ij} = 2. - $$ - - - 对于邻居 $k$,同理得到: - - $$ - e_{ik} = 3. - $$ - -3. **计算 softmax 得到归一化注意力系数 $\alpha_{ij}$:** - $$ - \alpha_{ij} = \frac{\exp(2)}{\exp(2)+\exp(3)} = \frac{e^2}{e^2+e^3}\approx 0.269. - $$ - - - - 同理: - $$ - \alpha_{ik} = \frac{\exp(3)}{\exp(2)+\exp(3)} \approx 0.731. - $$ - - ### 特征聚合 **单头注意力聚合(得到新的节点特征)** $$ -\mathbf{h}_i' = \sigma\Bigl(\sum_{j \in \mathcal{N}_i} \alpha_{ij} \,W \mathbf{h}_j\Bigr) +\mathbf{h}_i' = \sigma\Bigl(\sum_{j \in \mathcal{N}_i} \alpha_{ij} \,W \mathbf{h}_j\Bigr)=\sigma\left(\sum_{j \in \mathcal{N}_i} \alpha_{ij} \mathbf{z}_j\right) $$ 对$i$ 的邻居节点加权求和,再经过非线性激活函数得到新的特征表示 @@ -388,9 +396,9 @@ $$ 如果有 $K$ 个独立的注意力头,每个头输出 $\mathbf{h}_i'^{(k)}$,则拼接后的输出为: $$ -\mathbf{h}_i' = -\big\Vert_{k=1}^K -\sigma\Bigl(\sum_{j \in \mathcal{N}_i} \alpha_{ij}^{(k)} \, W^{(k)} \mathbf{h}_j\Bigr) +\begin{align*} +\mathbf{h}_i' = \Bigg\Vert_{\substack{k=1 \\ ~}}^{K} \mathbf{h}_i^{(k)} +\end{align*} $$ 其中,$\big\Vert$ 表示向量拼接操作,$\alpha_{ij}^{(k)}$、$W^{(k)}$ 分别为第 $k$ 个注意力头对应的注意力系数和线性变换。 @@ -407,19 +415,80 @@ $$ = \begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix} \,\Vert\, \begin{bmatrix} 0.6 \\ 1.4 \end{bmatrix} = \begin{bmatrix} 0.6 \\ 0.4 \\ 0.6 \\ 1.4 \end{bmatrix}. $$ +意义:不同注意力头可以学习到节点之间不同类型的依赖关系。例如: + +- 一个头可能关注**局部邻居**(如一阶邻居的拓扑结构), +- 另一个头可能关注**全局特征相似性**(如节点特征的余弦相似性)。 + + + **多头注意力(输出层时平均)** 在最终的输出层(例如分类层)通常会将多个头的结果做平均,而不是拼接: $$ -\mathbf{h}_i' = -\sigma\Bigl( -\frac{1}{K} \sum_{k=1}^K \sum_{j \in \mathcal{N}_i} -\alpha_{ij}^{(k)} \, W^{(k)} \mathbf{h}_j -\Bigr) +\begin{align*} +\mathbf{h}_i' = \sigma\left(\frac{1}{K}\sum_{k=1}^K \mathbf{h}_i^{(k)}\right) +\end{align*} $$ +#### **多头注意力比喻:盲人摸象 + 团队合作** + +**场景**: +- **大象** = 图中的目标节点及其邻居(待分析的复杂结构) +- **盲人** = 多个注意力头(每个头独立"观察") +- **团队指挥** = 损失函数(指导所有盲人协作) + +**1. 初始摸象(前向传播)** + +- **盲人A(头1)**: + - 摸到**腿**(关注局部结构邻居),心想:"柱子!这动物像房子。"(生成表示 $\mathbf{h}_i^{(1)}$) + - **初始偏好**:腿的粗细、纹理(权重 $W^{(1)}$ 和 $\mathbf{a}^{(1)}$ 的初始化倾向) + +- **盲人B(头2)**: + - 摸到**鼻子**(关注特征相似的邻居),心想:"软管!这动物能喷水。"(生成表示 $\mathbf{h}_i^{(2)}$) + - **初始偏好**:鼻子的长度、灵活性(权重 $W^{(2)}$ 和 $\mathbf{a}^{(2)}$ 不同) + +- **盲人C(头3)**: + - 摸到**尾巴**(关注远距离邻居),心想:"绳子!这动物有附件。"(生成表示 $\mathbf{h}_i^{(3)}$) + +**2. 团队汇报(多头聚合)** + +- **综合报告**: + - 将三人的描述拼接:"柱子+软管+绳子"($\mathbf{h}_i' = \text{concat}(\mathbf{h}_i^{(1)}, \mathbf{h}_i^{(2)}, \mathbf{h}_i^{(3)})$) + - 指挥者(分类器)猜测:"这可能是大象。"(预测结果 $\hat{y}_i$) + +**3. 指挥者反馈(损失函数)** + +- **真实答案**:是大象(标签 $y_i$) +- **损失计算**: + - 当前综合报告遗漏了"大耳朵"(交叉熵损失 $\mathcal{L}$ 较高) + - 指挥者说:"接近答案,但还缺关键特征!"(反向传播梯度) + +**4. 盲人调整(梯度更新)** + +- **盲人A(头1)**: + - **听到反馈**:"需要更多特征,但你的柱子描述还行。" + - **调整**:更精确测量腿的**直径和硬度**(更新 $W^{(1)}$),而非改摸鼻子 + - **结果**:下次报告"粗柱子上有横向褶皱"(更接近象腿的真实特征) + +- **盲人B(头2)**: + - **听到反馈**:"软管描述不够独特。" + - **调整**:更仔细感受鼻子的**褶皱和肌肉运动**(更新 $W^{(2)}$) + - **结果**:下次报告"可弯曲的软管,表面有环形纹路" + +- **盲人C(头3)**: + - **听到反馈**:"绳子太模糊。" + - **调整**:注意尾巴的**末端毛发**(更新 $W^{(3)}$) + - **结果**:下次报告"短绳末端有硬毛刷" + +**5. 最终协作** + +- **新一轮综合报告**:"褶皱粗柱 + 环形软管 + 带毛刷短绳" → 指挥者确认:"是大象!"(损失 $\mathcal{L}$ 降低) + + + ## 直推式学习与归纳式学习 **直推式学习(Transductive Learning)** @@ -447,6 +516,15 @@ $$ +| 特性 | 直推式(Transductive) | 归纳式(Inductive) | +| ---------------- | ---------------------- | ------------------------------- | +| 训练时是否读全图 | 是 | 否(局部采样) | +| 参数 W 依赖 | 固定图的全局结构 | 只依赖“中心节点 + 邻居”局部结构 | +| 推理时能否换图 | 不能 | 能(只要给出邻居列表和特征) | +| 典型算法 | Kipf&Welling GCN | GraphSAGE, GAT, SGC (简化版) 等 | + + + ## GNN的优点: **参数共享** diff --git a/科研/草稿.md b/科研/草稿.md index 7584c01..7a270ab 100644 --- a/科研/草稿.md +++ b/科研/草稿.md @@ -1,108 +1,78 @@ -### 严格推导过程(修正用户对白噪声的理解) +### **LSTM+GAT训练过程说明(RWP网络节点移动预测)** -您提出的疑问非常关键。让我们重新梳理这个推导过程,特别注意白噪声项的处理。 +#### **1. 数据构造** +**输入数据**: +- **节点轨迹数据**: + - 每个节点在1000个时间单位内的二维坐标 $(x, y)$,形状为 $[N, 1000, 2]$($N$个节点,1000个时间步,2维特征)。 +- **动态邻接矩阵序列**: + - 每个时间步的节点连接关系(基于距离阈值或其他规则生成),得到1000个邻接矩阵 $[A_1, A_2, \dots, A_{1000}]$,每个 $A_t$ 的形状为 $[2, \text{num\_edges}_t]$(稀疏表示)。 + +**滑动窗口处理**: +- **窗口大小**:12(用前12个时间步预测第13个时间步)。 +- **滑动步长**:1(每次滑动1个时间步,生成更多训练样本)。 +- **生成样本数量**: + - 总时间步1000,窗口大小12 → 可生成 $1000 - 12 = 988$ 个样本。 + +**样本格式**: +- **输入序列** $X^{(i)}$:形状 $[N, 12, 2]$($N$个节点,12个时间步,2维坐标)。 +- **目标输出** $Y^{(i)}$:形状 $[N, 2]$(第13个时间步所有节点的坐标)。 +- **动态邻接矩阵**:每个样本对应12个邻接矩阵 $[A^{(i)}_1, A^{(i)}_2, \dots, A^{(i)}_{12}]$(每个 $A^{(i)}_t$ 形状 $[2, \text{num\_edges}_t]$)。 --- -#### **1. 模型设定** -AR(1)模型定义为: -$$ -z_t = \rho z_{t-1} + \varepsilon_t -$$ -其中: -- $\varepsilon_t \sim \text{WN}(0, \sigma_\varepsilon^2)$ 是白噪声(独立同分布) -- $|\rho| < 1$ 保证平稳性 +#### **2. 训练过程** +**模型结构**: +1. **LSTM层**: + - 输入:$[N, 12, 2]$($N$个节点的12步历史轨迹)。 + - 输出:每个节点的时序特征 $[N, 12, H]$($H$为LSTM隐藏层维度)。 + - **关键点**:LSTM独立处理每个节点的时序,节点间无交互。 + +2. **GAT层**: + - 输入:取LSTM最后一个时间步的输出 $[N, H]$(即每个节点的最终时序特征)。 + - 动态图输入:使用第12个时间步的邻接矩阵 $A^{(i)}_{12}$(形状 $[2, \text{num\_edges}]$)。 + - 输出:通过图注意力聚合邻居信息,得到空间增强的特征 $[N, H']$($H'$为GAT输出维度)。 + +3. **预测层**: + - 全连接层将 $[N, H']$ 映射到 $[N, 2]$,预测下一时刻的坐标。 + +**训练步骤**: +1. **前向传播**: + - 输入 $[N, 12, 2]$ → LSTM → $[N, 12, H]$ → 取最后时间步 $[N, H]$ → GAT → $[N, H']$ → 预测 $[N, 2]$。 +2. **损失计算**: + - 均方误差(MSE)损失:比较预测坐标 $[N, 2]$ 和真实坐标 $[N, 2]$。 +3. **反向传播**: + - 梯度从预测层回传到GAT和LSTM,更新所有参数。 --- -#### **2. 递推展开(关键步骤)** -通过无限递推将 $z_t$ 表示为历史噪声的线性组合: -$$ -\begin{aligned} -z_t &= \varepsilon_t + \rho z_{t-1} \\ -&= \varepsilon_t + \rho (\varepsilon_{t-1} + \rho z_{t-2}) \\ -&= \varepsilon_t + \rho \varepsilon_{t-1} + \rho^2 \varepsilon_{t-2} + \cdots \\ -&= \sum_{j=0}^\infty \rho^j \varepsilon_{t-j} -\end{aligned} -$$ - -**为什么需要 $\varepsilon_{t-j}$?** -虽然所有 $\varepsilon_{t-j}$ 的方差都是 $\sigma_\varepsilon^2$,但它们是**不同时刻**的独立随机变量。不能合并为一个 $\varepsilon$,因为: -- 每个时间点 $t-j$ 的噪声 $\varepsilon_{t-j}$ 是独立的新信息 -- 合并会丢失时间维度信息,破坏模型结构 +#### **3. 数据维度变化总结** +| **步骤** | **数据形状** | **说明** | +| --------------------- | -------------- | -------------------------------------- | +| 原始输入 | $[N, 1000, 2]$ | $N$个节点,1000个时间步的$(x,y)$坐标。 | +| 滑动窗口样本 | $[N, 12, 2]$ | 每个样本包含12个历史时间步。 | +| LSTM输入 | $[N, 12, 2]$ | 输入LSTM的节点独立时序数据。 | +| LSTM输出 | $[N, 12, H]$ | $H$为LSTM隐藏层维度。 | +| GAT输入(最后时间步) | $[N, H]$ | 提取每个节点的最终时序特征。 | +| GAT输出 | $[N, H']$ | $H'$为GAT输出维度,含邻居聚合信息。 | +| 预测输出 | $[N, 2]$ | 下一时刻的$(x,y)$坐标预测。 | --- -#### **3. 方差计算(严格推导)** -利用方差的性质(独立变量线性组合的方差): -$$ -\text{Var}(z_t) = \text{Var}\left( \sum_{j=0}^\infty \rho^j \varepsilon_{t-j} \right) -$$ +#### **4. 关键注意事项** +1. **动态图的处理**: + - 每个滑动窗口样本需匹配对应时间步的邻接矩阵(如第 $i$ 到 $i+11$ 步的 $[A^{(i)}_1, \dots, A^{(i)}_{12}]$),但GAT仅使用最后一步 $A^{(i)}_{12}$。 + - 若图结构变化缓慢,可简化为所有窗口共享 $A^{(i)}_{12}$。 -**步骤分解:** -1. **独立性**:$\varepsilon_{t-j}$ 相互独立 ⇒ 方差可加 - $$ - = \sum_{j=0}^\infty \text{Var}(\rho^j \varepsilon_{t-j}) - $$ -2. **常数提取**:$\rho^j$ 是非随机系数 - $$ - = \sum_{j=0}^\infty \rho^{2j} \text{Var}(\varepsilon_{t-j}) - $$ -3. **同方差性**:$\text{Var}(\varepsilon_{t-j}) = \sigma_\varepsilon^2$ 对所有 $j$ 成立 - $$ - = \sigma_\varepsilon^2 \sum_{j=0}^\infty \rho^{2j} - $$ -4. **级数求和**:$|\rho|<1$ 时几何级数收敛 - $$ - = \sigma_\varepsilon^2 \cdot \frac{1}{1-\rho^2} = \frac{\sigma_\varepsilon^2}{1-\rho^2} - $$ +2. **数据划分**: + - 按时间划分训练/验证集(如前800个窗口训练,后188个验证),避免未来信息泄露。 + +3. **模型改进方向**: + - **多步预测**:输出 $[N, K, 2]$(预测未来$K$步),需调整损失函数。 + - **时空耦合**:改用ST-LSTM或先GAT后LSTM,更早引入交互。 --- -#### **4. 为什么不能简化为单一 $\varepsilon$?** -若错误地尝试合并: -$$ -\text{错误写法:} \quad z_t \overset{?}{=} \varepsilon_t (1 + \rho + \rho^2 + \cdots) = \frac{\varepsilon_t}{1-\rho} -$$ -会导致: -1. **方差计算错误**: - $$ - \text{Var}(z_t) \overset{?}{=} \frac{\text{Var}(\varepsilon_t)}{(1-\rho)^2} = \frac{\sigma_\varepsilon^2}{(1-\rho)^2} - $$ - (与正确结果 $\frac{\sigma_\varepsilon^2}{1-\rho^2}$ 不符) - -2. **物理意义错误**: - - 忽略了不同时刻噪声的独立性 - - 错误地假设所有历史噪声完全相关 - ---- - -#### **5. 结论** -- **正确结果**: - $$ - \text{Var}(z_t) = \frac{\sigma_\varepsilon^2}{1-\rho^2} \quad \text{(与时间 $t$ 无关)} - $$ -- **核心要点**: - 1. 必须保留 $\varepsilon_{t-j}$ 的下标,表示不同时刻的独立噪声 - 2. 几何级数求和时,系数是 $\rho^{2j}$(不是 $\rho^j$),因为方差运算涉及平方 - ---- - -### 补充说明 -此推导方法是时间序列分析的标准技术(参考Box & Jenkins《Time Series Analysis》)。白噪声的独立性是保证方差可加性的关键,任何简化合并 $\varepsilon_{t-j}$ 的操作都会破坏模型的时间依赖性结构。 - - - - - -根据引理1,$\text{Var}[\lambda_1(A_t)] \approx 2\sigma^2 = \sigma_1^2$。为使模型与理论一致,可设: - -$$ -\sigma_\varepsilon^2 = (1 - \rho^2) \cdot 2\sigma^2 -$$ - -此时: - -$$ -\text{Var}[\tilde{z}_t] = 2\sigma^2 = \sigma_1^2 -$$ \ No newline at end of file +### **总结** +- **数据流**:滑动窗口切割时序 → LSTM独立编码节点轨迹 → GAT聚合空间信息 → 预测坐标。 +- **节点交互时机**:仅在GAT阶段通过注意力机制融合邻居信息,LSTM阶段节点独立。 +- **适用性**:适合RWP等移动模型预测,兼顾时序动态和空间依赖。 \ No newline at end of file diff --git a/科研/陈茂森论文.md b/科研/陈茂森论文.md index 46530d6..ea05362 100644 --- a/科研/陈茂森论文.md +++ b/科研/陈茂森论文.md @@ -363,6 +363,8 @@ $$ ### 瑞利商公式 +目的:求对称矩阵A的最大特征值 + 1. 集中式: $$ @@ -469,11 +471,11 @@ $$ $$ c. **隐式收缩($n>0$时)**: $$ - y_j^{(t+1)} \gets y_j^{(t+1)} - \sum_{m=0}^{n-1} \sigma_m^2 v_{m,j} \cdot \underbrace{\text{Consensus}\left(\sum_k v_{m,k} y_k^{(t+1)}\right)}_{\text{投影系数计算}} + y_j^{(t+1)} \gets y_j^{(t+1)} - \sum_{m=0}^{n-1} \sigma_m^2 v_{m,j} \cdot \underbrace{\text{Consensus}\left(\sum_k v_{m,k} y_k^{(t+1)}\right)}_{\text{投影系数计算}} $$ d. **归一化**: $$ - v_{n,j}^{(t+1)} = \frac{y_j^{(t+1)}}{\sqrt{\text{Consensus}\left(\sum_k (y_k^{(t+1)})^2\right)}} + v_{n,j}^{(t+1)} = \frac{y_j^{(t+1)}}{\sqrt{\text{Consensus}\left(\sum_k (y_k^{(t+1)})^2\right)}} $$ e. **计算Rayleigh商**: $$ @@ -656,7 +658,7 @@ $$ #### **符号说明** - **$i$**: 节点索引,$N$ 为总节点数 -- **$x_i(k)$**: 节点 $i$ 在时刻 $k$ 的状态分量 ($x$) +- **$x_i(k)$**: 节点 $i$ 在时刻 $k$ 的状态分量 (相当于$x$) - **$b_i(k)$**: 节点 $i$ 的本地状态估计值 (相当于$Ax$) - **$a_{ij}$**: 邻接矩阵元素(链路权重) - **$Q_k, R_k$**: 过程噪声与观测噪声协方差 diff --git a/科研/颜佳佳论文.md b/科研/颜佳佳论文.md index 512fb77..afa89b1 100644 --- a/科研/颜佳佳论文.md +++ b/科研/颜佳佳论文.md @@ -93,6 +93,8 @@ $$ #### **2. 测量模型** +$v_k$ + 观测到的特征值向量 $z_k$ 为: $$ z_k = \lambda_k + v_k @@ -437,3 +439,86 @@ TCN的卷积核仅在**单个通道内滑动**,计算时仅依赖该节点自 - **时间步对齐**:通常取最后一个时间步的特征(例如 `H_T^l[:, :, -1]`)作为当前节点特征。 - **空间聚合**:GAT 根据邻接矩阵计算无人机间的注意力权重,例如考虑“无人机2的当前流量可能受到无人机1过去3分钟流量变化的影响”。 + + + + +### **LSTM+GAT训练过程说明(RWP网络节点移动预测)** + +先LSTM后GAT侧重点在时序特征的提取;先GAT后LSTM侧重点在空间特征的提取。 + +#### **1. 数据构造** + +**输入数据**: + +- **节点轨迹数据**: + - 每个节点在1000个时间单位内的二维坐标 $(x, y)$,形状为 $[N, 1000, 2]$($N$个节点,1000个时间步,2维特征)。 +- **动态邻接矩阵序列**: + - 每个时间步的节点连接关系(基于距离阈值或其他规则生成),得到1000个邻接矩阵 $[A_1, A_2, \dots, A_{1000}]$,每个 $A_t$ 的形状为 $[2, \text{num\_edges}_t]$(稀疏表示)。 + +**滑动窗口处理**: + +- **窗口大小**:12(用前12个时间步预测第13个时间步)。 +- **滑动步长**:1(每次滑动1个时间步,生成更多训练样本)。 +- **生成样本数量**: + - 总时间步1000,窗口大小12 → 可生成 $1000 - 12 = 988$ 个样本。 + +**样本格式**: + +- **输入序列** $X^{(i)}$:形状 $[N, 12, 2]$($N$个节点,12个时间步,2维坐标)。 +- **目标输出** $Y^{(i)}$:形状 $[N, 2]$(第13个时间步所有节点的坐标)。 +- **动态邻接矩阵**:每个样本对应12个邻接矩阵 $[A^{(i)}_1, A^{(i)}_2, \dots, A^{(i)}_{12}]$(每个 $A^{(i)}_t$ 形状 $[2, \text{num\_edges}_t]$)。 + +--- + +#### **2. 训练过程** + +**模型结构**: + +1. **LSTM层**: + - 输入:$[N, 12, 2]$($N$个节点的12步历史轨迹)。 + - 输出:每个节点的时序特征 $[N, 12, H]$($H$为LSTM隐藏层维度)。 + - **关键点**:LSTM独立处理每个节点的时序,节点间无交互。 + +2. **GAT层**: + - 输入:取LSTM最后一个时间步的输出 $[N, H]$(即每个节点的最终时序特征)。 + - 动态图输入:使用第12个时间步的邻接矩阵 $A^{(i)}_{12}$(形状 $[2, \text{num\_edges}]$)。 + - 输出:通过图注意力聚合邻居信息,得到空间增强的特征 $[N, H']$($H'$为GAT输出维度)。 + +3. **预测层**: + - 全连接层将 $[N, H']$ 映射到 $[N, 2]$,预测下一时刻的坐标。 + +**训练步骤**: + +1. **前向传播**: + - 输入 $[N, 12, 2]$ → LSTM → $[N, 12, H]$ → 取最后时间步 $[N, H]$ → GAT → $[N, H']$ → 预测 $[N, 2]$。 +2. **损失计算**: + - 均方误差(MSE)损失:比较预测坐标 $[N, 2]$ 和真实坐标 $[N, 2]$。 +3. **反向传播**: + - 梯度从预测层回传到GAT和LSTM,更新所有参数。 + +--- + +#### **3. 数据维度变化总结** + +| **步骤** | **数据形状** | **说明** | +| --------------------- | -------------- | -------------------------------------- | +| 原始输入 | $[N, 1000, 2]$ | $N$个节点,1000个时间步的$(x,y)$坐标。 | +| 滑动窗口样本 | $[N, 12, 2]$ | 每个样本包含12个历史时间步。 | +| LSTM输入 | $[N, 12, 2]$ | 输入LSTM的节点独立时序数据。 | +| LSTM输出 | $[N, 12, H]$ | $H$为LSTM隐藏层维度。 | +| GAT输入(最后时间步) | $[N, H]$ | 提取每个节点的最终时序特征。 | +| GAT输出 | $[N, H']$ | $H'$为GAT输出维度,含邻居聚合信息。 | +| 预测输出 | $[N, 2]$ | 下一时刻的$(x,y)$坐标预测。 | + +--- + +#### **4. 关键注意事项** + +1. **动态图的处理**: + - 每个滑动窗口样本需匹配对应时间步的邻接矩阵(如第 $i$ 到 $i+11$ 步的 $[A^{(i)}_1, \dots, A^{(i)}_{12}]$),但GAT仅使用最后一步 $A^{(i)}_{12}$。 + - 若图结构变化缓慢,可简化为所有窗口共享 $A^{(i)}_{12}$。 + +2. **数据划分**: + - 按时间划分训练/验证集(如前800个窗口训练,后188个验证),避免未来信息泄露。 + diff --git a/自学/Java笔记本.md b/自学/Java笔记本.md index 4303a97..8fc9cbe 100644 --- a/自学/Java笔记本.md +++ b/自学/Java笔记本.md @@ -976,6 +976,37 @@ MyBatis的XML映射文件的**namespace属性** ### JAVA面向对象 +```java +public class Dog { + // 成员变量 + private String name; + + // 构造函数 + public Dog(String name) { + this.name = name; + } + + // 一个函数:让狗狗“叫” + public void bark() { + System.out.println(name + " says: Woof! Woof!"); + } + + // (可选)获取狗狗的名字 + public String getName() { + return name; + } + + // 测试主方法 + public static void main(String[] args) { + Dog myDog = new Dog("Buddy"); + myDog.bark(); // 输出:Buddy says: Woof! Woof! + System.out.println("Name: " + myDog.getName()); + } +} +``` + + + #### **JAVA**三大特性 **封装** @@ -1061,7 +1092,7 @@ class Calculator { double add(double a, double b) { return a + b; } - +} ``` diff --git a/自学/力扣Hot 100题.md b/自学/力扣Hot 100题.md index 67791da..0db77c8 100644 --- a/自学/力扣Hot 100题.md +++ b/自学/力扣Hot 100题.md @@ -119,6 +119,38 @@ System.out.println(b); // 输出 12 +### Random + +`Random` 是伪随机数生成器 + +| `nextInt()` | 任意 int | `Integer.MIN_VALUE` … `Integer.MAX_VALUE` | +| ---------------- | ----------------------- | ----------------------------------------- | +| `nextInt(bound)` | 0(含)至 bound(不含) | `[0, bound)` | + +```java +import java.util.Random; +import java.util.stream.IntStream; + +public class RandomDemo { + public static void main(String[] args) { + Random rnd = new Random(); // 随机种子 + Random seeded = new Random(2025L); // 固定种子 + + // 1) 随机整数 + int a = rnd.nextInt(); // 任意 int + int b = rnd.nextInt(100); // [0,100) + System.out.println("a=" + a + ", b=" + b); + + // 2) 随机浮点数与布尔 + double d = rnd.nextDouble(); // [0.0,1.0) + boolean flag = rnd.nextBoolean(); + System.out.println("d=" + d + ", flag=" + flag); + } +} +``` + + + ## 常用数据结构 ### String @@ -254,6 +286,16 @@ public class HashMapExample { } ``` +如何在创建的时候初始化?“双括号”初始化 + +``` +Map map = new HashMap<>() {{ + put(1, 'a'); + put(2, 'b'); + put(3, 'c'); +}}; +``` + 记录二维数组中某元素是否被访问过,推荐使用: ```java diff --git a/自学/草稿.md b/自学/草稿.md index 0eb5aeb..85c3184 100644 --- a/自学/草稿.md +++ b/自学/草稿.md @@ -1,67 +1,70 @@ -在 **0/1 背包问题**中,使用一维 DP 数组时**必须逆序遍历背包容量**,主要原因在于**避免同一物品被重复计算**。这与二维 DP 的实现方式有本质区别。下面通过公式和例子详细说明。 +下面是 Java 中 `java.util.Random` 类的简要介绍及几种最常用的用法示例。 ---- +------ -## 为什么一维 DP 必须逆序遍历? +## 1. 基本概念 -### 状态定义 -一维 DP 数组定义为: -$$ -dp[j] = \text{背包容量为 } j \text{ 时的最大价值} -$$ +- `Random` 是伪随机数生成器,内部用线性同余法(LCG)产生序列。 +- 如果不传 seed,默认以当前时间作为种子;传入相同 seed 会得到相同的“随机”序列,方便测试。 -### 状态转移方程 -对于物品 $i$(重量 $w_i$,价值 $v_i$): -$$ -dp[j] = \max(dp[j], dp[j-w_i] + v_i) \quad (j \geq w_i) -$$ +```java +import java.util.Random; -### 关键问题 -- **正序遍历**会导致 $dp[j-w_i]$ 在更新 $dp[j]$ 时**已被当前物品更新过**,相当于重复使用该物品。 -- **逆序遍历**保证 $dp[j-w_i]$ 始终是**上一轮(未考虑当前物品)**的结果,符合 0/1 背包的“一次性”规则。 +Random rnd1 = new Random(); // 随机种子 +Random rnd2 = new Random(12345L); // 固定种子 -> 每次结果相同 +``` ---- +------ -## 二维 DP 为何不需要逆序? +## 2. 常用方法 -二维 DP 定义为: -$$ -dp[i][j] = \text{前 } i \text{ 个物品,容量 } j \text{ 时的最大价值} -$$ -状态转移: -$$ -dp[i][j] = \max(dp[i-1][j], dp[i-1][j-w_i] + v_i) -$$ -- 由于直接依赖 **上一行 $dp[i-1][\cdot]$**,不存在状态覆盖问题,正序/逆序均可。 +| 方法 | 功能 | 返回值范围 | +| ---------------- | ----------------------- | ----------------------------------------- | +| `nextInt()` | 任意 int | `Integer.MIN_VALUE` … `Integer.MAX_VALUE` | +| `nextInt(bound)` | 0(含)至 bound(不含) | `[0, bound)` | +| `nextLong()` | 任意 long | 整个 long 范围 | +| `nextDouble()` | double 小数 | `[0.0, 1.0)` | +| `nextBoolean()` | 布尔值 | `true` 或 `false` | +| `nextGaussian()` | 高斯(正态)分布 | 均值 0、标准差 1 | ---- +------ -## 例子演示 -假设物品 $w=2$, $v=3$,背包容量 $C=5$。 +## 3. 示例代码 -错误的正序遍历($j=2 \to 5$) +```java +import java.util.Random; +import java.util.stream.IntStream; -1. $j=2$: - $dp[2] = \max(0, dp[0]+3) = 3$ - $\Rightarrow dp = [0, 0, 3, 0, 0, 0]$ -2. $j=4$: - $dp[4] = \max(0, dp[2]+3) = 6$ - $\Rightarrow$ **错误**:物品被重复使用两次! +public class RandomDemo { + public static void main(String[] args) { + Random rnd = new Random(); // 随机种子 + Random seeded = new Random(2025L); // 固定种子 -### 正确的逆序遍历($j=5 \to 2$) -1. $j=5$: - $dp[5] = \max(0, dp[3]+3) = 0$ ($dp[3]$ 未更新) -2. $j=2$: - $dp[2] = \max(0, dp[0]+3) = 3$ - $\Rightarrow dp = [0, 0, 3, 3, 3, 0]$ - **正确**:物品仅使用一次。 + // 1) 随机整数 + int a = rnd.nextInt(); // 任意 int + int b = rnd.nextInt(100); // [0,100) + System.out.println("a=" + a + ", b=" + b); ---- + // 2) 随机浮点数与布尔 + double d = rnd.nextDouble(); // [0.0,1.0) + boolean flag = rnd.nextBoolean(); + System.out.println("d=" + d + ", flag=" + flag); -## 总结 -| 维度 | 遍历顺序 | 原因 | -| ------ | -------- | ------------------------------------------------------------ | -| 一维DP | **逆序** | 防止 $dp[j-w_i]$ 被当前物品污染,确保每个物品只计算一次。 | -| 二维DP | 任意顺序 | 状态分层存储($dp[i][j]$ 只依赖 $dp[i-1][\cdot]$),无覆盖风险。 | + // 3) 高斯分布 + double g = rnd.nextGaussian(); // 均值0,σ=1 + System.out.println("gaussian=" + g); -**核心思想**:一维 DP 的空间优化需要逆序来保证状态的**无后效性**。 \ No newline at end of file + // 4) 生成一组随机数流 + IntStream stream = rnd.ints(5, 50, 60); // 5 个 [50,60) 的随机 ints + System.out.print("stream: "); + stream.forEach(n -> System.out.print(n + " ")); + } +} +``` + +------ + +## 4. 小贴士 + +- 并发环境下可用 `ThreadLocalRandom.current()`,避免多线程竞争。 +- 若只需加密强度随机数,请使用 `SecureRandom`。 \ No newline at end of file