def build_pes(model, pes, rule):
    conn = rule.connection

    # Create input error signal
    error = Signal(np.zeros(rule.size_in), name="PES:error")
    model.add_op(Reset(error))
    model.sig[rule]['in'] = error  # error connection will attach here

    acts = filtered_signal(
        model, pes, model.sig[conn.pre_obj]['out'], pes.pre_tau)
    acts_view = acts.reshape((1, acts.size))

    # Compute the correction, i.e. the scaled negative error
    correction = Signal(np.zeros(error.shape), name="PES:correction")
    local_error = correction.reshape((error.size, 1))
    model.add_op(Reset(correction))

    # correction = -learning_rate * (dt / n_neurons) * error
    n_neurons = (conn.pre_obj.n_neurons if isinstance(conn.pre_obj, Ensemble)
                 else conn.pre_obj.size_in)
    lr_sig = Signal(-pes.learning_rate * model.dt / n_neurons,
                    name="PES:learning_rate")
    model.add_op(DotInc(lr_sig, error, correction, tag="PES:correct"))

    if conn.solver.weights or (
            isinstance(conn.pre_obj, Neurons) and
            isinstance(conn.post_obj, Neurons)):
        post = get_post_ens(conn)
        weights = model.sig[conn]['weights']
        encoders = model.sig[post]['encoders']

        # encoded = dot(encoders, correction)
        encoded = Signal(np.zeros(weights.shape[0]), name="PES:encoded")
        model.add_op(Reset(encoded))
        model.add_op(DotInc(encoders, correction, encoded, tag="PES:encode"))
        local_error = encoded.reshape((encoded.size, 1))
    elif not isinstance(conn.pre_obj, (Ensemble, Neurons)):
        raise ValueError("'pre' object '%s' not suitable for PES learning"
                         % (conn.pre_obj))

    # delta = local_error * activities
    model.add_op(Reset(model.sig[rule]['delta']))
    model.add_op(ElementwiseInc(
        local_error, acts_view, model.sig[rule]['delta'], tag="PES:Inc Delta"))

    # expose these for probes
    model.sig[rule]['error'] = error
    model.sig[rule]['correction'] = correction
    model.sig[rule]['activities'] = acts

    model.params[rule] = None  # no build-time info to return
Exemple #2
0
def build_pes(model, pes, rule):
    # TODO: Filter activities
    conn = rule.connection
    activities = model.sig[conn.pre_obj]['out']
    error = model.sig[pes.error_connection]['out']

    scaled_error = Signal(np.zeros(error.shape),
                          name="PES:error * learning_rate")
    scaled_error_view = scaled_error.reshape((error.size, 1))
    activities_view = activities.reshape((1, activities.size))
    lr_sig = Signal(pes.learning_rate * model.dt, name="PES:learning_rate")

    model.add_op(Reset(scaled_error))
    model.add_op(DotInc(lr_sig, error, scaled_error, tag="PES:scale error"))

    if conn.solver.weights or (
            isinstance(conn.pre_obj, Neurons) and
            isinstance(conn.post_obj, Neurons)):
        post = (conn.post_obj.ensemble if isinstance(conn.post_obj, Neurons)
                else conn.post_obj)
        transform = model.sig[conn]['transform']
        encoders = model.sig[post]['encoders']
        encoded_error = Signal(np.zeros(transform.shape[0]),
                               name="PES: encoded error")

        model.add_op(Reset(encoded_error))
        model.add_op(DotInc(
            encoders, scaled_error, encoded_error, tag="PES:Encode error"))

        encoded_error_view = encoded_error.reshape((encoded_error.size, 1))
        model.add_op(ElementwiseInc(
            encoded_error_view, activities_view, transform,
            tag="PES:Inc Transform"))
    elif isinstance(conn.pre_obj, Neurons):
        transform = model.sig[conn]['transform']
        model.add_op(ElementwiseInc(
            scaled_error_view, activities_view, transform,
            tag="PES:Inc Transform"))
    else:
        assert isinstance(conn.pre_obj, Ensemble)
        decoders = model.sig[conn]['decoders']
        model.add_op(ElementwiseInc(
            scaled_error_view, activities_view, decoders,
            tag="PES:Inc Decoder"))

    # expose these for probes
    model.sig[rule]['scaled_error'] = scaled_error
    model.sig[rule]['activities'] = activities

    model.params[rule] = None  # no build-time info to return
Exemple #3
0
def test_signal_reshape():
    """Tests Signal.reshape"""
    three_d = Signal(np.ones((2, 2, 2)))
    assert three_d.reshape((8,)).shape == (8,)
    assert three_d.reshape((4, 2)).shape == (4, 2)
    assert three_d.reshape((2, 4)).shape == (2, 4)
    assert three_d.reshape(-1).shape == (8,)
    assert three_d.reshape((4, -1)).shape == (4, 2)
    assert three_d.reshape((-1, 4)).shape == (2, 4)
    assert three_d.reshape((2, -1, 2)).shape == (2, 2, 2)
    assert three_d.reshape((1, 2, 1, 2, 2, 1)).shape == (1, 2, 1, 2, 2, 1)
