Creating a Neural Network for Classification in Matlab - matlab

I am trying to do classification using neural network and I have written the following code. Is this the code required to perform the training and classification?
%n1 to s5(n1=147,n2=205,n3=166,n4=204,n5=167,b1=156,b2=172,b3=153,b4=151,b5=160,r1=133,r2=135,r3=190,r4=143,ru1=133,ru2=153,ru3=154,ru4=137,s1=132,165,130,136,148)
%code:
T = [n1,n2,n3,n4,n5,b1,b2,b3,b4,b5,r1,r2,r3,r4,r5,ru1,ru2,ru3,ru4,s1,s2,s3,s4,s5];
x = [0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 4 4 4 4 4];
net1 = newff(minmax(T),[30 20 1],{'logsig','logsig','purelin'},'trainrp');
net1.trainParam.show = 1000;
net1.trainParam.lr = 0.04;
net1.trainParam.epochs = 7000;
net1.trainParam.goal = 1e-5;
[net1] = train(net1,T,x);
save net1 net1
Additionally, if I have more samples with more features then how should I represent it in T and X? How do I write T and x? For example:
sample 1 ..... 123 0.56 78 127 .......0
sample 2 .......127 0.89 56 132 ........0
sample3...... 134 0.72 65 140...1
sample4 156 0.55 69 145 .....1
sample 5 112 0.10 12 120 .......2
sample 6 123 0.15 24 99 .......2
sample 7 95 0.32 98 198 ....3
sample 8 90 0.45 90 200...... 3

Yes your solution appears correct. I should note, newff is obsolete as of R2010b NNET 7.0 and it's last used in R2010a NNET 6.0.4. The recommended function is now is feedforwardnet. The feedforwardnet implementation should be as follows
net = feedforwardnet([30 20]);
net.layers{1:2}.transferFcn = 'logsig'
net.trainParam.show = 1000;
net.trainParam.lr = 0.04;
net.trainParam.epochs = 7000;
net.trainParam.goal = 1e-5;
[net1] = train(net1,T,x);
save net1 net1
I'm not quite sure what you're trying to do with minmax but that should be the basic structure of the feedforward NN.
To structure T and x, say you have the following data:
[123 0.56 78 127] belongs to class 1
[127 0.89 56 132] belongs to class 1
[134 0.72 65 140] belongs to class 2
[156 0.55 69 145] belongs to class 2
[112 0.10 12 120] belongs to class 3
[123 0.15 24 99] belongs to class 3
You can set T and x as follows:
T = [ 123 0.56 78 127; 127 0.89 56 132; 134 0.72 65 140; 156 0.55 69 145; 112 0.10 12 120; 123 0.15 24 99];
x = [1; 1; 2; 2; 3; 3];

Related

Polynomial Evaluation

I read a Matlab tutorial script and I'm not sure how the function polyvalm works.
The polynomial is as follow: p(X)=X^3 -2*X -5I (where I is the identity matrix)
polynomial coefficients of p(X)is [1 0 -2 -5]
X = [2 4 5; -1 0 3; 7 1 5];
Y = polyvalm(p,X)
My interpretation is X.^3 - 2*X -5*eye(3) but my result is totally different.
Sorry for the ugly typesetting but stack overflow doesn't offer Latex so can't help it
You are using element wise cube (X.^3) which is of course different from actually cubing a matrix. So for your p the polynomial is actually X^3 - 2*X - 5*eye(size(X)):
p = [1 0 -2 -5];
X = [2 4 5; -1 0 3; 7 1 5];
% anonymous function to illustrate
f = #(X,p) p(1)*X^3 + p(2)*X^2 + p(3)*X + p(4)*eye(size(X));
y_polyvalm = polyvalm(p,X)
y_fun = f(X,p)
This results in
y_polyvalm =
377 179 439
111 81 136
490 253 639
y_fun =
377 179 439
111 81 136
490 253 639

Find the difference between positive and negative peaks MATLAB

