Seq2Seq in CNTK : Run Time Error Function Only supports 2 dynamic axis - deep-learning

I am trying to implement a basic translation model where input and output are sentences in different languages in CNTK using LSTMs.
To achieve this I am creating model as follows :
def create_model(x):
with c.layers.default_options():
m = c.layers.Recurrence(c.layers.LSTM(input_vocab_size))(x)
m = sequence.last(m)
y = c.layers.Recurrence(c.layers.LSTM(label_vocab_size))(m)
return m
batch_axis = Axis.default_batch_axis()
input_seq_axis = Axis('inputAxis')
input_dynamic_axes = [batch_axis, input_seq_axis]
raw_input = input_variable(shape = (input_vocab_dim), dynamic_axes = input_dynamic_axes, name = 'raw_input')
z= create_model(raw_input)
But I am getting following error :
RuntimeError: Currently PastValue/FutureValue Function only supports input operand with 2 dynamic axis (1 sequence-axis and 1 batch-axis)
As per I understand, dynamic axis are basically those axis which gets decided after data gets loaded, in this case batch size and length of input sentence. I don't think I am changing the dynamic axis of input anywhere.
Any help is highly appreciated.

The last() operation strips the dynamic axis, since it reduces the input sequence to a single value (the thought vector).
The thought vector should then become the initial state for the second recurrence. So it should not be passed as the data argument to the second recurrence.
In the current version, the initial_state argument of Recurrence() cannot be data dependent. This will be soon possible, it is already under code review and will be merged to master soon.
Until then, there is a more complicated way to pass a data-dependent initial state, where you manually construct the recurrence (without Recurrence() layer), and manually add the initial hidden state in the recurrence. It is illustrated in the sequence-2-sequence sample.

This might be :
input_dynamic_axes= [Axis.default_batch_axis(), Axis.default_dynamic_axis()]
The first one will be the number of sample in your minibatch, the second will be the sequence length automagically inferred by CNTK

Related

Is there a way to change the y axis of the calc.ece function when plotting?

I am trying to plot the calc.ece function and have been successful with just the basic plot function. However, I need to be able to zoom in to show the observed and calibrated lines better. Such as in this example here
LR.same = c(4135, 4135, 4135, 4135, 4135, 4135)
LR.different = c(0.00334, 0.00334, 0.00334, 0.00334, 0.00334)
ece.1 = calc.ece(LR.same, LR.different)
plot(ece.1)
I cannot use the ylim as I get this error Error in xy.coords(x, y, xlabel, ylabel, log) : argument "x" is missing, with no default. I am unsure what to do. Any ideas?
Well, I still cannot change the y-axis in R, but if you just unlist() the data and export you get the data. I then put the data into excel and added a column of log10 odds which is calculated by log10(prior/(1-prior)). Then I just created a scatter plot of this making the log10 odds the x-axis. That seemed to work.

How to apply a complex function to every row of a .csv file in MATLAB?

