2018-06-13 20:04:10 u010866505 阅读数 6632
  • AndroidStudio开发APP-脸脸[网络版]

    本项目可拓展为适用于人脸识别、人脸签到、出席会议等相关场景中。【项目源码放在最后一节的课件里了】脸脸【网络版】项目的实现技术支撑包括My SQL数据库服务器、Java Web后台管理和Android移动APP。其中后台管理使用My Eclipse集成开发工具和Tomcat服务器;Android移动APP使用Android Studio集成开发工具。 后台管理提供接口与Android移动APP进行数据交互功能描述1.人脸库 通过移动端APP采集数据信息,提交到后台处理,最后存储到数据库中;也可以直接批量的存储到数据库中,完成人脸库的数据采集。2.移动端APP 具备采集和签到两个功能,采集功能收集用户的人脸图像和个人基本信息。 签到功能,用户刷脸后,与后台采集的信息对比,并显示最终的结果信息,成功识别则进行语音播报,在后台记录存储记录。 附: 移动端的开发是基于“AndroidStudio开发APP-脸脸[单机版]”,所以这块不熟悉的可以先看[单机版]后再来学习[网络版]。 最近周围有施工的噼里啪啦的心烦意乱脑仁疼,但是全部知识点都ok,大家只需要在自己关心的地方拓展完善即可,我相信大家只要看了之后,肯定都会有所收获的。

    124 人正在学习 去看看 朱松

GMM-HMM语音识别原理

1.       HMM

隐马尔科夫模型(HMM)是一种统计模型,用来描述含有隐含参数的马尔科夫过程。难点是从隐含状态确定出马尔科夫过程的参数,以此作进一步的分析。下图是一个三个状态的隐马尔可夫模型状态转移图,其中x 表示隐含状态,y 表示可观察的输出,a 表示状态转换概率,b 表示输出概率:

a:转移概率

b:输出概率

y:观测状态

x:隐含状态

一个HMM模型是一个五元组(π,A,B,O,S)

其中π:初始概率向量

A:   转移概率

B:   输出概率

O:观测状态

S:隐含状态

围绕着HMM,有三个和它相关的问题:

1.       已知隐含状态数目,已知转移概率,根据观测状态,估计观测状态对应的隐含状态

2.       已知隐含状态数目,已知转移概率,根据观测状态,估计输出这个观测状态的概率

3.       已知隐含状态数目,根据大量实验结果(很多组观测状态),反推转移概率

对于第一个问题,所对应的就是维特比算法

对于第二个问题,所对应的就是前向算法

对于第三个问题,就是前向后向算法

语音识别的过程其实就是上述的第一个问题。根据HMM模型和观测状态(即语音信号数字信号处理后的内容),得到我们要的状态,而状态的组合就是识别出来的文本。

为啥呢?

1)       在语音处理中,一个word有一个或多个音素构成。怎么说呢?这里补充一下语言学的一些知识。在语言学中,word(字)还可以再分解成音节(syllable),音节可以再分成音素(phoneme),音素之后就不能再分了.因此音素是语音中最小的单元,不管语音识别还是语音合成,都是在最小单元上进行操作的,即phoneme。比如我们的“我”,它的拼音是wo3(这个其实就是word,即字),由于中文的word和syllable是相同的,即中文是单音节语言,即中文有且只有一个音节,但英文就不一样,比如hello这个单词,他就是有两个音节,hello=hae|low,即hello有hae和low这两个音节组成.音节下一层是phoneme(音素),语音识别的过程就是把这些 音素找到,然后音素拼接成音节,音节在拼接成word.如下图所示

在识别过程中如果识别出来了音素,向上递归,就能得到word。

因此我们的目标是获取音素phoneme.

2)       在训练时,一个HMM对应一个音素,每个HMM包含n个state(状态),有的是3个状态,有的是5个状态,状态数在训练前确定后,一旦训练完成所有HMM的状态个数都是一致的,比如3个。

GMM是当做发射概率的,即在已知观测状态情况下,哪一种音素会产生这种状态的概率,概率最大的就是我们要的音素。因此,GMM是来计算某一个音素的概率。

GMM的全称是gaussmixture model(高斯混合模型),在训练前,一般会定义由几个高斯来决定音素的概率(高斯数目是超参数)。如下图所示为3高斯:

假设现在我们定义一个HMM由3个状态组成,每个状态中有一个GMM,每个GMM中是由3个gauss。

如上图假设y有状态1,2,3组成,每一个状态下面有一个GMM,高斯个数是3.

由此我们训练的参数有HMM的转移概率矩阵+每一个单高斯的方差,均值和权重(当然还有一个初始概率矩阵).如果我们能得到这些参数,我们是不是就能进行语音识别了?

接下来,就看看GMM-HMM到底是如何做到的?

1:将送进来的语音信号进行分帧(一般是20ms一帧,帧移是10ms),然后提取特征

2:用GMM,判断当前的特征序列属于哪个状态(计算概率)

3:根据前面两个步骤,得出状态序列,其实就得到了音素序列,即得到了声韵母序列。

如下面图所示.

对于GMM-HMM实现语音识别(确切的说是非连续语音识别),到此基本上就结束了,对于连续语音识别而言,还有一个语言模型(主要是通过语料库,n-gram模型)。而前面的GMM-HMM就是声学模型.

 

代码解析:

下面是关于GMM-HMM声学模型,特征序列提取到训练,并且实现识别的完整代码(操作系统:ubuntu16.04,python2)

该demo总共有三个文件,

1:gParam.py,主要是为了配置一些参数

2:核心文件是my_hmm.py,里面实现的是主要代码。

3:test.py是运行文件.

该demo主要是实现识别阿拉伯数字,1,2,3,4.....你可以自己录制训练数据和测试数据.然后设置好路径,运行下面的程序.

程序是完整的

程序是完整的

程序是完整的

说三遍.

wav数据的格式是:


gParam.py 代码解析:

#! /usr/bin python
# encoding:utf-8

TRAIN_DATA_PATH = './data/train/'
TEST_DATA_PATH = './data/test/'
NSTATE = 4
NPDF = 3
MAX_ITER_CNT = 100
NUM=10

这个就没什么好说的。设置路径参数而已.

核心文件my_hmm.py:

#! /usr/bin python
# encoding:utf_8

import numpy as np
from numpy import *
from sklearn.cluster import KMeans
from scipy import sparse
import scipy.io as sio
from scipy import signal
import wave
import math
import gParam
import copy

def pdf(m,v,x):
	'''计算多元高斯密度函数
	输入:
	m---均值向量 SIZE×1
	v---方差向量 SIZE×1
	x---输入向量 SIZE×1
	输出:
	p---输出概率'''
	test_v = np.prod(v,axis=0)
	test_x = np.dot((x-m)/v,x-m)
	p = (2*math.pi*np.prod(v,axis=0))**-0.5*np.exp(-0.5*np.dot((x-m)/v,x-m))
	return p

# class of every sample infomation
class sampleInfo:
	"""docstring for ClassName"""
	def __init__(self):		
		self.smpl_wav = []
		self.smpl_data = []
		self.seg = []
	def set_smpl_wav(self,wav):
		self.smpl_wav.append(wav)
	def set_smpl_data(self,data):
		self.smpl_data.append(data)
	def set_segment(self, seg_list):
		self.seg = seg_list

#class of mix info from KMeans
class mixInfo:
	"""docstring for mixInfo"""
	def __init__(self):
		self.Cmean = []
		self.Cvar = []
		self.Cweight = []
		self.CM = []