I need to find the difference between positive and negative peaks where the difference is greater than +-3.
I am using findpeaks function in MATLAB to find the positive and negative peaks of the data.
In an example of my code:
[Ypos, Yposloc] = findpeaks(YT0);
[Yneg, Ynegloc] = findpeaks(YT0*-1);
Yneg = Yneg*-1;
Yposloc and Ynegloc return the locations of the positive and negative peaks in the data.
I want to concatenate Ypos and Yneg based on the order of the peaks.
For example, my peaks are
Ypos = [11 6 -10 -10 6 6 6 6 6 -5]
Yneg = [-12 -14 -11 -11 -11 5 5 5 -6]
Locations in YT0
Yposloc = [24 63 79 84 93 95 97 100 156]
Ynegloc = [11 51 78 81 85 94 96 99 154]
In this case, where both Yposloc and Ynegloc are 9x1, I can do the following;
nColumns = size(Yposs,2);
YTT0 = [Yneg, Ypos]';
YTT0 = reshape(YTT0(:),nColumns,[])';
YTT0 = diff(YTT0)
YT0Change = numel(YTT0(YTT0(:)>=3 | YTT0(:)<=-3));
Total changes that I am interested is 6
However, I need to concatenate Yneg and Ypos automatically, based on their locations. So I think I need to to do an if statement to figure out if my positive or negative peaks come first? Then, I am not sure how to tackle the problem of when Ypos and Yneg are different sizes.
I am running this script multiple times where data changes and the negative/positive peak order are constantly changing. Is there a simple way I can compare the peak locations or am I on the right track here?
I would check each minimum with both the previous and the next maxima. In order to do that you can first combine positive and negative peaks according to their order:
Y = zeros(1, max([Yposloc, Ynegloc]));
Yloc = zeros(size(Y));
Yloc(Yposloc) = Yposloc;
Yloc(Ynegloc) = Ynegloc;
Y(Yposloc) = Ypos; % I think you inserted one extra '6' in your code!
Y(Ynegloc) = Yneg;
Y = Y(Yloc ~= 0) % this is the combined signal
Yloc = Yloc(Yloc ~= 0) % this is the combined locations
% Y =
%
% -12 11 -14 6 -11 -10 -11 -10 -11 6 5 6 5 6 5 6 -6 -5
%
% Yloc =
%
% 11 24 51 63 78 79 81 84 85 93 94 95 96 97 99 100 154 156
And then calculate the differences:
diff(Y)
% ans =
%
% 23 -25 20 -17 1 -1 1 -1 17 -1 1 -1 1 -1 1 -12 1
If you want changes of at least 6 units:
num = sum(abs(diff(Y)) > 6)
% num =
%
% 6
Ypos = [11 6 -10 -10 6 6 6 6 -5];
Yneg = [-12 -14 -11 -11 -11 5 5 5 -6];
Yposloc = [24 63 79 84 93 95 97 100 156];
Ynegloc = [11 51 78 81 85 94 96 99 154];
TOTAL=[Yposloc Ynegloc;Ypos Yneg];
%creatin a vector with positions in row 1 and values in row 2
[~,position]=sort(TOTAL(1,:));
%resort this matrix so the values are in the orginial order
TOTAL_sorted=TOTAL(:,position);
%look at the changes of the values
changes=diff(TOTAL_sorted(2,:));
if changes(1)>0
disp('First value was a Minimum')
else
disp('First value was a MAximum')
end
%same structure at the TOTAL matrix
%abs(changes)>3 produces a logical vector that shows where the absolute values was bigger
%than 3, in my opinon its rather intresting where the end is then were the start is
% thats why i add +1
Important_changes=TOTAL_sorted(:,find(abs(changes)>3)+1);
plot(TOTAL_sorted(1,:),TOTAL_sorted(2,:))
hold on
plot(Important_changes(1,:),Important_changes(2,:),...
'Marker','o','MarkerSize',10, 'LineStyle','none');
hold off

How to classify a matrix within a Matlab parfor loop?

I am looking to classify the values of a matrix. The following example works outside of a parfor loop, however it does not work when used within a parfor loop. What are my options to classify matrices, following the provided example, within a parfor loop?
% Sample data
Imag1 = [ 62 41 169 118 210;
133 158 96 149 110;
211 200 84 194 29;
209 16 15 146 28;
95 144 13 249 170];
% Perform the classification
Imag1(find(Imag1 <= 130)) = 4;
Imag1(find(Imag1 >= 150)) = 1;
Imag1(find(Imag1 > 140)) = 2;
Imag1(find(Imag1 > 130)) = 3;
Results in the following (outside parfor loop):
Imag1 =
62 41 169 118 210
133 158 96 149 110
211 200 84 194 29
209 16 15 146 28
95 144 13 249 170
Imag1 =
4 4 1 4 1
3 1 4 2 4
1 1 4 1 4
1 4 4 2 4
4 2 4 1 1
You can use another matrix to store the result.
Imag2 = zeros(size(Imag1));
% Perform the classification
Imag2(find(Imag1 <= 130)) = 4;
Imag2(find(Imag1 >= 150)) = 1;
Imag2(find(Imag1 > 140)) = 2;
Imag2(find(Imag1 > 130)) = 3;
so you can use a parfor loop somehow. Since parfor doesn't care about order of execution. Your code doesn't work in a parfor loop because right now you are modifying the values of Imag1, then comparing those values again, aka any loop iteration would be be dependent on the prior loop iterations
Here's another approach:
parfor c = 1:size(Imag1,2)
Imag2(:,c) = 4-min(ceil(max((Imag1(:,c) - 130),0)/10),3);
end
Now you can split it up however you like; by rows, by columns, by blocks, by alternate columns...
Edit:
Unfortunately this classifies a value of 150 as 2. So you probably shouldn't use this one.
Take 3
class = [150 141 131 0]; %// minimum values for class 1, 2, 3, 4
[m, n] = size(Imag1);
parfor c=1:n
for r=1:m
Imag3(r,c) = find(Imag1(r,c) >= class, 1);
end
end

