心胸决定格局,眼界决定境界...

摘要: 实时语音通信发展到今天,用户对通话语音质量提出了越来越高的要求。由于终端设备的多样性以及使用场景的差异,声音问题依然存在。传统的音频处理技术从声音信号本身出发,挖掘其时频特性,作出假设,建立物理模型,很多参数都需要人工进行精细化微调,比较费时费力。随着AI技术的发展,凭借着其强大的拟合能力,利用数据 阅读全文
posted @ 2019-03-14 14:28 WELEN 阅读(9042) 评论(2) 推荐(1) 编辑
摘要: 噪声问题一直是语音识别的一个老大难的问题,在理想的实验室的环境下,识别效果已经非常好了,之前听很多音频算法工程师抱怨,在给识别做降噪时,经常发现WER不降反升,降低了识别率,有点莫名其妙,又无处下手。 刚好,前段时间调到了AIlab部门,有机会接触这块,改善语音识别的噪声问题,虽然在此之前,询问过同 阅读全文
posted @ 2019-03-13 16:32 WELEN 阅读(10764) 评论(3) 推荐(9) 编辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
SyncTaskQueue.h
#pragma once
#include <list>
#include <mutex>
#include <condition_variable>
#include <iostream>
 
template <typename TASK>
class SyncTaskQueue//队列内部实现加锁,保证操作同步
{ //这个队列是被线程池使用,因此具体实例在线程池中定义
public:
    SyncTaskQueue(int max_size) :max_size_(max_size) {
 
 
    }
    ~SyncTaskQueue() {//何时析构   如果有个操作在一个线程中阻塞, 对象无法析构
        Stop();
        std::cout << "SyncTaskQueue destruction" << std::endl;
    }
    void  Stop() {//退出循环
        stop_ = true;
        not_empty_cond_.notify_one();
        not_full_cond_.notify_one();
        std::cout << "SyncTaskQueue Stop" << std::endl;
    }
 
    bool IsFull() {
        std::lock_guard<std::mutex>  locker;
        return list_task_.size() == max_size_;
 
    }
 
    bool IsEmpty() {
        std::lock_guard<std::mutex> locker;
        return list_task_.size() == 0;
    }
 
    void Push(TASK &&data) {
        std::unique_lock<std::mutex> locker(mutex_);
        while (Full() && !stop_) {//避免多次获取互斥锁
            std::cout << "task queue is full, wait" << std::endl;//阻塞
            //满的时候等待, 阻塞等待消费
            not_full_cond_.wait_for(locker, std::chrono::milliseconds(500));
        }
        if (stop_) {
            return;
        }
        if (!Full()) {
            list_task_.push_back(std::forward<TASK>(data));//为什么需要std::forward,保证右值,移动拷贝?
            not_empty_cond_.notify_one();//not empty cond signal  
        }
 
    }
 
    void Pop(TASK& data){//没有用返回值的形式
        std::unique_lock<std::mutex> locker(mutex_);
        while (Empty() && !stop_) {
            std::cout << "task queue is empty, wait" << std::endl;//阻塞
            not_empty_cond_.wait_for(locker, std::chrono::milliseconds(500));
        }
        if (!Empty()) {
            data = list_task_.front();
            list_task_.pop_front();//list  pop操作分为2步
            not_full_cond_.notify_one();//not full cond signal       
        }
    }
 
private:
    bool Full() {
        return list_task_.size() == max_size_;
    }
    bool Empty() {
        return list_task_.size() == 0;
    }
    std::mutex   mutex_;
    int max_size_;
    std::atomic<bool>   stop_ = false;
    std::condition_variable   not_full_cond_;//没有满的时候激发
    std::condition_variable   not_empty_cond_;
    std::list<TASK>  list_task_;
};
 
ThreadPool.h
#pragma once
#include <list>
#include <thread>
#include <functional>
#include <memory>
#include <atomic>
#include "SyncTaskQueue.h"
#include <mutex>
#include <condition_variable>
#include <iostream>
 
class ThreadPool {
public:
    using Task = std::function<void()>;//使用别名
    ThreadPool();
    ~ThreadPool();
 
    void Stop();
    void AddTask(Task &&task);
private:
    void Start(int num_thread);
    void RunThread();
    void StopThread();
 
private:
    //多个线程对象容器,方便管理
    std::list<std::shared_ptr<std::thread>> thread_group_;
    int thread_num_;//线程数
    SyncTaskQueue<Task>  queue_;//任务队列
    std::atomic<bool> stop_ = false;//需要包含头文件atomic
    std::once_flag  flag_;
};
 
ThreadPool.cpp
#include "ThreadPool.h"
 
 
ThreadPool::ThreadPool():queue_(10)
{//构造函数  Start私有化  保证也只能执行一次
    thread_num_ = std::thread::hardware_concurrency();
    Start(thread_num_);
}
ThreadPool::~ThreadPool()
{
   Stop();
}
 
