예제 #1
0
    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
예제 #2
0
 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()
예제 #3
0
    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('基元载入完成 √')
예제 #4
0
    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()  # 清空数据内存
예제 #5
0
        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
예제 #6
0
    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()  # 清空数据内存
예제 #7
0
 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()  # 清空数据内存
예제 #8
0
    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