确定性跳跃循环状态网络(CRJ)教程

确定性跳跃循环状态网络(CRJ)教程

本篇文章是上一篇文章回声状态网络(ESN)的延申,在阅读本文之前,希望您已经阅读了上一篇博文。

确定性跳跃循环状态网络(CRJ)是ESN的一个变种,如下图所示:

确定性跳跃循环状态网络

在CRJ中,中间节点通过单向的循环边和双向的跳跃边连接,所有的输入权重、循环权重、跳跃权重分别共享值 r i r c r j 。特别地,输入权重的符号由某个无理数的小数展开 d 0 . d 1 d 2 d 3 . . . 决定,如果 0 d n 4 ,则第n个输入连接的符号为-(负);反之,如果 0 d n 4 ,则第n个输入连接的符号为+(正)。给定N = 500, r i = 0.5 r c = 0.8 r j = 0.7 ,跳跃步长l = 10,输入连接的符号见文件signv.mat中变量y。

例如,假设中间节点的个数为 R n o ,输入节点的个数为 V n o ,则输入连接的符号为 y ( 1 : R n o ; 1 : V n o + 1 ) ,这里 V n o + 1 是因为一般会在输入序列上加入一维全为1的数值作为偏差(这点参考上一节的代码实现,其实就是神经网络中的b值啦)。

其中要用到的signv.mat,上一节提到的MackeyGlass-t17.txt文件,我会在本文最后给出下载的连接。

OK,现在我们来考虑如何实现CRJ。相比于上次实现的ESN,实际上不同之处只有两处:

  • 输入的权值Win不同(见上次的代码第24行),原来是随机产生的,此时我们固定了Win,即 r i ,且其符号由signv.mat中的变量y决定;
  • 储备池的权重W不同(见上次的代码第25行),原来的值和连接状态是随机的,现在我们使用 r c r j 来确定权重W。

对于Win的确定很简单,我们首先加载符号文件signv.mat(其中值为+1和-1,分别表示正和负),生成符号矩阵;然后生成一个全0的矩阵,size与我们实现ESN时相同,然后将该0矩阵加上0.5( r j = 0.5 ),最后点乘符号矩阵即可,代码如下:

% 第一步:load符号
load('signv.mat')
% 第二步:生成符号矩阵
signal = y(1:500,1:2) %500表示中间节点个数,2表示输入节点个数加上1个偏置
% 第三步:生成0.5的矩阵,并点乘符号矩阵
Win = (zeros(500,2)+0.5) .* signal;

相对比较麻烦的是中间的权重W的生成。首先,先不考虑跳跃边的连接,我们如何用矩阵来表示这个环形的结构呢?看下面一个简单的例子。

这里写图片描述

对于图(a)所示的四个节点的循环网络,可以用右侧图(b)的矩阵来表示,设该矩阵为W,其中1表示存在连接,0表示不存在连接,则 W 12 = 1 , W 23 = 1 , W 34 = 1 , W 41 = 1 分别表示节点1连接节点2,节点2连接节点3,节点3连接节点4,节点4连接节点1;这里要注意是单方向的,比如矩阵中有 W 21 = 0

扫描二维码关注公众号,回复: 2788358 查看本文章

图(b)中的0和1仅表示是否存在连接,如果要加上权重的信息,如图(c)所示,权重都为0.8,则矩阵可以写为图(d)的形式。

从而对于有N个中间节点且权重为0.8的循环状态网络,可以用矩阵表示为:

这里写图片描述

OK,现在我们在实现一下这个环形的结构,实际上我们只需要先生成一个单位矩阵,乘以权值,然后做一下简单的变换就OK了。

%使用eye生成一个单位矩阵,乘以权值
W = eye(resSize) * 0.8;
%进行变换操作,得到环形结构的矩阵表示
W = circshift(W,[1,2]);

