Python ile Konuşma Tanıma Uygulamaları Geliştirmek (1): (2019 Güncellemesiyle)

Güncelleme: Konuşma tanıma hakkında uzun zaman önce yazmış olduğum bu yazıyı güncel python ve kütüphane sürümleriyle tekrar ele almak niyetindeydim. Epey zaman geçti. Fakat geç olması hiç olmamasından iyidir 🙂

Öncelikle yaptığım değişikliklerden bahsetmek gerekirse, şu an itibariyle python 3.6.8 sürümüne (64 bit) geçtim. Python 3.7 sürümünü kullanmamamın sebebi PortAudio kütüphanesi ile uyumlu olmaması. Kütüphanelerin hangi sürümlerini kullandığımı yazının ilerleyen bölümlerinde anlatacağım.

Projeyi github ortamına taşıdım: PythonSpeechRecognizer.

Kendi sesimle kaydettiğim wav dosyalarını da github projesine dahil ettim. Eğitim (training) ve Test etme aşamalarını denemek için bu dosyaları kullanabilirsiniz.

Daha önce kullanmış olduğum melfeat.py dosyası yerine python_speech_features kütüphanesi kullanıyorum. Kütüphane içerisinde mfcc oluşturan bir fonksiyon var.

Konuşma tanıma ile ilgili çok fazla sayıda kütüphane var. Wikipedia’da bu kütüphaneler hakkında bir sayfa var.

Benim niyetim, bu kütüphaneleri kullanmadan, konuşma tanıma (speech recognition) ile ilgili temel yöntemleri kullanarak, makine öğrenmesi yöntemiyle, python dilini kullanarak basit bir sayı tanıma uygulaması yapmak. 1’den 10’a kadar olan rakamları tanıyan bir program olacak bu.

Speech and Language Processing kitabından ve matlab ile benzer bir konuşma tanıma uygulamasının anlatıldığı bir blog yazısından faydalandığımı belirtmeliyim.

Geliştirme yaptığım ortam, Windows 10 – 64 bit ve python 3.6.8 sürümünü kullanıyorum. Makina öğrenmesi işi için scikit-learn kütüphanesini kullanıyorum. Tabii sistemde numpy, scipy gibi kütüphanelerinde kurulu olması gerekiyor.

Konuşma tanıma (speech recognition) temel olarak bir makina öğrenmesi (machine learning) işidir. Temel aşamalarını kabaca listelemek gerekirse:

  • Training için kullanılacak, ses dosyalarının mfcc formatına göre çevrilmesi
  • Saklı markov modellerinin (Hidden markov models) oluşturulup, mfcc datalarına göre eğitilmesi
  • Test için oluşturulmuş, ses dosyalarının bu modellerle ne kadar uyuştuğunun tespit edilmesi (scoring), elde edilen olasılık rakamlarına göre max. olanın bulunması

Projenin klasör yapısına bakalım:

python konuşma tanıma klasör yapısı
Python kodlarını yazmak için PyCharm idesini (Community) kullanıyorum. Siz istediğiniz geliştirme ortamını kullanabilirsiniz.

PyCharm içerisine hmmlearn, PyAudio ve python-speech-features kütüphanelerini artı işaretine tıklayarak öncelikle eklemek gerekiyor. Bağlı kütüphaneleri pycharm kendisi otomatik olarak ekleyecektir.

File -> Settings -> Project Interpreter

pycharm kütüphane kurulumları

Farklı bir geliştirme ortamı kullanıyorsanız aynı şekilde hmmlearn, pyaudio ve python_speech_recognition kütüphanelerini eklemeniz gerekiyor.

Birinci Aşama: Eğitim (Training) Aşaması

Training için kullanılacak wav dosyalarını oluşturuyoruz. Bunun için Audacity programını kullanıyorum. Burada dikkat edilmesi gereken şey, ses dosyalarını hazırlarken, hem training hemde testing için, (Proje Hızı) 16000 Hz, mono (tek kanallı) ve 16 bit pcm şeklinde hazırlanması gerekiyor.

Training ve testing için aynı microfon, aynı ortam kullanılırsa, tanıma başarısı daha yüksek olur.

Kök dizinin dizinin altına trainingwav dizini oluşturuyorum. Oluşturacağım ses dosyalarını bu dizine atacağım. Eğitim aşamasında her rakam için beş wav dosyası oluşturuyorum. Örneğin, bir için 1_01.wav, 1_02.wav, 1_03.wav, 1_04.wav, 1_05.wav, iki için 2_01.wav, 2_02.wav, 2_03.wav, 2_04.wav, 2_05.wav.