class hmmInfo:
	'''hmm model param'''
	def __init__(self):
		self.init = [] #初始矩阵
		self.trans = [] #转移概率矩阵
		self.mix = [] #高斯混合模型参数
		self.N = 0 #状态数
# class of gmm_hmm model
class gmm_hmm:
	def __init__(self):
		self.hmm = [] #单个hmm序列,
		self.gmm_hmm_model = [] #把所有的训练好的gmm-hmm写入到这个队列
		self.samples = [] # 0-9 所有的音频数据
		self.smplInfo = [] #这里面主要是单个数字的音频数据和对应mfcc数据
		self.stateInfo = [gParam.NPDF,gParam.NPDF,gParam.NPDF,gParam.NPDF]#每一个HMM对应len(stateInfo)个状态,每个状态指定高斯个数(3)
	def loadWav(self,pathTop):
		for i in range(gParam.NUM):
			tmp_data = []
			for j in range(gParam.NUM):
				wavPath = pathTop + str(i) + str(j) + '.wav'
				f = wave.open(wavPath,'rb')
				params = f.getparams()
				nchannels,sampwidth,framerate,nframes = params[:4]
				str_data = f.readframes(nframes)
				#print shape(str_data)
				f.close()
				wave_data = np.fromstring(str_data,dtype=short)/32767.0
				#wave_data.shape = -1,2
				#wave_data = wave_data.T
				#wave_data = wave_data.reshape(1,wave_data.shape[0]*wave_data.shape[1])
				#print shape(wave_data),type(wave_data)				
				tmp_data.append(wave_data)
			self.samples.append(tmp_data)
	#循环读数据,然后进行训练		
	def hmm_start_train(self):
		Nsmpls = len(self.samples)
		for i in range(Nsmpls):
			tmpSmplInfo0 = []
			n = len(self.samples[i])
			for j in range(n):
				tmpSmplInfo1 = sampleInfo()
				tmpSmplInfo1.set_smpl_wav(self.samples[i][j])
				tmpSmplInfo0.append(tmpSmplInfo1)
			#self.smplInfo.append(tmpSmplInfo0)
			print '现在训练第%d个HMM模型' %i
			hmm0 = self.trainhmm(tmpSmplInfo0,self.stateInfo)
			print '第%d个模型已经训练完毕' %i
			# self.gmm_hmm_model.append(hmm0)
	#训练hmm		
	def trainhmm(self,sample,state):
		K = len(sample)
		print '首先进行语音参数计算-MFCC'
		for k in range(K):
			tmp = self.mfcc(sample[k].smpl_wav)
			sample[k].set_smpl_data(tmp) # 设置MFCCdata
		hmm = self.inithmm(sample,state)
		pout = zeros((gParam.MAX_ITER_CNT,1))
		for my_iter in range(gParam.MAX_ITER_CNT):
			print '第%d遍训练' %my_iter
			hmm = self.baum(hmm,sample)
			for k in range(K):
				pout[my_iter,0] = pout[my_iter,0] + self.viterbi(hmm,sample[k].smpl_data[0])
			if my_iter > 0:
				if(abs((pout[my_iter,0] - pout[my_iter-1,0])/pout[my_iter,0]) < 5e-6):
					print '收敛'
					self.gmm_hmm_model.append(hmm)
					return hmm
		self.gmm_hmm_model.append(hmm)
	#获取MFCC参数
	def mfcc(self,k):
		M = 24 #滤波器的个数		
		N = 256	#一帧语音的采样点数
		arr_mel_bank = self.melbank(M,N,8000,0,0.5,'m')
		arr_mel_bank = arr_mel_bank/np.amax(arr_mel_bank)
		#计算DCT系数, 12*24
		rDCT = 12
		cDCT = 24
		dctcoef = []
		for i in range(1,rDCT+1):			
			tmp = [np.cos((2*j+1)*i*math.pi*1.0/(2.0*cDCT)) for j in range(cDCT)]
			dctcoef.append(tmp)
		#归一化倒谱提升窗口
		w = [1+6*np.sin(math.pi*i*1.0/rDCT) for i in range(1,rDCT+1)]
		w = w/np.amax(w)
		#预加重
		AggrK = double(k)
		AggrK = signal.lfilter([1,-0.9375],1,AggrK)# ndarray
		#AggrK = AggrK.tolist()
		#分帧
		FrameK = self.enframe(AggrK[0],N,80)
		n0,m0 = FrameK.shape
		for i in range(n0):
			#temp = multiply(FrameK[i,:],np.hamming(N))
			#print shape(temp)
			FrameK[i,:] = multiply(FrameK[i,:],np.hamming(N))	
		FrameK = FrameK.T
		#计算功率谱
		S = (abs(np.fft.fft(FrameK,axis=0)))**2
		#将功率谱通过滤波器组		
		P = np.dot(arr_mel_bank,S[0:129,:])
		#取对数后做余弦变换
		D = np.dot(dctcoef,log(P))
		n0,m0 = D.shape
		m = []
		for i in range(m0):
			m.append(np.multiply(D[:,i],w))
		n0,m0 = shape(m)
		dtm = zeros((n0,m0))
		for i in range(2,n0-2):
			dtm[i,:] = -2*m[i-2][:] - m[i-1][:] + m[i+1][:] + 2*m[i+2][:]
		dtm = dtm/3.0
		# cc = [m,dtm]
		cc =np.column_stack((m,dtm))
		# cc.extend(list(dtm))
		cc = cc[2:n0-2][:]
		#print shape(cc)
		return cc
			
	#melbank
	def melbank(self,p,n,fs,f1,fh,w):
		f0 = 700.0/(1.0*fs)
		fn2 = floor(n/2.0)
		lr = math.log((float)(f0+fh)/(float)(f0+f1))/(float)(p+1)
		tmpList = [0,1,p,p+1]
		bbl = []
		for i in range(len(tmpList)):
			bbl.append(n*((f0+f1)*math.exp(tmpList[i]*lr) - f0))
		#b1 = n*((f0+f1) * math.exp([x*lr for x in tmpList]) - f0)
		#print bbl
		b2 = ceil(bbl[1])
		b3 = floor(bbl[2])
		if(w == 'y'):
			pf = np.log((f0+range(b2,b3)/n)/(f0+f1))/lr #note
			fp = floor(pf)
			r = [ones((1,b2)),fp,fp+1, p*ones((1,fn2-b3))]						
			c = [range(0,b3),range(b2,fn2)]
			v = 2*[0.5,ones((1,b2-1)),1-pf+fp,pf-fp,ones((1,fn2-b3-1)),0.5]				          
			mn = 1
			mx = fn2+1
		else:
			b1 = floor(bbl[0])+1
			b4 = min([fn2,ceil(bbl[3])])-1
			pf = []
			for i in range(int(b1),int(b4+1),1):
				pf.append(math.log((f0+(1.0*i)/n)/(f0+f1))/lr)
			fp = floor(pf)
			pm = pf - fp
			k2 = b2 - b1 + 1
			k3 = b3 - b1 + 1
			k4 = b4 - b1 + 1
			r = fp[int(k2-1):int(k4)]
			r1 = 1+fp[0:int(k3)]
			r = r.tolist()
			r1 = r1.tolist()
			r.extend(r1)
			#r = [fp[int(k2-1):int(k4)],1+fp[0:int(k3)]]
			c = range(int(k2),int(k4+1))
			c2 = range(1,int(k3+1))
			# c = c.tolist()
			# c2 = c2.tolist()
			c.extend(c2)
			#c = [range(int(k2),int(k4+1)),range(0,int(k3))]
			v = 1-pm[int(k2-1):int(k4)]
			v = v.tolist()
			v1 = pm[0:int(k3)]
			v1 = v1.tolist()
			v.extend(v1)#[1-pm[int(k2-1):int(k4)],pm[0:int(k3)]]
			v = [2*x for x in v]
			mn = b1 + 1
			mx = b4 + 1
		if(w == 'n'):
			v = 1 - math.cos(v*math.pi/2)
		elif (w == 'm'):
			tmpV = []
			# for i in range(v):
			# 	tmpV.append(1-0.92/1.08*math.cos(v[i]*math))
			v = [1 - 0.92/1.08*math.cos(x*math.pi/2) for x in v]
		#print type(c),type(mn)
		col_list = [x+int(mn)-2 for x in c]
		r = [x-1 for x in r]
		x = sparse.coo_matrix((v,(r,col_list)),shape=(p,1+int(fn2)))
		matX = x.toarray()
		#np.savetxt('./data.csv',matX, delimiter=' ')
		return matX#x.toarray()
	#分帧函数
	def enframe(self,x,win,inc):
		nx = len(x)
		try:
			nwin = len(win)
		except Exception as err:
			# print err
			nwin = 1	
		if (nwin == 1):
			wlen = win
		else:
			wlen = nwin					
		#print inc,wlen,nx	
		nf = fix(1.0*(nx-wlen+inc)/inc)	#here has a bug that nf maybe less than 0	
		f = zeros((int(nf),wlen))
		indf = [inc*j for j in range(int(nf))]
		indf = (mat(indf)).T
		inds = mat(range(wlen))
		indf_tile = tile(indf,wlen)
		inds_tile = tile(inds,(int(nf),1))
		mix_tile = indf_tile + inds_tile
		for i in range(nf):
			for j in range(wlen):
				f[i,j] = x[mix_tile[i,j]]
				#print x[mix_tile[i,j]]
		if nwin>1: #TODOd
			w = win.tolist()
			#w_tile = tile(w,(int))
		return f
	# init hmm
	def inithmm(self,sample,M):
		K = len(sample)
		N0 = len(M)
		self.N = N0
		#初始概率矩阵
		hmm = hmmInfo()
		hmm.init = zeros((N0,1))
		hmm.init[0] = 1
		hmm.trans = zeros((N0,N0))
		hmm.N = N0
		#初始化转移概率矩阵
		for i in range(self.N-1):
			hmm.trans[i,i] = 0.5
			hmm.trans[i,i+1] = 0.5
		hmm.trans[self.N-1,self.N-1] = 1
		#概率密度函数的初始聚类
		#分段
		for k in range(K):
			T = len(sample[k].smpl_data[0])
			#seg0 = []
			seg0 = np.floor(arange(0,T,1.0*T/N0))
			#seg0 = int(seg0.tolist())
			seg0 = np.concatenate((seg0,[T]))
			#seg0.append(T)
			sample[k].seg = seg0
		#对属于每个状态的向量进行K均值聚类,得到连续混合正态分布
		mix = []
		for i in range(N0):
			vector = []
			for k in range(K):
				seg1 = int(sample[k].seg[i])
				seg2 = int(sample[k].seg[i+1])
				tmp = []
				tmp = sample[k].smpl_data[0][seg1:seg2][:]
				if k == 0:
					vector = np.array(tmp)
				else:
					vector = np.concatenate((vector, np.array(tmp)))
				#vector.append(tmp)
			# tmp_mix = mixInfo()
			# print id(tmp_mix)
			tmp_mix = self.get_mix(vector,M[i],mix)
			# mix.append(tmp_mix)
		hmm.mix = mix
		return hmm
	# get mix data
	def get_mix(self,vector,K,mix0):
		kmeans = KMeans(n_clusters = K,random_state=0).fit(np.array(vector))
		#计算每个聚类的标准差,对角阵,只保存对角线上的元素
		mix = mixInfo()
		var0 = []
		mean0 = []
		#ind = []
		for j in range(K):
			#ind = [i for i in kmeans.labels_ if i==j]
			ind = []
			ind1 = 0
			for i in kmeans.labels_:
				if i == j:
					ind.append(ind1)
				ind1 = ind1 + 1
			tmp = [vector[i][:] for i in ind]
			var0.append(np.std(tmp,axis=0))
			mean0.append(np.mean(tmp,axis=0))
		weight0 = zeros((K,1))
		for j in range(K):
			tmp = 0
			ind1 = 0
			for i in kmeans.labels_:
				if i == j:
					tmp = tmp + ind1
				ind1 = ind1 + 1
			weight0[j] = tmp
		weight0=weight0/weight0.sum()
		mix.Cvar = multiply(var0,var0)
		mix.Cmean = mean0
		mix.CM = K
		mix.Cweight = weight0
		mix0.append(mix)
		return mix0
	#baum-welch 算法实现函数体
	def baum(self,hmm,sample):
		mix = copy.deepcopy(hmm.mix)#高斯混合
		N = len(mix)  #HMM状态数
		K = len(sample) #语音样本数
		SIZE = shape(sample[0].smpl_data[0])[1]	#参数阶数,MFCC维数
		print '计算样本参数.....'
		c = []
		alpha = []
		beta = []
		ksai = []
		gama = []
		for k in range(K):
			c0,alpha0,beta0,ksai0,gama0 = self.getparam(hmm, sample[k].smpl_data[0])
			c.append(c0)
			alpha.append(alpha0)
			beta.append(beta0)
			ksai.append(ksai0)
			gama.append(gama0)
		# 重新估算概率转移矩阵
		print '----- 重新估算概率转移矩阵 -----'
		for i in range(N-1):
			denom = 0
			for k in range(K):
				ksai0 = ksai[k]
				tmp = ksai0[:,i,:]#ksai0[:][i][:]
				denom = denom + sum(tmp)
			for j in range(i,i+2):
				norm = 0
				for k in range(K):
					ksai0 = ksai[k]
					tmp = ksai0[:,i,j]#[:][i][j]
					norm = norm + sum(tmp)
				hmm.trans[i,j] = norm/denom
		# 重新估算发射概率矩阵,即GMM的参数
		print '----- 重新估算输出概率矩阵,即GMM的参数 -----'
		for i in range(N):
			for j in range(mix[i].CM):
				nommean = zeros((1,SIZE))
				nomvar = zeros((1,SIZE))
				denom = 0
				for k in range(K):
					gama0 = gama[k]
					T = shape(sample[k].smpl_data[0])[0]
					for t in range(T):
						x = sample[k].smpl_data[0][t][:]
						nommean = nommean + gama0[t,i,j]*x
						nomvar = nomvar + gama0[t,i,j] * (x - mix[i].Cmean[j][:])**2
						denom = denom + gama0[t,i,j]
				hmm.mix[i].Cmean[j][:] = nommean/denom
				hmm.mix[i].Cvar[j][:] = nomvar/denom
				nom = 0
				denom = 0
				#计算pdf权值
				for k in range(K):
					gama0 = gama[k]
					tmp = gama0[:,i,j]
					nom = nom + sum(tmp)
					tmp = gama0[:,i,:]
					denom = denom + sum(tmp)
				hmm.mix[i].Cweight[j] = nom/denom
		return hmm
				
	#前向-后向算法
	def getparam(self,hmm,O):
		'''给定输出序列O,计算前向概率alpha,后向概率beta
		标定系数c,及ksai,gama
		输入: O:n*d 观测序列
		输出: param: 包含各种参数的结构'''
		T = shape(O)[0]
		init = hmm.init #初始概率
		trans = copy.deepcopy(hmm.trans) #转移概率
		mix = copy.deepcopy(hmm.mix) #高斯混合
		N = hmm.N #状态数
		#给定观测序列,计算前向概率alpha
		x = O[0][:]
		alpha = zeros((T,N))
		#----- 计算前向概率alpha -----#
		for i in range(N): #t=0
			tmp = hmm.init[i] * self.mixture(mix[i],x)
			alpha[0,i] = tmp #hmm.init[i]*self.mixture(mix[i],x)
		#标定t=0时刻的前向概率
		c = zeros((T,1))
		c[0] = 1.0/sum(alpha[0][:])
		alpha[0][:] = c[0] * alpha[0][:] 
		for t in range(1,T,1): # t = 1~T
			for i in range(N):
				temp = 0.0
				for j in range(N):
					temp = temp + alpha[t-1,j]*trans[j,i]
				alpha[t,i] = temp *self.mixture(mix[i],O[t][:])
			c[t] = 1.0/sum(alpha[t][:])
			alpha[t][:] = c[t]*alpha[t][:]

		#----- 计算后向概率 -----#
		beta = zeros((T,N))
		for i in range(N): #T时刻
			beta[T-1,i] = c[T-1]
		for t in range(T-2,-1,-1):
			x = O[t+1][:]
			for i in range(N):
				for j in range(N):
					beta[t,i] = beta[t,i] + beta[t+1,j]*self.mixture(mix[j],x) * trans[i,j]
			beta[t][:] = c[t] * beta[t][:]
		# 过渡概率ksai
		ksai = zeros((T-1,N,N))
		for t in range(0,T-1):
			denom = sum(np.multiply(alpha[t][:],beta[t][:]))
			for i in range(N-1):
				for j in range(i,i+2,1):
					norm = alpha[t,i]*trans[i,j]*self.mixture(mix[j],O[t+1][:])*beta[t+1,j]
					ksai[t,i,j] = c[t]*norm/denom
		# 混合输出概率 gama
		gama = zeros((T,N,max(self.stateInfo)))
		for t in range(T):
			pab = zeros((N,1))
			for i in range(N):
				pab[i] = alpha[t,i]*beta[t,i]
			x = O[t][:]
			for i in range(N):
				prob = zeros((mix[i].CM,1))
				for j in range(mix[i].CM):
					m = mix[i].Cmean[j][:]
					v = mix[i].Cvar[j][:]
					prob[j] =  mix[i].Cweight[j] * pdf(m,v,x)
					if mix[i].Cweight[j] == 0.0:
						print pdf(m,v,x)
				tmp = pab[i]/pab.sum()
				tmp = tmp[0]
				temp_sum = prob.sum()
				for j in range(mix[i].CM):
					gama[t,i,j] = tmp*prob[j]/temp_sum
		return c,alpha,beta,ksai,gama				
	def mixture(self,mix,x):
		'''计算输出概率
		输入:mix--混合高斯结构
		x--输入向量 SIZE*1
		输出: prob--输出概率'''		

		prob = 0.0
		for i in range(mix.CM):
			m = mix.Cmean[i][:]
			v = mix.Cvar[i][:]
			w = mix.Cweight[i]
			tmp = pdf(m,v,x)
			#print tmp
			prob = prob + w * tmp #* pdf(m,v,x)
		if prob == 0.0:
			prob = 2e-100
		return prob
    #维特比算法
	def viterbi(self,hmm,O):
		'''%输入:
		hmm -- hmm模型
		O   -- 输入观察序列, N*D, N为帧数,D为向量维数
		输出:
		prob -- 输出概率
		q    -- 状态序列
		'''
		init = copy.deepcopy(hmm.init)
		trans = copy.deepcopy(hmm.trans)#hmm.trans
		mix = hmm.mix
		N = hmm.N
		T = shape(O)[0]
		#计算Log(init)
		n_init = len(init)
		for i in range(n_init):
			if init[i] <= 0:
				init[i] = -inf
			else:
				init[i]=log(init[i])
		#计算log(trans)
		m,n = shape(trans)
		for i in range(m):
			for j in range(n):
				if trans[i,j] <=0:
					trans[i,j] = -inf
				else:
					trans[i,j] = log(trans[i,j])
		#初始化
		delta = zeros((T,N))
		fai = zeros((T,N))
		q = zeros((T,1))
		#t=0
		x = O[0][:]
		for i in range(N):
			delta[0,i] = init[i] + log(self.mixture(mix[i],x))
		#t=2:T
		for t in range(1,T):
			for j in range(N):
				tmp = delta[t-1][:]+trans[:][j].T
				tmp = tmp.tolist()
				delta[t,j] = max(tmp)
				fai[t,j] = tmp.index(max(tmp))
				x = O[t][:]
				delta[t,j] = delta[t,j] + log(self.mixture(mix[j],x))
		tmp = delta[T-1][:]
		tmp = tmp.tolist()
		prob = max(tmp)
		q[T-1]=tmp.index(max(tmp))
		for t in range(T-2,-1,-1):
			q[t] = fai[t+1,int(q[t+1,0])]
		return prob




