当前位置: 首页 > news >正文

【深度学习-Day 47】告别单向依赖:深入解析双向RNN与堆叠RNN,解锁序列建模新高度

Langchain系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
08-【万字长文】MCP深度解析:打通AI与世界的“USB-C”,模型上下文协议原理、实践与未来

Python系列文章目录

PyTorch系列文章目录

机器学习系列文章目录

深度学习系列文章目录

Java系列文章目录

JavaScript系列文章目录

深度学习系列文章目录

01-【深度学习-Day 1】为什么深度学习是未来?一探究竟AI、ML、DL关系与应用
02-【深度学习-Day 2】图解线性代数:从标量到张量,理解深度学习的数据表示与运算
03-【深度学习-Day 3】搞懂微积分关键:导数、偏导数、链式法则与梯度详解
04-【深度学习-Day 4】掌握深度学习的“概率”视角:基础概念与应用解析
05-【深度学习-Day 5】Python 快速入门:深度学习的“瑞士军刀”实战指南
06-【深度学习-Day 6】掌握 NumPy:ndarray 创建、索引、运算与性能优化指南
07-【深度学习-Day 7】精通Pandas:从Series、DataFrame入门到数据清洗实战
08-【深度学习-Day 8】让数据说话:Python 可视化双雄 Matplotlib 与 Seaborn 教程
09-【深度学习-Day 9】机器学习核心概念入门:监督、无监督与强化学习全解析
10-【深度学习-Day 10】机器学习基石:从零入门线性回归与逻辑回归
11-【深度学习-Day 11】Scikit-learn实战:手把手教你完成鸢尾花分类项目
12-【深度学习-Day 12】从零认识神经网络:感知器原理、实现与局限性深度剖析
13-【深度学习-Day 13】激活函数选型指南:一文搞懂Sigmoid、Tanh、ReLU、Softmax的核心原理与应用场景
14-【深度学习-Day 14】从零搭建你的第一个神经网络:多层感知器(MLP)详解
15-【深度学习-Day 15】告别“盲猜”:一文读懂深度学习损失函数
16-【深度学习-Day 16】梯度下降法 - 如何让模型自动变聪明?
17-【深度学习-Day 17】神经网络的心脏:反向传播算法全解析
18-【深度学习-Day 18】从SGD到Adam:深度学习优化器进阶指南与实战选择
19-【深度学习-Day 19】入门必读:全面解析 TensorFlow 与 PyTorch 的核心差异与选择指南
20-【深度学习-Day 20】PyTorch入门:核心数据结构张量(Tensor)详解与操作
21-【深度学习-Day 21】框架入门:神经网络模型构建核心指南 (Keras & PyTorch)
22-【深度学习-Day 22】框架入门:告别数据瓶颈 - 掌握PyTorch Dataset、DataLoader与TensorFlow tf.data实战
23-【深度学习-Day 23】框架实战:模型训练与评估核心环节详解 (MNIST实战)
24-【深度学习-Day 24】过拟合与欠拟合:深入解析模型泛化能力的核心挑战
25-【深度学习-Day 25】告别过拟合:深入解析 L1 与 L2 正则化(权重衰减)的原理与实战
26-【深度学习-Day 26】正则化神器 Dropout:随机失活,模型泛化的“保险丝”
27-【深度学习-Day 27】模型调优利器:掌握早停、数据增强与批量归一化
28-【深度学习-Day 28】告别玄学调参:一文搞懂网格搜索、随机搜索与自动化超参数优化
29-【深度学习-Day 29】PyTorch模型持久化指南:从保存到部署的第一步
30-【深度学习-Day 30】从MLP的瓶颈到CNN的诞生:卷积神经网络的核心思想解析
31-【深度学习-Day 31】CNN基石:彻底搞懂卷积层 (Convolutional Layer) 的工作原理
32-【深度学习-Day 32】CNN核心组件之池化层:解密最大池化与平均池化
33-【深度学习-Day 33】从零到一:亲手构建你的第一个卷积神经网络(CNN)
34-【深度学习-Day 34】CNN实战:从零构建CIFAR-10图像分类器(PyTorch)
35-【深度学习-Day 35】实战图像数据增强:用PyTorch和TensorFlow扩充你的数据集
36-【深度学习-Day 36】CNN的开山鼻祖:从LeNet-5到AlexNet的架构演进之路
37-【深度学习-Day 37】VGG与GoogLeNet:当深度遇见宽度,CNN架构的演进之路
38-【深度学习-Day 38】破解深度网络退化之谜:残差网络(ResNet)核心原理与实战
39-【深度学习-Day 39】玩转迁移学习与模型微调:站在巨人的肩膀上
40-【深度学习-Day 40】RNN入门:当神经网络拥有记忆,如何处理文本与时间序列?
41-【深度学习-Day 41】解密循环神经网络(RNN):深入理解隐藏状态、参数共享与前向传播
42-【深度学习-Day 42】RNN的“记忆”难题:深入解析长期依赖与梯度消失/爆炸
43-【深度学习-Day 43】解密LSTM:深入理解长短期记忆网络如何克服RNN的遗忘症
44-【深度学习-Day 44】GRU详解:LSTM的优雅继任者?门控循环单元原理与PyTorch实战
45-【深度学习-Day 45】实战演练:用 RNN/LSTM 构建情感分析模型 (PyTorch)
46-【深度学习-Day 46】词嵌入 (Word Embedding) 深度解析:让机器读懂你的语言
47-【深度学习-Day 47】告别单向依赖:深入解析双向RNN与堆叠RNN,解锁序列建模新高度


