Commit on 2025/04/29 周二 18:12:50.83

This commit is contained in:
zhangsan 2025-04-29 18:12:50 +08:00
parent 99686ea1af
commit cfc666641a
9 changed files with 459 additions and 234 deletions

View File

@ -1,3 +1,9 @@
如何确定kmeans的簇数节点之间的流量空间转为时间的图。
压缩感知 函数拟合 采样定理 傅里叶变换
gat有没有问题 比如初始训练好的w和a 后面新加入节点 这个w和a不变会不会导致问题 我现在能实时重构出邻接矩阵a和特征矩阵 是否有帮助? 是否也能替换与邻居节点的通信 因为卡尔曼能重构,知道邻居节点的特征?

View File

@ -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点确定性采样**
**目的**:根据当前状态均值和协方差,生成一组代表状态分布的采样点。

View File

@ -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}.
\mathbf{z}_i = W \mathbf{h}_i, \quad \mathbf{z}_j = W \mathbf{h}_j
$$
- **线性变换矩阵 $W$**
为了简化,我们令 $W$ 为单位矩阵(即 $W\mathbf{h} = \mathbf{h}$)。
### 自注意力系数计算(关键步骤)
- **目标**:计算节点 $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$ 归一化:
$$
W = \begin{bmatrix}1 & 0 \\ 0 & 1\end{bmatrix}.
\alpha_{ij} = \text{softmax}_j(e_{ij}) = \frac{\exp(e_{ij})}{\sum_{k \in \mathcal{N}_i} \exp(e_{ik})}
$$
- **可学习向量 $\mathbf{a}$**
假设 $\mathbf{a}$ 为 4 维向量,设
$$
\mathbf{a} = \begin{bmatrix}1 \\ 1 \\ 1 \\ 1\end{bmatrix}.
$$
- **关键点**:分母只包含节点 $i$ 的直接邻居(包括自己,如果图含自环)。
- 激活函数使用 LeakyReLU负数斜率设为0.2,但本例中结果为正数,所以不变)。
---
**计算步骤:**
### 注意力系数计算示例(带数值模拟)
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]
$$
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.
\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. **拼接特征**
$$
\alpha_{ik} = \frac{\exp(3)}{\exp(2)+\exp(3)} \approx 0.731.
[\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
$$
### 特征聚合
**单头注意力聚合(得到新的节点特征)**
$$
\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的优点
**参数共享**

View File

@ -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
$$
### **总结**
- **数据流**:滑动窗口切割时序 → LSTM独立编码节点轨迹 → GAT聚合空间信息 → 预测坐标。
- **节点交互时机**仅在GAT阶段通过注意力机制融合邻居信息LSTM阶段节点独立。
- **适用性**适合RWP等移动模型预测兼顾时序动态和空间依赖。

View File

@ -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$**: 过程噪声与观测噪声协方差

View File

@ -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个验证避免未来信息泄露。

View File

@ -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;
}
}
```

View File

@ -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<Integer, Character> map = new HashMap<>() {{
put(1, 'a');
put(2, 'b');
put(3, 'c');
}};
```
记录二维数组中某元素是否被访问过,推荐使用:
```java

View File

@ -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 的空间优化需要逆序来保证状态的**无后效性**。
// 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`