void ThreadPool::Stop() {//保证stop 只有一次
    std::call_once(flag_, [this] {StopThread(); });
}
 
void ThreadPool::AddTask(Task &&task) {
    queue_.Push(std::forward<Task>(task));
}
 
void ThreadPool::Start(int num_thread) {
    thread_num_ = num_thread;
    std::cout << "thread pool start" << std::endl;
    for (int i = 0; i < thread_num_; i++) {
        thread_group_.push_back(std::make_shared<std::thread>(&ThreadPool::RunThread, this));//创建线程的过程中将线程函数传进去       
        std::cout << "thread " << thread_group_.back()->get_id() << " create " << std::endl;
    }
#if 0
    for (auto thread : thread_group_) {
        thread->get_id();
    }
#endif
     
}
 
//所有的子线程都会从任务队列里面去取任务执行
void ThreadPool::RunThread() {//线程从任务队列中取任务
    //多个线程里面只有队列任务共享的,stop_数据是共享的
    while (!stop_) {//如果没有停止,则一直在while循环
        Task  task_object;
        queue_.Pop(task_object);//如果没有数据,会自动阻塞
        if (stop_) {//如果时停止,则直接return
            return;
        }
        task_object();//取出任务执行,本线程不结束,继续从队列里面取任务执行
        std::cout << "thread id " << std::this_thread::get_id() << " exec one task" << std::endl;
 
    }
}
 
void ThreadPool::StopThread() {
    stop_ = true;
    queue_.Stop();//任务队列可能阻塞,需要先停止
    //等待线程池中的所有线程执行结束
    for (auto it = thread_group_.begin(); it != thread_group_.end(); it++) {
        (*it)->join();
    }
    thread_group_.clear();//线程对象列表清除
    std::cout << "thread pool stop" << std::endl;
}
 
void test_ThreadPool()
{
 
    ThreadPool  thread_pool;
 
    std::thread  thread1([&thread_pool] {
        auto id = std::this_thread::get_id();
        std::cout << "thread id " << id << " add task " << std::endl;
        thread_pool.AddTask([id]() {       
            std::cout << "thread id " << id << " exec task " <<std::endl;
        });
    });
        
    std::thread  thread2([&thread_pool] {
        auto id = std::this_thread::get_id();
        std::cout << "thread id " << id << " add task " << std::endl;
        thread_pool.AddTask([id]() {
            std::cout << "thread id " << id << " exec task " << std::endl;
        });
    });
 
    std::thread  thread3([&thread_pool] {
        auto id = std::this_thread::get_id();
        std::cout << "thread id " << id << "add task" << std::endl;
        thread_pool.AddTask([id]() {
            std::cout << "thread id " << id << "exec task" << std::endl;
        });
    });
 
    //过完2s再结束
    std::this_thread::sleep_for(std::chrono::seconds(2));
    thread_pool.Stop();//线程池结束
    thread1.join();
    thread2.join();
    thread3.join();//同步线程函数执行完
}

  