# ----------- 以下是用于测试的程序 ---------- #
#
	def vad(self,k,fs):
		'''语音信号端点检测程序
		k 	---语音信号
		fs 	---采样率
		返回语音信号的起始和终止端点'''
		k = double(k)
		k = multiply(k,1.0/max(abs(k)))

		# 计算短时过零率
		FrameLen = 240
		FrameInc = 80
		FrameTemp1 = self.enframe(k[0:-2], FrameLen, FrameInc)
		FrameTemp2 = self.enframe(k[1:], FrameLen, FrameInc)
		signs = np.sign(multiply(FrameTemp1, FrameTemp2))
		signs = map(lambda x:[[i,0] [i>0] for i in x],signs)
		signs = map(lambda x:[[i,1] [i<0] for i in x], signs)
		diffs = np.sign(abs(FrameTemp1 - FrameTemp2)-0.01)
		diffs = map(lambda x:[[i,0] [i<0] for i in x], diffs)
		zcr = sum(multiply(signs, diffs),1)
		# 计算短时能量		
		amp = sum(abs(self.enframe(signal.lfilter([1,-0.9375],1,k),FrameLen, FrameInc)),1)
		# print '短时能量%f' %amp
		# 设置门限
		print '设置门限'
		ZcrLow = max([round(mean(zcr)*0.1),3])#过零率低门限
		ZcrHigh = max([round(max(zcr)*0.1),5])#过零率高门限
		AmpLow = min([min(amp)*10,mean(amp)*0.2,max(amp)*0.1])#能量低门限
		AmpHigh = max([min(amp)*10,mean(amp)*0.2,max(amp)*0.1])#能量高门限
		# 端点检测
		MaxSilence = 8 #最长语音间隙时间
		MinAudio = 16 #最短语音时间
		Status = 0 #状态0:静音段,1:过渡段,2:语音段,3:结束段
		HoldTime = 0 #语音持续时间
		SilenceTime = 0 #语音间隙时间
		print '开始端点检测'
		StartPoint = 0
		for n in range(len(zcr)):
			if Status ==0 or Status == 1:
				if amp[n] > AmpHigh or zcr[n] > ZcrHigh:
					StartPoint = n - HoldTime
					Status = 2
					HoldTime = HoldTime + 1
					SilenceTime = 0
				elif amp[n] > AmpLow or zcr[n] > ZcrLow:
					Status = 1
					HoldTime = HoldTime + 1
				else:
					Status = 0
					HoldTime = 0
			elif Status == 2:
				if amp[n] > AmpLow or zcr[n] > ZcrLow:
					HoldTime = HoldTime + 1
				else:
					SilenceTime = SilenceTime + 1
					if SilenceTime < MaxSilence:
						HoldTime = HoldTime + 1
					elif (HoldTime - SilenceTime) < MinAudio:
						Status = 0
						HoldTime = 0
						SilenceTime = 0
					else:
						Status = 3
			elif Status == 3:
					break
			if Status == 3:
				break
		HoldTime = HoldTime - SilenceTime
		EndPoint = StartPoint + HoldTime
		return StartPoint,EndPoint												

	def recog(self,pathTop):
		N = gParam.NUM
		for i in range(N):						
			wavPath = pathTop + str(i) + '.wav'
			f = wave.open(wavPath,'rb')
			params = f.getparams()
			nchannels,sampwidth,framerate,nframes = params[:4]
			str_data = f.readframes(nframes)
			#print shape(str_data)
			f.close()
			wave_data = np.fromstring(str_data,dtype=short)/32767.0
			x1,x2 = self.vad(wave_data,framerate)
			O = self.mfcc([wave_data])
			O = O[x1-3:x2-3][:]
			print '第%d个词的观察矢量是:%d' %(i,i)
			pout = []
			for j in range(N):
				pout.append(self.viterbi(self.gmm_hmm_model[j],O))
			n = pout.index(max(pout))
			print '第%d个词,识别是%d' %(i,n)

