离散型Hopfield神经网络在联想和识别上的应用

一、离散型Hopfield处理数字图片,并比较外积法直接求得的网络和通过自带工具箱newhop函数创建的网络有何不同

程序如下:

clear

clc

load data1 array_one

load data2 array_two

%这里加载的两个数组都是10X10的数组,里面的值为-1和+1两种情况。据目前对离散型Hopfield的使用,数据都是-1或者+1,因为这个要求和设定激励函数为取符号函数还有能量函数有很大关系。

%这两个数组将会在后面的结果里面显示出来,+1的地方会表示为白色,-1的地方表示为黑色。

T=[array_one;array_two]';%这个地方将两个图片堆叠起来,并进行了转置。至于数据为什么要进行转置上不太清楚。现在T是一个10X20的数组

net=newhop(T);%通过自带的newhop函数创建一个Hopfield网络。

%接下来应该检查T中两组数据是否是在稳定点上,也就是将T中的数据输入到net中,观察输出的数据,是否和T一样,如果一样,就说明两组数据是在稳定点。

[Y,Pf,Af]=sim(net,{10,5},{},T(:,1:10));

%然后观察Y中一共有5个元包,每个元包是一个10X10的数组,就是把T中的第一个数据T(:,1:10)输入net中,经过5步的变化,每一步的结果都放在了对应的元包当中,观察每个元宝中的数组,和T对照会发现完全相同,因为数字1的对称性非常好。

%下面是原始数据和输出结果Y中每个元包中数据的比照