Her rakam için bir yerine beş ses dosyası kullanmamın sebebi, sistemin tanıma başarısını arttırmak, modellerimi daha iyi eğitmek için.

Bir de model dosyalarımızı atmak için hmm diye bir dizin oluşturuyoruz.

Dosya klasör yapısını oluşturmak için yukarıda bahsetmiş olduğum resimdeki klasör yapısına bakabilirsiniz. Ayrıca github projesini de bilgisayarınıza indirip inceleyebilirsiniz.

training.py programını yazalım:

import os
import pickle
import numpy as np
from python_speech_features import mfcc
import scipy.io.wavfile as wav
from hmmlearn import hmm

def trainmodel(model,wavlist):
    X = np.array([])
    for wavfile in wavlist:
        path = os.path.join('trainingwav', wavfile)
        (rate, sig) = wav.read(path)
        mfcc_feat = mfcc(sig, rate, nfft=1024)

        if len(X) == 0:
            X = mfcc_feat
        else:
            X = np.append(X, mfcc_feat, axis=0)

    modelSayi = hmm.GaussianHMM(n_components=5, covariance_type='diag', n_iter=1000)
    modelSayi.fit(X)

    hmmPath = os.path.join('hmm',model)
    file = open(hmmPath,"wb")
    pickle.dump(modelSayi,file)
    file.close()

def main():
    trainmodel('bir', ['1_01.wav','1_02.wav','1_03.wav', '1_04.wav','1_05.wav'])
    trainmodel('iki',['2_01.wav','2_02.wav','2_03.wav', '2_04.wav','2_05.wav'])
    trainmodel('uc',['3_01.wav', '3_02.wav', '3_03.wav', '3_04.wav', '3_05.wav'])
    trainmodel('dort',['4_01.wav','4_02.wav','4_03.wav', '4_04.wav','4_05.wav'])
    trainmodel('bes',['5_01.wav','5_02.wav','5_03.wav','5_04.wav','5_05.wav'])
    trainmodel('alti',['6_01.wav', '6_02.wav', '6_03.wav', '6_04.wav', '6_05.wav'])
    trainmodel('yedi',['7_01.wav', '7_02.wav', '7_03.wav', '7_04.wav', '7_05.wav'])
    trainmodel('sekiz',['8_01.wav', '8_02.wav', '8_03.wav', '8_04.wav', '8_05.wav'])
    trainmodel('dokuz',['9_01.wav','9_02.wav','9_03.wav', '9_04.wav','9_05.wav'])
    trainmodel('on',['10_01.wav', '10_02.wav', '10_03.wav', '10_04.wav', '10_05.wav'])
if __name__ == '__main__':
    main()

Mfcc (Mel-frequency cepstral coefficients), oluşturmak için python_speech_features kütüphanesini kullanıyorum.

cmd.exe içerisinden, sistemimizi eğitebiliriz. Kök dizinine geçerek python programımızı çalıştırabiliriz (Python’un path içerisinde tanımlı olması gerekiyor):

python training.py

Önemli Not: Bu aşamada hmm dizinin içerisinde model dosyalarının oluşmuş olması gerekiyor.

İkinci Aşama: Testing aşaması

Testing aşaması için yine wav dosyalarını oluşturuyoruz:

bir rakamını test etmek için 1_01.wav, iki rakamını test etmek için 2_01.wav dosyasını diğer rakamlar için de benzer şekilde audacity programını kullanarak oluşturuyorum.

Bunları testingwav dizinine atıyoruz.

testing.py dosyamızı yazalım:

import os
import pickle
import sys
from python_speech_features import mfcc

import scipy.io.wavfile as wav

def loadModels():
    global modelBir, modelIki, modelUc, modelDort, modelBes, modelAlti, modelYedi, modelSekiz, modelDokuz, modelOn
    hmmPath = os.path.join('hmm', 'bir')
    file = open(hmmPath, "rb")
    modelBir = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'iki')
    file = open(hmmPath, "rb")
    modelIki = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'uc')
    file = open(hmmPath, "rb")
    modelUc = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'dort')
    file = open(hmmPath, "rb")
    modelDort = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'bes')
    file = open(hmmPath, "rb")
    modelBes = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'alti')
    file = open(hmmPath, "rb")
    modelAlti = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'yedi')
    file = open(hmmPath, "rb")
    modelYedi = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'sekiz')
    file = open(hmmPath, "rb")
    modelSekiz = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'dokuz')
    file = open(hmmPath, "rb")
    modelDokuz = pickle.load(file)
    file.close()
    hmmPath = os.path.join('hmm', 'on')
    file = open(hmmPath, "rb")
    modelOn = pickle.load(file)
    file.close()