接下来就是test.py文件:

#! /usr/bin python
# encoding:utf-8

import numpy as np
from numpy import *
import gParam
from my_hmm import gmm_hmm
my_gmm_hmm = gmm_hmm()
my_gmm_hmm.loadWav(gParam.TRAIN_DATA_PATH)
#print len(my_gmm_hmm.samples[0])
my_gmm_hmm.hmm_start_train()
my_gmm_hmm.recog(gParam.TEST_DATA_PATH)
#my_gmm_hmm.melbank(24,256,8000,0,0.5,'m')
# my_gmm_hmm.mfcc(range(17280))
#my_gmm_hmm.enframe(range(0,17280),256,80)

最后运行的结果如下图所示:

最后:如果您想直接跑程序,您可以通过以下方式获取我的数据和源程序。由于考虑到个人的人工成本,我形式上只收取5块钱的人工费,既是对我的支持,也是对我的鼓励。谢谢大家的理解。把订单后面6位号码发送给我,我把源码和数据给您呈上。谢谢。

1:扫如下支付宝或微信二维码,支付5元

2:把支付单号的后6位,以邮件发送到我的邮箱middleautumn@foxmail.com

3:您也可以在下方留言,把订单号写上来,我会核实。

谢谢大家。

			


2018-11-13 12:24:32 m0_37605956 阅读数 271
  • AndroidStudio开发APP-脸脸[网络版]

    本项目可拓展为适用于人脸识别、人脸签到、出席会议等相关场景中。【项目源码放在最后一节的课件里了】脸脸【网络版】项目的实现技术支撑包括My SQL数据库服务器、Java Web后台管理和Android移动APP。其中后台管理使用My Eclipse集成开发工具和Tomcat服务器;Android移动APP使用Android Studio集成开发工具。 后台管理提供接口与Android移动APP进行数据交互功能描述1.人脸库 通过移动端APP采集数据信息,提交到后台处理,最后存储到数据库中;也可以直接批量的存储到数据库中,完成人脸库的数据采集。2.移动端APP 具备采集和签到两个功能,采集功能收集用户的人脸图像和个人基本信息。 签到功能,用户刷脸后,与后台采集的信息对比,并显示最终的结果信息,成功识别则进行语音播报,在后台记录存储记录。 附: 移动端的开发是基于“AndroidStudio开发APP-脸脸[单机版]”,所以这块不熟悉的可以先看[单机版]后再来学习[网络版]。 最近周围有施工的噼里啪啦的心烦意乱脑仁疼,但是全部知识点都ok,大家只需要在自己关心的地方拓展完善即可,我相信大家只要看了之后,肯定都会有所收获的。

    124 人正在学习 去看看 朱松