文章目录

  • Langchain系列文章目录
  • Python系列文章目录
  • PyTorch系列文章目录
  • 机器学习系列文章目录
  • 深度学习系列文章目录
  • Java系列文章目录
  • JavaScript系列文章目录
  • 深度学习系列文章目录
  • 摘要
  • 一、回顾:简单RNN的局限性
      • 1.1 单向处理的“短视”问题
      • 1.2 浅层结构的表达能力瓶颈
  • 二、双向循环神经网络 (Bidirectional RNN, BiRNN)
      • 2.1 核心思想:兼顾过去与未来
      • 2.2 BiRNN的架构详解
        • (1) 前向与后向传播
        • (2) 状态合并
        • (3) 可视化图解
      • 2.3 BiRNN的优势与适用场景
      • 2.4 PyTorch/TensorFlow代码实现
        • (1) PyTorch 实现
        • (2) TensorFlow (Keras) 实现
  • 三、堆叠循环神经网络 (Stacked RNN / Deep RNN)
      • 3.1 核心思想:增加网络深度
      • 3.2 Stacked RNN的架构详解
        • (1) 层级间的连接
        • (2) 可视化图解
      • 3.3 Stacked RNN的优势与挑战
      • 3.4 PyTorch/TensorFlow代码实现
        • (1) PyTorch 实现
        • (2) TensorFlow (Keras) 实现
  • 四、结合使用:双向堆叠RNN
  • 五、总结


摘要

在掌握了基础的循环神经网络(RNN)、长短期记忆网络(LSTM)和门控循环单元(GRU)之后,我们已经能够处理多种序列数据任务。然而,基础的RNN结构在面对复杂序列时,仍存在信息利用不充分和模型表达能力有限的问题。本文将深入探讨两种重要的RNN进阶结构:双向RNN(Bidirectional RNN)堆叠RNN(Stacked RNN)。我们将详细解析它们的核心原理、架构设计,并通过图解和代码示例,展示它们如何分别从“广度”和“深度”上增强模型对序列信息的捕捉能力,最终帮助您在实际项目中构建更强大、更精准的序列模型。

一、回顾:简单RNN的局限性

在深入了解进阶结构之前,我们首先需要明确标准RNN(包括LSTM和GRU)存在的两个主要局限,这正是催生出双向和堆叠RNN的根本原因。

1.1 单向处理的“短视”问题

标准的RNN按照时间顺序处理序列,即在时间步 ttt 时,模型的隐藏状态 hth_tht 只包含了过去(从时间步1到 t−1t-1t1)的信息,而对未来(从时间步 t+1t+1t+1 到结尾)的信息一无所知。

