一、離散型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網絡在優化旅行商問題上的應用。