torch/nn - Joining arrays of Tensors element wise - lua

The subject of this question is joining tensors for neural networks with torch/nn and torch/nngraph libraries for Lua. I started coding in Lua a few weeks ago so my experience is very minimal. In the text below, I refer to lua tables as arrays.
Context
I am working with a recurrent neural network for speech recognition.
At some point in the network there are N number of arrays of m Tensors.
a = {a1, a2, ..., aM},
b = {b1, b2, ..., bM},
... N times
Where ai and bi are tensors and {} represents an array.
What needs to be done is join all those arrays element-wise so that output is an array of M Tensors where output[i] is the result of joining every ith Tensors from the N arrays over the second dimension.
output = {z1, z2, ..., zM}
Example
|| used to represent Tensors
x = {|1 1|, |2 2|}
|1 1| |2 2|
Tensors of size 2x2
y = {|3 3 3|, |4 4 4|}
|3 3 3| |4 4 4|
Tensors of size 2x3
|
| Join{x,y}
\/
z = {|1 1 3 3 3|, |2 2 4 4 4|}
|1 1 3 3 3| |2 2 4 4 4|
Tensors of size 2x5
So the first Tensor of x of size 2x2 was joined with the first Tensor of y of size 2x3 over the second dimension and same thing for second Tensor of each array resulting in z an array of Tensors 2x5.
Problem
Now this is a basic concatenation, but I can't seem to find a module in the torch/nn library that would allow me to do that. I could write my own module of course, but if an already existing module does it then I would rather go with that.
The only existing module I know that joins table is (obviously) JoinTable. It takes an array of Tensors and joins them together. I want to join arrayS of tensors element-wise.
Also, as we are feeding input to our network, the number of Tensors in the N arrays varies, so m from the context above is not constant.
Idea
What I thought I could do in order to use the module JoinTable is convert my arrays into Tensors instead and then JoinTable on the converted N Tensors. But then again I would need a module that does such a conversion and and another one to convert back to an array in order to feed it to the next layers of the network.
Last resort
Write a new module that iterates over all given arrays and concatenates element-wise. Of course it's do-able, but the whole purpose of this post is to find a way to avoid writing smelly modules. It seems weird to me that such a module doesn't already exist.
Conclusion
I finally decided to do as I wrote in Last resort. I wrote a new module that iterates over all given arrays and concatenates element-wise.
Though, the answer given by #fmguler does the same without having to write a new module.

You can do it with nn.SelectTable and nn.JoinTable like this;
require 'nn'
x = {torch.Tensor{{1,1},{1,1}}, torch.Tensor{{2,2},{2,2}}}
y = {torch.Tensor{{3,3,3},{3,3,3}}, torch.Tensor{{4,4,4},{4,4,4}}}
res = {}
res[1] = nn.JoinTable(2):forward({nn.SelectTable(1):forward(x),nn.SelectTable(1):forward(y)})
res[2] = nn.JoinTable(2):forward({nn.SelectTable(2):forward(x),nn.SelectTable(2):forward(y)})
print(res[1])
print(res[2])
If you want this to be done in a module, wrap it in nnGraph;
require 'nngraph'
x = {torch.Tensor{{1,1},{1,1}}, torch.Tensor{{2,2},{2,2}}}
y = {torch.Tensor{{3,3,3},{3,3,3}}, torch.Tensor{{4,4,4},{4,4,4}}}
xi = nn.Identity()()
yi = nn.Identity()()
res = {}
--you can loop over columns here>>
res[1] = nn.JoinTable(2)({nn.SelectTable(1)(xi),nn.SelectTable(1)(yi)})
res[2] = nn.JoinTable(2)({nn.SelectTable(2)(xi),nn.SelectTable(2)(yi)})
module = nn.gModule({xi,yi},res)
--test like this
result = module:forward({x,y})
print(result)
print(result[1])
print(result[2])
--gives the result
th> print(result)
{
1 : DoubleTensor - size: 2x5
2 : DoubleTensor - size: 2x5
}
th> print(result[1])
1 1 3 3 3
1 1 3 3 3
[torch.DoubleTensor of size 2x5]
th> print(result[2])
2 2 4 4 4
2 2 4 4 4
[torch.DoubleTensor of size 2x5]

Related

Vectorization of FOR loop

