def from_npz(cls, filename, device, iteration=None): if iteration is not None: filename = '{}.{}'.format(ensure_npz(filename, inverse=True), iteration) data = np.load(ensure_npz(filename)) t_matrix = torch.from_numpy(data['t_matrix']) means = torch.from_numpy(data['means']) inv_covariances = torch.from_numpy(data['inv_covariances']) prior_offset = torch.from_numpy(data['prior_offset']) return IVectorExtractor(t_matrix, means, inv_covariances, prior_offset, device)
def save_npz(self, filename): np.savez(filename, t_matrix=self.t_matrix.cpu().numpy(), means=self.means.cpu().numpy(), inv_covariances=self.inv_covariances.cpu().numpy(), prior_offset=self.prior_offset.cpu().numpy()) print('I-vector extractor saved to {}'.format(ensure_npz(filename)))
def from_npz(cls, filename, device): data = np.load(ensure_npz(filename)) weights = torch.from_numpy(data['weights']) means = torch.from_numpy(data['means']) covariances = torch.from_numpy(data['covariances']) return Gmm(means, covariances, weights, device)
def train(self, rxspecifiers, feature_loader, output_filename, settings, resume=0): if resume < 0: resume = 0 elif resume > 0: print('Resuming i-vector extractor training from iteration {}...'. format(resume)) extractor = IVectorExtractor.from_npz( '{}.{}'.format(ensure_npz(output_filename, inverse=True), resume), self.t_matrix.device) self.t_matrix = extractor.t_matrix self.means = extractor.means self.inv_covariances = extractor.inv_covariances self.prior_offset = extractor.prior_offset print('Training i-vector extractor ({} iterations)...'.format( settings.n_iterations)) n_utts = len(rxspecifiers[0]) component_batches = self._get_component_batches( settings.n_component_batches) print('Allocating memory for accumulators...') z = torch.zeros(self.n_components, device=self.t_matrix.device) S = torch.zeros(self.n_components, self.feat_dim, self.feat_dim, device=self.t_matrix.device) Y = torch.zeros(self.n_components, self.feat_dim, self.ivec_dim, device=self.t_matrix.device) R = torch.zeros( self.n_components, self.ivec_dim, self.ivec_dim, device=self.t_matrix.device) # The biggest memory consumer! h = torch.zeros(self.ivec_dim, device=self.t_matrix.device) H = torch.zeros(self.ivec_dim, self.ivec_dim, device=self.t_matrix.device) iteration_times = [] start_time = time.time() for iteration in range(1, settings.n_iterations + 1): iter_start_time = time.time() print('Initializing statistics loader...') accumulate_2nd_stats = settings.update_covariances and iteration == 1 # 2nd order stats need to be accumulated only once stat_loader = self._get_stat_loader(rxspecifiers, feature_loader, accumulate_2nd_stats, settings.batch_size_in_utts, settings.dataloader_workers) print('Iterating over batches of utterances...') for batch_index, batch in enumerate(stat_loader): if accumulate_2nd_stats: n_all, f_all, s_batch_sum = batch S += s_batch_sum.to(self.t_matrix.device) else: n_all, f_all = batch batch_size = n_all.size()[0] print( 'Iteration {} ({:.0f} seconds), Batch {}/{}: utterance count = {}' .format(iteration + resume, time.time() - iter_start_time, batch_index + 1, stat_loader.__len__(), batch_size)) n_all = n_all.to(self.t_matrix.device) f_all = f_all.to(self.t_matrix.device) if iteration == 1: # Need to be accumulated only once z += torch.sum(n_all, dim=0) means, covariances = self._compute_posterior_means_and_covariances( n_all, f_all, batch_size, component_batches) # Accumulating... h += torch.sum(means, dim=0) yy = torch.baddbmm(covariances, means.unsqueeze(2), means.unsqueeze(1)) H += torch.sum(yy, dim=0) yy = yy.permute((1, 2, 0)) for bstart, bend in component_batches: # Batching over components saves GPU memory n = n_all[:, bstart:bend] f = f_all[bstart:bend, :, :] Y[bstart:bend, :, :] += torch.matmul(f, means) R[bstart:bend, :, :] += torch.matmul(yy, n).permute( (2, 0, 1)) self.weights = z / torch.sum(z) * n_utts h = h / n_utts H = H / n_utts H = H - torch.ger(h, h) # Updating: if settings.update_projections: self._update_projections(Y, R, component_batches) if settings.update_covariances: self._update_covariances(Y, R, z, S, component_batches) if settings.minimum_divergence: self._minimum_divergence_whitening(h, H, component_batches) if settings.update_means: self._minimum_divergence_centering(h, component_batches) print('Zeroing accumulators...') Y.zero_() R.zero_() h.zero_() H.zero_() if settings.save_every_iteration: self.save_npz('{}.{}'.format( ensure_npz(output_filename, inverse=True), iteration + resume)) iteration_times.append(time.time() - iter_start_time) self.save_npz(output_filename) print('Training completed in {:.0f} seconds.'.format(time.time() - start_time)) return iteration_times
def save_npz(self, filename): np.savez(filename, weights=self.weights.cpu().numpy(), means=self.means.cpu().numpy(), covariances=self.covariances.cpu().numpy()) print('GMM saved to {}'.format(ensure_npz(filename)))