posted @ 2021-03-17 19:24 WELEN 阅读(237) 评论(0) 推荐(0) 编辑
摘要: 消息总线模式 == 等价于 发布-订阅模式 消息总线 == 事件处理中心 观察者应该主动向消息总线注册事件,因为消息总线并不知道哪些对象需要别注册。 当主题发生变化时,主动向消息总线发送消息。 消息总线会找到关注指定消息的所有观察者,进行通告,观察者做出行动。 Observer Message Bu 阅读全文
posted @ 2021-03-17 16:19 WELEN 阅读(428) 评论(0) 推荐(0) 编辑
摘要: complex.h #pragma once #include <iostream> #define FRIEND_FUNC 1 #define INLINE_FUNC 1 class ostream; class istream; class Complex { public: Complex() 阅读全文
posted @ 2021-02-28 15:56 WELEN 阅读(137) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2017-11-18 09:50 WELEN 阅读(6) 评论(0) 推荐(0) 编辑
摘要: 这次wer由15%下降到0%了,后面跑更多的模型 LOG (apply-cmvn[5.2.124~1396-70748]:main():apply-cmvn.cc:162) Applied cepstral mean normalization to 20 utterances, errors on 阅读全文
posted @ 2017-10-13 11:28 WELEN 阅读(2779) 评论(0) 推荐(0) 编辑
摘要: 基本模型没有变化,主要是调参,配置: %WER 65% 下降到了 15% 后面再继续优化... Graph compilation finish!steps/decode.sh --nj 1 --cmd utils/run.pl exp/mono0/graph_tgpr data/waves_tes 阅读全文
posted @ 2017-09-29 16:31 WELEN 阅读(2406) 评论(0) 推荐(0) 编辑
摘要: train_mono.sh prepare_lang.sh run.sh 阅读全文
posted @ 2017-09-29 16:27 WELEN 阅读(2878) 评论(0) 推荐(0) 编辑
摘要: http://blog.csdn.net/u013677156/article/details/77893661 1、kaldi解码过程 kaldi识别解码一段语音的过程是:首先提取特征,然后过声学模型AM,然后过解码网络HCLG.fst,最后输出识别结果。 HCLG是解码时的重要组成部分。HCLG 阅读全文
posted @ 2017-09-29 15:38 WELEN 阅读(4162) 评论(0) 推荐(1) 编辑
摘要: 孤立词参考的例子就是yes/no脚本。 这里我们做10个词识别实验,熟悉整条链路。 后续尝试一些新的模型提高识别率; 再尝试模型语速、语调、平稳噪声的鲁棒性,尝试已有去噪处理算法的优化前端; 扩大孤立词的数量,裁剪模型,效率优化,熟悉FST解码器,将嵌入式硬件的孤立词识别能做到实用层面。 最后做连续 阅读全文
posted @ 2017-09-26 15:53 WELEN 阅读(5228) 评论(3) 推荐(0) 编辑
摘要: SRILM是一个建立和使用统计语言模型的开源工具包,从1995年开始由SRI 口语技术与研究实验室(SRI Speech Technology and Research Laboratory)开发,现在仍然不断推出新版本,被广泛应用于语音识别、机器翻译等领域。这个工具包包含一组C++类库、一组进行语 阅读全文
posted @ 2017-09-25 18:15 WELEN 阅读(13442) 评论(0) 推荐(0) 编辑
摘要: 转自:http://blog.csdn.net/xmdxcsj/article/details/54695506 overview Karel’s DNN和Dan’s DNN格式不兼容,可以使用egs/rm/s5/local/run_dnn_convert_nnet2.sh进行格式转化。 nnet1 阅读全文
posted @ 2017-09-22 10:08 WELEN 阅读(3350) 评论(0) 推荐(0) 编辑
摘要: 作者:zqh_zy链接:http://www.jianshu.com/p/c5fb943afaba來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 本文通过简单kaldi源码,分析DNN训练声学模型时神经网络的输入与输出。在进行DNN训练之前需要用到之前GMM-HMM训 阅读全文
posted @ 2017-09-21 11:34 WELEN 阅读(5140) 评论(0) 推荐(2) 编辑
摘要: 转自: http://www.jianshu.com/p/5b19605792ab?utm_campaign=maleskine&utm_content=note&utm_medium=pc_all_hots&utm_source=recommendation http://www.jianshu. 阅读全文
posted @ 2017-09-21 11:26 WELEN 阅读(3318) 评论(0) 推荐(0) 编辑
摘要: 转自:http://blog.csdn.net/inger_h/article/details/52789339 在已经训练好模型的情况下,需要针对一个新任务做在线识别应该怎么做呢? 一种情况是,用已有的声学模型和新训练的语言模型。 语言模型可以同srilm等工具训练,但是怎样将语言模型与DNN声学 阅读全文
posted @ 2017-09-21 10:49 WELEN 阅读(3660) 评论(0) 推荐(0) 编辑
摘要: 转自:http://blog.csdn.net/huchad/article/details/52092796 使用kaldi的DNN做音频分类,异常声音检测。 HMM/GMM -》 HMM/DNN 基本上沿用语音识别的思路,有两点注意一下即可。 1. 在训HMM/GMM时,训到monophone即 阅读全文
posted @ 2017-09-21 10:47 WELEN 阅读(1664) 评论(0) 推荐(0) 编辑
摘要: 转自:http://blog.csdn.net/zjm750617105/article/details/55211992 对于每个类别的GMM有几种思路: 第一是将所有训练数据按类别分开,每类的数据训练一个GMM模型 第二是将所有的数据训练一个UBM模型,然后将训练数据按类别分开,用MAP去训练每 阅读全文
posted @ 2017-09-21 10:40 WELEN 阅读(1994) 评论(0) 推荐(0) 编辑
摘要: 参考:https://zhuanlan.zhihu.com/p/24979135?refer=ycgkk 阅读全文
posted @ 2017-09-19 17:42 WELEN 阅读(1439) 评论(0) 推荐(0) 编辑
摘要: 运行getdata.sh,下载voxforge语音库 修改cmd.sh queue.pl为run.pl. install_srilm.sh 执行该脚本 按照网址下载srilm.tgz,然后运行install_srilm.sh 提示安装 sudo ./install_sequitur.sh sudo 阅读全文
posted @ 2017-09-19 11:04 WELEN 阅读(1978) 评论(0) 推荐(0) 编辑
点击右上角即可分享
微信分享提示