最后考虑跳跃连接,令其从第一个节点开始,每隔步长l=10连接另一个节点,注意这里的连接是双向的,实际上即: W 1 , 11 = W 11 , 1 = 0.7 , W 11 , 21 = W 21 , 11 = 0.7 . . . , W 491 , 1 = W 1 , 491 = 0.7 。我们只需要一个for循环,按照步长l=10,通过赋值操作就可以实现了,但是要注意一点,最后一个连接 W 491 , 1 = W 1 , 491 = 0.7 ,我们使用一个取模运算来保证这一点。

step = 10;
for i=1:step:resSize
    id = mod(i+step, resSize);
    W(i,id) = 0.7;
    W(id,i) = 0.7;
end

完整代码如下:

% A minimalistic Echo State Networks demo with Mackey-Glass (delay 17) data 
% in "plain" Matlab.
% by Mantas Lukosevicius 2012
% http://minds.jacobs-university.de/mantas

% load the data
trainLen = 3000;
testLen = 1000;
initLen = 100;

data = load('MackeyGlass-t17.txt');
load('signv.mat');

% plot some of it
% figure(10);
% plot(data(1:1000));
% title('A sample of data');

% generate the ESN reservoir
inSize = 1; outSize = 1;
resSize = 500;
a = 0.3; % leaking rate

signal = y(1:500,1:2); %signal of W_in
%rand( 'seed', 42 );
Win = (zeros(resSize,1+inSize)+0.5) .* signal; %r=0.5
W = eye(resSize) * 0.8;
W = circshift(W,[1,2]); % generate circle

step = 10;
for i=1:step:resSize
    id = mod(i+step, resSize);
    W(i,id) = 0.7;
    W(id,i) = 0.7;
end

% Option 1 - direct scaling (quick&dirty, reservoir-specific):
% W = W .* 0.13;
% Option 2 - normalizing and setting spectral radius (correct, slower):
disp 'Computing spectral radius...';
opt.disp = 0;
rhoW = abs(eigs(W,1,'LM',opt));
disp 'done.'
W = W .* ( 1.25 /rhoW);

% allocated memory for the design (collected states) matrix
X = zeros(1+inSize+resSize,trainLen-initLen);
% set the corresponding target matrix directly
Yt = data(initLen+2:trainLen+1)';

% run the reservoir with the data and collect X
x = zeros(resSize,1);
for t = 1:trainLen
    u = data(t);
    x = (1-a)*x + a*tanh( Win*[1;u] + W*x );
    if t > initLen
        X(:,t-initLen) = [1;u;x];
    end
end

% train the output
reg = 1e-8;  % regularization coefficient
X_T = X';
% Wout = Yt*X_T * inv(X*X_T + reg*eye(1+inSize+resSize));
Wout = Yt*X_T / (X*X_T + reg*eye(1+inSize+resSize));
% Wout = Yt*pinv(X);

% run the trained ESN in a generative mode. no need to initialize here, 
% because x is initialized with training data and we continue from there.
Y = zeros(outSize,testLen);
u = data(trainLen+1);
for t = 1:testLen 
    x = (1-a)*x + a*tanh( Win*[1;u] + W*x );
    y = Wout*[1;u;x];
    Y(:,t) = y;
    % generative mode:
    u = y;
    % this would be a predictive mode:
    u = data(trainLen+t+1);
end

errorLen = 1000;
mse = sum((data(trainLen+2:trainLen+errorLen+1)'-Y(1,1:errorLen)).^2)./errorLen;
disp( ['MSE = ', num2str( mse )] );

% plot some signals
figure(1);
plot( data(trainLen+2:trainLen+testLen+1), 'color', [0,0.75,0] );
hold on;
plot( Y', 'b' );
hold off;
axis tight;
title('Target and generated signals y(n) starting at n=0');
legend('Target signal', 'Free-running predicted signal');

figure(2);
plot( X(1:20,1:200)' );
title('Some reservoir activations x(n)');

figure(3);
bar( Wout' )
title('Output weights W^{out}');

最后给出代码中要用到的文件:
- signv.mat
- MackeyGlass-t17.txt
- ESN和CRJ源码

请点击这里下载

备注:如果要使用上述代码,请仔细检查,编程小菜鸟。。。

猜你喜欢

转载自blog.csdn.net/cassiePython/article/details/80701662
今日推荐