这种单向性在很多现实场景中是一个巨大的限制。例如:

  • 文本填空:在句子“今天天气很好,我决定去___打篮球”中,要准确预测空格里的词,我们需要看到后面的“打篮球”,从而推断出地点应该是“篮球场”或“体育馆”。
  • 命名实体识别(NER):在句子“王先生在北京工作”中,要判断“北京”是一个地名,仅仅看到“王先生在”是不够的,还需要看到后面的“工作”。完整的上下文对于实体类型的判断至关重要。

简单RNN的这种“短视”特性,使其无法利用完整的上下文信息来做出最准确的判断。

1.2 浅层结构的表达能力瓶颈

我们之前构建的RNN模型通常只有一个循环层。这就像一个浅层的神经网络,虽然能工作,但其从输入序列中提取和抽象特征的能力有限。对于非常复杂或长期的依赖关系,单层RNN可能难以学习到足够丰富的层次化特征。

类比于卷积神经网络(CNN),我们通过堆叠多个卷积层来学习从边缘、纹理到物体部件的层次化视觉特征。同样,在序列数据中,也可能存在不同抽象层次的时间模式。例如,在文本中,底层模式是单词组合成短语,高层模式是短语构成句子,更高层则是句子表达段落主旨。单层RNN很难独自完成这种多层次的抽象。

二、双向循环神经网络 (Bidirectional RNN, BiRNN)

为了解决单向处理的问题,双向RNN应运而生。它的核心思想非常直观:让模型在做决策时,既能看到过去,也能看到未来

2.1 核心思想:兼顾过去与未来

BiRNN通过引入一个额外的RNN层来实现这一目标。它包含两个并行的、独立的RNN(可以是标准RNN、LSTM或GRU):

  1. 前向RNN (Forward RNN):与标准RNN一样,从序列的开头(t=1t=1t=1)到结尾(t=Tt=Tt=T)进行处理,在每个时间步 ttt 生成一个前向隐藏状态 ht→\overrightarrow{h_t}ht
  2. 后向RNN (Backward RNN):从序列的结尾(t=Tt=Tt=T)到开头(t=1t=1t=1)反向进行处理,在每个时间步 ttt 生成一个后向隐藏状态 ht←\overleftarrow{h_t}ht

2.2 BiRNN的架构详解

(1) 前向与后向传播

对于一个输入序列 x1,x2,...,xTx_1, x_2, ..., x_Tx1,x2,...,xT,BiRNN的计算过程如下:

  • 前向传播
    ht→=f(W→xt+V→ht−1→+b→)\overrightarrow{h_t} = f(\overrightarrow{W} x_t + \overrightarrow{V} \overrightarrow{h_{t-1}} + \overrightarrow{b}) ht=f(Wxt+Vht1+b)
  • 后向传播
    ht←=f(W←xt+V←ht+1←+b←)\overleftarrow{h_t} = f(\overleftarrow{W} x_t + \overleftarrow{V} \overleftarrow{h_{t+1}} + \overleftarrow{b}) ht=f(Wxt+Vht+1+b)
    其中,fff 是激活函数(如tanh或ReLU),W→,V→,b→\overrightarrow{W}, \overrightarrow{V}, \overrightarrow{b}W,V,bW←,V←,b←\overleftarrow{W}, \overleftarrow{V}, \overleftarrow{b}W,V,b 分别是前向和后向RNN的参数,它们不共享。
(2) 状态合并

在每个时间步 ttt,模型同时拥有了来自过去的前向信息 ht→\overrightarrow{h_t}ht 和来自未来的后向信息 ht←\overleftarrow{h_t}ht。为了得到该时间步的最终表示,需要将这两个隐藏状态合并。最常见的方式是拼接(Concatenation)

ht=[ht→;ht←]h_t = [\overrightarrow{h_t} ; \overleftarrow{h_t}] ht=[ht;ht]

拼接后的 hth_tht 就成了一个更全面的特征表示,它融合了当前时间步的完整上下文信息。这个 hth_tht 随后可以被送到输出层进行预测。

(3) 可视化图解

下面的图清晰地展示了BiRNN的结构。在每个时间步,输入 xtx_txt 同时送入前向和后向RNN。最终的输出 yty_tyt 是基于两个方向的隐藏状态合并后计算得出的。

