create a python sequence of 1-D array_like in C++ - c++

I'm trying to embed Python in my C++ code.
Now what I'm trying to do is use the function scipy.stats.anderson_ksamp that takes as input a "sequence of 1-D array_like".
the thing is that in Python one would call the function in this simple way:
from scipy import stats
# two example np-arrays
samp1 = np.array([1,2,3,4,5,6,7,8,9,0])
samp2 = np.array([0,5,6,7,3,9,2,7,1,7])
ander_out1, ander_out2, ander_out3 = stats.anderson_ksamp([samp1, samp2])
print("Anderson statistic: %s, critical values: %s, significance level: %s"% (ander_out1, ander_out2, ander_out3))
In C++ instead I call this function in this way:
#include <Python.h>
#include <numpy/arrayobject.h>
std::vector<int> sample1 = {1,2,3,4,5,6,7,8,9,0};
std::vector<int> sample2 = {0,5,6,7,3,9,2,7,1,7};
Py_Initialize();
import_array();
npy_intp dim1[] = {(npy_intp)sample1.size()};
PyObject* np_array1 = PyArray_SimpleNewFromData(1, dim1, NPY_INT, &sample1[0]);
npy_intp dim2[] = {(npy_intp)sample2.size()};
PyObject* np_array2 = PyArray_SimpleNewFromData(1, dim2, NPY_INT, &sample2[0]);
pModule2 = PyImport_ImportModule("scipy.stats");
if (pModule2 != NULL) {
pValue3 = PyObject_CallMethod(pModule2, "anderson_ksamp", "O", /*HERE GOES THE 1-D SEQUENCE*/);
if (pValue3 != NULL) {
Py_ssize_t pValue3Size = PyTuple_Size(pValue3); // size of the tuple
printf("Anderson tuple: (");
for (Py_ssize_t j = 0; j < pValue3Size; j++) {
pElem3 = PyTuple_GetItem(pValue3, j); // getting item j of tuple
printf("%f", PyFloat_AsDouble(pElem3)); // printing item j
if (j!=pValue3Size-1) {
printf(", ");
}
}
printf(")\n");
} else {
printf("Call to anderson_ksamp failed.\n");
PyErr_Print();
}
}
What I miss is how to "merge" the two vectors sample1 and sample2 in order to make a Python object that resembles the Python statement [samp1, samp2].
I tried to create a 2-D vector in C++
std::vector<std::vector<int>> sample3 = {{1,2,3,4,5,6,7,8,9,0}, {0,5,6,7,3,9,2,7,1,7}};
and then use
npy_intp dim3[] = {10, 2};
PyObject* both_np_arrays = PyArray_SimpleNewFromData(2, dim3, NPY_INT, &sample3);
in order to create the object I need. But the object I get is something like this:
array([[ 8003984, 1],
[ 8004032, 1],
[ 8004032, 1],
[50571184, 1],
[50411920, 1],
[ 0, 0],
[ 0, 0],
[ 0, 0],
[ 0, 0],
[ 0, 0]], dtype=int32)
That is definitely not what I want.
I've also tried to do it this way:
int sample3[10][2] = {{1,0}, {2,5}, {3,6}, {4,7}, {5,3}, {6,9}, {7,2}, {8,7}, {9,1}, {0,7}};
npy_intp dim3[] = {10, 2};
PyObject* both_np_arrays = PyArray_SimpleNewFromData(2, dim3, NPY_INT, &sample3);
but the result is this:
array([[1, 0],
[2, 5],
[3, 6],
[4, 7],
[5, 3],
[6, 9],
[7, 2],
[8, 7],
[9, 1],
[0, 7]], dtype=int32)
so, again, not what I need.
I think that to use the function properly I'd need to obtain something like this:
array([[1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
[0, 5, 6, 7, 3, 9, 2, 7, 1, 7]], dtype=int32)
How can I do it?

Related

Pytorch tensor dimension multiplication

I'm trying to implement the grad-camm algorithm:
https://arxiv.org/pdf/1610.02391.pdf
My arguments are:
activations: Tensor with shape torch.Size([1, 512, 14, 14])
alpha values : Tensor with shape torch.Size([512])
I want to multiply each activation (in dimension index 1 (sized 512)) in each corresponding alpha value: for example if the i'th index out of the 512 in the activation is 4 and the i'th alpha value is 5, then my new i'th activation would be 20.
The shape of the output should be torch.Size([1, 512, 14, 14])
Assuming the desired output is of shape (1, 512, 14, 14).
You can achieve this with torch.einsum:
torch.einsum('nchw,c->nchw', x, y)
Or with a simple dot product, but you will first need to add a couple of additional dimensions on y:
x*y[None, :, None, None]
Here's an example with x.shape = (1, 4, 2, 2) and y = (4,):
>>> x = torch.arange(16).reshape(1, 4, 2, 2)
tensor([[[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15]]]])
>>> y = torch.arange(1, 5)
tensor([1, 2, 3, 4])
>>> x*y[None, :, None, None]
tensor([[[[ 0, 1],
[ 2, 3]],
[[ 8, 10],
[12, 14]],
[[24, 27],
[30, 33]],
[[48, 52],
[56, 60]]]])