def testWav(file):
    (rate, sig) = wav.read(file)
    mfcc_feat_test = mfcc(sig, rate, nfft=1024)

    modelSkorBir = modelBir.score(mfcc_feat_test)
    modelSkorIki = modelIki.score(mfcc_feat_test)
    modelSkorUc = modelUc.score(mfcc_feat_test)
    modelSkorDort = modelDort.score(mfcc_feat_test)
    modelSkorBes = modelBes.score(mfcc_feat_test)
    modelSkorAlti = modelAlti.score(mfcc_feat_test)
    modelSkorYedi = modelYedi.score(mfcc_feat_test)
    modelSkorSekiz = modelSekiz.score(mfcc_feat_test)
    modelSkorDokuz = modelDokuz.score(mfcc_feat_test)
    modelSkorOn = modelOn.score(mfcc_feat_test)

    t = max(modelSkorBir, modelSkorIki, modelSkorUc, modelSkorDort, modelSkorBes, modelSkorAlti, modelSkorYedi,
            modelSkorSekiz, modelSkorDokuz, modelSkorOn)

    if (t == modelSkorBir):
        return 'bir'
    if (t == modelSkorIki):
        return 'iki'
    if (t == modelSkorUc):
        return 'uc'
    if (t == modelSkorDort):
        return 'dort'
    if (t == modelSkorBes):
        return 'bes'
    if (t == modelSkorAlti):
        return 'alti'
    if (t == modelSkorYedi):
        return 'yedi'
    if (t == modelSkorSekiz):
        return 'sekiz'
    if (t == modelSkorDokuz):
        return 'dokuz'
    if (t == modelSkorOn):
        return 'on'


if __name__ == '__main__':
    loadModels()
    fileName = sys.argv[1]
    testFile = os.path.join('testingwav', fileName)
    print(testWav(testFile))

Artık cmd.exe içerisinden, wav dosyalarımızı test edebiliriz. Kök dizine geçerek python programımızı çalıştırabiliriz (Python’un path içerisinde tanımlı olması gerekiyor):

python testing.py 1_01.wav

Sonuç olarak bir dönecek.

Bu şekilde, teker teker dosyalarımızı test edebiliriz.

2_01.wav (iki) testi için:

python testing.py 2_01.wav

Sonuç

İnternetteki bazı makalelerde training ve test fonksiyonlarının aynı program içerisinde olduğunu gördüm. Bunun yerine ben ikisini ayrı ayrı implement ettim.

Training kısmında oluşturduğum hmm modellerini binary olarak dosyaya kaydediyorum.

Testing aşamasında bu dosyaları okuyarak, her test komutunda modellerimi sıfırdan oluşturmaktan kurtulmuş oluyorum.

Mikrofondan gelen canlı sesi çevirmek için de benzer bir mantığı kullandım. Hmm modellerimi eğitim aşamasında oluşturup binary formatında kaydettim. Daha sonra modelleri kullanacağım zaman pickle kütüphanesini kullanarak yükleyerek yoluma devam ettim.

Böylece birden ona kadar sayıları tanıyan bir uygulama geliştirmiş olduk. Sistem sizin kendi sesinizle eğitildiği için, sadece sizin verdiğiniz komutları tanıyacaktır. Konuşma tanımanın genel mantığını öğrenmiş ve ufak bir demo yapmış olduk.

Github projesine buradan ulaşabilirsiniz.

Genel amaçlı bir konuşma tanıma uygulaması geliştirmek istiyorsak, elimizde daha çok ve farklı kişilerden elde edilmiş ses dosyaları olması gerekiyor. Ya da bu modelleri size sunan hazır apileri kullanabilirsiniz:

Google cloud speach api ve microsoft bing voice recognition servislerini kullanmak için güzel bir python kütüphanesi var. SpeechRecognition kütüphanesini kullanarak google ve microsoftun konuşma tanıma servislerini kendi uygulamanızda kullanabilirsiniz.

SpeechRecognition kütüphanesini anlatan ingilizce bir yazıya buradan ulaşabilirsiniz.

Mikrofondan gelen sesi canlı olarak nasıl test edeceğinizi görmek için yazının devamına tıklayınız.

Faydalandığım Kaynaklar

http://www.practicalcryptography.com/miscellaneous/machine-learning/guide-mel-frequency-cepstral-coefficients-mfccs/

https://github.com/PacktPublishing/Python-Machine-Learning-Cookbook/blob/master/Chapter07/speech_recognizer.py