graph TDsubgraph Bidirectional RNNdirection LRsubgraph "Forward Layer (→)"direction LRx1 --> hf1(h→₁)x2 --> hf2(h→₂)x3 --> hf3(h→₃)hf1 --> hf2 --> hf3endsubgraph "Backward Layer (←)"direction LRx1 --> hb1(h←₁)x2 --> hb2(h←₂)x3 --> hb3(h←₃)hb3 --> hb2 --> hb1endhf1 --- C1(Combine)hb1 --- C1C1 --> y1[Output y₁]hf2 --- C2(Combine)hb2 --- C2C2 --> y2[Output y₂]hf3 --- C3(Combine)hb3 --- C3C3 --> y3[Output y₃]endInputs[x₁, x₂, x₃] --> x1 & x2 & x3

2.3 BiRNN的优势与适用场景

  • 优势:显著提升模型对上下文的理解能力,在许多序列任务上都能带来性能提升。
  • 适用场景
    • 命名实体识别 (NER)
    • 情感分析
    • 词性标注 (Part-of-Speech Tagging)
    • 机器翻译(尤其是在Encoder部分)
  • 局限:BiRNN需要完整的输入序列才能开始计算后向传播,因此不适用于需要实时预测的流式任务(如实时语音识别),因为在这些任务中无法预知未来的输入。

2.4 PyTorch/TensorFlow代码实现

在主流深度学习框架中,实现BiRNN非常简单。

(1) PyTorch 实现

在PyTorch中,只需在nn.LSTMnn.GRU层中设置bidirectional=True即可。

import torch
import torch.nn as nn# 定义超参数
input_size = 10  # 输入特征维度
hidden_size = 20 # 隐藏状态维度
num_layers = 1   # 单层# 创建一个双向LSTM
# 注意:输出维度将是 2 * hidden_size,因为前向和后向的状态会拼接
bi_lstm_layer = nn.LSTM(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers,bidirectional=True, # 关键参数!batch_first=True)# 准备输入数据 (batch_size, seq_length, input_size)
dummy_input = torch.randn(5, 3, 10)# 前向传播
output, (h_n, c_n) = bi_lstm_layer(dummy_input)# 查看输出维度
print("Output shape:", output.shape) # torch.Size([5, 3, 40]) -> 40 = 2 * 20
# h_n shape: (num_layers * 2, batch_size, hidden_size)
print("Hidden state shape:", h_n.shape) # torch.Size([2, 5, 20]) -> 2 = 1_layer * 2_directions
(2) TensorFlow (Keras) 实现

在Keras中,使用tf.keras.layers.Bidirectional包装器来包裹一个循环层。

import tensorflow as tf# 定义超参数
input_size = 10
hidden_size = 20
seq_length = 3# 创建一个双向LSTM
# 使用Bidirectional层包装一个LSTM层
bi_lstm_layer = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(units=hidden_size, return_sequences=True) # return_sequences=True 返回每个时间步的输出
)# 准备输入数据 (batch_size, seq_length, input_size)
dummy_input = tf.random.normal((5, seq_length, input_size))# 前向传播
output = bi_lstm_layer(dummy_input)# 查看输出维度
print("Output shape:", output.shape) # (5, 3, 40) -> 40 = 2 * 20

三、堆叠循环神经网络 (Stacked RNN / Deep RNN)

为了解决浅层结构表达能力不足的问题,我们可以将多个RNN层堆叠起来,构建一个更深的模型。

3.1 核心思想:增加网络深度

Stacked RNN的核心思想是构建一个层次化的时间特征表示

  • 第一层RNN:接收原始输入序列,学习底层的、局部的时序模式。
  • 后续RNN层:将前一层RNN的隐藏状态序列作为其输入,从而学习更高级、更抽象、跨度更长的时间模式。

这种深度结构增强了模型的容量和非线性表达能力,使其能够捕捉到更加复杂的序列动态。

3.2 Stacked RNN的架构详解

(1) 层级间的连接

在一个LLL层的Stacked RNN中,第 lll 层的输入是第 l−1l-1l1 层的隐藏状态序列 hl−1=(h1l−1,h2l−1,...,hTl−1)h^{l-1} = (h_1^{l-1}, h_2^{l-1}, ..., h_T^{l-1})hl1=(h1l1,h2l1,...,hTl1)。第 111 层的输入是原始的输入序列 xxx

