用 PyTorch 构建液态神经网络(LNN)
文章目录
什么是液态神经网络
2020年,麻省理工学院(MIT)的两名研究人员带领团队推出了一种基于现实生活中的自然智能、而非人工智能的新型神经网络。他们从微小的秀丽隐杆线虫(Caenorhabditis elegans)中汲取灵感,尽管这种微生物的神经系统只有302个神经元,但却能够产生复杂的行为。受此启发,研究团队创造了所谓的 “液态神经网络” (Liquid Neural Networks)。经过2022年的突破,这种新型网络已经足够灵活,足以在某些应用中取代传统的神经网络。
液态神经网络(LNN)是一种神经网络,它顺序处理数据并能够实时适应变化的数据,非常类似于人类大脑。
本质上,液态神经网络是一种时间连续的递归神经网络(RNN),它顺序处理数据,保留过去输入的记忆,根据新输入调节其行为,并能够处理可变长度的输入以增强神经网络的任务理解能力。强大的可适应性赋予了液态神经网络持续学习和适应的能力,并最终使其能够比传统神经网络更有效地处理时间序列数据。
一个连续时间神经网络是具有以下特点的神经网络 f f f:
d x d t = f ( n , k , l t y p e ) ( x ( t ) , I ( t ) , θ ) \frac{dx}{dt} = f(n,k,l_{type})(x(t),I(t),\theta) dtdx=f(n,k,ltype)(x(t),I(t),θ)
其中
- n n n: 层数
- k k k: 宽度
- l t y p e l_{type} ltype: 激活函数
- x ( t ) x(t) x(t): 隐藏状态
- I ( t ) I(t) I(t): 输入
- θ \theta θ: 模型参数
如果 f f f 参数化了隐藏状态的导数,我们可以从离散的计算图转变为连续的时间图。这使得我们能够实现液态神经网络(LNN)的以下两个特性:
- 由于液态状态,可能的函数空间大大增加。
- 可以计算任意时间帧使得 LNN 非常适合序列数据处理。
为什么需要液态神经网络
过去的35年里,我们构建的都是基于数据和学习参数( θ \theta θ)输出预测结果的概率模型。每个神经元都是一个逻辑回归门。将其与反向传播结合起来——一种基于模型损失重新训练参数权重的方法,就得到了神经网络。
然而,神经网络在现代世界中存在一些局限:
- 神经网络在单一任务上表现良好,但无法跨任务泛化知识,即具有固态性。
- 神经网络以非顺序方式处理数据,使其在处理实时数据时效率不高。
液态神经网络就是为了弥补传统神经网络的不足,它是一种在工作中学习的神经网络,不仅仅在训练阶段学习。液态神经网络提供了许多核心优势,包括:
- 实时决策能力;
- 快速响应各种数据分布;
- 具有韧性,并能过滤异常或噪声数据;
- 比黑箱机器学习算法具有更高的可解释性;
- 降低计算成本。
LNN 与 RNN 的区别
- 神经元状态架构:在液态状态机(LSM)中,递归连接是随机生成并固定的。输入信号被送入这个随机连接的网络,网络对这些输入的响应进一步用于分类或预测等任务。
- 训练:递归神经网络(RNN)通常通过时序反向传播(BPTT)进行训练,而液态神经网络(LNN)通常依赖于一种称为“蓄水池计算”的无监督学习形式。在这种方法中,递归连接(蓄水池)是随机生成并保持固定的。只有读出层,即将蓄水池的动态映射到所需输出的层,使用监督学习技术进行训练。这使得 LSM 的训练相比于 RNN 来说更为简单。
- 梯度消失问题:由于固定的递归连接,LNN 通常被认为对参数变化更为稳健。
- 应用:RNN 非常适合顺序建模,而 LNN 可以用来解决各种任务,包括语音识别、机器人控制和时间模式识别等。
用 PyTorch 实现 LNN
在 PyTorch 中训练液态神经网络(LNN)包括如下步骤:定义网络架构、实现常微分方程(ODE)求解器和优化网络参数。下面我们一步一步在 PyTorch 中实现一个 LNN :
Step 1. 导入必要的库
import torch
import torch.nn as nn
import torch.optim as opt
import numpy as np
Step 2. 定义网络架构
LNN 由一系列层组成,每一层对输入应用非线性变换。每层的输出都会通过一个 Leaky ReLU 激活函数,该函数有助于在网络中引入非线性。
class LiquidNeuralNetwork(nn.Module):
def __init__(self, input_size, hidden_size, num_layers):
super(LiquidNeuralNetwork,self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.layers = nn.ModuleList([self._create_layer(input_size,hidden_size) for _inrange(num_layers)])
def _create_layer(self, input_size, hidden_size):
return nn.Sequential(
nn.Linear(input_size, hidden_size),
nn.LeakyReLU(),
nn.Linear(hidden_size, hidden_size)
)
def forward(self,x):
for i, layer in enumerate(self.layers):
x = layer(x)
return x
Step 3. 实现 ODE 求解器
ODE 求解器负责根据输入数据更新网络的权重。我们可以使用 PyTorch 的自动微分系统(autograd)来实现 ODE 求解器。
class ODESolver(nn.Module):
def __init__(self, model, dt):
super(ODESolver, self).__init__()
self.model = model
self.dt = dt
def forward(self, x):
with torch.enable_grad():
outputs = []
for i, layer in enumerate(self.model):
outputs.append(layer(x))
x = outputs[-1]
return x
def loss(self, x, t):
with torch.enable_grad():
outputs =[]
for i,layer in enumerate(self.model):
outputs.append(layer(x))
x = outputs[-1]
return x
Step 4. 定义训练逻辑
训练逻辑根据输入数据和 ODE 求解器来更新网络的权重。
def train(model, dataset, optimizer, epochs, batch_size):
model.train()
total_loss = 0
for epoch in range(epochs):
for batch in dataset:
inputs,labels = batchoptimizer.zero_grad()
outputs = model(inputs)
loss = model.loss(inputs,outputs)
loss.backward()optimizer.step()
total_loss += loss.item()
print(f'Epoch {epoch+1}, Loss:{total_loss /len(dataset)}')
LNN 的缺陷
虽然液态神经网络非常有用,但它们也存在一些不足,包括:
- 在处理静态或固定数据时会遇到困难;
- 由于梯度爆炸或消失,训练难度增加;
- 由于梯度问题而在学习长期依赖性方面存在限制;
- 缺乏对液态神经网络功能进行广泛研究;
- 参数调整过程非常耗时;
这些问题需要通过进一步的研究和技术改进来解决,以便更好地利用液态神经网络的潜力。
总结
在人工智能领域,液态神经网络是最关键的新兴模型之一。
它与传统的深度学习神经网络并存,却更适合处理如自动驾驶汽车、温度或气候监测、股市评估等极其复杂的任务,而传统的深度学习神经网络则更擅长处理静态或一次性数据。
麻省理工学院的计算机科学与人工智能实验室(CSAIL)的研究人员一直在尝试将液态神经网络的能力扩展到更多的应用场景,但这需要时间。
液态神经网络和传统的深度学习神经网络在更广泛的人工智能领域中都有其确定的角色,二者配合使用其效果这绝对是 1+1>2。