Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing list comps from numpy code

I'm in the middle of constructing a geometric neural net, and I'm running up against an issue with vectorization. Basically there is a lambda function I have defined that really should run on each sample provided as input. Problem being that it would be most convenient to pass in the inputs as an array with the last axis of that array serving as the "sample axis" (axis where each index is a full sample)

I have a solution that works, that basically just does this in a listcomp and then converts it back to a numpy array for the rest of the calculations. (Let me know if you want to see any of the functions defined, but I don't think they're hugely relevant)

class GeometricNeuralNet(object):

    def __init__(self, c, weight_domain=math.log(2)):
        """
        Dimensions of c should be a tuple that indicates the size of each layer.

        First number should be the number of input units, and the last should be the number of output units.
        Other entries should be the sizes of hidden layers.
        """
        weight_matrix = lambda a, b: np.exp(np.random.uniform(-weight_domain, weight_domain, [a,b]))
        self.weights = [weight_matrix(c[i], c[i+1]) for i in range(len(c) - 1)]
        self.predict = lambda input_vector, end=None: reduce(transfer_function, [input_vector] + self.weights[:end])

    def train(self, samples, outputs, learning_rate):
        # Forward Pass
        true_inputs = np.array([self.predict(sample, -1) for sample in samples])
        print true_inputs.shape

My major problem with this code is the weird way that true_inputs is being calculated. Is there any way around this? np.vectorize and np.frompyfunc don't seem to allow an axis argument, which would really be crucial here.

EDIT:

Here's the transfer_function method.

def transfer_function(x, y):
    return gmean(np.power(x, y.T), axis=1)
like image 766
Slater Victoroff Avatar asked Apr 20 '26 07:04

Slater Victoroff


1 Answers

You should checkout numpy's apply_along_axis method: http://docs.scipy.org/doc/numpy/reference/generated/numpy.apply_along_axis.html

>>> def my_func(a):
...     """Average first and last element of a 1-D array"""
...     return (a[0] + a[-1]) * 0.5
>>> b = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> np.apply_along_axis(my_func, 0, b)
array([ 4.,  5.,  6.])
>>> np.apply_along_axis(my_func, 1, b)
array([ 2.,  5.,  8.])
like image 65
Madison May Avatar answered Apr 22 '26 23:04

Madison May



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!