Understanding 3D surface plot

As in this link, I have:
| 0.1 0.2 0.3 0.4
----------------------
1 | 10 11 12 13
2 | 11 12 13 14
3 | 12 13 14 15
4 | 13 14 15 16
Y = [0.1 0.2 0.3 0.4];
X = [1 2 3 4];
Z = [10 11 12 13; 11 12 13 14; 12 13 14 15; 13 14 15 16];
I plotted the surface Z using the command "surf(X,Y,Z)" in matlab. I got:
But really I don't understand the plotted surface. Can someone explain to me in details (in a text) what happens in this surface? For example: how can we observe the point (2,0.2,12)?
Include some labels and a colorbar and everything should be clear:
Y = [0.1 0.2 0.3 0.4];
X = [1 2 3 4];
Z = [10 11 12 13; 11 12 13 14; 12 13 14 15; 13 14 15 16];
surf(X,Y,Z)
colorbar
xlabel('X')
ylabel('Y')
zlabel('Z')
As suggested in the comments you can find your point on the surface by adding:
hold on;
plot3(2,0.2,12,'ro','MarkerSize',10,'MarkerFaceColor','r');
it then appears as a red dot.
Your table contains 16 points, these are plotted and the area inbetween, colored according to the applied colormap with the lowest z-value of the group of 4, which is according to the doc the surface height.
Actually it would be cleaner coding if you'd include the following line before the plot:
[X,Y] = meshgrid(X,Y);
this way all your input variables get the same dimensions:
X =
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
Y =
0.1 0.1 0.1 0.1
0.2 0.2 0.2 0.2
0.3 0.3 0.3 0.3
0.4 0.4 0.4 0.4
Z =
10 11 12 13
11 12 13 14
12 13 14 15
13 14 15 16
In case of surf the function does that for you, but other plotting functions are may not that tolerant.

strange result with JPEG compression

I want to implement the JPEG compression by using MATLAB. Well at the point where the symbols' probabilities (Huffman coding) are calculated i can see some NEGATIVE values. I am sure that this is not correct!!! if someone can give some help or directions i would really appreciate it. Thank all of you in advance. I use MATLAB R2012b. Here is the code:
clc;
clear all;
a = imread('test.png');
b = rgb2gray(a);
b = imresize(b, [256 256]);
b = double(b);
final = zeros(256, 256);
mask = [1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0];
qv1 = [ 16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99];
t = dctmtx(8);
DCT2D = #(block_struct) t*block_struct.data*t';
msk = #(block_struct) mask.*block_struct.data;
for row = 1:8:256
for column = 1:8:256
x = (b(row:row+7, column:column+7));
xf = blockproc(x, [8 8], DCT2D);
xf1 = blockproc(xf, [8 8], msk);
xf1 = round(xf1./qv1).*qv1;
final(row:row+7, column:column+7) = xf1;
end
end
[symbols,p] = hist(final,unique(final));
bar(p, symbols);
p = p/sum(p); %NEGATIVE VALUES????
I think you might have the outputs of hist (symbols and p) swapped. The probability should be calculated from the bin counts, which is the first output of hist.
[nelements,centers] = hist(data,xvalues) returns an additional row vector, centers, indicating the location of each bin center on the x-axis. To plot the histogram, you can use bar(centers,nelements).
In other words, instead of your current line,
[symbols,p] = hist(final,unique(final));
just use,
[p,symbols] = hist(final,unique(final));
Also, final is a matrix rather than a vector, so nelements will be a matrix:
If data is a matrix, then a histogram is created separately for each column. Each histogram plot is displayed on the same figure with a different color.