This question already has answers here:
Building a matrix by merging the same row vector multiple times
(2 answers)
Closed 1 year ago.
I want to add the same data in different lines using Matlab. In my first version, I copied the data as shown in the code below.
Is there a better way to do that?
data=[-5:1:14;-5:1:14;-5:1:14;-5:1:14;]
answer:
-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12
-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12
-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12
-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12
You can try repmat
repmat(-5:14,4)
or kron
kron(-5:14,ones(4,1))
Related
Can someone check did I guess correct number of neurons in input/hidden/output layer and overall params please.
My idea of this ANN:
Input neurons : 784 (28x28)
Hidden Layers : 1
Size of hidden layer(s) : 25
Activation function : Log-sigmoid
Training method : gradient descent
Data size : 400 + 200
There are 400 bmp images used for training of it, and 200 for checking (however only 1-50 get guessed with 100% rate and others 0% rate...)
clear all;
clc
for kk=1:400
pl=ones(28,28); %³õʼ»¯28*28¶þֵͼÏñΪȫ°×
m=strcat('b',int2str(kk),'.bmp'); %Á¬½Ó×Ö·ûµÃµ½Ñù±¾ÎļþÃû
x=imread(m,'bmp'); %¶ÁÈëÑб¾ÎļþͼÏñ
pl=im2bw(x,0.5); %°ÑÑù±¾Í¼Ïñת»¯Îª¶þֵͼ
for m=0:27 %ÐγÉÉñ¾ÍøÂçÊäÈëÏòÁ¿
p(m*28+1:(m+1)*28,kk)=pl(1:28,m+1);
end
end
%ÊÖдÌåÑù±¾¶ÔÓ¦µÄÊý×Ö£¨´Ób1.bmpµ½b400.bmp ¹²400¸ö£©£º
t=[5 0 4 1 9 2 1 3 1 4 3 6 3 6 1 7 2 8 6 9 4 0 9 1 1 2 4 3 2 7 8 8 6 9 0 5 6 0 7......
6 1 8 7 9 3 9 8 5 9 3 3 0 7 4 9 8 0 9 4 1 4 4 6 0 4 5 6 1 0 0 1 7 1 6 3 0 2 1......
1 7 8 0 2 6 7 8 3 9 0 4 6 7 4 6 8 0 7 8 3 1 5 7 1 7 1 1 6 3 0 2 9 3 1 1 0 4 9......
2 0 0 2 0 2 7 1 8 6 4 1 6 3 4 1 9 1 3 3 9 5 4 7 7 4 2 8 5 8 6 0 3 4 6 1 9 9 6......
0 3 7 2 8 2 9 4 4 6 4 9 7 0 9 2 7 5 1 5 9 1 2 3 1 3 5 9 1 7 6 2 8 2 2 6 0 7 4......
9 7 8 3 2 1 1 8 3 6 1 0 3 1 0 0 1 1 2 7 3 0 4 6 5 2 6 4 7 1 8 9 9 3 0 7 1 0 2......
0 3 5 4 6 5 8 6 3 7 5 8 0 9 1 0 3 1 2 2 3 3 6 4 7 5 0 6 2 7 9 8 5 9 2 1 1 4 4......
5 6 4 1 2 5 3 9 3 9 0 5 9 6 5 7 4 1 3 4 0 4 8 0 4 3 6 8 7 6 0 9 7 5 7 2 1 1 6......
8 9 4 1 5 2 2 9 0 3 9 6 7 2 0 3 5 4 3 6 5 8 9 5 4 7 4 2 7 3 4 8 9 1 9 2 1 7 9......
1 8 7 4 1 3 1 1 0 2 3 9 4 9 2 1 6 8 4 7 7 4 4 9 2 5 7 2 4 4 2 1 9 2 2 8 7 6 9......
8 2 3 8 1 6 5 1 1 0];
%´´½¨BPÍøÂç
pr(1:784,1)=0;
pr(1:784,2)=1;
t1=clock; %¼Æʱ¿ªÊ¼
%ÉèÖÃѵÁ·²ÎÊý
net=newff(pr,[25 1],{'logsig','purelin'},'traingdx','learngdm');
net.trainParam.epochs=5000; %ÉèÖÃѵÁ·´ÎÊý
net.trainParam.goal=0.05; %ÉèÖÃÐÔÄܺ¯Êý
net.trainParam.show=10; %ÿ10ÏÔʾ
net.trainParam.Ir=0.05; %ÉèÖÃѧϰËÙÂÊ
net=train(net,p,t); %ѵÁ·BPÍøÂç
datat=etime(clock,t1) %¼ÆËãÉè¼ÆÍøÂçµÄʱ¼äΪ66.417s
%Éú³É²âÊÔÑù±¾
pt(1:784,1)=1;
pl=ones(28,28); %³õʼ»¯28*28¶þֵͼÏñÏñËØ
for kk=401:600
pl=ones(28,28); %³õʼ»¯28*28¶þֵͼÏñΪȫ°×
m=strcat('b',int2str(kk),'.bmp'); %Á¬½Ó×Ö·ûµÃµ½Ñù±¾ÎļþÃû
x=imread(m,'bmp'); %¶ÁÈëÑб¾ÎļþͼÏñ
pl=im2bw(x,0.5); %°ÑÑù±¾Í¼Ïñת»¯Îª¶þֵͼ
for m=0:27 %ÐγÉÉñ¾ÍøÂçÊäÈëÏòÁ¿
pt(m*28+1:(m+1)*28,kk-400)=pl(1:28,m+1);
end
end
[a,Pf,Af]=sim(net,pt); %ÍøÂç·ÂÕæ
a=round(a) %Êä³öʶ±ð½á¹û
%²âÊÔÑù±¾¶ÔÓ¦µÄÊý×Ö£¨´Ób401.bmpµ½b600.bmp ¹²200¸ö£©£º
tl=[2 6 4 5 8 3 1 5 1 9 2 7 4 4 4 8 1 5 8 9 5 6 7 9 9 3 7 0 9......
0 6 6 2 3 9 0 7 5 4 8 0 9 4 1 1 8 7 1 2 6 1 0 3 0 1 1 8 2 0 3 9 4 0 5 0 6 1 7......
7 8 1 9 2 0 5 1 2 2 7 3 5 4 4 7 1 8 3 9 6 0 3 1 1 2 0 3 5 7 6 8 2 9 5 8 5 7 4......
1 1 3 1 7 5 5 5 2 5 8 2 0 9 7 7 5 0 9 0 0 8 9 2 4 8 1 6 1 6 5 1 8 3 4 0 5 5 8......
3 4 2 3 9 2 1 1 5 2 1 3 2 8 7 3 7 2 4 6 9 7 2 4 2 8 1 1 3 8 4 0 6 5 9 3 0 9 2......
4 7 1 1 9 4 2 6 1 8 9 0 6 6 7];
k=0;
for i=1:200
if a(i)==tl(i)
k=k+1;
end
end
rate=1.00*k/200; %¼ÆËã×îºóÕýÈ·ÂÊΪ0.495
I might be wrong, since you don't specify the number of output neurons and the number of patterns per class in your dataset. However, it seems that you have created only one output neuron for your network. In this case, the network assings ALL patterns to the same class, and the classification accuracy you get is equal to the a priori probability. If, for example, the first 50 patterns of your dataset belong to the same class, and the rest to different classes, a classifier with one output will assign all patterns to the first class, so you will get the first 50 right.
If this is the case, you should create a classifier with N outputs, where N is the number of classes in your dataset. In this case, the classifier will vote for each class, and the pattern will be assigned to the class with the maximum output. If for example you have 3 classes, and the output for a specific pattern is [0.2, 0.83, 0.6], the pattern will be assigned to the second class.
Moreover, converting to image to black-and-white is probably not the best way. It would be better to convert the image to grayscale (to preserve the histogram to some extent), and use some normalization to compensate for differences in lighting.
Finally, keep in mind that neural networks essentially detect similarity between input vectors. So, if you need to classify pictures, you need to find a representation such that similar images produce similar input vectors. Feeding the values of the pixels into the classifier is not a such representation. For example, if you turn the image upside down, the input vector changes completely, even though it still shows the same object. You don't want that. You want features that depend on the object shown, and not on lighting/angle etc. However, extracting such features is a different matter altogether (for example see some examples for image preprocessing and feature extraction from the OpenCV framework, the standard image processing and computer vision tool in C++/python)
If you are interested in neural networks and not image processing, it would be better to start with some standard classification problems from the UCI repository (eg. iris flower, wisconsin breast cancer) and practice with them until you produce good results and feel comfortable with the tools you are using.
Anybody know a fast way to produce a matrix consisting of a linspace for each row? For example, the sort of pattern I'm looking for in this matrix is:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
...
1 2 3 4 5 6 7 8 9 10
Anyone know any fast tricks to produce this WITHOUT using a for loop?
I just figured this out, so just in case anyone else was troubled by this, we can achieve this exact pattern by:
a=linspace(1,10,10);
b=ones(3,1)*a;
This will give:
>> a = 1 2 3 4 5 6 7 8 9 10
>> b = 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You need to use repmat.
Example:
>> B = repmat(1:10,[3 1])
B =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You can vary the value of 3 there. You can change it accordingly.
Another shortcut I can recommend is similar to repmat, but you specify a base array first of a = 1:10;. Once you do this, you specify a series of 1s in the first dimension when indexing which should produce a matrix of the same vectors with many rows as you want, where each row consists of the base array a. As such:
%// number of times to replicate
n = 4;
a = 1:10;
a = a(ones(1,n),:);
Result:
a =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Insert this command: transpose(ndgrid(1:10,1:n));, where n is the number of rows desired in the result.
You can consider these solutions:
With basic matrix indexing (taken from here)
b=a([1:size(a,1)]' * ones(1,NumToReplicate), :) %row-wise replication
b=a(:, ones(NumToReplicate, 1)) %column-wise replication
With bsxfun:
bsxfun(#times,a,(ones(1,NumToReplicate))') %row-wise replication
bsxfun(#times,a',(ones(1,NumToReplicate))) %column-wise replication
You are welcome to benchmark above two solutions with repmat.
This question already has answers here:
Grouping matrix rows in terms of one column
(2 answers)
Closed 9 years ago.
How can I calculate the mean of a group of rows and put the in a matrix such as:
1 4 5
1 34 4
1 65 0
1 5 3
2 3 44
2 52 4
2 5 6
3 9 2
3 9 1
3 9 9
So I can have a matrix as
1 27 4
2 20 18
3 9 4
Thx
Assuming original data is in matrix A:
indx=unique(A(:,1));
for ii=1:numel(indx)
RowMean(ii,:)=mean(A(1,:)==indx(ii),:);
end
I have random matrix(A) and I find a result I'd like to use later for my code
A=randint(5,7,[1,9])
ans A =
8 1 2 2 6 7 7
9 3 9 4 1 7 1
2 5 9 9 8 4 3
9 9 5 8 9 6 1
6 9 8 9 7 2 1
How can I now get:
A = [8,1,2,2,6,7,7;9,3,9...7,2,1];
without having to type it myself.
MATLAB has a function for that: MAT2STR
>> A = randi([1,9],[5,7]);
>> mat2str(A)
ans =
[5 5 7 5 3 2 5;5 6 5 3 8 4 1;9 8 8 1 7 9 6;1 5 5 1 8 6 3;3 4 5 8 9 9 5]
This is suitable for use with EVAL
Just thought of another way. Your goal is to have A in your script - right?
You can just paste it as follows:
A = [
8 1 2 2 6 7 7
9 3 9 4 1 7 1
2 5 9 9 8 4 3
9 9 5 8 9 6 1
6 9 8 9 7 2 1
]
(note the square brackets)
It will evaluate to your original matrix.
Make the string yourself:
Str = ['[' sprintf('%i',A(1)) sprintf(',%i',A(2:end)) ']']
Note this string does not contain any ; as in your example. so when you evaluate it you will get a 1x35 vector (instead of the original 5x7matrix)
So easiest way to fix this would be to add after you evaluate the string.
A = reshape(A,5,7)
It will look like
B = [....
B = reshape(B,5,7)
I am trying to create a matrix that is 3 x n, with each of the columns being the same. What's the easiest way of achieving it? Concatenation?
After
n=7
x=[1;2;3]
it's either
repmat(x,[1 n])
or
x(:,ones(1,n))
(Octave can be considered as an open source/free version of MATLAB)
octave-3.0.3:2> rowvec = [1:10]
rowvec =
1 2 3 4 5 6 7 8 9 10
octave-3.0.3:3> [rowvec; rowvec; rowvec]
ans =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Use repmat if the number of rows is large.
octave-3.0.3:7> repmat(rowvec, 10, 1)
ans =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Use multiplication with a 1 x 3 matrix of ones
eg, x * [1 1 1]
Edit:
In Octave:
octave-3.0.3.exe:1> x = [1;2;3;4]
x =
1
2
3
4
octave-3.0.3.exe:5> x * [1 1 1]
ans =
1 1 1
2 2 2
3 3 3
4 4 4