Kendi ses tanıma kodumu yazma [kapalı]


17

Sorun Açıklaması

Ses tanımayı, tamamen kendi içinde olmasını istediğim bir donanım projesinin parçası olarak kullanmak istiyorum (Arduino ve Raspberry Pi'nin, Kinects vb.Gibi düşük hızlı, düşük hızlı cihazlar kullanıyorum, geleneksel bilgisayar kullanmıyorum Bir işletim sistemi söz konusudur, bu yüzden kapalı / müstakil bir proje).

Ses tanıma, istediğiniz karmaşıklık düzeyine bağlı olarak çok karmaşık olabilir. Ben inanıyorum ne nispeten basit bir dizi gereksinimleri var. Sadece kendi sesimi tanımak istiyorum ve tanımak istediğim 20 kadar kelimeden oluşan küçük bir sözlüğüm var. Bu nedenle, karmaşık konuşma-metin ve ses tanıma kütüphanelerine veya İnternet arama motorları aracılığıyla bulduğum mükemmel 3. taraf yazılımlardan herhangi birine ihtiyaç duymuyorum (bunların sıkıntısı yok!). Gereksinimlerimin kendi çözümümü kodlayabileceğim "yeterince basit" olduğuna inanıyorum. Herkesin kendi süreçlerini böyle yazıp yazmadığını merak ediyorum ve yöntemim büyük ölçüde kusurlu mu? Yüksek bir matematik seviyesi gerektirmeden veya karmaşık bir algoritma yazmak zorunda kalmadan bunu yapmanın daha iyi bir yolu var mı? Aşağıda düşünmeye çalıştığım çözüm bu.

Çözüm Tanımı

Bunu C dilinde yazacağım, ancak sürecin kendiliğine odaklanan bir dil agnostik sürecini tartışmak istiyorum. Yani, eğer yapabilirsek, görmezden gelelim.

1. Konuşulanlarla eşleştirmek için kelimeler sözlüğümü önceden kaydedeceğim. 20 farklı kelimemin 20 kaydını ya da belki iki ya da üç kelimeden oluşan kısa cümleleri ya da cümleleri yazabileceğimizi hayal edebiliriz. Bunun, iki kayıt dosyasını gerçekten sesi metne dönüştürmekten ve iki dizeyi karşılaştırmaktan daha kolay hale getirdiğine inanıyorum.

2. Kodumu çalıştıran donanım aygıtıma bir mikrofon bağlı. [1]. Kod, örneğin sabit uzunluktaki numuneleri, örneğin 10msn uzunluğunda sürekli olarak alıyor ve örneğin birbirini izleyen 10 örneği dairesel bir kayıt tarzında saklıyor. [2]. (Bu rakamları kafamın üstünden icat ediyorum, bu yüzden sadece süreci tanımlamak için örnekler).

[1] Bu, muhtemelen kaydedilen ve toplanan ses örneklerini daha küçük tutmak için sözlük kayıtlarında olduğu gibi bir bant geçiren filtre ve op-amp ile bağlanacaktır.

[2] Tam olarak nasıl bir örnek alacağımdan emin değilim, 10msec'lik bir örneğin (belki bir CRC değeri) sesini temsil eden sayısal bir rakam (tamsayı / float / double) üretmiş olsam da bir yöntem bulmam gerekiyor veya ses örneğinin MD5 toplamı vb.) veya bir şekil akışı (belki de frekansların ses okumaları akışı). Sonuçta bir "örnek" sayısal bir rakam veya rakamlar olacaktır. Bu bölüm çok daha fazla donanım içerecek, bu yüzden burada tartışmak için değil.

3. Kod, ardışık 10 örnek depolanmış olarak bakar ve bir kelime veya kelime öbeğinin söylendiğini (sessizlikten kopuş) belirtmek için hacim artışı arar ve sonra artış, örneğin 500 örnek demek için art arda örnek toplamadır. Bu, 10 msn'lik örneklerde 5 saniyelik ses yakaladığı anlamına gelir.

Kaydedilen ses ve yakalanan ses arasında karşılaştırılan bu örnekler veya "dilimler" dir. Yakalanan örneklerin yeterince yüksek bir yüzdesi eşdeğer saklananlarla eşleşirse, kod aynı kelimeyi varsayar.

The start of a store recording of the world "hello" for example,
stored words are split into 10 msec samples also

Stored Sample No           | 1| 2| 3| 4| 5| 6| 7|  8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming audio (me saying "hello") with some "blank" samples
at the start to symbolise silence

Incoming Sample No         | 1| 2| 3| 4| 5| 6| 7| 8| 9|10| 11|12|
Incoming Sample Value      |  |  |  |20|27|38|46|16|59|77|200|78|

4. Kod tam bir örnek akışı topladıktan sonra, aşağıdaki ses kaydını üretmek için başlangıçtaki boşluk örneklerini keser. Ayrıca saklanan örnekle daha iyi hizalamak için örnek setini birkaç yer ileri ve geri hareket ettirebilir.

Bu, aşağıdaki gibi bir örnek set üretir:

Stored Sample No           | 1| 2| 3| 4| 5| 6|  7| 8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming Sample No      |-1| 1| 2| 3| 4| 5| 6|  7| 8|
Incoming Sample Value   |20|27|38|46|16|59|81|201|78|

5. Her örneğin ne kadar yakın olması gerektiğine dair bir yüzde değerine sahip olacağına göre, örnek 7,% 1'den az olan 1 değerine ve örnek eşleştirme yüzdesi içinde olması gereken toplam örnek sayısı için yüzde değerine göre değişir. , kodun kolayca ayarlanabilen bir doğruluk seviyesi vardır.

Daha önce hiç böyle bir şey sesle yapmadım, çok fazla iş olabilirdi. Bu yüzden bu soruyu soruyorum, belki de bu sorunun cevabını açık olarak biliyorsan (bu cevap ne olursa olsun). Kullanacağım donanımın bir kısmı düşük sn şeyler olacağından, bu işlemin büyük bir görev olmayacağını umuyorum. Megahertz yüzlerce (Belki de bir saat Rasp Pi kullanarak 1 Ghz). Bu, daha düşük hesaplama gücü kullanarak ses örneklerini eşleştirmek için oldukça kaba bir yoldur. Anında sonuçlar almayı değil, iyi bir konsept kanıtı için 30 saniyeden az bir süre hedefliyorum.

PS Bunu "ses", "ses tanıma", "ses", "ses tanıma" gibi yeni bir etiketle etiketleyecek temsilcim yok.


17
VR oldukça karmaşıktır ve sahada bilgisi olmayan birinin çok fazla okuma yapmadan çok ilerleyebileceğinden şüpheliyim. Algoritmanız hakkında bana ilk gelen şey, bir kelimenin ne kadar hızlı konuşulduğu konusundaki farklılıkları ele almamasıdır. Basit VR'nin bile doğru olması yıllar sürdü.
Robotu Gort

4
Aslında. Yıllar boyunca gelişimde sorun olmazsa, hedefinize derleyebileceğiniz kütüphanelere bakmak isteyebilirsiniz. Eminim varlar.
Rig

6
Ek bir adım öneririm - her numunenin fourier dönüşümünü yapın. Bu, doğrudan örneklerle uğraşmak yerine her bir ses frekansının zaman içindeki yoğunluğunu verir. Sesli harfler için normalde konuşabildiğiniz sesli harfler için oldukça tutarlı bir temel frekans olacaktır. Sadece sesin değil, konuşmanın belirli özelliklerine de bakmanız gerekir. Diğerlerinin söylediği gibi, bu zor bir görevdir.
Paul Anderson

1
Son ürün için kullanamasanız bile bazı ses tanıma kütüphaneleriyle oynamayı denemenizi öneririm. Bir kavram kanıtı oluşturmak için yararlı olurlar.
sav

Yanıtlar:


3

Arduino'nun bunu yapacak at gücüne sahip olduğuna inanmıyorum. 16Mhz'de çalışıyor Bir Arduino'nun yaklaşık 32K belleği var. Mp3'de örneklenen 20 kelime bile (daha küçük sonra wav), sadece kendi sesinize rağmen, ona sığmaz.

Rasberi pi, 512 MB belleğe sahip olabileceği sürüme bağlı olarak 700Mhz'de çalışarak hile yapabilir. Bu hala çok fazla hamur değil.

Fourier'e ihtiyacınız olabilir ( http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199500857 )

Veya hacim kullanmayı düşünüyorsanız,
x = (x + x [n-1] + x [n-2] + x [n-3]) / 4 // gibi önceki örneklerle birkaç ortalama yapın. daha fazlasına ihtiyaç var

Yapmanız gereken bir sonraki şey, bu X değerlerini çizmeniz gerektiğini düşünüyorum.O zaman bu çizginin bir tür eğim tespitine ihtiyacınız var, çünkü hacme dayalı komutları tespit etmek, aksi takdirde mesafeye çok bağlıdır. sözler

Sonra, eğimin nasıl kaydedileceği biraz değişir, böylece desen başka bir zamana sığar. Demek istediğim, bir bilgisayar eşleşebilir ve eğim biraz daha dik olabilir tam tempoda konuşmuyor. Sonunda bu çizgilerin ne kadar dik olduğunu ve uzunlukları y eksenini biraz ortalama olması gerektiğini düşünüyorum


1
  1. Arduino ve Raspberry Pi, üzerinde küçük yongalar bulunan prototip tahtalar. Önce çipe odaklanmalısınız. DSP (dijital sinyal işleme) araç kutusuyla bir şey arayın, belki zaten bir DSP araç kutunuz var ve bunu bilmiyorsunuz. DSP araç kutuları, hızlı frekans etki alanı analizi için fft (hızlı fourier dönüşümü) ve ifft (ters fft) gibi çağrılarda algoritmalara sahiptir.

  2. Programlı stilinize odaklanın: Örnekleriniz bir yığın veya kuyrukta mı? Bu tür veriler için bir kuyruk isteyeceksiniz. Bir kuyruk şöyle görünür:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |5|7|9|1|2|2|9|8|
    

    Sonraki yineleme:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |0|5|7|9|1|2|2|9|
    ->  First in First out (FIFO)
    

    İşlerin “doğru” ya nasıl geçtiğine dikkat edin? Bence "dairesel" bir algoritma tanımladınız. En eski örnekleri en eski ikinci örneklerin üzerine yazın, sonra en eski ikinci örneklerin üzerine üçüncü en eski örneklerin üzerine yazın, ..., en yeni verilerinizi eklediğiniz kuyruğun başına kadar.

  3. "Kod sürekli olarak sabit uzunluklu numuneler alıyor, mesela 10msn" <- yanlış Bu şekilde düşünün: Kod, saniyede 10000 örneklik örnekleme hızında, niceliksel (yükseklik) numuneleri isteğe bağlı olarak nicelikli olarak alıyor.

    Örnekleme sıklığınız nedir? Nicelleştiricinizdeki bit hızı nedir? Düşük sayılar hafızayı boşaltmanıza yardımcı olur. Saniyede 6600 örnek (Nyquist) gibi düşük bir örnekleme oranı öneririm. 4 bit (16 seviye) tanıma için yeterli olacaktır. Yani saniyede 3300 bayt kayıt. Şimdi fft yapın ve 3300 Hz (telefon filtresi) üzerindeki her şeyi silin. Artık bir saniyelik ses için 1650 baytınız var. Bu DSP püf noktaları çok fazla bellek tasarrufu sağlayacaktır.

    512 MB'ın kimin küçük olduğunu düşündüğünü bilmiyorum. Yukarıdaki bilgilerle 300.000+ saniyelik kayıt ... 3 günden fazla sağlam.

  4. Ses tanımayı gerçekleştirmek için (fft kullanarak) frekans alanını bulacağınızı düşünüyorum.

Umarım seni daha da şaşırtmadım :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.