下载了阿里云实时语音识别android sdk 2.0后,
网址:https://help.aliyun.com/document_detail/84705.html?spm=a2c4g.11186623.6.569.724114b7o7QBZm

使用android studio导入,编译报错:You must specify a URL for a Maven repository.

解决:在源码的build.gradle中,maven里面内容为空,如下,
repositories {
flatDir {
dirs ‘libs’
}
maven {
}
}

需要加入一个网址,网址从另外一个build.gradle中获取到。改动后如下:
repositories {
flatDir {
dirs ‘libs’
}
maven {
url “http://oss.sonatype.org/content/repositories/snapshots
}
}

之后重新编译,通过

2017-09-08 22:00:11 qq_37572875 阅读数 16453
  • AndroidStudio开发APP-脸脸[网络版]

    本项目可拓展为适用于人脸识别、人脸签到、出席会议等相关场景中。【项目源码放在最后一节的课件里了】脸脸【网络版】项目的实现技术支撑包括My SQL数据库服务器、Java Web后台管理和Android移动APP。其中后台管理使用My Eclipse集成开发工具和Tomcat服务器;Android移动APP使用Android Studio集成开发工具。 后台管理提供接口与Android移动APP进行数据交互功能描述1.人脸库 通过移动端APP采集数据信息,提交到后台处理,最后存储到数据库中;也可以直接批量的存储到数据库中,完成人脸库的数据采集。2.移动端APP 具备采集和签到两个功能,采集功能收集用户的人脸图像和个人基本信息。 签到功能,用户刷脸后,与后台采集的信息对比,并显示最终的结果信息,成功识别则进行语音播报,在后台记录存储记录。 附: 移动端的开发是基于“AndroidStudio开发APP-脸脸[单机版]”,所以这块不熟悉的可以先看[单机版]后再来学习[网络版]。 最近周围有施工的噼里啪啦的心烦意乱脑仁疼,但是全部知识点都ok,大家只需要在自己关心的地方拓展完善即可,我相信大家只要看了之后,肯定都会有所收获的。

    124 人正在学习 去看看 朱松

0 语音识别概述 1
1 语音识别的算法 2
1.1.1 DNN-HMM 2
1.1.2 RNN-CTC 3
1.1.4FSMN 3
1.1.5 LSTM-DNN电话交谈语音识别 3
1.1.6Android科大讯飞语音识别源码及API下载 3
2. 语音识别的应用场景 4
2.1语音识别的智能家居框架 4
2.2移动端的使用 5
2.3内容监管上的运用 6
2.3.1 语音识别技术应用之音频切分和分类技术 6
2.3.2 语音识别技术应用之音频模板匹配技术 6
2.3.3 语音识别技术应用之节目的自动发现技术 7
2.4 语音导航系统 7
2.4.1 语音导航系统构架 7
2.5 医疗领域 9
2.6 在社交方面的运用 9
3 语音识别数据集 11
4 语音识别行业分析 12
4.1 智能语音技术取得重大突破,商业化落地成为可能 12
4.2 智能车载、智能家居及可穿戴设备风潮的兴起加速语音技术落地 13
4.3科技巨头,初创公司纷纷从不同维度布局相关产业链 14
4.4 面向物联网的智能语音产业链的形成将引起商业模式的变化 16