InvalidArgumentError indices[i,0] = x is not in [0, x) in keras

I have the code using keras 1.2 and tensorflow 1.1. I have run it but with error
import numpy as np
import keras
from keras import backend as K
from keras import initializers
from keras.models import Sequential, Model, load_model, save_model
from keras.layers.core import Dense, Lambda, Activation
from keras.layers import Embedding, Input, Dense, Multiply, Reshape, Flatten
from keras.optimizers import Adagrad, Adam, SGD, RMSprop
from keras.regularizers import l2
from sklearn.metrics import average_precision_score
from sklearn.metrics import auc
def init_normal(shape, name=None):
return initializers.lecun_uniform(seed=None)
def get_model(num_a, num_b, num_c, dim, regs=[0,0,0]):
a = Input(shape=(1,), dtype='int32', name = 'a')
b = Input(shape=(1,), dtype='int32', name = 'b')
c = Input(shape=(1,), dtype='int32', name = 'c')
Embedding_a = Embedding(input_dim = num_a, output_dim = dim,
embeddings_initializer='uniform', W_regularizer = l2(regs[0]), input_length=1)
Embedding_b = Embedding(input_dim = num_b, output_dim = dim,
embeddings_initializer='uniform', W_regularizer = l2(regs[1]), input_length=1)
Embedding_c = Embedding(input_dim = num_c, output_dim = dim,
embeddings_initializer='uniform', W_regularizer = l2(regs[2]), input_length=1)
a_latent = Flatten()(Embedding_a(a))
b_latent = Flatten()(Embedding_b(b))
c_latent = Flatten()(Embedding_c(c))
predict_vector = Multiply()([a_latent, b_latent, b_latent])
prediction = Dense(1, activation='sigmoid', init='lecun_uniform', name = 'prediction')(predict_vector)
model = Model(input=[a, b, c], output=prediction)
return model
def evaluate_model(model, test_pos, test_neg):
global _model
global _test_pos
global _test_neg
_model = model
_test_pos = test_pos
_test_neg = test_neg
print(_test_neg)
a, b, c, labels = [],[],[],[]
for item in _test_pos:
a.append(item[0])
b.append(item[1])
c.append(item[2])
labels.append(1)
for item in _test_neg:
a.append(item[0])
b.append(item[1])
c.append(item[2])
labels.append(0)
a = np.array(a)
b = np.array(b)
c = np.array(c)
predictions = _model.predict([a, b, c],
batch_size=100, verbose=0)
return average_precision_score(labels, predictions), auc(labels, predictions)
model = get_model(4, 8, 12, 2, [0,0,0])
model.compile(optimizer=Adam(lr=0.001), loss='binary_crossentropy')
pos_test = [[0, 0, 2], [4, 8, 8], [2, 5, 4], [0, 0, 0]]
neg_test = [[3, 3, 2], [2, 1, 8], [1, 4, 1], [3, 3, 12]]
aupr, auc = evaluate_model(model, pos_test, neg_test)
print(aupr, auc)
However, It give me error:any way to fix it?
InvalidArgumentError (see above for traceback): indices[1,0] = 4 is not in [0, 4)
[[Node: embedding_4/embedding_lookup = Gather[Tindices=DT_INT32, Tparams=DT_FLOAT, _class=["loc:#embedding_4/embeddings"], validate_indices=true, _device="/job:localhost/replica:0/task:0/cpu:0"](embedding_4/embeddings/read, _recv_a_1_0)]]
The problem is, you defined embedding input_dim as 4, 8 and 12 while it should be is 5, 9, 13. Because input_dim in embedding should be max_index + 1. It is also clearly mentioned in Keras docs:
Size of the vocabulary, i.e. maximum integer index + 1.
How to fix the issue?
Change get_model method to:
model = get_model(5, 9, 13, 2, [0, 0, 0])
Or alternatively change index of data to:
pos_test = [[0, 0, 2], [3, 7, 7], [2, 5, 4], [0, 0, 0]]
neg_test = [[3, 3, 2], [2, 1, 7], [1, 4, 1], [3, 3, 11]]

