def __flat_start(self, label_data): """ 均一起步 (停止使用) 计算全局均值和方差 :param label_data: 所有数据 :return: """ '''data为所有数据的合集''' data = list(label_data.values()) _data = None size = 0 for index in range(len(data)): size += sum(data[index][1]) tmp_data = data[index][0][0] for d in range(1, len(data[index][0])): tmp_data = np.append(tmp_data, data[index][0][d], axis=0) if _data is None: _data = tmp_data else: _data = np.append(_data, tmp_data, axis=0) label = list(label_data.keys()) _label = [] for l in label: _label.extend(l.split(',')) '''取不重复基元''' label = list(set(_label)) cluster = Clustering.ClusterInitialization(_data, self.__mix_level, self.__vector_size, self.log) mean, covariance, alpha, clustered_data = cluster.kmeans(algorithm=1) '''训练GMM''' tmp_gmm = Clustering.GMM(None, self.__vector_size, self.__mix_level) tmp_gmm.data = data tmp_gmm.mean = mean tmp_gmm.covariance = covariance tmp_gmm.alpha = alpha '''GMM Baulm-Welch迭代''' tmp_gmm.baulm_welch() '''获取均值、协方差和权重值''' mean = tmp_gmm.mean covariance = tmp_gmm.covariance alpha = tmp_gmm.alpha for i in range(len(label)): hmm = self.__unit[label[i]][1] for j in range(1, len(hmm.profunction) - 1): '''除去前后两个虚方法''' gmm = hmm.profunction[j] gmm.mean = mean gmm.covariance = covariance gmm.alpha = alpha
def __flat_start(self, path_list, file_count, proportion=0.25, step=1, differentiation=True, coefficient=1.): """ 均一起步 计算全局均值和方差 :param path_list: 数据路径列表 :param file_count: 数据总量 :param proportion: 训练数据中,用于计算全局均值和协方差的数据占比 :param step: 在帧中跳跃选取的跳跃步长 :param differentiation: GMM中各分模型参数差异化处理 :param coefficient: 差异化程度,区间[0,1] :return: """ self.log.note('flat starting...', cls='i') p_file_count = int(file_count * proportion) p_data = self.__load_audio(path_list[0][0]) p_data = p_data[::step] for index in range(1, p_file_count): data = self.__load_audio(path_list[index][0]) # 加载音频数据 data = data[::step] p_data = np.append(p_data, data, axis=0) cluster = Clustering.ClusterInitialization(p_data, 1, self.__vector_size, self.log) mean, covariance, alpha, clustered_data = cluster.kmeans( algorithm=1, cov_matrix=True) covariance_diagonal = covariance[0].diagonal() units = self.__loaded_units '''''' diff_coefficient = np.zeros((self.__mix_level, 1)) if differentiation: '''差异化处理''' assert 0 <= coefficient <= 1, '差异化系数不满足区间[0,1]' diff_coefficient = (np.random.random( (self.__mix_level, 1)) - np.random.random( (self.__mix_level, 1))) * coefficient for unit in units: hmm = self.init_unit(unit, new_log=True) gmms = hmm.profunction[1:-1] for g in gmms: g.mean = mean.repeat( self.__mix_level, axis=0) + diff_coefficient * covariance_diagonal g.covariance = covariance.repeat(self.__mix_level, axis=0) self.__save_parameter(unit, hmm) self.delete_trainInfo()
def initialize_unit(self, unit_type='XIF'): """ 初始化基元 :param unit_type: 基元类型 :return: """ unit_type_path = unit + unit_type self.__unit_type = unit_type if os.path.exists(unit_type_path) is False: raise FileExistsError('Error: 基元文件%s不存在' % unit_type) else: if os.path.exists(path_parameter + unit_type) is False: os.mkdir(path_parameter + unit_type) with open(unit_type_path) as f: u = f.readline() print('使用基元:', u) print('载入基元中...') while u: u = f.readline() if len(u) == 0: break u = u.strip('\n').split(',') for i in range(len(u)): '''状态集合''' states = {_: u[i] for _ in range(self.__state_num)} '''观测概率表示(GMM)''' observations = ['GMM_probability'] '''状态转移矩阵''' A = np.zeros((self.__state_num, self.__state_num)) '''开始状态,为虚状态,只允许向下一个状态转移''' A[0][1] = 1. for j in range(1, self.__state_num - 1): for k in range(j, j + 2): A[j][k] = 0.5 '''初始化GMM''' gmm = [ Clustering.GMM(self.__vector_size, self.__mix_level) for _ in range(self.__state_num - 2) ] '''初始化虚状态评分类''' virtual_gmm_1 = AcousticModel.VirtualState(0.) virtual_gmm_2 = AcousticModel.VirtualState(0.) gmm.insert(0, virtual_gmm_1) gmm.append(virtual_gmm_2) '''生成hmm实例''' lhmm = LHMM(states, observations, None, A=A, profunc=gmm) '''数据结构:{基元:[训练次数,HMM],}''' self.__unit[u[i]] = [0, lhmm] print('基元载入完成 √')
def __cal_gmm(self, unit, unit_data, init=False, smem=False, show_q=False, c_covariance=1e-3): """ 计算GMM :param unit: 当前基元 :param unit_data: 基元数据 :param init: 是否初始化 :param smem: 是否进行SMEM算法 :param show_q: 显示当前似然度 :param c_covariance: 修正数值,纠正GMM中的Singular Matrix :return: """ hmm = self.__unit[unit] gmms_num = len(hmm.profunction) - 2 # 高斯混合模型数 for i in range(1, len(hmm.profunction) - 1): '''除去前后两个虚方法''' gmm = hmm.profunction[i] gmm.log.note('正在训练GMM%d,共 %d GMM,混合度为 %d' % (i, gmms_num, self.__mix_level), cls='i') data = unit_data[i - 1] # 对应高斯模型的数据 gmm.add_data(data) if len(data) < self.__mix_level: gmm.log.note('数据过少,忽略该组数据', cls='w') continue if init or gmm.mixture != self.__mix_level: # 当初始化模型或高斯混合度变化时,重新聚类 cluster = Clustering.ClusterInitialization( data, self.__mix_level, self.__vector_size, gmm.log) mean, covariance, alpha, clustered_data = cluster.kmeans( algorithm=1, cov_matrix=True) gmm.mixture = self.__mix_level gmm.mean = mean gmm.covariance = covariance gmm.alpha = alpha '''GMM Baulm-Welch迭代''' gmm.baulm_welch(show_q=show_q, smem=smem, c_covariance=c_covariance) gmm.clear_data() # 清空数据内存
def generate(_unit): """""" '''状态集合''' states = {_: _unit for _ in range(self.__state_num)} '''观测概率表示(GMM)''' observations = ['GMM_probability'] '''状态转移矩阵''' A = np.zeros((self.__state_num, self.__state_num)) '''开始状态,为虚状态,只允许向下一个状态转移''' A[0][1] = 1. for j in range(1, self.__state_num - 1): for k in range(j, j + 2): A[j][k] = 0.5 '''创建基元文件夹''' unit_path = PARAMETERS_FILE_PATH + '/%s/%s' % (self.__unit_type, _unit) if not os.path.exists(unit_path): os.mkdir(unit_path) '''''' '''''' '''''' log = Log(self.__unit_type, _unit, console=self.__console) if new_log: log.generate() else: log.append() '''初始化GMM''' gmm = [ Clustering.GMM(self.__vector_size, self.__mix_level, log) for _ in range(self.__state_num - 2) ] '''初始化虚状态评分类''' virtual_gmm_1 = AcousticModel.VirtualState(0.) virtual_gmm_2 = AcousticModel.VirtualState(0.) gmm.insert(0, virtual_gmm_1) gmm.append(virtual_gmm_2) '''生成hmm实例''' lhmm = LHMM(states, observations, log, T=None, A=A, profunc=gmm, pi=None) '''数据结构:{基元:HMM,...}''' self.__unit[_unit] = lhmm
def __cal_gmm(self, hmm, unit_data, init=False, smem=False, show_q=False, c_covariance=1e-3): """ 计算GMM :param hmm: 外部传入HMM实例 :param unit_data: 基元数据 :param init: 是否初始化 :param smem: 是否进行SMEM算法 :param show_q: 显示当前似然度 :param c_covariance: 修正数值,纠正GMM中协方差值过小问题 :return: """ for i in range(1, self.__state_num - 1): '''除去前后两个虚方法''' gmm = hmm.profunction[i] data = unit_data[i - 1] # 对应高斯模型的数据 gmm.add_data(data) if len(data) < self.__mix_level: gmm.log.note('数据过少,忽略该组数据', cls='w') continue if init or gmm.mixture != self.__mix_level: # 当初始化模型或高斯混合度变化时,重新聚类 cluster = Clustering.ClusterInitialization( data, self.__mix_level, self.__vector_size, gmm.log) mean, covariance, alpha, clustered_data = cluster.kmeans( algorithm=1, cov_matrix=True) gmm.mixture = self.__mix_level gmm.mean = mean gmm.covariance = covariance gmm.alpha = alpha '''GMM Baulm-Welch迭代''' gmm.em(show_q=show_q, smem=smem, c_covariance=c_covariance) gmm.clear_data() # 清空数据内存
def __cal_gmm(self, label, c=True): """初始化GMM""" hmm = self.__unit[label][1] for i in range(1, len(hmm.profunction) - 1): '''除去前后两个虚方法''' gmm = hmm.profunction[i] data = gmm.data if len(data) < self.__mix_level: continue if c: '''重新聚类''' cluster = Clustering.ClusterInitialization( data, self.__mix_level, self.__vector_size) μ, σ, alpha, clustered_data = cluster.kmeans(algorithm=1) gmm.set_k(self.__mix_level) gmm.set_μ(μ) gmm.set_sigma(σ=σ) gmm.set_alpha(alpha) '''GMM Baulm-Welch迭代''' gmm.baulm_welch(show_q=True, smem=True) else: gmm.baulm_welch(show_q=True) gmm.clear_data() # 清空数据内存
def init_unit(self, unit, new_log=True, fix_code=0): """ 初始化基元,生成基元的复合数据结构 :param unit: 初始化指定基元 :param new_log: 是否删除先前日志 :param fix_code: 关闭参数更新,000=0 001=1 010=2 100=4... :return: """ """""" '''状态集合''' states = {_: unit for _ in range(self.__state_num)} '''状态转移矩阵''' transmat = np.zeros((self.__state_num, self.__state_num)) '''开始状态,为虚状态,只允许向下一个状态转移''' transmat[0][1] = 1. for j in range(1, self.__state_num - 1): transmat[j][j] = 0.5 # 第一个转移概率 transmat[j][j + 1] = 0.5 # 第二个转移概率 '''创建基元文件夹''' unit_path = PARAMETERS_FILE_PATH + '/%s/%s' % (self.__unit_type, unit) log_hmm_path = unit_path + '/HMM' log_gmm_path = [ unit_path + '/GMM_%d' % gmm_id for gmm_id in range(self.__state_num - 2) ] try: os.mkdir(unit_path) except FileExistsError: pass try: os.mkdir(log_hmm_path) except FileExistsError: pass try: for gmm_id in range(self.__state_num - 2): os.mkdir(log_gmm_path[gmm_id]) except FileExistsError: pass '''''' '''''' '''''' log_hmm = Log(self.__unit_type, log_hmm_path, console=self.__console) log_gmm = [ Log(self.__unit_type, path=log_gmm_path[gmm_id], console=self.__console) for gmm_id in range(self.__state_num - 2) ] if new_log: log_hmm.generate() for gmm_id in range(self.__state_num - 2): log_gmm[gmm_id].generate() else: log_hmm.append() for gmm_id in range(self.__state_num - 2): log_gmm[gmm_id].append() '''初始化GMM''' gmm = [] for gmm_id in range(self.__state_num - 2): gmm.append( Clustering.GMM(log_gmm[gmm_id], dimension=self.__vector_size, mix_level=self.__mix_level, gmm_id=gmm_id)) '''初始化虚状态评分类''' virtual_gmm_1 = AcousticModel.VirtualState(1.) virtual_gmm_2 = AcousticModel.VirtualState(0.) gmm.insert(0, virtual_gmm_1) gmm.append(virtual_gmm_2) '''生成hmm实例''' lhmm = LHMM(states, self.__state_num, log_hmm, transmat=transmat, profunc=gmm, fix_code=fix_code) return lhmm