Dr. Volkan Tunalı'nın Kişisel Blogu

Bilgisayar, Bilim, Teknoloji, Sanat

Archive for the ‘sinyal işleme’ tag

Matlab ile Örnek Bir Konuşma Tanıma Uygulaması – Sonuç

5 comments

Matlab kullanarak örnek bir Konuşma Tanıma uygulamasının nasıl yapılabileceğine ilişkin Giriş ve Gelişme başlıklı iki yazı yazmıştım. Bu yazılara şu bağlantılardan ulaşabilirsiniz:

Matlab ile Örnek Bir Konuşma Tanıma Uygulaması – Giriş
Matlab ile Örnek Bir Konuşma Tanıma Uygulaması – Gelişme

Şimdi bu yazı serisini bir Sonuç yazısı ile sonlandırmak istiyorum.

Giriş ve Gelişme yazılarımdan sonra beklediğim gibi, bana bu konuda e-posta ile ulaşanların sayısı sıfıra yaklaştı. Umarım gerçekten yararlı olmuştur; bu konuda geri bildirim gelmediği için bilgim yok. Keşke bu yazılardan yararlananlar yaptıkları çalışmalar hakkında kısaca bilgi verseler, bu alanda yapılan çalışmaları bilmek gerçekten hoşuma gider. Nadiren de olsa konuşma tanımayı kullanan değişik uygulamalar (cihaz denetimi vb.) yapmayla ilgili bilgi ve fikir almak için e-posta ile ulaşanlar oluyor, bu da bana örnek uygulamanın deneyenler tarafından kullanılabilir olduğunu ve işe yaradığını gösteriyor.

Yazımı Konuşma Tanıma alanında çalışan herkese başarılar dileyerek bitirmek istiyorum. Kolay gelsin.

Written by vtunali

Nisan 4th, 2011 at 1:55 am

Matlab ile Örnek Bir Konuşma Tanıma Uygulaması – Gelişme

60 comments

Sıra geldi uygulamayı yapmaya. Bunun için daha önce bahsettiğim gibi Voicebox ve H2M toolbox’larını kullanacağız. Güncel sürümlerini bulup kullanabilirsiniz. İsterseniz aşağıdaki adreslerden benim kullandığım sürümlerini indirebilirsiniz. Bu toolbox’ları indirin ve açın; bunların bulunduğu klasörleri Matlab’ın path’ine ekleyin. Matlab arayüzünden klasöre sağ tıklayıp “Add to path” komutunu çalıştırmanız da geçici olarak yeterli olabilir. Bu konuda ayrıntıya girmeyeceğim, Matlab ortamını tanıyor olduğunuzu varsayıyorum. Ben Matlab 7.9.0 (R2009b) sürümünü kullandım bu uygulamayı yazarken ancak bu kodların Matlab 6 sürümünde de çalıştığını kesin olarak biliyorum, tezimi yazarken 6 sürümünü kullanmıştım.

www.vtunali.com/download/voicebox.zip
www.vtunali.com/download/h2m.zip

Training – Sistemin Eğitimi

Konuşma Tanımayla (daha genel olarak Örüntü Tanımayla) ilgilenenlerin bileceği gibi, önce sisteme bilinen sözcükleri tanıtacağız. Bu aşama genel olarak Training olarak isimlendiriliyor. Bunun için şu iki Matlab fonksiyonunu yazacağız:

  • train_word: parametre olarak verdiğimiz wav dosyasını işleyip HMM model parametrelerini üretir ve hmm_model_files klasörüne kaydeder.
  • train_all_words: train_word fonksiyonunu kullanarak sisteme tanıtacağımız tüm sözcükleri işlemden geçirir. Çalışmayı kolaylaştırmak ve anlatımı basitleştirmek için kullandım.

Şimdi bu fonksiyonların içine bakalım ve üzerinden adım adım geçelim:

train_all_words.m

function train_all_words
    warning('off','MATLAB:dispatcher:InexactCaseMatch');
    numStates = 5;

    % Train word 1 - ALAN
    train_word('alan', numStates);

    % Train word 2 - BİZİM
    train_word('bizim', numStates);

    % Train word 3 - KALAN
    train_word('kalan', numStates);

    % Train word 4 - MERKEZ
    train_word('merkez', numStates);

    % Train word 5 - ZAMAN
    train_word('zaman', numStates);
