Computation on a Tensor as numpy array in graph? - python

Is there any way to do some computation on a tensor in graph.
Example my graph:
slim = tf.contrib.slim
def slim_graph(images, train=False):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
activation_fn=tf.nn.relu,
weights_initializer=tf.truncated_normal_initializer(0.0, 0.01),
weights_regularizer=slim.l2_regularizer(0.0005)):
net = slim.repeat(images, 2, slim.conv2d, 64, [3, 3], scope='conv1')
// Do my compute by numpy on net
np_array_result = my_func(net)
// It will return a numpy array
// Use numpy array as input of graph
net = slim.max_pool2d(np_array_result, [2, 2], scope='pool1')
...
return logits
Can we do somethings like that?
How to get feature maps in graph to compute?
I can separate graph into 2 parts and use Session.run([part1])
After that use the result to input my function, then feed it to Session.run([part2])
But it seems weird.

You can use tf.py_func wrapper for python functions.

Related

What is the proper way to to get dot product of two N-D (3-D) matrices using numpy?

I want to get dot product of two arrays along the batch dimension. np.dot gave a super weird result. Let suppose I have a batch of size 2. So what would be the proper way to get the results?
X = np.random.randn(2,3,4)
X_t = np.transpose(X,axes=[0,2,1]) # shape now is [2,4,3]
np.matmul(X,X_t) # shape is [2,3,3]
np.dot(X,X_t) # shape is [2,3,2,3] SUPER Weird
np.einsum('ijk,ikl->ijl',X,X_t) # Dimension as [2,3,3] Same as Matmul()
What is the correct way of matrix multiplication for conditions like these?
Use # operator. It reduces the first (0th) dimention.
Matmul for other dims.
import numpy as np
x = np.random.randn(2, 3, 4)
x_t = np.transpose(x, axes=[0, 2, 1]) # shape now is [2,4,3]
wrong = np.dot(x, x_t) # shape is [2,3,2,3] SUPER Weird
res = x # x_t
print(res.shape)
print(wrong.shape)
out:
(2, 3, 3)
(2, 3, 2, 3)

Extracting from tensor using indices like numpy

I have a tensor for example called tensor1 of shape (1,20,4). I am trying to create a tensor using certain indices (1,4,5) from this tensor. I could do this form numpy for example using: tensor[:,[1,4,5],:]. From what I understand this could be done using "tf.gather_nd" but I don't really see how it could be done.
What you want can be done with tf.gather:
tensor2 = tf.gather(tensor1, [1, 4, 5], axis=1)

Extract patches similar to that of max pooling or separable convolution

I am trying to create a custom layer that is similar to Max Pooling or the first step of a separable convolution.
For example with a 2-Tensor in which I want to extract the non-overlapping 2x2 patches:
if I have the [4,4] tensor
[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9,10,11],
[12,13,14,15]]
I want to end up with the following [2,2,4] Tensor
[[[ 0, 1, 4, 5],[ 2, 3, 6, 7]],
[[ 8, 9,12,13],[10,11,14,15]]]
For a 3-Tensor, I want something similar but to also separate out the 3rd dimension. tf.extract_image_patches almost does what I want, but it folds the "depth" dimension into each patch.
Ideally if I had a tensor of shape [32,64,7] and wanted to extract all the [2,2] patches out of it: I would end up with a shape of [16,32,7,4]
To be clear, I just want to extract the patches, not to actually do max pooling nor separable convolution.
Since I am not actually augmenting the data, I suspect that you can do it with some tf.reshape trickery... Is there any nice way to achieve this in tensorflow without resorting to slicing+stitching/for loops?
Also, what is the correct terminology for this operation? Windowing? Tiling?
Turns out this is really easy to do with tf.transpose. The solution that ended up working for me is:
#Assume x is in BHWC form
def pool(x,size=2):
channels = x.get_shape()[-1]
x = tf.extract_image_patches(
x,
ksizes=[1,size,size,1],
strides=[1,size,size,1],
rates=[1,1,1,1],
padding="SAME"
)
x = tf.reshape(x,[-1],x.get_shape()[1:3]+[size**2,channels])
x = tf.transpose(x,[0,1,2,4,3])
return x

PyBrain addSample multi-dimensional array

In all of the examples it seems that addSample(input, target) is used with 1 dimensional arrays, such as:
INPUT = 5
OUTPUT = 1
input = [5, 5, 5, 5, 5]
target = [1]
ds = SequentialDataSet(5, 1)
#add data using addSample
How does one do this when the input is multi-dimensional in this way:
input = [[5, 5, 5, 5, 5], [5, 5, 5, 5, 5]]
target = [1]
How does one use addSample with such structures? I tried this:
ds = SequentialDataSet(2, 1)
ds.addSample(input, target)
and get the error message:
Could not broadcast input array from shape (2, 5) into shape 2.
Meaning the SequentialDataSet(2, 1) does not work for this structure, but SequentialDataSet((2, 5), 1) also errors. This should be easy but I cannot find the answer.
It looks like you're trying to train some sort of Feed Forward network, perhaps a multi-layer perceptron? 5 layers in, one or more hidden layers, and a single output layer but it's not clear so this is a leap on my end.
Either way your input layer should be a single array. If you have a structure, or multi-dimensional array you'll need to collapse it and feed it in as a single set of data. So for your 5x2 suggestion you'd simply have 10 elements on the input, and you would be responsible for "parsing" your input structures consistently as they're fed into the network. For a 5x5 structure you'd have 25 inputs etc.
In my experience a big part of the success/challenge with ANNs is structuring the data in so that the input form is normalized and represented in a way that the network can mathematically find a pattern with.
According to the post linked beneath you should just input one array:
Pybrain multi dimensional data input
For SequentialDataSet I used this example:
data = [(1,2), (1,3), (10,2), (2,0), (2,9), (4,3), (1,2), (10,5)]
ds = SequentialDataSet(2,2)
for sample, next_sample in zip(data, cycle(test_data[1:])):
ds.addSample(sample, next_sample)

About Theano.tensor

Recently I use theano to create a gragh whitch is used for identifying flowers, however, the output of theano's inner function seem not be the type that I expect, for example:
a = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
sum = theano.tensor.sum(a, axis = 1)
sum_array = numpy.asarray(sum, dtype = numpy.float32)
I don't know why it doesn't work, simply I just want to creat an array to store the sum-result.
It just a simple example, in my project, I use the function "conv2d" and create an output after convolving the images, but I can't get the information of the output like the shape:
conv_out = conv2d(input, filter_shape, image_shape, ...)
output = theano.tensor.tanh(con_out, bias.dimshuffle('x','0','x','x'))
How can I change the 'output' into a 4D matrix and conveniently get its shape and other information?
Theano is different from regular python in that what you are creating are symbolic functions.
You need call Theano.function() for the symbolic function to be compiled. Then you need to call the resulting function with parameters.

Categories