예제 #1
0
class CFSPRF_Plugin(param.Parameterized):
    """
    Generic large-scale response function based on a simple single-CF function.

    Applies the single_cf_fn to each CF in turn.  For the default single_cf_fn
    of DotProduct(), does a basic dot product of each CF with the corresponding
    slice of the input array.  This function is likely to be slow to run, but
    it is easy to extend with any arbitrary single-CF response function.

    The single_cf_fn must be a function f(X,W) that takes two identically
    shaped matrices X (the input) and W (the CF weights) and computes a scalar
    activation value based on those weights.
    """

    single_cf_fn = param.ClassSelector(ResponseFn,
                                       default=DotProduct(),
                                       doc="""
        Accepts a ResponseFn that will be applied to each CF individually.""")

    def __call__(self, projection, **params):
        single_cf_fn = self.single_cf_fn
        for i, cf in enumerate(projection.flatcfs):
            X = cf.input_sheet_slice.submatrix(projection.src.activity)
            projection.activity.flat[i] = single_cf_fn(X, cf.weights)
        projection.activity *= projection.strength
예제 #2
0
class CFPRF_DotProduct_cython(CFPRF_Plugin):
    """
    Wrapper written to allow transparent non-optimized fallback;
    equivalent to CFPRF_Plugin(single_cf_fn=DotProduct()).
    """

    single_cf_fn = param.ClassSelector(ResponseFn, DotProduct(),readonly=True)

    def __init__(self,**params):
        super(CFPRF_DotProduct_cython,self).__init__(**params)
예제 #3
0
class CFPRF_ActivityBased(CFPResponseFn):
    """
    Calculate the activity of each unit nonlinearly based on the input activity.

    The activity is calculated from the input activity, the weights,
    and a strength that is a function of the input activity. This
    allows connections to have either an excitatory or inhibitory
    effect, depending on the activity entering the unit in question.

    The strength function is a generalized logistic curve (Richards'
    curve), a flexible function for specifying a nonlinear growth
    curve::

    y = l + ( u /(1 + b exp(-r (x - 2m)) ^ (1 / b)) )

    This function has five parameters::

    * l: the lower asymptote, i.e. the value at infinity;
    * u: the upper asymptote minus l, i.e. (u + l) is the value at minus infinity;
    * m: the time of maximum growth;
    * r: the growth rate;
    * b: affects near which asymptote maximum growth occurs.

    Richards, F.J. 1959 A flexible growth function for empirical use.
    J. Experimental Botany 10: 290--300, 1959.
    http://en.wikipedia.org/wiki/Generalised_logistic_curve
    """

    l = param.Number(default=-1.3, doc="Value at infinity")
    u = param.Number(default=1.2, doc="(u + l) is the value at minus infinity")
    m = param.Number(default=0.25, doc="Time of maximum growth.")
    r = param.Number(default=-200, doc="Growth rate, controls the gradient")
    b = param.Number(default=2, doc="Controls position of maximum growth")
    single_cf_fn = param.ClassSelector(ResponseFn,
                                       default=DotProduct(),
                                       doc="""
        ResponseFn to apply to each CF individually.""")

    def __call__(self, iterator, input_activity, activity, strength):
        single_cf_fn = self.single_cf_fn
        normalize_factor = max(input_activity.flat)

        for cf, r, c in iterator():
            r1, r2, c1, c2 = cf.input_sheet_slice
            X = input_activity[r1:r2, c1:c2]
            avg_activity = sum(X.flat) / len(X.flat)
            x = avg_activity / normalize_factor
            strength_fn = self.l + (
                self.u / (1 + exp(-self.r * (x - 2 * self.m)))**(1.0 / self.b))
            activity[r, c] = single_cf_fn(X, cf.weights)
            activity[r, c] *= strength_fn
예제 #4
0
class CFPRF_DotProduct_opt(CFPResponseFn):
    """
    Dot-product response function.

    Written in C for a manyfold speedup; see CFPRF_DotProduct for an
    easier-to-read version in Python.  The unoptimized Python version
    is equivalent to this one, but it also works for 1D arrays.
    """

    single_cf_fn = param.ClassSelector(ResponseFn, DotProduct(), readonly=True)

    def __call__(self, iterator, input_activity, activity, strength, **params):

        temp_act = activity  # pyflakes:ignore (passed to weave C code)
        irows, icols = input_activity.shape
        X = input_activity.ravel()  # pyflakes:ignore (passed to weave C code)
        cfs = iterator.flatcfs
        num_cfs = len(cfs)  # pyflakes:ignore (passed to weave C code)
        mask = iterator.mask.data  # pyflakes:ignore (passed to weave C code)

        cf_type = iterator.cf_type  # pyflakes:ignore (passed to weave C code)

        # Note: no performance hit from array indexing of mask and
        # temp_act (r11447).
        code = c_header + """
            DECLARE_SLOT_OFFSET(weights,cf_type);
            DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type);

            %(cfs_loop_pragma)s
            for (int r=0; r<num_cfs; ++r) {
                if(mask[r] == 0.0) {
                    temp_act[r] = 0;
                } else {
                    PyObject *cf = PyList_GetItem(cfs,r);

                    // CONTIGUOUS_ARRAY_FROM_SLOT_OFFSET(float,weights,cf) <<<<<<<<<<<

                    LOOKUP_FROM_SLOT_OFFSET_UNDECL_DATA(float,weights,cf);
                    char *data = weights_obj->data;                  
                    int s0 = weights_obj->strides[0];
                    int s1 = weights_obj->strides[1];

                    LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf);

                    UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice);

                    double tot = 0.0;
                    npfloat *xj = X+icols*rr1+cc1;

                    // computes the dot product
                    for (int i=rr1; i<rr2; ++i) {
                        npfloat *xi = xj;


                    //    float *wi = weights;                       
                    //    for (int j=cc1; j<cc2; ++j) {
                    //        tot += *wi * *xi;
                    //        ++wi;
                    //        ++xi;
                    //    }


                   for (int j=cc1; j<cc2; ++j) {
                      tot += *((float *)(data + (i-rr1)*s0 + (j-cc1)*s1)) * *xi;
                      ++xi;
                   }

                        xj += icols;
                 //       weights += cc2-cc1;
                    }  
                    temp_act[r] = tot*strength;

                //    DECREF_CONTIGUOUS_ARRAY(weights);
                }
            }
        """ % c_decorators
        inline(code, [
            'mask', 'X', 'strength', 'icols', 'temp_act', 'cfs', 'num_cfs',
            'cf_type'
        ],
               local_dict=locals(),
               headers=['<structmember.h>'])
예제 #5
0
 def __init__(self, **params):
     super(CFPRF_DotProduct, self).__init__(single_cf_fn=DotProduct(),
                                            **params)