ValueError: Tensor A must be from the same graph as Tensor B

I'm doing text matching using tensorflow, before i call tf.nn.embedding_lookup(word_embedding_matrix, combine_result), I have to combine some words from 2 sentence(get m words from sentence S1 and also get m words from sentence S2, then combine them together as "combine_result"), but when the code gose to tf.nn.embedding_lookup(word_embedding_matrix, combine_result) it gives me the error:
ValueError: Tensor("Reshape_7:0", shape=(1, 6), dtype=int32) must be
from the same graph as Tensor("word_embedding_matrix:0", shape=(26320,
50), dtype=float32_ref).
the code is as bellow:
import tensorflow as tf
import numpy as np
import os
import time
import datetime
import data_helpers
NUM_CLASS = 2
SEQUENCE_LENGTH = 47
# Placeholders for input, output and dropout
input_x = tf.placeholder(tf.int32, [None, 2, SEQUENCE_LENGTH], name="input_x")
input_y = tf.placeholder(tf.float32, [None, NUM_CLASS], name="input_y")
dropout_keep_prob = tf.placeholder(tf.float32, name="dropout_keep_prob")
def n_grams(text, window_size):
text_left_window = []
# text_left_window = tf.convert_to_tensor(text_left_window, dtype=tf.int32)
for z in range(SEQUENCE_LENGTH-2):
text_left = tf.slice(text, [z], [window_size])
text_left_window = tf.concat(0, [text_left_window, text_left])
text_left_window = tf.reshape(text_left_window, [-1, window_size])
return text_left_window
def inference(vocab_size, embedding_size, batch_size, slide_window_size, conv_window_size):
# # Embedding layer
word_embedding_matrix = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
name="word_embedding_matrix")
# convo_unit = tf.Variable(tf.random_uniform([slide_window_size*2, ], -1.0, 1.0), name="convo_unit")
text_comp_result = []
for x in range(batch_size):
# input_x_slice_reshape = [[1 1 1...]
# [2 2 2...]]
input_x_slice = tf.slice(input_x, [x, 0, 0], [1, 2, SEQUENCE_LENGTH])
input_x_slice_reshape = tf.reshape(input_x_slice, [2, SEQUENCE_LENGTH])
# text_left_flat: [294, 6, 2, 6, 2, 57, 2, 57, 147, 57, 147, 5, 147, 5, 2,...], length = SEQUENCE_LENGTH
# text_right_flat: [17, 2, 2325, 2, 2325, 5366, 2325, 5366, 81, 5366, 81, 1238,...]
text_left = tf.slice(input_x_slice_reshape, [0, 0], [1, SEQUENCE_LENGTH])
text_left_flat = tf.reshape(text_left, [-1])
text_right = tf.slice(input_x_slice_reshape, [1, 0], [1, SEQUENCE_LENGTH])
text_right_flat = tf.reshape(text_right, [-1])
# extract both text.
# text_left_window: [[294, 6, 2], [6, 2, 57], [2, 57, 147], [57, 147, 5], [147, 5, 2],...]
# text_right_window: [[17, 2, 2325], [2, 2325, 5366], [2325, 5366, 81], [5366, 81, 1238],...]
text_left_window = n_grams(text_left_flat, slide_window_size)
text_right_window = n_grams(text_right_flat, slide_window_size)
text_left_window_sha = text_left_window.get_shape()
print 'text_left_window_sha:', text_left_window_sha
# composite the slice
text_comp_list = []
# text_comp_list = tf.convert_to_tensor(text_comp_list, dtype=tf.float32)
for l in range(SEQUENCE_LENGTH-slide_window_size+1):
text_left_slice = tf.slice(text_left_window, [l, 0], [1, slide_window_size])
text_left_slice_flat = tf.reshape(text_left_slice, [-1])
for r in range(SEQUENCE_LENGTH-slide_window_size+1):
text_right_slice = tf.slice(text_right_window, [r, 0], [1, slide_window_size])
text_right_slice_flat = tf.reshape(text_right_slice, [-1])
# convo_unit = [294, 6, 2, 17, 2, 2325]
convo_unit = tf.concat(0, [text_left_slice_flat, text_right_slice_flat])
convo_unit_reshape = tf.reshape(convo_unit, [-1, slide_window_size*2])
# convo_unit_shape_val = convo_unit_reshape.get_shape()
# print 'convo_unit_shape_val:', convo_unit_shape_val
embedded_chars = tf.nn.embedding_lookup(word_embedding_matrix, convo_unit_reshape)
embedded_chars_expanded = tf.expand_dims(embedded_chars, -1)
...
could please someone help me? Thank you very much!
Yaroslav answered in a comment above - moving to an answer:
This error happens when you create new default graph. Try to do tf.reset_default_graph() before the computation and not create any more graphs (i.e., calls to tf.Graph)

