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
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
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)
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
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()