Beispiel #1
0
    def _triplet_loss(self, feat_q, targets):
        dist_mat = euclidean_dist(feat_q, self.queue.t())

        N, M = dist_mat.size()
        is_pos = targets.view(N, 1).expand(N, M).eq(self.queue_label.expand(N, M)).float()

        sorted_mat_distance, positive_indices = torch.sort(dist_mat + (-9999999.) * (1 - is_pos), dim=1,
                                                           descending=True)
        dist_ap = sorted_mat_distance[:, 0]
        sorted_mat_distance, negative_indices = torch.sort(dist_mat + 9999999. * is_pos, dim=1,
                                                           descending=False)
        dist_an = sorted_mat_distance[:, 0]

        y = dist_an.new().resize_as_(dist_an).fill_(1)

        loss = F.soft_margin_loss(dist_an - dist_ap, y)
        if loss == float('Inf'): loss = F.margin_ranking_loss(dist_an, dist_ap, y, margin=0.3)

        return loss
Beispiel #2
0
def generate_layer_outputs(num_polarities, features, tau, r, width, height,
                           events):
    """
    Generate events at the output of a layer from a stream of incoming events

    :param num_polarities: number of polarities of incoming events
    :param features: list of trained features for this layer
    :param tau: time constant [us]
    :param r: radius [pixels]
    :param width: [pixels]
    :param height: [pixels]
    :param events: list of incoming events. Must be at least as many elements as N.
    :return: events at output of layer
    """

    S = [
        TimeSurface(height, width, region_size=r, time_constant=tau)
        for _ in range(num_polarities)
    ]
    events_out = []

    for e in events:
        # update time surface with incoming event. Select the time surface corresponding to polarity of event.

        S[e.p].process_event(e)

        # select the closest feature to this time surface

        dists = [
            euclidean_dist(feature.reshape(-1),
                           S[e.p].time_surface.reshape(-1))
            for feature in features
        ]

        k = np.argmin(dists)

        # create output event

        events_out.append(Event(x=e.x, y=e.y, ts=e.ts, p=k))

    return events_out
Beispiel #3
0
def test_euclidean_distance_for_different_vectors_gives_non_zero_scalar():
    a = np.array([1, 0])

    b = np.array([0, 1])

    assert euclidean_dist(a, b) == np.sqrt(2)
Beispiel #4
0
def test_euclidean_distance_for_same_vectors_gives_0():
    a = np.array([1, 2])

    b = np.array([1, 2])

    assert euclidean_dist(a, b) == 0
Beispiel #5
0
def train_layer(C,
                N,
                tau,
                r,
                width,
                height,
                events,
                num_polarities,
                layer_number,
                plot=False):
    """
    Train the time surface prototypes in a single layer

    :param C: time surface prototypes (i.e. cluster centers) that have been initialised
    :param N:
    :param tau:
    :param r:
    :param width:
    :param height:
    :param events:
    :param num_polarities:
    :param layer_number: the number of this layer
    :param plot:
    :return:
    """

    # initialise time surface
    S = [
        TimeSurface(height, width, region_size=r, time_constant=tau)
        for _ in range(num_polarities)
    ]

    p = [1] * N

    alpha_hist = []
    beta_hist = []
    p_hist = []
    k_hist = []
    dists_hist = []
    S_prev = deepcopy(S)
    event_times = []

    for i, e in enumerate(events):
        valid = S[e.p].process_event(e)

        if not valid:
            continue

        # find closest cluster center (i.e. closest time surface prototype, according to euclidean distance)

        dists = [
            euclidean_dist(c_k.reshape(-1), S[e.p].time_surface.reshape(-1))
            for c_k in C
        ]

        k = np.argmin(dists)

        # print('k:', k, dists)

        # update prototype that is closest to

        alpha = 0.01 / (
            1 + p[k] / 20000.
        )  # TODO: testing. If p[k] >> 0 then alpha -> 0 (maybe reset p after each event stream?)

        beta = cosine_dist(C[k].reshape(-1), S[e.p].time_surface.reshape(-1))
        C[k] += alpha * (S[e.p].time_surface - beta * C[k])

        p[k] += 1

        if False:  # TODO: testing
            if i % 500 == 0:
                fig, ax = plt.subplots(1, N, figsize=(25, 5))
                for i in range(N):
                    ax[i].imshow(C[i], vmin=0, vmax=1)
                    ax[i].set_title('Layer {}. Time surface {} (p={})'.format(
                        layer_number, i, p[i]))
                plt.show()

        # record history of values for debugging purposes

        alpha_hist.append(alpha)
        beta_hist.append(beta)
        p_hist.append(p[:])
        k_hist.append(k)
        dists_hist.append(dists[:])
        S_prev = deepcopy(S)
        event_times.append(e.ts)

    # print(e, dists, k, alpha, beta, p)

    if plot:
        p_hist = np.array(p_hist)
        dists_hist = np.array(dists_hist)

        fig, ax = plt.subplots(1, N, figsize=(25, 5))

        for i in range(N):
            ax[i].imshow(C[i], vmin=0, vmax=1)
            ax[i].set_title('C_{} (p={})'.format(i, p[i]))

        fig, ax = plt.subplots(6, 1, sharex=True, figsize=(12, 12))
        ax[0].plot(alpha_hist, label='alpha')
        ax[1].plot(beta_hist, label='beta')
        for j in range(p_hist.shape[1]):
            ax[2].plot(p_hist[:, j], label='p_{}'.format(j))
        ax[2].legend()
        for j in range(dists_hist.shape[1]):
            ax[3].plot(dists_hist[:, j], label='dist_{}'.format(j))
        ax[3].legend()
        ax[4].plot(beta_hist, label='k')
        ax[5].plot(event_times, label='e.ts')
        ax[0].set_title('alpha')
        ax[1].set_title('beta')
        ax[2].set_title('p')
        ax[3].set_title('dists')
        ax[4].set_title('k')
        ax[5].set_title('e.ts')

        plt.show()