imshow(imresize(T(:,1:10)',20));


imshow(imresize(Y{1}',20));

imshow(imresize(Y{2}',20));

imshow(imresize(Y{3}',20));

imshow(imresize(Y{4}',20));

imshow(imresize(Y{5}',20));


会发现这些图片都一样,说明第一个数据也就是表示1的图片数据是稳定的。

下面看第二组数据的稳定性,观察输出结果和输入结果是否相同:

[Y,Pf,Af]=sim(net,{10,5},{},T(:,11:20));

为了方便,不在显示T中表示2数字的图片,也不再显示5个步骤中没步骤的结果只显示最后一步的结果

imshow(imresize(Y{5}',20));


%然后我们可以看到结果发现输入和输出完全相同,说明目标数据(T中的两组数据是稳定的),然后处理带有噪声的数据。看看net能否联想到目标数据。

noisy_array_one=array_one;
for i = 1:100
    a = rand;
    if a < 0.2
       noisy_array_one(i) = -array_one(i);
    end
end


noisy_array_two=array_two;
for i = 1:100
    a = rand;
    if a < 0.2
       noisy_array_two(i) = -array_two(i);
    end
end

% 在上面的程序中,噪声的比率为20%

%然后比照目标图片,噪声图片,和处理过的噪声图片

noisy_one = {(noisy_array_one)'};
identify_one = sim(net,{10,10},{},noisy_one);%这里面{10,10}中的第二个10代表的是步骤,和前面的5是一个意思
identify_one{10}';
noisy_two = {(noisy_array_two)'};
identify_two = sim(net,{10,10},{},noisy_two);%这里面{10,10}中的第二个10代表的是步骤,和前面的5是一个意思
identify_two{10}';


%% ????????
Array_one = imresize(array_one,20);
subplot(3,2,1)
imshow(Array_one)
title('????(????1)') 
Array_two = imresize(array_two,20);
subplot(3,2,2)
imshow(Array_two)
title('????(????2)') 
subplot(3,2,3)
Noisy_array_one = imresize(noisy_array_one,20);
imshow(Noisy_array_one)
title('????(????1)') 
subplot(3,2,4)
Noisy_array_two = imresize(noisy_array_two,20);
imshow(Noisy_array_two)
title('????(????2)')
subplot(3,2,5)
imshow(imresize(identify_one{10}',20))
title('????(????1)')
subplot(3,2,6)
imshow(imresize(identify_two{10}',20))
title('????(????2)')

结果如下:


因为我们不太清楚运行10步,是否达到了稳定点。所以我们在运行20步试试,如果结果相同,说明在10步的时候就已经达到了稳定点。

 noisy_one = {(noisy_array_one)'};
identify_one = sim(net,{10,20},{},noisy_one);
identify_one{10}';
noisy_two = {(noisy_array_two)'};
identify_two = sim(net,{10,20},{},noisy_two);
identify_two{10}';
Array_one = imresize(array_one,20);
subplot(3,2,1)
imshow(Array_one)
title('????(????1)') 
Array_two = imresize(array_two,20);
subplot(3,2,2)
imshow(Array_two)
title('????(????2)') 
subplot(3,2,3)
Noisy_array_one = imresize(noisy_array_one,20);
imshow(Noisy_array_one)
title('????(????1)') 
subplot(3,2,4)
Noisy_array_two = imresize(noisy_array_two,20);
imshow(Noisy_array_two)
title('????(????2)')
subplot(3,2,5)
imshow(imresize(identify_one{20}',20))
title('????(????1)')
subplot(3,2,6)
imshow(imresize(identify_two{20}',20))
title('????(????2)')

结果如下:


观察发现结果和上一个结果一样,所以网络10步的时候已经到达了稳定点,输出结果为第三行图片。我们通过让网络观察第一行的两个图片,然后对网络输入有噪声的第二行的图片,网络通过联想出了第三行的图片。

这是通过自带的程序newhop函数创建的网络。还有一种简单的方法,通过外积法用目标数据来求取权值的。下面介绍这种方法,并比照结果

接着上面的程序

T = array_two; 


%% ????????????????????
[m,n] = size(T);
w = zeros(m);
for i = 1:n
    w = w + T(:,i) * T(:,i)' - eye(m);
end

noisy_array=noisy_array_two;

v0 = noisy_array;
v = zeros(m,n);
for k = 1:10
    for i = 1:m
        v(i,:) = sign(w(i,:)*v0);
    end
    v0 = v;
end


%% ????
subplot(3,1,1)
t = imresize(T,20);
imshow(t)
title('????')
subplot(3,1,2)
Noisy_array = imresize(noisy_array,20);
imshow(Noisy_array)
title('????')
subplot(3,1,3)
V = imresize(v,20);
imshow(V)
title('????')

结果如下:


通过观察发现,外积法的网络只观察了一组目标数据,按照道理来说联想的结果应该联想的更好一些。但是效果并不怎么理想。还没有用newhop函数创建的网络效果好,newhop函数是封装好的,里面具体实现的机制也不是很清楚,不过可以肯定使用的方法肯定比简单的外积法求取权值高大上的多,外积法求取权值,连阀值都没有(也就是默认为零)

二、一个简单的对二维座标进行联想的程序

T = [+1 -1; ...
      -1 +1];


%%
% Here is a plot where the stable points are shown at the corners.  All possible
% states of the 2-neuron Hopfield network are contained within the plots
% boundaries.


plot(T(1,:),T(2,:),'r*')
axis([-1.1 1.1 -1.1 1.1])
title('Hopfield Network State Space')
xlabel('a(1)');
ylabel('a(2)');


上图中为目标数据中的两个点,也就是让网络观察的两个点。之后网络会对输入数据向这两个数据联想

net = newhop(T);


%%
% First we check that the target vectors are indeed stable.  We check this by
% giving the target vectors to the Hopfield network.  It should return the two
% targets unchanged, and indeed it does.


[Y,Pf,Af] = net([],[],T);%这一部分就是对目标数据进行验证,看目标数据是否稳定。其实对于这么简单的数据都一样,在这里我就不再显示Y了和T一模一样



a = {rands(2,1)};%这里随机了一个座标点
[y,Pf,Af] = net({20},{},a);%将a输入网络,并运行20步

record = [cell2mat(a) cell2mat(y)];
start = cell2mat(a);
hold on
plot(start(1,1),start(2,1),'bx',record(1,:),record(2,:))%画出点a在逐步往目标数据联想的过程


color = 'rgbmy';
for i=1:25
   a = {rands(2,1)};
   [y,Pf,Af] = net({20},{},a);
   record=[cell2mat(a) cell2mat(y)];
   start=cell2mat(a);
   plot(start(1,1),start(2,1),'kx',record(1,:),record(2,:),color(rem(i,5)+1))
end

上面的这段程序就是随机找到25个点,并观察这25个点每一步是如何靠近(联想)目标数据的。



三、总结

        虽然第一个程序处理的是二维图片,但是中间逐步变化的过程没有表现出来,其实在我实验的时候,我曾把每一步的结果都画了出来,也就是从原来带有噪声的输入如何逐步向目标的两组数据靠近的,不过碍于篇幅,并没有像第二个程序那么把中间的过程完全显示出来。但是相对来说第一个程序显然是更复杂一点的。因为第一个程序处理的是二维的图像,每组数据有100个数值。第二个程序处理的就相对来说简单了好多。但是遗憾的是一直弄不明白newhop函数是如何求取权值和阀值的。这其实才是问题的真正求解过程。在前一篇博客上描述到求取权值和阀值有多中方法,但是始终不理解newhop具体使用的是哪一种。但是可以看到效果还是非常明显的,非常好的,比简单的外积法求取权值要好的多。唯一美中不足的地方应该就是newhop函数的细节没有弄明白了。

       其实准确的来说,离散型的Hopfield网络并没有识别的能力,不像是SVM和一些其他的神经网络一样,可以做模式识别。它的作用只是联想而已,其实这样的联想可以用在模式识别前的降噪处理。用处还是非常大的。

下篇博客会介绍连续型hopfleld网络在优化旅行商问题上的应用。

发布了24 篇原创文章 · 获赞 20 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章