I would like to apply an external code with a particualr function (chaos; https://figshare.com/s/80891dfb34c6ee9c8b34) from a paper by Toker et al. 2020 (https://www.nature.com/articles/s42003-019-0715-9#Sec1) in order to test whether my data are stochastic or chaotic.
I tried loops, for, cellfun, but none of these work in this case.
When I tried to use the following code:
T = readtable('ibfrq3.csv');
C = table2array(T);
D = num2cell(C, 2);
rowSums = cellfun(#sum, D)
chaos = cellfun(#chaos, D)
I received three errors:
Unable to perform assignment because the size of the left side is 1-by-14 and the size of the right side is
1-by-3.
Error in chaos>surrogate (line 989)
surr(k,:)=unwrap(horzcat(st,parts{randperm(j)},en));
Error in chaos (line 157)
[surr, params] = surrogate(zscore(surr_y), num_surr, 'CPP', 1, 1);
Interestingly, I am able to make the function work, but only for separate rows (by copying them into square brackets and labelling as y e.g. y = [1,2,3,4,5,6,7,8,9,5,6,7,8,8]).
My desired output is a string (or ideally a column added to my .csv) with chaos function outputs (one word per row: 'stochastic' or 'chaotic' depending on the result).
My data are available here: https://drive.google.com/file/d/1I2BChrv0iqNr1dcEKTQKxKF7DDl_hF23/view?usp=sharing
The .csv consists of allele frequencies over different time periods.
EDIT:
Trying
numRows = size(C, 1);
for row = 1:numRows
result(row) = chaos(C(row,:));
end
Yielded similar errors as above.
I also tried to run the code row by row on my data to check which row causes problems using
row1 = C(1,:);
chaos(row1)
for every row. Interestingly, it works perfectly giving the desired output for rows no.1, 3-9, 11-100. Rows no.2 and no.10 are not different from the others and do not contain any special characters or values. I have no clue what's wrong with them.
cellfun (and its close relative arrayfun) are not suitable here because they apply a function to each element of an array separately, while you want to apply a function to each row. Also, you're assigning a value to chaos which is already the name of a function, which is likely to lead to confusing behaviour.
If C is an m x n numeric array, and chaos is a function that takes a row vector as input and returns a scalar value as output, then
numRows = size(C, 1);
for row = 1:numRows
result(row) = chaos(C(row,:));
end
will create a 1 x m vector result containing the output of the function for each row of C.
If the chaos function returns a character vector, you'll need to store the result in a cell array instead, by changing the line inside the loop to
result{row} = chaos(C(row,:));
However the error message you've added to your question suggests there's another issue, because it tells us that an operation inside the chaos function is failing. If you say that chaos seems to work OK when you give it one row of data at a time, then either your array C doesn't contain what you think it does, or there's a row of data that causes it to fail for some reason. You need to debug this. For a start you could add a disp(row) inside the loop, which will show you which row of C causes the error.

Tensorflow 1.1 Error : Attempt to reuse RNNCell with a different variable scope than its first use

I am trying to run the seq2seq translate example present on Tensorflow website and getting following error. I am using tensorflow-gpu==1.1.0
ValueError: Attempt to reuse RNNCell
with a different variable scope than its first use.
First use of cell was with scope
'embedding_attention_seq2seq/embedding_attention_decoder/attention_decoder/gru_cell',
this attempt is with scope 'embedding_attention_seq2seq/rnn/gru_cell'.
Please create a new instance of the cell if you would like it to use a
different set of weights. If before you were using:
MultiRNNCell([GRUCell(...)] * num_layers), change to:
MultiRNNCell([GRUCell(...) for _ in range(num_layers)]). If before
you were using the same cell instance as both the forward and reverse
cell of a bidirectional RNN, simply create two instances (one for
forward, one for reverse). In May 2017, we will start transitioning
this cell's behavior to use existing stored weights, if any, when it
is called with scope=None (which can lead to silent model degradation,
so this error will remain until then.)
On github people were suggesting to change the add the reuse argument to cell as follows :
def single_cell():
return tf.contrib.rnn.GRUCell(size, reuse = tf.get_variable_scope().reuse)
if use_lstm:
def single_cell():
return tf.contrib.rnn.BasicLSTMCell(size, reuse = tf.get_variable_scope().reuse)
cell = single_cell()
if num_layers > 1:
cell = tf.contrib.rnn.MultiRNNCell([single_cell() for _ in range(num_layers)])
But still I am getting the same error. What's the issue and how to resolve it ?
Any help is highly appreciated.
P.S: A similar post was there on stackoverflow,but that solution didn't work for me and since the version of TF is different, I created a new post.

Provide mean pixel values to Caffe's python classify.py

I'd like to test a Caffe model with the Python wrapper:
python classify.py --model_del ./deploy.prototxt --pretrained_model ./mymodel.caffemodel input.png output
Is there a simple way to give mean_pixel values to the python wrapper? It seems to only support a mean_file argument?
The code makes use of args.mean_file variable to read a numpy format data to a variable mean. The easiest method will be to bring on a new parser argument named args.mean_pixel which has a single mean value, store it a mean_pixel variable, then create an array called mean which has the same dimensions as that of input data and copy the mean_pixel value to all the elements in the array. The rest of the code will function as normal.
parser.add_argument(
"--mean_pixel",
type=float,
default=128.0,
help="Enter the mean pixel value to be subtracted."
)
The above code segment will try to take a command line argument called mean_pixel.
Replace the code segment:
if args.mean_file:
mean = np.load(args.mean_file)
with:
if args.mean_file:
mean = np.load(args.mean_file)
elif args.mean_pixel:
mean_pixel = args.mean_pixel
mean = np.array([image_dims[0],image_dims[1],channels]) #where channels is the number of channels of the image
mean.fill(mean_pixel)
This will make the code to pick the mean_pixel value passed on as an argument, if mean_file is not passed as an argument. The above code will create an array with the dimensions as that of the image and fill it with the mean_pixel value.
The rest of the code needn't be changed.

how do i decode/encode the url parameters for the new google maps?

Im trying to figure out how to extract the lat/long of the start/end in a google maps directions link that looks like this:
https://www.google.com/maps/preview#!data=!1m4!1m3!1d189334!2d-96.03687!3d36.1250439!4m21!3m20!1m4!3m2!3d36.0748342!4d-95.8040972!6e2!1m5!1s1331-1399+E+14th+St%2C+Tulsa%2C+OK+74120!2s0x87b6ec9a1679f9e5%3A0x6e70df70feebbb5e!3m2!3d36.1424613!4d-95.9736986!3m8!1m3!1d189334!2d-96.03687!3d36.1250439!3m2!1i1366!2i705!4f13.1&fid=0
Im guessing the "!" is a separator between variables followed by XY where x is a number and y is a lower case letter, but can not quite figure out how to reliably extract the coordinates as the number/order of variables changes as well as their XY prefixes.
ideas?
thanks
Well, this is old, but hey. I've been working on this a bit myself, so here's what I've figured out:
The data is an encoded javascript array, so the trick when trying to generate your own data string is to ensure that your formatting keeps the structure of the array intact. To do this, let's look at what each step represents.
As you're correctly figured out, each exclamation point defines the start of a value definition. The first character, an int value, is an inner count, and (I believe) acts as an identifier, although I'm not 100% certain on this. It seems to be pretty flexible in terms of what you can have here, as long as it's an int. The second character, however, is much more important. It defines the data type of the value. I don't know if I've found all the data types yet, but the ones I have figured out are:
m: matrix
f: float
d: double
i: integer
b: boolean
e: enum (as integer)
s: string
u: unsigned int
x: hexdecimal value?
the remaining characters actually hold the value itself, so a string will just hold the string, a boolean will be '1' or '0', and so on. However, there's an important gotcha: the matrix data type.
The value of the matrix will be an integer. This is the length of the matrix, measured in the number of values. That is, for a matrix !1mx, the next x value definitions will belong to the matrix. This includes nested matrix definitions, so a matrix of form [[1,2]] would look like !1m3!1m2!1i1!2i2 (outer matrix has three children, inner matrix has 2). this also means that, in order to remove a value from the list, you must also check it for matrix ancestors and, if they exist, update their values to reflect the now missing member.
The x data type is another anomaly. I'm going to guess it's hexdecimal encoded for most purposes, but in my particular situation (making a call for attribution info), they appear to also use the x data type to store lat/long information, and this is NOT encoded in hex, but is an unsigned long with the value set as
value = coordinate<0 ? (430+coordinate)*1e7 : coordinate*1e7
An example (pulled directly from google maps) of the x data type being used in this way:
https://www.google.com/maps/vt?pb=!1m8!4m7!2u7!5m2!1x405712614!2x3250870890!6m2!1x485303036!2x3461808386!2m1!1e0!2m20!1e2!2spsm!4m2!1sgid!2sznfCVopRY49wPV6IT72Cvw!4m2!1ssp!2s1!8m11!13m9!2sa!15b1!18m5!2b1!3b0!4b1!5b0!6b0!19b1!19u12!3m1!5e1105!4e5!18m1!1b1
For the context of the question asked, it's important to note that there are no reliable identifiers in the structure. Google reads the values in a specific order, so always keep in mind when building your own encoded data that order matters; you'll need to do some research/testing to determine that order. As for reading, your best hope is to rebuild the matrix structure, then scan it for something that looks like lat/long values (i.e. a matrix containing exactly two children of type double (or x?))
Looks like the developer tools from current browsers (I am using Chrome for that) can give you a lot of info.
Try the following:
Go to Google Maps with Chrome (or adapt the instructions for other browser);
Open Developer Tools (Ctrl + Shift + I);
Go to Network tab. Clear the current displayed values;
Drag the map until some url with encoded data appears;
Click on that url, and then go to the Preview sub-tab;
Try this.
function URLtoLatLng(url) {
this.lat = url.replace(/^.+!3d(.+)!4d.+$/, '$1');
this.lng = url.replace(/^.+!4d(.+)!6e.+$/, '$1');
return this;
}
var url = new URLtoLatLng('https://www.google.com/maps/preview#!data=!1m4!1m3!1d189334!2d-96.03687!3d36.1250439!4m21!3m20!1m4!3m2!3d36.0748342!4d-95.8040972!6e2!1m5!1s1331-1399+E+14th+St%2C+Tulsa%2C+OK+74120!2s0x87b6ec9a1679f9e5%3A0x6e70df70feebbb5e!3m2!3d36.1424613!4d-95.9736986!3m8!1m3!1d189334!2d-96.03687!3d36.1250439!3m2!1i1366!2i705!4f13.1&fid=0');
console.log(url.lat + ' ' + url.lng);