htl=f(Wlhtl−1+Vlht−1l+bl)h_t^l = f(W^l h_t^{l-1} + V^l h_{t-1}^l + b^l) htl=f(Wlhtl1+Vlht1l+bl)
注意,这里的 htl−1h_t^{l-1}htl1 是来自下层同一时间步的输出,而 ht−1lh_{t-1}^lht1l 是来自本层前一时间步的隐藏状态。

(2) 可视化图解

下图展示了一个2层的Stacked RNN。可以看到,Layer 1的输出序列成为了Layer 2的输入序列。

graph TDsubgraph "Stacked RNN (2 Layers)"direction TBsubgraph "Input Sequence (x)"direction LRx1(x₁) --.-> x2(x₂) --.-> x3(x₃)endsubgraph "Layer 1 (RNN)"direction LRh1_0(h¹₀) --> h1_1(h¹₁) --> h1_2(h¹₂) --> h1_3(h¹₃)endsubgraph "Layer 2 (RNN)"direction LRh2_0(h²₀) --> h2_1(h²₁) --> h2_2(h²₂) --> h2_3(h²₃)endx1 --> h1_1x2 --> h1_2x3 --> h1_3h1_1 --> h2_1h1_2 --> h2_2h1_3 --> h2_3h2_1 --> y1[Output y₁]h2_2 --> y2[Output y₂]h2_3 --> y3[Output y₃]end

3.3 Stacked RNN的优势与挑战

  • 优势
    • 更强的表达能力:模型容量更大,能学习更复杂的函数。
    • 特征层次化:自动学习不同抽象级别的时序特征。
  • 挑战
    • 参数量增加:模型更复杂,需要更多数据来训练,以避免过拟合。
    • 梯度问题:虽然LSTM/GRU缓解了梯度消失,但非常深的网络仍然可能面临训练不稳定的问题。通常需要配合正则化技术(如Dropout)和归一化(如Layer Normalization)使用。

3.4 PyTorch/TensorFlow代码实现

实现Stacked RNN同样非常简单。

(1) PyTorch 实现

在PyTorch中,只需设置num_layers参数为一个大于1的整数。