Sorting HashMap on values of type List

I have a map with keys as String and values as a List, Need to sort the map on values
HashMap<String, List<Integer>> data = new HashMap<String, List<Integer>>();
Where List is of size 3 and need to sort on item1, item2 and then item3 of list in asc order
for example if i have a map like below
K1=[3, 1, 96],
K2=[0, 4, 4],
K3=[3, 2, 88],
K4=[2, 2, 12],
K5=[3, 3, 64],
K6=[2, 4, 12],
K7=[3, 4, 64],
K8=[2, 1, 12],
K9=[2, 3, 12],
K10=[1, 2, 33],
K11=[3, 1, 45],
K12=[1, 1, 12],
K13=[0, 1, 6],
K14=[0, 1, 3],
K15=[2, 1, 12],
K16=[3, 4, 22],
After Sort :
K14=[0, 1, 3],
K13=[0, 1, 6],
K2=[0, 4, 4],
K12=[1, 1, 12],
K10=[1, 2, 33],
K8=[2, 1, 12],
K15=[2, 1, 12],
K4=[2, 2, 12],
K9=[2, 3, 12],
K6=[2, 4, 12],
K11=[3, 1, 45],
K1=[3, 1, 96],
K3=[3, 2, 88],
K5=[3, 3, 64],
K16=[3, 4, 22],
K7=[3, 4, 64]
How can this be done?
Thanks
My suggestion is that you transfer your elements to a List<Map.Entry<String, List<Integer>>> (for example by calling new ArrayList<>(data.entrySet())) which can then be sorted using a Comparator<Map.Entry<String, List<Integer>>>.
The horrible parameter types can of course be simplified for example if you don't need the map keys.
It would go something like this(at least in Java 8. Java 7 would require slightly more boilerplate code):
List<Map.Entry<String, List<Integer>>> dataList;
dataList = new ArrayList<>(data.entrySet());
dataList.sort((x, y) -> {
int comparison = Integer.compare(x.getValue().get(0), y.getValue().get(0));
if (comparison != 0) return comparison;
comparison = Integer.compare(x.getValue().get(1), y.getValue().get(1));
if (comparison != 0) return comparison;
return Integer.compare(x.getValue().get(2), y.getValue().get(2));
});
Edit: If you just want to sort a List<List<Integer>> list it gets as simple as this(Java 7 this time):
Collections.sort(list, new Comparator<List<Integer>>(){
public int compare(List<Integer> a, List<Integer> b) {
int comparison = a.get(0).compareTo(b.get(0));
if (comparison != 0) return comparison;
comparison = a.get(1).compareTo(b.get(1));
if (comparison != 0) return comparison;
return a.get(2).compareTo(b.get(2));
}
});

How to replace values in a list at indexed positions?

I have following list of text positions with all values being set to '-999' as default:
List = [(70, 55), (170, 55), (270, 55), (370, 55),
(70, 85), (170, 85), (270, 85), (370, 85)]
for val in List:
self.depth = wx.TextCtrl(panel, -1, value='-999', pos=val, size=(60,25))
I have indexed list and corresponding values at them such as:
indx = ['2','3']
val = ['3.10','4.21']
I want to replace index locations '2' and '3' with values '3.10' and '4.21' respectively in 'List' and keep the rest as '-999'. Any suggestions?
Solved. I used following example:
>>> s, l, m
([5, 4, 3, 2, 1, 0], [0, 1, 3, 5], [0, 0, 0, 0])
>>> d = dict(zip(l, m))
>>> d #dict is better then using two list i think
{0: 0, 1: 0, 3: 0, 5: 0}
>>> [d.get(i, j) for i, j in enumerate(s)]
[0, 0, 3, 0, 1, 0]
from similar question.