复杂系统的数据驱动建模:储备池计算教程
导语
对天气、湍流和股票市场等混沌系统,即使初始条件下有微小的不确定性,也会导致误差指数增长,从而限制了对此类系统的任何预测。虽然当前技术倾向于使用噪声和部分的测量信息来约束物理模型,但控制这些系统的方程通常是未知的。因此,使用机器学习等数据驱动方法来预测此类系统非常重要。储备池计算(Reservoir Computing)是一种简化的循环神经网络结构,在预测复杂系统的动力学方面已经显示出优越的性能。本文以洛伦兹吸引子为例,简要介绍了储备池计算在训练、预测和优化方面所需的代码,并讨论了优化以找到正确参数的重要性。
研究领域:混沌系统,洛伦兹吸引子,储备池计算,循环神经网络
Jason Platt | 作者
刘志航 | 译者
梁金 | 审校
邓一雪 | 编辑
1. 洛伦兹“蝴蝶”吸引子
1. 洛伦兹“蝴蝶”吸引子
图1. 这里的几何对象被称为具有分形维数的“奇异吸引子”。 准确地说,吸引子的维数是 2.06。| 图片来自作者
图2. 由正李亚普诺夫指数引起的扰动增长。| 图片来源:Yapparina 制作
2. 储备池计算
2. 储备池计算
图3. 储备池计算中的信息流。输入u(t) 通过输入层将信号投射到高维储备池中,使我们能够用线性读出层来逼近非线性动力学。然后,读出层预测 u(t+1)。接着将 u(t+1) 反馈到输入层,得到我们的预测。| 图片由作者提供
3. 储备池计算的结构
3. 储备池计算的结构
表1:控制储备池整体性质的参数以及循环神经网络方程的更新
using Random
using SparseArrays
using Arpack
struct rc
“””Structure holding the reservoir computer
Args:
D::Int : Input system Dimension
N::Int : Reservoir Dimension
SR::Float : Spectral Radius
ρA::Float : Density of A
α::Float : Leak Rate
σ::Float : Input Strength
random_state::Int : Random seed
σb::Float : Bias
β::Float : Tikhonov regularization
“””
D::Int # Input System Dimension
N::Int # Reservoir Dimension
ρSR::Float64 # Spectral Radius of A
ρA::Float64 # Density of A
α::Float64 # Leak Rate
σ::Float64 # Input Strength
σb::Float64 # Input Bias
β::Float64 # Tikhonov Regularization
A::SparseMatrixCSC{Float64, Int64} # Adjacency Matrix
Win::Array{Float64,2} # Input Matrix
Wout::Array{Float64,2} # Output Matrix
rng::MersenneTwister # Random Number Generator
# Constructor Function
function rc(D, N, ρSR , ρA, α, σ, σb, β; random_state=111111)
rng = MersenneTwister(random_state)
A, Win, Wout = initialize_weights(D, N, ρSR, ρA, σ, rng)
new(D, N, ρSR , ρA, α, σ, σb, β, A, Win, Wout, rng)
end
end
function initialize_weights(D, N, SR, ρA, σ, rng)
A = get_connection_matrix(N, ρA, ρSR, rng)
Win = rand(rng, Uniform(-σ, σ), N, D)
Wout = Array{Float64}(undef, (D, N))
return A, Win, Wout
end
function get_connection_matrix(N, ρA, ρSR, rng)
# Define that numbers selected between [-1, 1]
rf(rng, N) = rand(rng, Uniform(-1.0, 1.0), N)
# NxN sparse random matrix
A = sprand(rng, N, N, ρA, rf)
# calculate eigenvalues and rescale
eig, _ = eigs(A, nev=1)
maxeig = abs(eig[1])
A = A.*(ρSR/maxeig)
return A
end
注:储备池计算采用表1中所示的参数。我们看到邻接矩阵A被实现为稀疏矩阵,因为已经证明,连接度非常低的储备池实际上预测效果最好(ρA~0.02)。此外,稀疏矩阵的矢量乘法也非常高效。然后,A 被其最大特征值重新标度。Win 在 [-σ, σ] 之间随机产生。Wout 的内存在初始化中被分配,但储备池计算还没有被训练。
4. 训练储备池计算
4. 训练储备池计算
function train_RC(rc::rc, u; spinup = 100, readout = false)
“””Train the rc
This function sets the matrix rc.Wout
u ∈ D×T
r ∈ N×T
Args:
rc : reservoir struct
u : Array of data of shape D×Time
spinup : Amount of data to use for spinup
Returns:
if readout=true: Wout*r, the readout of the rc training data
else: return the last state of r, can be used to predict
forward from the training data
“””
r = generate(rc, u)
compute_Wout(rc, r[:, 1+spinup:end], u[:, 1+spinup:end])
if readout == true return rc.Wout*r end
return r[:, end]
end
function driven_rc!(rtp1, rc::rc, rt, ut)
“””Drive the rc with data
Args:
rtp1 : r(t+1)
rc : reservoir computer
rt : r(t)
ut : u(t)
“””
rtp1[:] .= rc.α.*tanh.(rc.A*rt .+ rc.Win*ut .+ rc.σb).+(1 .- rc.α).*rt
end
function generate(rc::rc, u)
T = size(u)[2]
r = Array{Float64}(undef, (rc.N, T))
r[:, 1] = zeros(rc.N)
for t in 2:T
driven_esn!(r[:, t], rc, r[:, t-1], u[:, t-1])
end
return r
end
function compute_Wout(rc::rc, r, u)
rc.Wout[:, :] .= (Symmetric(r*r’+esn.β*I)(r*u’))’
end
注:训练储备池计算需要输入一个数据序列 u(t)。我们生成对应于输入u(t)的隐藏状态r(t),从那里可以计算出输出矩阵。
5. 预测
5. 预测
function forecast_RC(rc::rc, nsteps; uspin=nothing, r0 = nothing)
“””Forecast nsteps forward in time from the end of uspin or from rc state r0
Make sure to train the RC before forecasting. Requires either uspin or r0.
If both are provided will use uspin to set r0.
“””
if !isnothing(uspin)
rspin = generate(rc, uspin)
r0 = rspin[:, end]
end
@assert !isnothing(r0)
# Initialize array of hidden states and set r(0)=r0
rfc = Array{Float64}(undef, (rc.N, nsteps))
rfc[:, 1] = r0
# Now iterate the autonomous RC nsteps times for the forecast
for t in 1:nsteps-1
auto_esn!(rfc[:, t+1], rc, rfc[:, t])
end
return esn.Wout*rfc
end
function auto_rc!(rtp1, rc::rc, rt)
“””Autonomous RC update rule”””
rtp1[:] .= rc.α.*tanh.(rc.A*rt .+ rc.Win*rc.Wout*rt .+ rc.σb).+(1 .- rc.α).*rt
end
注:预测可以从一小片数据 uspin 或一个储备池状态 r(0) 开始。然后函数会预测 n 步之后的状态。
6. 洛伦兹吸引子示例
6. 洛伦兹吸引子示例
using BasicReservoirComputing
using Plots
function L63_ex()
# make the training and testing data (not defined here)
utrain, utest = make_lor63(train_time = 100, test_time = 20, n_test = 100)
#define the RC
D=3; N=200; σ=0.084; α=0.6; SR=0.8; ρA=0.02; β=8.5e-8; σb=1.6; Δt=0.01
reservoir = rc(D, N, ρA, Δt, SR, α, σ, σb, β))
# Training
nspin = 100
train_RC(reservoir, utrain, spinup=nspin)
# Forecast and compare to truth
utrue = utest[:, nspin:end]
nsteps = size(utrue)[2]
upred = forecast_RC(rc, nsteps, uspin = utest[:, 1:nspin])
# now plot results (not defined here)
t = collect(0:nsteps-1)*Δt
p = plot_prediction(t, upred, utrue)
display(p)
end
L63_ex()
图4. 从t=0开始对X、Y和Z进行预测。注意良好的短期预测以及长期统计的再现。图片由作者提供。
7. 测试储备池计算
7. 测试储备池计算
图5. 测试储备池计算的初始条件。这些预测的有效预测时间(VPT)显示在下面的直方图中。从吸引子的中心开始预测未来的行为要比从叶片开始预测难得多。图片由作者提供。
图6. 直方图显示上述100个初始条件下的预测时间分布。图片由作者提供。
8. 如何找到正确的参数
8. 如何找到正确的参数
图7. 预测对储备池计算参数变化的敏感度。红色表示平均VPT高的区域,蓝色表示VPT低的区域。在整个参数空间中进行搜索是一个不简单的问题。图片由作者提供。
我将采用一个三步优化方法。该程序是
1、固定参数
2、通过线性回归训练Wout
function Loss(data, spinup_steps, rc::esn)
“””Loss function for an individual forecast”””
uspin = data[:, 1:spinup_steps]
utrue = data[:, spinup_steps:end]
Ttrue = size(utrue)[2]
upred = forecast_RC(rc, Ttrue; uspin=uspin)
err = upred.-utrue
weight = exp.(-(1:Ttrue)./Ttrue)
return norm(err.*weight’)
end
function obj(θ)
“””The objective function to minimize over the optimization
Args:
θ : Array of parameters
Returns:
objective value
“””
SR, α, logσ, σb, logβ = θ
D, _ = size(f.train_data)
# build the RC
rc = esn(D, f.N, SR, f.ρA, α, exp(logσ), σb, exp(logβ))
# Train the RC
train_RC(rc, f.train_data)
# Compute loss over n_valid forecasts
n_valid = length(f.valid_data_list)
loss = zeros(n_valid)
for i in 1:n_valid
loss[i] = Loss(f.valid_data_list[i], f.spinup_steps, rc)
end
# Objective is sum of loss functions
return sum(loss)
end
9. 总结
9. 总结
本文翻译自:Towards Data Science 原文题目: Data Driven Modeling of Complex Systems: A Reservoir Computing Tutorial 原文链接: https://towardsdatascience.com/data-driven-modeling-of-complex-systems-8a96dc92abf9
复杂科学最新论文
集智斑图顶刊论文速递栏目上线以来,持续收录来自Nature、Science等顶刊的最新论文,追踪复杂系统、网络科学、计算社会科学等领域的前沿进展。现在正式推出订阅功能,每周通过微信服务号「集智斑图」推送论文信息。扫描下方二维码即可一键订阅:
推荐阅读
-
什么是吸引子:从数学定义到动力学方程迭代 | 集智百科 -
混沌数学理论从她笔下悄悄流出丨陈关荣 -
离散混沌传奇丨陈关荣 -
蝴蝶效应和混沌故事 | 陈关荣 -
《张江·复杂科学前沿27讲》完整上线! -
成为集智VIP,解锁全站课程/读书会 -
加入集智,一起复杂!
点击“阅读原文”,追踪复杂科学顶刊论文