Is there a way to vectorize this FOR loop I know about gallery ("circul",y) thanks to user carandraug
but this will only shift the cell over to the next adjacent cell I also tried toeplitz but that didn't work).
I'm trying to make the shift adjustable which is done in the example code with circshift and the variable shift_over.
The variable y_new is the output I'm trying to get but without having to use a FOR loop in the example (can this FOR loop be vectorized).
Please note: The numbers that are used in this example are just an example the real array will be voice/audio 30-60 second signals (so the y_new array could be large) and won't be sequential numbers like 1,2,3,4,5.
tic
y=[1:5];
[rw col]= size(y); %get size to create zero'd array
y_new= zeros(max(rw,col),max(rw,col)); %zero fill new array for speed
shift_over=-2; %cell amount to shift over
for aa=1:length(y)
if aa==1
y_new(aa,:)=y; %starts with original array
else
y_new(aa,:)=circshift(y,[1,(aa-1)*shift_over]); %
endif
end
y_new
fprintf('\nfinally Done-elapsed time -%4.4fsec- or -%4.4fmins- or -%4.4fhours-\n',toc,toc/60,toc/3600);
y_new =
1 2 3 4 5
3 4 5 1 2
5 1 2 3 4
2 3 4 5 1
4 5 1 2 3
Ps: I'm using Octave 4.2.2 Ubuntu 18.04 64bit.
I'm pretty sure this is a classic XY problem where you want to calculate something and you think it's a good idea to build a redundant n x n matrix where n is the length of your audio file in samples. Perhaps you want to play with autocorrelation but the key point here is that I doubt that building the requested matrix is a good idea but here you go:
Your code:
y = rand (1, 3e3);
shift_over = -2;
clear -x y shift_over
tic
[rw col]= size(y); %get size to create zero'd array
y_new= zeros(max(rw,col),max(rw,col)); %zero fill new array for speed
for aa=1:length(y)
if aa==1
y_new(aa,:)=y; %starts with original array
else
y_new(aa,:)=circshift(y,[1,(aa-1)*shift_over]); %
endif
end
toc
my code:
clear -x y shift_over
tic
n = numel (y);
y2 = y (mod ((0:n-1) - shift_over * (0:n-1).', n) + 1);
toc
gives on my system:
Elapsed time is 1.00379 seconds.
Elapsed time is 0.155854 seconds.

ML coursera submission (week 2) Feature Normalization

I have written the following code for section "feature normalization"
Here X is the Feature matrix (m*n) such that
m = number of examples
n = number of features
Code
mu = mean(X);
sigma = std(X);
m = size(X,1);
% Subtracting the mean from each row
for i = 1:m
X_norm(i,:) = X(i,:)-mu;
end;
% Dividing the STD from each row
for i = 1:m
X_norm(i,:) = X(i,:)./sigma;
end;
But on submitting it to the server built for Andrew Ng's class, It's not giving me any confirmation if it's wrong or correct.
==
== Part Name | Score | Feedback
== --------- | ----- | --------
== Warm-up Exercise | 10 / 10 | Nice work!
== Computing Cost (for One Variable) | 40 / 40 | Nice work!
== Gradient Descent (for One Variable) | 50 / 50 | Nice work!
== Feature Normalization | 0 / 0 |
== Computing Cost (for Multiple Variables) | 0 / 0 |
== Gradient Descent (for Multiple Variables) | 0 / 0 |
== Normal Equations | 0 / 0 |
== --------------------------------
== | 100 / 100 |
Is this a bug in the web frontend presentation layer or my code?
When the submit() does not give you any points, this means your answer is not correct.
This usually means, that either you have not implemented it yet, or there is a mistake in your implementation.
From what I can see, your indices are not correct. However, in order not to violate the code of conduct of this course, you should ask your question in the Coursera forum (without posting your code).
There are also tutorials with each programming exercise. Those are usually very helpful and guide you through the entire exercise.
You need to iterate for EACH feature
m = size(X,1);
What you are actually getting with m is the number of ROWS (example), but you want to get the number of COLUMNS (Features)
solution:
m = size(X,2);
Try this it worked for and notice that you're making mistake with dividing each row of X without subtracting to mean.
Combine both and do with less code like this -
% Subtracting the mean and Dividing the STD from each row:
for i = 1:m
X_norm(i,:) = (X(i,:) - mu) ./ sigma;
end;
At the end of the class, the final correct answer was given as featureNormalize.m:
function [X_norm, mu, sigma] = featureNormalize(X)
%description: Normalizes the features in X
% FEATURENORMALIZE(X) returns a normalized version of X where
% the mean value of each feature is 0 and the standard deviation
% is 1. This is often a good preprocessing step to do when
% working with learning algorithms.
X_norm = X;
mu = zeros(1, size(X, 2));
sigma = zeros(1, size(X, 2));
% Instructions: First, for each feature dimension, compute the mean
% of the feature and subtract it from the dataset,
% storing the mean value in mu. Next, compute the
% standard deviation of each feature and divide
% each feature by it's standard deviation, storing
% the standard deviation in sigma.
%
% Note that X is a matrix where each column is a
% feature and each row is an example. You need
% to perform the normalization separately for
% each feature.
mu = mean(X);
sigma = std(X);
X_norm = (X - mu)./sigma;
end
If you're taking this class and feel the urge to copy and paste, you're in a grey-area on academic honesty. You're supposed to figure it out from first principles, not google it and regurgitate the answer.

DeepLearning4j and DataVec read csv file with label

I have built a DL4j project. Everything is fine if I use MNIST dataset as follows:
DataSetIterator mnistTrain = new MnistDataSetIterator(batchSize, true, rngSeed);
DataSetIterator mnistTest = new MnistDataSetIterator(batchSize, false, rngSeed);
However, I want to switch to my own csv file with the following format:
A | B | C | X | Y
-------------------------
1 | 100 | 5 | 15 | 6
...
X and Y are the outcomes (or labels). As I plan to perform regression analysis, so both X and Y are real numbers. So I read the csv file using the following code:
RecordReader recordReaderTrain = new CSVRecordReader(1, ",");
recordReaderTrain.initialize(new FileSplit(new File("src/main/resources/data/Data.csv")));
DataSetIterator dataIterTrain = new RecordReaderDataSetIterator(recordReaderTrain, batchSize, 3, 2);
3 in the code means index of the labels and 2 means number of possible labels. There no much explanation about these two parameters. I guess they mean the labels start from the 4th column and has 2 labels.
When I run the code, it shows the following exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 14
I think it is because dl4j does not recognize 15 as label.
So my question is: how can I properly read the csv file for a regression analysis?
Many thanks.
Right so we have examples for regression:
https://github.com/deeplearning4j/dl4j-examples/tree/cc383de91bdf4e28e36859aa2e8749100cd63177/dl4j-examples/src/main/java/org/deeplearning4j/examples/feedforward/regression
You need to pass regression true (it's an extra part of the constructor) to the RecordReaderDataSetIterator.

Is there a way to use postgresql function to calculate weighted average in Rails?

To calculate weighted average by a company's market capacity, I have a method like this:
class Company < ActiveRecord::Base
def self.weighted_average(column)
market_cap_sum = sum(:market_cap)
array = []
find_each do |company|
next if company.send(column).nil?
next if company.market_cap.nil?
array << (company.market_cap.to_d/market_cap_sum) * company.send(column)
end
array.sum
end
end
This code works fine but it's just slow to calculate. If there is a way to calculate by postgresql function, I wanna use it.
To calculate standard deviation there is a function like this, but I couldn't find how to calculate standard deviation with weighted average.
Company.select('stddev_pop(price) as stddev')
Is it possible to do what I want?
The math in this method does not seem to be well known. Enjoy this old programmer's trick.
CREATE TABLE data (
w real, /* Weight. May be an integer count or other weight. */
v real); /* Value. The value v is to be weighted by w. */
Populate the table with one copy of value "1" and ten copies of value "10":
insert into data values(1, 1);
insert into data values(10, 2);
Then run the following query to obtain weighted statistical values:
SELECT
min(v),
sum(w*v)/sum(w) AS wavg,
max(v),
sqrt((sum(w*v^2)-(sum(w*v)^2)/sum(w))/(sum(w)-1)) AS wstdev
FROM data;
Result is:
min | wavg | max | wstdev
-----+---------+-----+-------------------
1 | 1.90909 | 2 | 0.301511344577763
(1 row)

Libsvm model file format No model number

I am using libsvm for document classification. I use svm.cc and svm.h in my project. I then call svm_train. I save the model in a file using svm_save_model.
I have there categories. The svm model file is:
svm_type c_svc
kernel_type rbf
gamma 0.001002
nr_class 3
total_sv 9
rho -0.000766337 0.00314423 0.00387654
label 0 1 2
nr_sv 3 3 3
SV
1 1 1:0.001 2:0.001 3:0.012521912 5:0.001 15:0.012521912 17:0.012521912 23:0.001
1 1 1:0.001 2:0.014176543 4:0.093235799 6:0.001 7:0.0058630699 9:0.040529628 10:0.001
1 1 11:0.38863495 33:0.08295242 46:0.041749886 58:0.08295242 89:0.08295242 127:0.15338862 -1 1 5:0.001 8:0.0565 10:0.001 13:0.001 18:0.0565 21:0.021483399 34:0.12453384 36:0.001
-1 1 13:0.034959612 34:0.090130132 36:0.034959612 45:0.034959612 47:0.12019824
-1 1 5:0.001 8:0.048037273 13:0.001 18:0.048037273 29:0.14715472 30:0.018360058 36:0.001
-1 -1 9:0.0049328688 12:0.090902344 18:0.1156038 27:0.0049328688 31:0.015144206
What are 1 and -1 before the vector values in the form of index:value ?
From the libsvm FAQ:
Q: Can you explain more about the model file?
In the model file,
after parameters and other informations such as labels , each line
represents a support vector. Support vectors are listed in the order
of "labels" shown earlier. (i.e., those from the first class in the
"labels" list are grouped first, and so on.) If k is the total number
of classes, in front of a support vector in class j, there are k-1
coefficients y*alpha where alpha are dual solution of the following
two class problems: 1 vs j, 2 vs j, ..., j-1 vs j, j vs j+1, j vs
j+2, ..., j vs k and y=1 in first j-1 coefficients, y=-1 in the
remaining k-j coefficients. For example, if there are 4 classes, the
file looks like:
+-+-+-+--------------------+
|1|1|1| |
|v|v|v| SVs from class 1 |
|2|3|4| |
+-+-+-+--------------------+
|1|2|2| |
|v|v|v| SVs from class 2 |
|2|3|4| |
+-+-+-+--------------------+
|1|2|3| |
|v|v|v| SVs from class 3 |
|3|3|4| |
+-+-+-+--------------------+
|1|2|3| |
|v|v|v| SVs from class 4 |
|4|4|4| |
+-+-+-+--------------------+
http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html#f402

Resources