end

Burada numStates değişkeni HMM durum makinasında (state machine) kullanılmasını istediğimiz durumların sayısını ifade ediyor. Teorisini okursanız daha anlamlı gelir. Genellikle konuşma tanımada bir sözcük için 5 durum efektif sonuç veriyor. Biz de bu nedenle 5 kullanıyoruz örneğimizde. İsterseniz farklı değerler vererek sonucu deneyebilirsiniz.

Eğitim için ben sabit olarak 5 farklı sözcük için yapmış olduğum kayıtları kullandım. Siz bu kısmı kendi uygulamanızın gereksinimlerine göre düzenleyebilirsiniz. Şimdi train_word fonksiyonuna bakalım.

train_word.m

function train_word( wordName, numStates )
disp(['Training word: ' wordName]);

% read wav file and generate cepstrum
wav_file_name = ['training_words/' wordName '.wav'];
[y, fs] = wavread(wav_file_name);
observationVector = melcepst(y, fs, '', 22, floor(3*log(fs)), 128, 32);

% Training parameters
DIAG_COV = 1;   % Force use diagonal covariance matrices
QUIET = 1;      % Make training routines silent
N = numStates;  % Number of states per word model
% Transition matrix is more or less arbitrary and will not be estimated (too
% few utterances are available)
A = sparse(0.85*diag(ones(1,N))+0.15*diag(ones(1,N-1),1));
A(N,N) = 1;
NIT = 10;       % Number of EM iterations
p = size(observationVector, 2);

X = [];
st = [];
st = [st; size(X,1)+1];
X = [X; observationVector];
T = size(X,1);

