I have input matrix as:
input =
1 0 0 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
0 0 1 0 0
0 1 1 1 0
0 1 1 1 0
and
T = [eye(10) eye(10) eye(10) eye(10)];
The neural network that I created is:
net = newff(input,T,[35], {'logsig'})
%net.performFcn = 'sse';
net.divideParam.trainRatio = 1; % training set [%]
net.divideParam.valRatio = 0; % validation set [%]
net.divideParam.testRatio = 0; % test set [%]
net.trainParam.goal = 0.001;
It works fine till now, but when i use train function the problem arises
[net tr] = train(net,input,T);
and the following error show up in matlab window:
??? Error using ==> network.train at 145
Targets are incorrectly sized for network.
Matrix must have 5 columns.
Error in ==> test at 103
[net tr] = train(net,input,T);
I've also tried the input' and T' as well. Any help is appreciated in advance
If you look at MATLAB's official documentaion of train, you'll notice that T must have the same amount of columns as the input matrix, which is 5 in your case. Instead, try:
T = ones(size(input, 1));
or
T = [1, size(input, 1) - 1];
and see if this works.
Related
I have a 2D matrix composed of ones and zeros.
mat = [0 0 0 0 1 1 1 0 0
1 1 1 1 1 0 0 1 0
0 0 1 0 1 1 0 0 1];
I need to find all consecutive repetitions of ones in each row and replace all ones with zeros only when the sequence size is smaller than 5 (5 consecutive ones):
mat = [0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0];
Any suggestion on how to approach this problem would be very welcome.
You can use diff to find the start and end points of the runs of 1, and some logic based on that to zero out the runs which are too short. Please see the below code with associated comments
% Input matrix of 0s and 1s
mat = [0 0 0 0 1 1 1 0 0
1 1 1 1 1 0 0 1 0
0 0 1 0 1 1 0 0 1];
% Minimum run length of 1s to keep
N = 5;
% Get the start and end points of the runs of 1. Add in values from the
% original matrix to ensure that start and end points are always paired
d = [mat(:,1),diff(mat,1,2),-mat(:,end)];
% Find those start and end points. Use the transpose during the find to
% flip rows/cols and search row-wise relative to input matrix.
[cs,r] = find(d.'>0.5); % Start points
[ce,~] = find(d.'<-0.5); % End points
c = [cs, ce]; % Column number array for start/end
idx = diff(c,1,2) < N; % From column number, check run length vs N
% Loop over the runs which didn't satisfy the threshold and zero them
for ii = find(idx.')
mat(r(ii),c(ii,1):c(ii,2)-1) = 0;
end
If you want to throw legibility out of the window, this can be condensed for a slightly faster and denser version, based on the exact same logic:
[c,r] = find([mat(:,1),diff(mat,1,2),-mat(:,end)].'); % find run start/end points
for ii = 1:2:numel(c) % Loop over runs
if c(ii+1)-c(ii) < N % Check if run exceeds threshold length
mat(r(ii),c(ii):c(ii+1)-1) = 0; % Zero the run if not
end
end
The vectorized solution by #Wolfie is nice and concise, but a bit hard to understand and far from the wording of the problem. Here is a direct translation of the problem using loops. It has the advantage of being easier to understand and is slightly faster with less memory allocations, which means it will work for huge inputs.
[m,n] = size(mat);
for i = 1:m
j = 1;
while j <= n
seqSum = 1;
if mat(i,j) == 1
for k = j+1:n
if mat(i,k) == 1
seqSum = seqSum + 1;
else
break
end
end
if seqSum < 5
mat(i,j:j+seqSum-1) = 0;
end
end
j = j + seqSum;
end
end
I try to build a basic feedforward system using patternnet command that can recognise the data from MNIST dataset. Here is my code
one = [1];
one = repelem(one,100);
%%%%%%%%%%%%%%%Create Neural network%%%%%%%%%%%%%%%%%%%%%
nn = patternnet([100 100]);
nn.numInputs = 1;
nn.inputs{1}.size = 784;
nn.layers{1}.transferFcn = 'logsig';
nn.layers{2}.transferFcn = 'logsig';
nn.layers{3}.transferFcn = 'softmax';
nn.trainFcn = 'trainscg';
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
%%%%%%%%%%%%%%%%Dealing with data%%%%%%%%%%%%%%%%%%%%%%%%%%
mnist_in = csvread('mnist_train_100.csv');
mnist_test_in = csvread('mnist_test_10.csv');
[i,j] = size(mnist_in);
data_in = mnist_in(:,2:785);
data_in = data_in';
target_in = mnist_in(:,1);
target_in = target_in';
nn = train(nn,data_in,target_in);
The problem is when I build this system the transfer function in output layer is set to softmax function. Somehow when I train my system the transfer function turn into 'logsig' function and it stay that way until I clear my workspace. I even try to set the transfer function of output layer in the code and program still find a way to change it to logsig. So is there anything I can do.
PS. I even try building this system using network() to make everything from scrath the program still change my tranfer function back from softmax to logsig.
As I see, there is a mistake in the divideParam parameter. You created the neural network as nn but the parameters that you changed is belong to a variable called net. Other than that, the creating neural network part is normal.
I think the problem lies in the data preparation part.
Your training target, the target_in, has the dimension of 1 x < Number of sample>. Because of that, the train function replace 'softmax' with 'logsig' to fit with the output.
The output data for softmax should be in the form of < Number of result> x < Number of sample>
For example, the output is either 1,2 or 3. Then the output array shouldn't be
[1 2 1 3 3 1 ...]
but it should be
[1 0 1 0 0 1 ...;
0 1 0 0 0 0 ...;
0 0 0 1 1 0 ...]
Hope this helps.
EDIT: To turn the single array (1 x < Number of sample>) to the multiple array (< Number of result> x < Number of sample>), the data in the single array will be map with index. For example, 11 sample in a single array:
[-1 -5.5 4 0 3.3 4 -1 0 0 0 -1]
Checking all the unique number and sort it. Now every number has its index.
[-5.5 -1 0 3.3 4] #index table
Going through the single array, for each number, place it in the right index. Basically, -1 will have index 2 so I will tick 1 in the second row at any column that -1 appear. Finally,
[ 0 1 0 0 0 0 0 0 0 0 0;
1 0 0 0 0 0 1 0 0 0 1; #there are three -1 in the single array
0 0 0 1 0 0 0 1 1 1 0;
0 0 0 0 1 0 0 0 0 0 0;
0 0 1 0 0 1 0 0 0 0 0]
Here is the code for it:
idx = sort(unique(target_in));
number_of_result = size(idx,2);
number_of_sample = size(target_in,2);
target_softmax = zeros(number_of_result,number_of_sample);
for i = 1:number_of_sample
place = find(idx == target_in(i)); % find the index of the value
target_softmax(place,i) = 1; % tick 1 at the row
end
i am in the process of learning neural networks using MATLAB, i'm trying implement a face recognition program using PCA for feature extraction, and a feedforward neural network for classification.
i have 3 people in my training set, the images are stored in 'data' directory.
i am using one network for each individual, and i train each network with all the images of my training set, the code for my project is presented below:
dirs = dir('data');
size = numel(dirs);
eigenVecs = [];
% a neural network for each individual
net1 = feedforwardnet(10);
net2 = feedforwardnet(10);
net3 = feedforwardnet(10);
% extract eigen vectors and prepare the input of the NN
for i= 3:size
eigenVecs{i-2} = eigenFaces(dirs(i).name);
end
trainSet= cell2mat(eigenVecs'); % 27X1024 double
% set the target for each NN, and then train it.
T = [1 1 1 1 1 1 1 1 1 ...
0 0 0 0 0 0 0 0 0 ...
0 0 0 0 0 0 0 0 0];
train(net1, trainSet', T);
T = [0 0 0 0 0 0 0 0 0 ...
1 1 1 1 1 1 1 1 1 ...
0 0 0 0 0 0 0 0 0];
train(net2, trainSet', T);
T = [0 0 0 0 0 0 0 0 0 ...
0 0 0 0 0 0 0 0 0 ...
1 1 1 1 1 1 1 1 1];
train(net3, trainSet', T);
after finishing with training the network, i get this panel:
nntraintool panel
** if anyone could explain to me the progress section of the panel, because i could not understand what those numbers meant. **
after training the networks, i try to test the network using the following:
sim(net1, L)
where L is a sample from my set which is a 1X1024 vector, the result i got is this :
Empty matrix: 0-by-1024
is my approach to training the neural networks wrong ? what can i do to fix this program ?
thank you
The code
train(net1, trainSet', T);
does not save the trained network into the net1 variable (it saves it into ans variable). This is the reason why the result of sim is empty: there is no trained network in net1. You have to save the trained network yourself:
net1= train(net1, trainSet', T);
I have an input 2D histogram that I want to do 2-fold cross-validation with. The problem is I don't know how to extract two mutually exclusive random samples of the data from a histogram. If it was a couple of lists of the positional information of each data point, that would be easy - shuffle the data in the lists in the same way, and split the lists equally.
So for a list I would do this:
list1 = [1,2,3,3,5,6,1];
list2 = [1,3,6,6,5,2,1];
idx = randperm(length(list1)); % ie. idx = [4 3 1 5 6 2 7]
shlist1 = list1(idx); % shlist1 = [3,3,1,5,6,2,1]
shlist2 = list2(idx); % shlist2 = [6,6,1,5,2,3,1]
slist1 = shlist1(1:3); % slist1 = [3,3,1]
elist1 = shlist1(4:6); % elist1 = [5,6,2,1]
slist2 = shlist2(1:3); % slist2 = [6,6,1]
elist2 = shlist2(4:6); % elist2 = [5,2,3,1]
But if this same data was presented to me as a histogram
hist = [2 0 0 0 0 0]
[0 0 0 0 0 1]
[0 1 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 0 1 0]
[0 0 2 0 0 0]
I want the result to be something like this
hist1 = [0 0 0 0 0 0]
[0 0 0 0 0 1]
[0 1 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 0 0 0]
[0 0 1 0 0 0]
hist2 = [2 0 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 0 1 0]
[0 0 1 0 0 0]
so that different halves of the data are randomly, and equally assigned to two new histograms.
Would this be equivalent to taking a random integer height of each bin hist(i,j), and adding that to the equivalent bin in hist1(i,j), and the difference to hist2(i,j)?
% hist as shown above
hist1 = zeros(6);
hist2 = zeros(6);
for i = 1:length(hist(:,1))*length(hist(1,:))
randNum = rand;
hist1(i) = round(hist(i)*randNum);
hist2(i) = hist(i) - hist1(i);
end
And if that is equivalent, is there a better way/built-in way of doing it?
My actual histogram is 300x300 bins, and contains about 6,000,000 data points, and it needs to be fast.
Thanks for any help :)
EDIT:
The suggested bit of code I made is not equivalent to taking a random sample of positional points from a list, as it does not maintain the overall probability density function of the data.
Halving the histograms should be fine for my 6,000,000 points, but I was hoping for a method that would still work for few points.
You can use rand or randi to generate two histograms. The first method is more efficient however the second is more random.
h = [[2 0 0 0 0 0]
[0 0 0 0 0 1]
[0 1 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 0 1 0]
[0 0 2 0 0 0]];
%using rand
h1 = round(rand(size(h)).*h);
h2 = h - h1;
%using randi
h1 = zeros(size(h));
for k = 1:numel(h)
h1(k) = randi([0 h(k)]);
end
h2 = h - h1;
Suppose H is your 2D histogram. The following code extracts a single random index with a probability proportional to the count at that index - which I think is what you want.
cc = cumsum(H(:));
if cc(1) ~= 0
cc = [0; cc];
end
m = cc(end);
ix = find(cc > m*rand, 1);
To extract multiple samples, you need to write your own find function (preferably a binary search for efficiency) that extracts some n number of samples in one call. This will give you a vector of indices (call it ix_vec) chosen with probability proportional to the Histogram count at each index.
Then if we denote by X the numerical values corresponding to each location in the Histogram, your random sample is:
R1 = X(ix_vec);
Repeat for the second random sample set.
I've a neural network in MATLAB that works well, but it should give me a result of 0 or 1, and it gets +/-0.05 error. (0.02, 0.97, 1.03, ...)
What should I change for the result to be more accurate?
p = [ 0 0 1 1; 0 1 0 1];
t = [0 1 1 0];
net = feedforwardnet(2,'trainlm');
net.trainParam.goal = 0.01*var(t',1);
net.divideFcn = 'dividetrain';
[net,tr] = train(net,p,t);
a = net(p)