0 语音识别概述

研究进程:
http://pan.baidu.com/s/1jHI22DS
算法演替:
https://www.leiphone.com/news/201608/4HJoePG2oQfGpoj2.html
基于深度学习的语音识别应用研究:
http://pan.baidu.com/s/1mhFG7xu
CNN在语音识别上的应用:
http://www.52cs.org/?p=1870
百度CNN语音识别:
https://www.jiqizhixin.com/articles/2016-11-04-4

1 语音识别的算法

1.1.1 DNN-HMM
这里写图片描述
DNN-HMM模型
介绍:
http://blog.csdn.net/xmdxcsj/article/details/52760080
程序:
https://github.com/wenjiegroup/DNN-HMM/tree/master/Codes_packaging

1.1.2 RNN-CTC
http://weibo.com/1402400261/Cz5lomszF?type=comment#_rnd1504833793294

1.1.4FSMN
Python代码:
https://github.com/katsugeneration/tensor-fsmn/blob/master/ptb.py

1.1.5 LSTM-DNN电话交谈语音识别
http://pan.baidu.com/s/1eRC4ZdC
LSTM介绍以及程序实现:https://zybuluo.com/hanbingtao/note/581764

1.1.6Android科大讯飞语音识别源码及API下载
https://www.google.co.in/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&cad=rja&uact=8&ved=0ahUKEwj38KDZj5TWAhWCv1QKHZBvB2QQFgg3MAM&url=http%3A%2F%2Fdditblog.com%2Fitshare_359.html&usg=AFQjCNG5tTtXuKWhNIxoqWUPxaJCKK1O9A

2.语音识别的应用场景

2.1语音识别的智能家居框架

本系统由软件和硬件两部分组成, 如图 2所示.软件部分又分为云端和嵌入式客户端. 云端和客户端各自集成了几个主要模块, 分别实现不同的功能
这里写图片描述

图2 系统架构模型
云端软件运行在 Linux 上, 它包含声学模型、语音模型、语料库、CMU Sphinx 工具包、Java 虚拟机. 云端主要功能是接受客户端发送的语音文件转化成文本文件返回, 应用程序模块全部使用 Java 开发, 调用
CMU Sphinx 提供的类库. 主要功能包含语音识别算法和语义转换模块, 它被部署在 Java 虚拟机上. 语音识别算法的主要过程有: 语音输入、预处理、特征提取、模型匹配、输出结果. 首先必须使用 CMU Sphinx的训练工具以特定声学模型为基础对语料库获取匹配的 MFCC 特征数据, 然后使用 MAP 和 MLLR 自适应技术来改进原来的声学模型。

2.2移动端的使用

随着移动互联网技术的不断发展,尤其是移动终端的小型化、多样化变化趋势,语音识别作为区别于键盘、触屏的人机交互手段之一,在需要解放双手的环境下、对于双手或视觉残障人士、对于无法通过触觉控制的微型设备都具有独特的优势。随着语音识别算法模型、自适应性的加强,相信在未来很长一段时间内,语音识别系统的应用将更加广泛与深入,更多丰富的移动终端语音识别产品将步入人们的日常生活。
就算对于正常人来说,例如寒冷的冬天,有无数次需要用手机却死活不想伸手。打电话,发微信,查路线,叫车,这些如果都可以用一个可穿戴设备通过语音控制实现,那该多好啊。目前出门问问团队以做出搭载 Moto 360 的智能手表操作系统Ticwear,可以实现直接语音控制滴滴打车。
早在一年前,Intel 就开发出可穿戴设备原型 Jarvis,可戴在耳朵上之后连入手机,以此实现听懂主人发出的指令、给予语音反馈的功能,充当类似 Siri 的个人语音助手角色

2.3内容监管上的运用

2.3.1 语音识别技术应用之音频切分和分类技术
音频切分和分类技术的应用范围非常广,以语音识别和关键词处理广播电视音频信息为例,首先要做的就是要打点切分音频打点切分的时候可以利用静音检测方法进行,静音检测法在定位方面确性更高,可以为之后的音频分类奠定基础。在音频打点切分完成后,将切分得到的各音频片段加以分类,使之后的音频处理有据可循。

2.3.2 语音识别技术应用之音频模板匹配技术
知道节目的片头曲或者片尾曲,则可以利用音频模板匹配技术对节目(片段)进行自动打点和分割。在压缩及信号传输的影响下,音频流与固定模板之间会产生巨大差别,而解决鲁棒性是其核心所在,通过基于多频带能量相对比率的特征提取方法,利用各时刻所对应的各个频带的能量分布趋势相对稳定这一特性,解决因为音频扭曲造成不稳定的问题。

2.3.3 语音识别技术应用之节目的自动发现技术
为了更好地进行本次研究,下面笔者将以广告识别作为样本,利用音频重复性检测获取新广告片段,具体内容概括如下:首先,因为针对的是自动发现未知新节目和广告而设计的,所以在实际过程中需要将待处理数据从已知模板中去除掉,以便能够减小计算量;其次,在进行重复候选位置的定位时,通过基于音频向量空间模型的快速音频搜索算法进行定位,但在具体过程中,因为会召回一些错误片段,所以有必要进行过滤处理;再有,利用基于音频指纹的搜索确认,用音频向量空间模型检测出来的重复片段,这样检测出的结果准确性更高,进行重复候选确认,进而检测出误报片段。
通过上述几个步骤的操作,余下的片段均是重复片段,既有广告内容的重复部分,也有新闻或者电视节目中的重复部分,然后利用图像帧变化率这一特征进行区分,将广告重复部分之外的内容去除。

2.4 语音导航系统

2.4.1 语音导航系统构架
这里写图片描述

1)客户通过手机或者固话,利用排队机接入呼叫中心系统,在 CTI 和 IVR 的控制下,当用户需要语音导航业务时,通过呼叫平台实现话务接入,平台记录下的原始语音文本,并进行播报用户确认无误后,将该文件作为语音识别引擎的输入;
2)原始的语音文件信息经过语音识别模块,分别经过特征提取、端点检测、去燥处理等语音识别预处理技术,经过处理过的较为干净的语音文件在经过离线解码、在线解码、置信度等处理,转出成自然语言文本信息,并将原始文件信息、原始语音信息、语音特征信息存入文本 / 语音语库中。
3)将自然语言文本信息经过自然语言处理,分别经过模式匹配、语法分析、语义解析、语义搜索、上下文管理、预测等技术处理,将自然语言文本信息转换成计算机能识别的语音信息作为输出物。
4)并进行业务需求的分析,为自然语言处理引擎提供关键数据输入。

2.5 医疗领域

不仅是简单的通过智能手表追踪运动情况和心率,还有直接根据人的身体状况匹配相应的服务如合适的餐厅或食物等,当然这些大多是基于可穿戴设备的。另外还需要考虑到更多场景,诸如紧急语音求助,医患对话存档,呼叫中心的对话听写等。
由于医疗领域词汇库专业性强演变性弱,只要建立完整的数据库,就可以做到对疾病名称、药品名称相对精确的识别。国内已有的应用如病历夹与珍立拍,为医生提供一个安全存储病历资料的云空间,方便查找病例,支持语音搜索功能。