Exemple #4
0
def test_signal_reshape():
    """Tests Signal.reshape"""
    # check proper shape after reshape
    three_d = Signal(np.ones((2, 2, 2)))
    assert three_d.reshape((8, )).shape == (8, )
    assert three_d.reshape((4, 2)).shape == (4, 2)
    assert three_d.reshape((2, 4)).shape == (2, 4)
    assert three_d.reshape(-1).shape == (8, )
    assert three_d.reshape((4, -1)).shape == (4, 2)
    assert three_d.reshape((-1, 4)).shape == (2, 4)
    assert three_d.reshape((2, -1, 2)).shape == (2, 2, 2)
    assert three_d.reshape((1, 2, 1, 2, 2, 1)).shape == (1, 2, 1, 2, 2, 1)

    # check with non-contiguous arrays (and with offset)
    value = np.arange(20).reshape(5, 4)
    s = Signal(np.array(value), name="s")

    s0slice = slice(0, 3), slice(None, None, 2)
    s0shape = 2, 3
    s0 = s[s0slice].reshape(*s0shape)
    assert s.offset == 0
    assert np.array_equal(s0.initial_value, value[s0slice].reshape(*s0shape))

    s1slice = slice(1, None), slice(None, None, 2)
    s1shape = 2, 4
    s1 = s[s1slice].reshape(s1shape)
    assert s1.offset == 4 * s1.dtype.itemsize
    assert np.array_equal(s1.initial_value, value[s1slice].reshape(s1shape))

    # check error if non-contiguous array cannot be reshaped without copy
    s2slice = slice(None, None, 2), slice(None, None, 2)
    s2shape = 2, 3
    s2 = s[s2slice]
    with pytest.raises(SignalError):
        s2.reshape(s2shape)

    # check that views are working properly (incrementing `s` effects views)
    values = SignalDict()
    values.init(s)
    values.init(s0)
    values.init(s1)

    values[s] += 1
    assert np.array_equal(values[s0], value[s0slice].reshape(s0shape) + 1)
    assert np.array_equal(values[s1], value[s1slice].reshape(s1shape) + 1)
Exemple #5
0
def test_signal_reshape():
    """Tests Signal.reshape"""
    # check proper shape after reshape
    three_d = Signal(np.ones((2, 2, 2)))
    assert three_d.reshape((8,)).shape == (8,)
    assert three_d.reshape((4, 2)).shape == (4, 2)
    assert three_d.reshape((2, 4)).shape == (2, 4)
    assert three_d.reshape(-1).shape == (8,)
    assert three_d.reshape((4, -1)).shape == (4, 2)
    assert three_d.reshape((-1, 4)).shape == (2, 4)
    assert three_d.reshape((2, -1, 2)).shape == (2, 2, 2)
    assert three_d.reshape((1, 2, 1, 2, 2, 1)).shape == (1, 2, 1, 2, 2, 1)

    # check with non-contiguous arrays (and with offset)
    value = np.arange(20).reshape(5, 4)
    s = Signal(np.array(value), name='s')

    s0slice = slice(0, 3), slice(None, None, 2)
    s0shape = 2, 3
    s0 = s[s0slice].reshape(*s0shape)
    assert s.offset == 0
    assert np.array_equal(s0.initial_value, value[s0slice].reshape(*s0shape))

    s1slice = slice(1, None), slice(None, None, 2)
    s1shape = 2, 4
    s1 = s[s1slice].reshape(s1shape)
    assert s1.offset == 4 * s1.dtype.itemsize
    assert np.array_equal(s1.initial_value, value[s1slice].reshape(s1shape))

    # check error if non-contiguous array cannot be reshaped without copy
    s2slice = slice(None, None, 2), slice(None, None, 2)
    s2shape = 2, 3
    s2 = s[s2slice]
    with pytest.raises(SignalError):
        s2.reshape(s2shape)

    # check that views are working properly (incrementing `s` effects views)
    values = SignalDict()
    values.init(s)
    values.init(s0)
    values.init(s1)

    values[s] += 1
    assert np.array_equal(values[s0], value[s0slice].reshape(s0shape) + 1)
    assert np.array_equal(values[s1], value[s1slice].reshape(s1shape) + 1)
Exemple #6
0
def test_opstomerge_check_signals():
    sig = Signal(np.arange(10))
    sig_orig = sig.reshape(10)
    sig_reshaped = sig.reshape(2, 5)
    assert not OpsToMerge.check_signals(Copy(sig_orig, sig_orig),
                                        Copy(sig_reshaped, sig_reshaped))