import torch
import torch.nn as nn# 定义超参数
input_size = 10
hidden_size = 20
num_layers = 3 # 关键参数!设置一个3层的堆叠LSTM# 创建一个堆叠LSTM
stacked_lstm_layer = nn.LSTM(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, # 大于1即可batch_first=True)# 准备输入数据 (batch_size, seq_length, input_size)
dummy_input = torch.randn(5, 3, 10)# 前向传播
output, (h_n, c_n) = stacked_lstm_layer(dummy_input)print("Output shape:", output.shape) # torch.Size([5, 3, 20])
# h_n shape: (num_layers, batch_size, hidden_size)
print("Hidden state shape:", h_n.shape) # torch.Size([3, 5, 20])

注意:在PyTorch中,output 始终是最后一层的隐藏状态序列。

(2) TensorFlow (Keras) 实现

在Keras中,只需将多个循环层依次添加到tf.keras.Sequential模型中即可。

重要陷阱:除了最后一层,所有中间的循环层都必须设置return_sequences=True,这样它们才会返回完整的隐藏状态序列作为下一层的输入。

import tensorflow as tf# 定义超参数
input_size = 10
hidden_size = 20# 创建一个3层的堆叠LSTM
stacked_lstm_model = tf.keras.Sequential([# 第1层:必须返回序列给下一层tf.keras.layers.LSTM(units=hidden_size, return_sequences=True, input_shape=(None, input_size)),# 第2层:也必须返回序列给下一层tf.keras.layers.LSTM(units=hidden_size, return_sequences=True),# 第3层(最后一层):可以只返回最后一个时间步的输出,也可以返回序列tf.keras.layers.LSTM(units=hidden_size, return_sequences=True) 
])# 准备输入数据 (batch_size, seq_length, input_size)
dummy_input = tf.random.normal((5, 3, 10))# 前向传播
output = stacked_lstm_model(dummy_input)print("Output shape:", output.shape) # (5, 3, 20)

四、结合使用:双向堆叠RNN

在实际应用中,双向和堆叠这两种技术常常结合在一起,形成双向堆叠RNN(Stacked Bidirectional RNN)。这是一种非常强大和常见的架构,它既有深度(层次化特征提取),又有广度(完整的上下文信息)。

一个 LLL 层的双向堆叠RNN,实际上包含了 2×L2 \times L2×L 个独立的RNN通路。这种模型在注意力机制和Transformer流行之前,是许多NLP任务(如机器翻译、问答系统)的SOTA(State-of-the-art)模型的标准配置。

在框架中实现它也非常直接,只需同时设置bidirectional=Truenum_layers > 1(PyTorch),或者将Bidirectional包装器应用于一个堆叠的Keras模型。

五、总结

本文详细介绍了两种用于增强RNN能力的进阶结构。通过今天的学习,我们应掌握以下核心要点:

  1. 基础RNN的局限:标准RNN存在单向处理(无法看到未来信息)和浅层结构(表达能力有限)两大问题。
  2. 双向RNN (BiRNN):通过一个前向RNN和一个后向RNN并行处理序列,然后在每个时间步合并它们的状态,从而解决了单向处理的局限。它能让模型在决策时利用到完整的上下文信息,在PyTorch中通过 bidirectional=True 实现。
  3. 堆叠RNN (Stacked RNN):通过将多个RNN层垂直堆叠,让上一层的输出作为下一层的输入,解决了浅层结构的瓶颈。它能学习到更深层次、更抽象的时序特征,在PyTorch中通过 num_layers > 1 实现。
  4. 强强联合:双向与堆叠RNN可以结合使用,构成功能强大的双向堆叠RNN,这在许多复杂的序列建模任务中都是一个非常有效的基线模型。
  5. 框架实现:现代深度学习框架使得这些复杂结构的实现变得异常简单,我们只需调整几个关键参数即可。但要特别注意Keras中堆叠RNN的 return_sequences=True 参数设置。

http://www.dtcms.com/a/380552.html

相关文章:

  • 为Excel和WPS表格多个不连续单元格设置同样的批注
  • 【Vite】打包优化
  • 3 遥感与机器学习
  • 汽车功能安全 Functional Safety ISO 26262 测试之一
  • 第八章 惊喜08 减负
  • Redis 持久化详解:RDB 与 AOF 原理、配置及选型
  • MySQL 索引学习全景笔记
  • Ethernaut Foundry Solutions - 完整系列教程
  • 【ARDUINIO】从串口读取数据的方法总结
  • Redis环境搭建指南:Windows/Linux/Docker多场景安装与配置
  • 如何使用 Linux ping 命令 ?
  • 分布式专题——10.3 ShardingSphere实现原理以及内核解析
  • 神经网络稀疏化设计构架方法和原理深度解析
  • 10-SpringBoot入门案例(下)
  • ⽹络请求Axios的概念和作用
  • 缓存三大劫攻防战:穿透、击穿、雪崩的Java实战防御体系(三)
  • 认知语义学对人工智能自然语言处理的深层语义分析:理论启示与实践路径
  • 快速搭建B/S架构HTML演示页:从工具选择到实战落地
  • Git 简介
  • Java 中 Word 文档的加密与解密
  • SAM-Med3D:面向三维医疗体数据的通用分割模型 (代码仓库笔记)
  • 嵌入式桌面集成 · GNOME 与 Yocto 在 Jetson AGX Orin 上的实战指南
  • Model Context Protocol (MCP) 安全风险与攻击方式解析
  • 计算机毕业设计 基于大数据技术的医疗数据分析与研究 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
  • 单片机烧录原理是怎样的?辉芒微单片机烧录程序步骤教程如下
  • CI/CD流水线优化实战:从30分钟到5分钟的效能革命
  • 融智学:构建AI时代学术的新范式
  • 自指与递归既是威力也是边界(会带来不可判定与不完备)
  • HarmonyOS 实战:如何用数据压缩和解压让应用更快更省
  • 软考-系统架构设计师 信息安全的抗攻击技术详细讲解