2.6 在社交方面的运用

A、熟人通讯方面,我们应该都见过这样的场景,出租车上司机们通过对讲平台互相勾兑、插科打诨。路上匆忙的低头族,很多都在回微信,而如果通过声控交互构建一个对讲平台,这个体验就完全不一样了,你不需要用眼和手也可以随时给某某捎去一段话,别人给你发来语音、声控交互会提示你是否接听,而如果这个交互可以通过耳麦自动识别微小的语音(并根据接听者情况适度放大),那么以后走在路上就可以轻松而不违和地与人通话了,这个事情的意义在于将从另一个角度接管用户的关系链,形成大网优势。
B、陌生人社交方面,当下社交产品最大的痛点就是社交质量差、低效社交多、效率远远赶不上用户预期,一个突出表现就是搭讪无人理睬、理睬也在若干小时之后(所以人们为何喜欢直播,因为美女主播至少会说谢谢反馈下),但是语音沟通是一个更加强调即时性和真实性的场景,又不像视频那么需要“化妆和端着”,所以反而可能成为新的突破口。至于当下的语音社交平台为何多数做的不好,因为太像色情声讯台了!
C、兴趣推荐。如果选择值得一听的声音节目成本如此之高,那么一个比较好的办法就是基于兴趣的推荐来降低选择难度。比如喜马拉雅已经推出了“猜你喜欢”系统,可以通过深度学习、进行类似今日头条那样的个性化推荐。那么再进一步,如果以后这个推荐可以不需要通过眼睛完成呢,直接传来一个声音:“小喜根据你的爱好搜到了几个节目,下面念下标题,你感兴趣就喊要这个……”
D、时空触发。这个意思是,应该给更多的信息赋予时空属性,比如在某一时刻放出,或者在某一位置放出。举一个例子,你今天刚到一家商场,连上wifi,耳麦里立刻提醒你有最新的优惠活动信息、要不要听。你像即刻那样设置一些关注节点,比如某股又跌了,当这个消息到来,耳麦里立刻提醒你要不要听。你到达某个景点,耳边响起景点的典故。你晚上睡不着了,耳边响起周围人的声音,像不像《her》?
E、做强参与。同为视频,直播爆火的劲头远远强于当年的视频平台和短视频,这也释放了一个信号,用户并不满足于成为单向的内容接受者,他们也希望成为内容的参与者甚至再创作者,他们也希望得到更多的互动和回馈,来满足参与感、存在感和归属感,所以类似电台的互动直播很重要。

3 语音识别数据集

一2000 HUB5 English:仅包含英语的语音数据集,百度最近的论文《深度语音:扩展端对端语音识别》使用的是这个数据集。
地址:https://catalog.ldc.upenn.edu/LDC2002T43
二:LibriSpeech:包含文本和语音的有声读物数据集,由近500小时的多人朗读的清晰音频组成,且包含书籍的章节结构。
地址:http://www.openslr.org/12/
三:VoxForge:带口音的语音清洁数据集,对测试模型在不同重音或语调下的鲁棒性非常有用。
地址:http://www.voxforge.org/
四:TIMIT:英文语音识别数据集。
地址:https://catalog.ldc.upenn.edu/LDC93S1
五:CHIME:包含环境噪音的语音识别挑战赛数据集。该数据集包含真实、模拟和清洁的语音录音,具体来说,包括4个扬声器在4个有噪音环境下进行的将近9000次录音,模拟数据是将多个环境组合及在无噪音环境下记录的数据。
地址:http://spandh.dcs.shef.ac.uk/chime_challenge/data.html
六:TED-LIUM:TED Talk 的音频数据集,包含1495个TED演讲的录音及全文的文字稿。
地址:http://www-lium.univ-lemans.fr/en/content/ted-lium-corpus
七:ai_challenger_interpretation_train
地址:http://pan.baidu.com/s/1skIUjiH

4 语音识别行业分析

4.1 智能语音技术取得重大突破,商业化落地成为可能

◈智能语音技术是人工智能产业链上的关键一环
人工智能产业链主要分为三个层次。
底层是基础设施,包括芯片、模组、传感器,以及以大数据平台、云计算服务和网络运营商。这部分参与者以芯片厂商、科技巨头、运营商为主。
中间层主要是一些基础技术研究和服务提供商。包括深度学习/机器学习、计算机视觉、语音技术和自然语言处理以及机器人等领域。这一模块需要有海量的数据,强大的算法,以及高性能运算平台支撑。代表性企业主要有BAT、科大讯飞、微软、亚马逊、苹果、facebook等互联网巨头和国内一些具有较强科技实力的人工智能初创公司。
最上层是行业应用。大致分为2B和2C两个方向。2B的代表领域包括安防、金融、医疗、教育、呼叫中心等。2C的代表领域包括智能家居、可穿戴设备、无人驾驶、虚拟助理、家庭机器人等。相关代表性企业既包括互联网科技巨头,也包括一些初创厂商。
◈ 中国人工智能市场规模持续增长,智能语音将居于重要地位
◈ 智能语音技术成熟,商业化应用成为可能
深度学习、高性能运算平台和大数据是人工智能技术取得突破的核心助推力。深度学习端到端解决了特征表示与序列影射的问题,使得人工智能的性能得到了快速提升;而互联网时代海量的数据又不断为算法模型提供了训练材料,同时,云计算的兴起和高性能的运算平台为智能化提供了强大的运算能力和服务能力。
在语音识别率方面,百度、谷歌,科大讯飞等主流平台识别准确率均在96%以上,稳定的识别能力为语音技术的落地提供了可能。
◈ 商业场景落地的重要环节语音交互有了重大突破
与此同时,语音交互的核心环节也取得重大突破。语音识别环节突破了单点能力,从远场识别,到语音分析和语义理解有了重大突破,呈现一种整体的交互方案。

4.2 智能车载、智能家居及可穿戴设备风潮的兴起加速语音技术落地

◈ 智能语音市场整体处于启动期,智能车载,智能家居,智能可穿戴等垂直领域处于爆发前夜
◈ 智能车载市场前景广阔,预计五年内车联网渗透率超过50%,语音将成为车载系统标配
◈ 智能家电渗透率提高,智能家居市场蕴涵千亿市场规模,语音作为家居交互入口将大有所为

4.3科技巨头,初创公司纷纷从不同维度布局相关产业链