% Training. Because there is very few available training data, the covariance
% matrices are diagonal and shared by all states of the word model (ie. all
% states have the same covariance matrix given by Sigma)
[my_mu,Sigma] = hmm_mint(X, st, N, DIAG_COV,QUIET);
Sigma = ones(N,1)*mean(Sigma);                       % Shares covariance
logl = zeros(1, NIT);
for n = 1:NIT
% Expectation step of the EM algorithm
[tmp, logl(n), gamma] = hmm_mest(X, st, A, my_mu, Sigma, QUIET);
% Unconstrained Maximization step of the EM algorithm
[my_mu, Sigma] = mix_par(X, gamma, DIAG_COV, QUIET);
% Modification of the EM Maximization due to the constraint that all
% covariance matrices are identical
Sigma = ones(N,1)*(sum((sum(gamma)'*ones(1,p)).*Sigma)/T);
end
my_sigma = Sigma(1,:);

% Write a separate mat file for each words model in subdirectory data
eval(['save hmm_model_files/' wordName ' my_mu my_sigma']);

end

Koddaki bazı yorumlar bana ait değil. H2M toolbox’ında örnek bir kod vardı, oradan aldığım bölümlerdeki yorumları da aynen bıraktım lazım olur diyerek. Şimdi eğitim için adım adım ne yaptığımıza bakalım:

% read wav file and generate cepstrum
wav_file_name = ['training_words/' wordName '.wav'];
[y, fs] = wavread(wav_file_name);
observationVector = melcepst(y, fs, '', 22, floor(3*log(fs)), 128, 32);

Kodun ilk bölümünde sisteme tanıtmak ve HMM model parametrelerini oluşturmak istediğimiz sözcüğün training_words klasöründe yer alan wav dosyasını okuyoruz ve voicebox toolbox’ında yer alan MELCEPST fonksiyonu ile bu sözcüğün Öznitelik Vektörlerini (Feature Vector) oluşturuyoruz. Yani, ses sinyalinden tanıma için yararlanabileceğimiz, bir sözcüğü diğerinden ayrıştırabilmemizi sağlayan öznitelik vektörünü elde ediyoruz. Bu vektörün adı değişik kaynaklarda Observation Vector olarak da geçer. Melcepst fonksiyonunun çeşitli parametreleri var, bunlar hakkında ayrıntıya girmeyeceğim ama mesela 22 ile oluşacak vektörün 22 boyutlu olmasını istediğimizi belirtiyoruz. Bu sayıda denemeler yapabilirsiniz, 12′den daha düşük bir sayı tanıma başarımını düşürebilir. Diğer parametreler ise sinyal üzerinde uygulanacak pencereleme ve pencerelerin üst üste binme (overlap) ayarlamaları için gerekiyor.

Bu fonksiyonun sonraki bölümü ise elde ettiğimiz öznitelik vektörünü kullanarak sözcük için HMM model parametrelerini üretiyor. Burada Expectation Maximization olarak adlandırılan bir teknik uygulanıyor. Bu işlemin sonucunda elimize 2 parametre geçiyor: my_mu ve my_sigma. Bu iki değişkeni hmm_model_files klasörü altında sözcükle aynı isimde bir MAT dosyasına saklıyoruz. Bu MAT dosyaları sistemin tanıma aşamasında kullanılacaklar. Gördüğünüz gibi, sisteme tanıttığımız sözcük için öznitelik vektörünü saklamıyoruz, bunun yerine HMM model parametrelerini saklıyoruz. Öznitelik vektörünü saklayıp tanıma aşamasında tekrar model parametrelerini oluşturabilirdik, ama bu durumda tanıma sırasında sisteme gereksiz bir yük getirmiş olurduk ve tanıma süresini uzatırdık.

Testing – Tanıma Aşaması

Bu aşamada, sisteme yeni bir sözcüğü vererek daha önce tanıttıklarımız arasından en benzerini bulmasını isteyeceğiz. Örnekte tanıttığımız 5 sözcük için bu kez farklı bir kayıt yaparak tanımasını isteyeceğiz. Eğitim için kullandığımız dosyanın aynısını test için kullanmayacağız, bu zaten mantıksız olur.

test_word.m

function test_word( wordName, numStates )

% List of words we have already trained and have
% HMM model files in hmm_model_files directory.
trainedWords = {'alan';
                'bizim';
                'kalan';
                'merkez';
                'zaman'};

% read testing wav file and generate cepstrum
wav_file_name = ['testing_words/' wordName '.wav'];
[y, fs] = wavread(wav_file_name);
observationVector = melcepst(y, fs, '', 22, floor(3*log(fs)), 128, 32);

% HMM Viterbi search
N = numStates;
A = sparse(0.85*diag(ones(1,N))+0.15*diag(ones(1,N-1),1));
A(N,N) = 1;
numIter = 10;

numberOfFiles = length(trainedWords);

for w=1:numberOfFiles
    fileName = trainedWords{w};
    modelFileName = ['hmm_model_files/' fileName '.mat'];
    load(modelFileName);

    Sigma = ones(N,1) * my_sigma;

    % make viterbi search and obtain a similarity score
    score(w) = hmm_vit(observationVector, A, [1 zeros(1,N-1)], my_mu, Sigma, 1);
end  % for w=3:num...

% Word with max score is the best recognized word.
result = find(score >= max(score));

disp(['Recognized word is ' trainedWords{result}]);

end

Sisteme daha önce tanıttığımız sözcükleri ben sabit olarak bir diziye yazdım. Siz uygulamanızda bu kısmı daha farklı düşünebilirsiniz. Tanıtılan sözcükleri ilgili klasörden okuyarak vs. kullanabilirsiniz.

Bu fonksiyonun ilk kısmı tanıdık geliyor. Burada da sistemin tanımasını istediğimiz sözcüğü önişlemeden geçirip öznitelik vektörünü elde ediyoruz. Bu öznitelik vektörünü sonraki aşamada HMM Viterbi Search işleminde kullanıyoruz.

for w=1:numberOfFiles
    fileName = trainedWords{w};
    modelFileName = ['hmm_model_files/' fileName '.mat'];
    load(modelFileName);

    Sigma = ones(N,1) * my_sigma;

    % make viterbi search and obtain a similarity score
    score(w) = hmm_vit(observationVector, A, [1 zeros(1,N-1)], my_mu, Sigma, 1);
end  % for w=3:num...

Gördüğünüz gibi çok basit bir döngüde, daha önce sisteme tanıttığımız sözcükler için model parametrelerini yüklüyoruz ve ardından hmm_vit fonksiyonu ile sistemin tanımasını istediğimiz sözcük için bir skor elde ediyoruz.

% Word with max score is the best recognized word.
result = find(score >= max(score));

disp(['Recognized word is ' trainedWords{result}]);

Eğitmiş olduğumuz sözcükler arasından en yüksek skora sahip olanı yani en benzer olanı tanınmış sözcük olarak raporluyoruz.

Nasıl Çalıştıracağız

Fonksiyonları yazdık ama nasıl deneyeceğiz? Hazırlık aşaması olarak:

  • Öncelikle yukarıda kodlarını verdiğim 3 adet .m dosyasını bir klasörde toplayın (train_all_words.m, train_word.m, test_word.m).
  • Aynı klasör içinde şu 3 klasörü oluşturun: training_words, testing_words, hmm_model_files.
  • Voicebox ve H2M toolbox’larının Matlab work path’ine eklenmesi gerektiğini tekrar hatırlatayım.
  • Sisteme öğretmek istediğiniz sözcükler için kısa ve temiz ses kayıtları yapıp training_words klasörüne koyun. Bu kayıtların mono olması ve 22 Khz olmasına dikkat edin.
  • Sistemin tanımasını istediğiniz sözcükler için de aynı şekilde kayıtlar yaparak testing_words klasörüne koyun.
  • test_all_words fonksiyonunda değişiklik yaparak kendi sözcükleriniz için model oluşturulmasını sağlayın.

Şimdi Matlab komut satırından deneme yapabiliriz:

>> train_all_words
Training word: alan
Training word: bizim
Training word: kalan
Training word: merkez
Training word: zaman
>> test_word('alan', 5);
Recognized word is alan
>> test_word('benim', 5);
Recognized word is bizim
>> test_word('kadar', 5);
Recognized word is kalan

train_all_words satırı ile tüm eğitim sözcükleri için model parametrelerinin oluşturulmasını sağladık. test_word(‘alan’, 5); satırı ile tanımasını istediğim “alan” sözcüğünü denedim ve sonuçta daha önce bu sözcüğü tanıtmış olduğum için yine en benzer olarak kendisini buldu. Aynı şeyi “benim” sözcüğü için denediğimde bu sözcüğe en yakın eğitim sözcüğü olan “bizim” sonucunu aldım. Yine daha önce tanıtmadığım “kadar” sözcüğünü denediğimde tanıtmış olduğum “kalan” sonucunu aldım. Gördüğünüz gibi, sistem sözcükler için oldukça efektif ve başarılı. Siz eğer en benzer sözcüğün sonuç olarak getirilmesini istemezseniz, elde edilen skor değerlerinden belli bir eşiğin üzerinde skorla benzer olanların doğru tanıma olarak kabul edilmesi şeklinde bir mantık uygulayabilirsiniz.

Umarım bu örnek uygulama bu alanda çalışmak isteyenlere fikir verir ve uygulama geliştirme aşamasında yardımcı olur. “Şu .m dosyalarına da bağlantı verseydiniz” dediğinizi duyar gibiyim. Özellikle bunu yapmadım, kodları bu sayfadan çıkartmaya ve açıklamalarımı okumaya üşenmeyin. Konuyla ilgili sorularınız olursa e-posta ile sormak yerine bu yazıya yorum bırakarak sorun, böylece vereceğim cevaplar ve gelişecek diyaloglar sonradan gelecekler için de yararlı olacaktır. Sorularınızı elimden geldiğince yanıtlayacağım ancak şu tür sorular olursa yanıtlamak istemiyorum: “kodu kopyaladım ama çalıştırırken xyz değişkeni bulunamadı diyor, ne yapmalıyım”, “Matlab’da wav dosyası nasıl kaydederim” gibi konu dışı ve Matlab’ın kullanımı ile ilgili sorular lütfen sormayın. Verdiğim kodlarda bir hata tespit ederseniz lütfen paylaşın, birlikte düzeltelim. Buraya çalıştırmadığım hiçbir kod koymadım, bu nedenle anlattığım şekilde uyguladığınızda çalışmaması için bir neden yok.

Konuşma Tanıma alanında çalışacak arkadaşlara başarılar dilerim. Kolay gelsin. Eğer burada yayınladığım bilgiler ve kodlar işinize yaradı ise bilmek isterim, hatta mümkünse bana proje raporunuzu, sunumunuzu, tezinizi vs. gönderirseniz yaptığınız çalışmaları okumaktan memnun olurum.

Written by vtunali

Aralık 5th, 2010 at 2:48 am

Matlab ile Örnek Bir Konuşma Tanıma Uygulaması – Giriş

9 comments

Konuşma Tanıma alanında proje yapmak isteyen öğrenciler sanıyorum ki sıklıkla benim tezimle ilgili sayfaya ulaşıyorlar ve benden bu konuda yardım istiyorlar. Genellikle de konuyla ilgili yardım istekleri şu şekilde oluyor:

  • Nereden başlayalım?
  • XYZ programlama diliyle yapmayı düşünüyorum, ne dersiniz?
  • Şöyle bir uygulama gerekiyor, yapılabilir mi?
  • Tezinizin Türkçe’si var mı?

Çok fazla zaman ayıramasam da bana ulaşan kimseyi yanıtsız ve yardımsız bırakmamak için en azından görüşlerimi paylaşıp yönlendirici bilgiler vermeye çalışıyorum. Genellikle de isteyen olursa tezimin Matlab kodlarını ve kullandığım Voicebox ve HMM toobox’larını veriyorum. Kodlardan ne kadar yararlanılabildi bu güne kadar pek bilemiyorum ama zaman zaman kodlardan da bir çıkış yolu ya da başlangıç noktası bulamayanlar oluyor. Bu nedenle ben de bu toolbox’ların nasıl kullanılabileceğini, basit bir konuşma tanıma uygulamasının nasıl yapılabileceğini örnek yaparak göstermeye karar verdim. Böylece pek çok kişi için başlangıç aşamasında daha büyük bir yardım sağlamış olurum diye düşünüyorum. Umarım bu, kopyala-yapıştır proje yapma meraklılarını fazla heveslendirmez.

Örnek uygulamayı kısa süre içerisinde hazırlayıp yayınlayacağım ve adım adım anlatacağım. Ancak, bunun öncesinde, özellikle konuşma tanıma alanında proje hazırlamayı düşünen arkadaşlarıma yönelik değinmek istediğim şeyler var.

Bazen lisans bitirme tezi, bazen de bir dersin dönem projesi olarak konuşma tanıma ile ilgili uygulamalar yapmak isteyenleri görüyorum. Şunun bilinmesini isterim ki basit, birkaç sözcük tanıması yeterli olan bir sistemi yapmak nispeten kolay, ama işin kapsamı genişledikçe, uygulamadan beklenen şeylerin çapı arttıkça zor bir yola girilmekte. Bu nedenle bu tür bir projeyi seçmeden önce buna dikkat edilmesini öneririm. Hatta, eğer akademik hayatınızın ileriki dönemlerinde benzer bir alanda çalışmayı düşünmüyorsanız bence yolun başındayken ileride de çalışmak isteyebileceğiniz başka bir konu seçin. Çok ciddiyim.

Matlab, sadece konuşma tanıma alanında değil, çok çeşitli bilim ve mühendislik alanlarında hızlı prototip geliştirme ve çabuk deneme yapma olanağı sağlayan mükemmel bir araç (hiç abartmıyorum). Yüksek lisans tezimi yaparken Matlab kullandım ve bunun çok avantajını gördüm. Sonrasında da pek çok projemde ve çalışmamda sıkça kullandım, halen doktora tezimle ilgili çalışmalarda da yoğun bir biçimde kullanmaktayım. Eğer başka bir dil kullanarak proje yapmanız gerekiyorsa biraz zorlanabilirsiniz, ses sinyali işleme ve örüntü tanıma (pattern recognition) alanında hazır kütüphanelere ihtiyacınız olacak. Eğer bir kısıtlamanız yoksa Matlab’ı tercih etmenizi öneririm. Herhangi bir programlama dilini biliyorsanız, Matlab’da program yazmayı birkaç örnek yaparak işinize yarayacak ölçüde öğrenebilirsiniz.

Konuşma Tanıma ile ilgili çalışacakların en başında şu 2 temel alandan bilgiler edinmeleri çok yararlı olacaktır:

  • Ses Sinyali İşleme: Temel bilgilere sahip olmanız çalışmanız ve araştırmanız sırasında karşılacağınız terimleri, yazıları, örnekleri daha rahat anlamanızı sağlar. Frekans, pencereleme, spektrum vs. bilinmesinde fayda var.
  • Örüntü Tanıma ve Sınıflandırma (Pattern Recognition & Classification): Genellikle Yapay Zeka başlığı altında incelenen bu konuda çok çeşitli yöntemler/algoritmalar geliştirilmiştir. Örneğin, HMM, Yapay Sinir Ağları, vs. Efektif olması ve hazır toolbox’a sahip olduğum için ben HMM kullanmayı tercih ettim. Konuşma Tanıma alanda çalışacakların bu konularda en azından ön bilgi sahibi olması çok yerinde olur.

Son olarak, benim tezim 2005 yılındaydı. O günden bugüne Türkçe veya değil, konuşma tanımayla ilgili pek çok tez yapıldığını tahmin ediyorum. Ben hiç takip etme fırsatı bulamadım ve zaten tamamen başka bir alanda çalışıyorum. YÖK’ün tez tarama sayfalarından mutlaka araştırma yapılmalı ve ilgili tezler incelenmeli. Hatta bu tezlerin sahipleriyle de iletişim kurularak bilgi alınması yararlı olabilir, akıl akıldan üstündür, yeni teknikler geliştirilmiş olabilir. Ayrıca, benim tezimin referanslar bölümünde çok yararlı kitaplar ve tezler yer alıyor, onlara bakılmasını da tavsiye ederim. Bundan 5-6 sene önce kitap bulmak zordu ama şimdi rahatlıkla pek çok kitabı e-book olarak bulabilirsiniz. Bulamadığınız olursa, ben Boğaziçi Üniversitesi’nin kütüphanesinden çok yararlanmıştım, oraya bakabilirsiniz. Tezimin Türkçe hali yok, orijinali İngilizce.

Bu yazdıklarımın Konuşma Tanıma alanında çalışmak isteyenlere az da olsa fikir verebildiğini umarım. Herkese çalışmalarında başarılar dilerim.

Not: Sorusu olan arkadaşlar, burada yorum bırakarak sorarlarsa, yapacağımız diyaloglar sonradan gelecek arkadaşlara da yararlı olabilir.

Written by vtunali

Aralık 3rd, 2010 at 12:29 am

Konuşmacı Tanıma Sistemi: Yüksek Lisans Tezi

4 comments

Önceki bir yazımda Ozan MUT’un tez projesinin bir konferansta yayınlanmış şeklini vermiştim. Şimdi yine kendisinin izniyle tez çalışmasını pdf formatında sitemde yayınlıyorum.


Ozan MUT’un tezini indirmek için tıklayın (500 KB).


22.12.2011 tarihli not: Ozan Bey uzun süredir bu alanda çalışmadığı ve zaman ayıramayacağı için bu konuda soru ve istekleri olan kişileri kendisine yönlendirmememi rica etti. Dolayısıyla, tezde anlatılanlardan yararlanmak durumundasınız, lütfen Matlab kodu vb. taleplerde bulunmayın, Ozan Bey’in iletişim bilgilerini istemeyin. Anlayışınız için teşekkürler.

Improved Weighted Matching for Speaker Recognition

leave a comment

Üniversiteden arkadaşım Ozan MUT da benim yüksek lisans tezime benzer bir konuda, Konuşmacı Tanıma konusunda yüksek lisans projesi olarak çalışmalar yaptı.

Çalışmalarını ayrıca The Third World Enformatika Conference, WEC’05 isimli konferansta yayınladı. İlgilenenler olabilir düşüncesiyle Ozan MUT’un da izniyle çalışmasını sitemde yayınlamak istedim.

Makaleyi indirmek için tıklayın (505KB).

Tez çalışmasının tamamını da yine kendisinin izniyle yakında sitemde yayınlayacağım.