15 thoughts on “Python ile Konuşma Tanıma Uygulamaları Geliştirmek (1): (2019 Güncellemesiyle)”

  1. Merhabalar yazınız için teşekkürler.
    Programı çalıştırmakta sorun yaşıyorum.
    C altına speech klasörünü ve içindeki klasörleri oluşturup wav dosyalarını ekledim.
    Kodlarınızı speech klasöründe oluşturdum.
    Anacondayı kurup scipy ve numpy kütüphanelerini anaconda üzerinden yükledim.
    Aşağıdaki hatayı alıyorum ne yapmalıyım ? Yardımcı olur musunuz ? Teşekkürler.
    Traceback (most recent call last):
    File “testing.py”, line 1, in
    from melfeat import *
    File “c:\Speech\melfeat.py”, line 1, in
    import scipy.io.wavfile
    ImportError: No module named ‘scipy’

    1. Anaconda kullanmadan yazıda anlattığım şekilde deneyebilir misiniz? Anaconda konusunda tecrübem yok. Fırsatım olursa bakarım.

      İyi çalışmalar

        1. Barış Bey. Anaconda ile uygulamayı çalıştırmayı başabildiniz mi. ben de de aynı sorun oldu. Normal şekilde python27 yüklediğimde scipy kütüphanesini bir türlü yükleyemedim. sürekli hata verdi. değişik versiyonları ile de denedim. Başaramadım.

    2. bu dersde kullanılan modüller scipy modülü dahilinde çalıstığı ıçın bu hatayı aldın demekki sende scipy modülü yok o modülü yükelmen gerekiyor (cmd>pip install scipy)

  2. Sayın Admin.
    Daha kapsamlı bir proje için uygulamanızı kullanmak istiyorum. öğreteceğim kelimeleri metin veya komut olarak seri porttan başka cihazlara göndermeyi düşünüyorum. Diğer çihazlarım seri port üzerinden haberleşiyorlar. python27 üzerine scipy kütüphanesini kurmakta sorun yaşadım. Bu konuda basit bir yardım istiyorum mümkünse. Örnek ses dosyaları ve kodların hangi dizinler altında olacağını tam anlayamadım. Hatalı yaptığım neresi var bulamadım. Mümkünse C:\speech dizinini zipleyerek bana mail ile gönderebilirmisiniz. Windows10 altında çalışıyorum ama LinuxMint makinem de var. Arduino ve RasperryPi ye seri porttan veri göndermek gibi basit bir işim var. Bunu sesli komut ile yapmak istiyorum.

      1. Sayın Admin.
        İlginize çok teşekkür ederim. Projedeki uygulamaları python ile geliştiriyorum. Ama Processing veya C# ile de konuşma tanıma kısmını yapabilirim hibrit proje olması benim açımdan sorun değil. Sadece google api lerini kullanmak istemiyorum sistem internet bağlantısı olmadan çalışıyor. Tabii ki öncelikli dileğim python27 . yukarıdaki uygulamanızı işletip biraz geliştirebilirsem (mikrofondan ses alma ; gürültü ve sessizlik tanıma gibi) mükemmel olur.

        Saygılarımla

        1. anaconda command prompt kullanarak denedim. hmm (hidden markov model) modülü başka bir yere taşınmış https://github.com/hmmlearn/hmmlearn. Bu modülü kullanarak programı çalıştırınca, hata verdi. Güncel anaconda ve scikit paketleri ile tekrar çalıştırabilirsem, sitede yayınlayacağım.

          1. hocam bir proje için gerekli olan ses işleme kısmında bulabildiğim en anlaşılır yazı size ait fakat şematik olarak anlamadığım bir problem oluştu. hmm dizin hatası almanın yanı sıra dosyanıj şematik yapısını anlamak acısından projeyi githuba yükliyebilirmisiniz hocam. anlatımınız için teşekkürler.

  3. Hocam selamlar… Yazınız çok aydınlatıcı oldu benim için… Benim kişiye özel değilde genel bir ses tanımada kullanabileceğim bir module ihtiyacım var yardımcı olabilirmisiniz…
    Minik bir projede kullanmak istiyorum…

  4. Hocam çalışmanız için ilk olarak teşekkür ederim. Bir projemde kullanmak için çalışıyorum makaleniz üzerinde.
    Bir soru sormak istedim.
    Bir sesi algılaması ve eğitmek için kısa kısa çok parçalı seslerle mi eğitmek gerekli yoksa tek parça şeklinde uzun ses dosyaları da iş görür mü?
    Ya da ses eğitirken hangi yolu izlemeliyim?

    Tekrardan teşekkürler.

Yorum bırakın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Scroll to Top