◈ 国外科技巨头:通过并购等手段,夯实核心技术,开放应用平台,在既有的产品和业务中实现AI first,扩展以AI为核心的生态系统
在技术层,科技巨头多推出算法平台吸引开发者,实现产品快速迭代,打造开发者生态链,形成行业标准。例如,谷歌通过一系列并购、开放平台的建立,软件硬件一体化来打造这个生态系统。
苹果在自身生态系统中相继推出面向可穿戴、家居、车载等领域的产品。亚马逊则基于自身电商生态业务,推出智能音箱,成功敲开了智能家居的大门。
◈ 谷歌:延续既有开放模式,打造开发者生态链,推出Google Home,试图建立物联网时代安卓系统
在谷歌的AI first战略中,一方面,推出人工智能学习系统平台TensorFlow,以吸引开发者,实现产品快速迭代,打造开发者生态链,形成行业标准;另一方面,推出谷歌家庭,试图建立物联网时代安卓系统。同时,将AI技术应用于其原有的产品中,比如Google输入法、Google 翻译、Google Now等,不断提升产品性能,优化用户体验。
◈ 苹果:基于智能硬件定标准、做平台、获数据 ,重视物联网时代生态控制权
与谷歌的开放生态不同,苹果依旧延续了其既有的封闭系统,瞄准物联网时代的生态控制权。同时,以硬件擅长的苹果这次仍从布局硬件起步,打造软硬件生态系统,依靠其广泛的OS系统用户,再基于已推广的OS系统拓展至物联网产业链。
◈ 国内互联网巨头:开放语音生态系统,以产业内合作的方式,将语音技术植入产品和或应用于相关业务场景,构建全产业生态链
在中国,以BAT等为代表的众多互联网巨头也纷纷开发智能语音市场。在语音生态系统方面,百度宣布语音识别技术及能力全面开放。腾讯、搜狗语音开放平台相继上线。
◈ 百度:瞄准人工智能战场,对外开放语音生态系统,对内在自身产品业务中实现AI First
◈ 国内智能语音公司:依托原有优势,从单一智能语音技术商转型全方位人工智能技术服务商
◈ 科大讯飞:传统优势明显,未来将更注重通用人工智能技术和平台级业务的拓展
科大讯飞长期在教育领域拥有绝对优势。除教育外,政府便民工程、呼叫中心和客服也是讯飞长期深耕的领域。
近两年讯飞的重点关注的领域开始向移动互联网和物联网转移。从业务布局层面看,先后发布讯飞云平台和人工智能交互平台AIUI,利用通用的人工智能技术和平台级业务,将语音识别、自然语言处理能力授权给第三方,或者与其他公司进行合作,并且开始向垂直领域拓展。
◈ 初创厂商:以垂直领域和细分场景为突破口,重点布局家居,车载和可穿戴设备
◈ 图灵机器人:定位于语义和认知计算的平台服务提供商,提供聊天机器人平台和机器人操作系统

4.4 面向物联网的智能语音产业链的形成将引起商业模式的变化

◈ 未来趋势:以语音为入口,建立以物联网为基础的商业模式
◈ 智能家居:以合适的入口级应用为载体,基于万物互联的标准,将技术与硬件结合,实现内容和服务的拓展
◈ 智能车载:车联网向纵深方向发展,硬件基础功能免费,基于用户数据的挖掘和增值服务将成为未来主要赢利点

转载自:
《新型工业化》开放式获取期刊:www.chinaxxgyh.com
语音识别技术在内容监管中的应用 郭莉亚 田书云 国家新闻出版广电总局 282 台
语音识别自适应算法在智能家居中的应用 蒋 泰, 张林军(桂林电子科技大学 计算机与信息安全学院, 桂林 541004
作者:辩手李慕阳
链接:https://www.zhihu.com/question/20128179/answer/109598639
来源:知乎
智能家居中语音识别系统的算法研究 郭莉莉,王 迪,魏惠芳 (沈阳城市建设学院,110167

2018-03-15 10:54:00 weixin_34195364 阅读数 17
  • AndroidStudio开发APP-脸脸[网络版]

    本项目可拓展为适用于人脸识别、人脸签到、出席会议等相关场景中。【项目源码放在最后一节的课件里了】脸脸【网络版】项目的实现技术支撑包括My SQL数据库服务器、Java Web后台管理和Android移动APP。其中后台管理使用My Eclipse集成开发工具和Tomcat服务器;Android移动APP使用Android Studio集成开发工具。 后台管理提供接口与Android移动APP进行数据交互功能描述1.人脸库 通过移动端APP采集数据信息,提交到后台处理,最后存储到数据库中;也可以直接批量的存储到数据库中,完成人脸库的数据采集。2.移动端APP 具备采集和签到两个功能,采集功能收集用户的人脸图像和个人基本信息。 签到功能,用户刷脸后,与后台采集的信息对比,并显示最终的结果信息,成功识别则进行语音播报,在后台记录存储记录。 附: 移动端的开发是基于“AndroidStudio开发APP-脸脸[单机版]”,所以这块不熟悉的可以先看[单机版]后再来学习[网络版]。 最近周围有施工的噼里啪啦的心烦意乱脑仁疼,但是全部知识点都ok,大家只需要在自己关心的地方拓展完善即可,我相信大家只要看了之后,肯定都会有所收获的。

    124 人正在学习 去看看 朱松

IBM将于周一宣布向两个源码开放软件组织公开其部分语音识别软件。

此举标明IBM意欲促进语音应用软件开发,是和微软等竞争对手较量中的出奇制胜之招。预计在今后几年内随着客户呼叫中心、汽车电子等的发展,该市场将呈上升趋势。为此,IBM再次亮出其杀手锏:公布部分专署软件源码,以便开发人员改进。

IBM负责软件业务的高级副总Steven A. Mills说:“我们努力推动源码标准,从而开发出越来越多的语音应用软件。我们的源码公开举措是为促使该产业生态形成而迈出的重要一步。这样将会为IBM带来更多的商业机会”

经过数十年的研发,语音识别已经开始逐步进入主流应用。统计建模、模式匹配算法等领域的进展以及处理能力的提高都使得语音识别范围较以前有了长足的提高。

以前语音识别应用软件都是客户化定制的,而如今变成了可重用的标准软件包。现在可以在Web应用程序中加入语音功能,这样程序开发人员就可以使用他们熟悉的工具而无需额外培训。

Opus研究机构分析师Mark Plakias说:“整个语音领域的发展趋势和信息技术业方向一致,语音软件成本应该大幅降低”。

IBM即将公开的语音识别源码是该公司花了大约1000万美元才开发而成的。一系列处理基本日期、时间、地名等的语音软件将交付给Apache软件组织。该公司还打算将其语音编辑工具捐赠给另一家源码开放机构Eclipse组织。

以前IBM就曾向源码开放团体公布过其代码。譬如,在8月份该公司曾向Apache公开了其用Java编写的数据库软件Cloudscape。而且IBM一直对诸如Apache Web服务器及Linux操作系统等源码开放项目鼎立支持。Mills 说:“这是我们一贯做法”。

IBM还将公布同呼叫中心供应商Avaya达成的一项合作协议,双方共同为企业客户开发基于语音的自助应用程序。Avaya通讯应用部副总Eileen Rudden说:“Web自助及语音服务可以同时开发。我们认为这是降低构建语音应用成本的一条有效途径,并且可以进一步拓展市场”。

根据该协议,Avaya计划为IBM的WebSphere提供其呼叫中心软件。然而这并非一个排它性协议。WebSphere是IBM软件战略的核心,它包括构建应用程序所需工具,并且其它软件可以在其平台上运行。

WebSphere是在操作系统之上的一层软件,对微软的Windows及.Net技术构成巨大威胁。

然而,微软也已经开发出了自己的语音识别标准工具,并于3月份发布了具有语音功能的Speech Server 2004。超过10万软件开发人员下载了微软基于.Net技术的免费语音开发工具。

据微软高层宣称,采用该公司技术构建语音应用程序比诸如IBM等其它公司的工具更加便宜和快速。

微软语音技术市场主管James Mastan说:“IBM在步微软后尘,IBM未能像微软一样将公司技术推向更加广阔的市场”。




原文出处:科技行者
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。

语音识别开源项目

阅读数 2961

没有更多推荐了,返回首页