بازشناسی گفتار (Speech Recognition) با پایتون — از صفر تا صد

۳۰۹۷ بازدید
آخرین به‌روزرسانی: ۱۰ تیر ۱۴۰۲
زمان مطالعه: ۲۳ دقیقه
بازشناسی گفتار (Speech Recognition) با پایتون — از صفر تا صد

بسیاری از افراد در پروژه‌های گوناگونی که با «زبان برنامه‌نویسی پایتون» (Python Programming Language) انجام می‌دهند نیاز به «بازشناسی گفتار» (Speech Recognition) دارند. این کار هرچند در ظاهر بسیار پیچیده و دشوار به نظر می‌رسد، ولی در عمل ساده‌تر از آن است. پروژه‌های بسیار موفقی که در آن‌ها از تشخیص صدا استفاده شده مانند «آمازون الکسا» (Amazon Alexa) اثبات کرده‌اند که وجود درجاتی از پشتیبانی گفتار در فناوری‌های لوازم خانگی، جنبه‌ای حیاتی برای خانه‌ها و شهرهای هوشمند آینده (در حال وقوع ) دارد. به کارگیری بازشناسی گفتار در برنامه‌های کاربردی پایتون، سطحی از تعامل و دسترسی‌پذیری را فراهم می‌کند که فناوری‌های کمی می‌توانند با آن تطبیق پیدا کنند.

بهبود دسترسی‌پذیری به تنهایی ارزش در نظر گرفته شدن را دارد. بازشناسی گفتار به سالمندان و افرادی که دچار اختلالات جسمانی و یا بینایی هستند این امکان را می‌دهد تا با محصولات و خدمات به شیوه‌ای سریع و طبیعی تعامل برقرار کنند، بدون آنکه به «رابط کاربری گرافیکی» (Graphical User Interface) نیازی باشد. بهتر از همه اینکه، استفاده از بازشناسی گفتار (speech recognition) در پروژه‌های پایتون واقعا کار آسانی است. در این راهنما انجام این کار آموزش داده می‌شود و مخاطبان چگونگی انجام کارهای زیر را می‌آموزند:

  • بازشناسی گفتار چگونه کار می‌کند.
  • چه «بسته‌هایی» (packages) در PyPI موجود هستند.
  • چگونگه می‌توان بسته «SpeechRecognition» - که یک کتابخانه پایتون برای بازشناسی گفتار با ویژگی‌های کامل و کاربری آسان است را نصب و استفاده کرد.

در پایان، آنچه آموزش داده شده در یک بازی «Guess the Word» ساده اعمال می‌شود تا مخاطبان به خوبی با چگونگی در کنار هم قرار دادن کلیه این موارد آشنا شوند.

بازشناسی گفتار چگونه کار می‌کند؟

پیش از آنکه به چگونگی انجام بازشناسی گفتار در پایتون پرداخته شود، نگاهی به مفهوم و چگونگی بازشناسی گفتار در حالت کلی انداخته خواهد شد. قطعا بررسی کلی در این حوزه در چندین جلد کتاب می‌گنجد، بنابراین در این مطلب جزئیات فنی مورد بررسی قرار نمی‌گیرند. در حقیقت، این بخش پیش‌نیاز سایر بخش‌های این راهنما نیست (هرچند مطالعه آن به شدت توصیه می‌شود).

بازشناسی گفتار ریشه در پژوهش‌های انجام شده در «آزمایشگاه‌های بِل» (Bell Labs) در اوایل ۱۹۵۰ دارد. سیستم‌های اولیه محدود به تک سخنران و واژگان محدودی بودند. سیستم‌های بازشناسی گفتار مدرن، راهی طولانی را پس از همتایان باستانی خود طی کرده‌اند تا به نقطه کنونی برسند. این سیستم‌ها می‌توانند گفتار را از چندین سخنران تشخیص دهند و دارای دایره لغات گسترده‌ای در زبان‌های متعدد هستند. اولین مولفه بازشناسی گفتار قطعا «گفتار» است. گفتار باید از صدای فیزیکی با میکروفون به یک سیگنال الکتریکی و سپس با یک «مبدل آنالوگ به دیجیتال» به داده دیجیتال تبدیل شود. پس از دیجیتال شدن گفتار، چندین مدل برای «رونویسی» (transcribe) صدا به متن وجود دارد.

تشخیص گفتار
رونویسی گفتار به متن

اغلب سیستم‌های بازشناسی گفتار مدرن بر چیزی که «زنجیره پنهان مارکوف» (Hidden Markov Model | HMM) نامیده می‌شود تکیه دارند. این رویکرد بر این فرض استوار است که سیگنال گفتار، هنگامی که در زمان‌بندی‌های (مقیاس‌های زمانی) به اندازه کافی کوچک نمایش داده شود (مثلا ده میلی ثانیه)، می‌تواند به عنوان یک «فرآیند مانا» (Stationary Process) در نظر گرفته شود. فرآیند مانا، فرآیندی است که در آن مشخصه‌های آماری در طول زمان تغییر نمی‌کنند.

در یک زنجیره پنهان مارکوف متداول، سگینال گفتار به قطعات ده میلی ثانیه‌ای تقسیم می‌شود. طیف قدرت هر قطعه، که اساسا یک بخش از قدرت سیگنال به عنوان تابع فرکانس است، به برداری از اعداد حقیقی که با عنوان «ضرایب کپسترال» (Cepstral Coefficients) شناخته شده‌اند نگاشت می‌شود. ابعاد این بردار معمولا کم و گاهی به کمی ۱۰ است، اما در سیستم‌های دقیق‌تر امکان دارد ابعادی بالغ بر ۳۲ یا بیشتر نیز داشته باشند. خروجی نهایی زنجیره پنهان مارکوف (HMM) یک توالی از این بردارها است.

برای «رمزگشایی» گفتار به متن، گروهی از بردارها با یک یا تعداد بیشتری «واج» (phoneme) - واحد پایه‌ای گفتار - تطبیق پیدا می‌کنند. این محاسبات نیازمند آموزش است، زیر صدای یک واج از سخنرانی به سخنران دیگر و حتی از یک نطق به نطق دیگر برای یک سخنران واحد متفاوت است. سپس، یک الگوریتم ویژه برای تعیین محتمل‌ترین کلمه (یا کلماتی) که توالی داده شده از واج‌ها را تولید می‌کند اعمال می‌شود.

ممکن است کسی تصور کند انجام چنین فرآیندی به لحاظ محاسباتی بسیار پرهزینه است. در بسیاری از سیستم‌های بازشناسی گفتار مدرن، «شبکه‌های عصبی» (Neural Networks) برای ساده کردن سیگنال‌های بازشناسی گفتار با استفاده از روش‌هایی برای «تبدیل ویژگی» (Feature Transformation) و «کاهش ابعاد» (Dimensionality Reduction) پیش از تشخیص زنجیره پنهان مارکوف مورد استفاده قرار می‌گیرند. همچنین، «تشخیص‌دهنده‌های فعالیت صدا» (Voice Activity Detectors | VAD) برای کاهش یک سیگنال صدا صرفا به بخش‌هایی که احتمال دارد دربرگیرنده گفتار باشند مورد استفاده قرار می‌گیرد.

خوشبختانه، یک برنامه‌نویس پایتون نیازی به نگرانی پیرامون هیچ یک از موارد بیان شده ندارد، زیرا سرویس‌های تشخیص صدای بسیاری برای استفاده آنلاین از طریق یک «رابط برنامه‌نویسی نرم‌افزارهای کاربردی» (Application Programming Interface | API) در دسترس هستند. بسیاری از این سرویس‌ها، «کیت توسعه نرم‌افزار» (Software Development Kit | SDK) پایتون ارائه می‌کنند.

انتخاب بسته بازشناسی گفتار پایتون

بسته‌های کاربردی برای بازشناسی گفتار در PyPI وجود دارد. برخی از این بسته‌ها در ادامه بیان شده‌اند.

  • apiai (+)
  • assemblyai (+)
  • google-cloud-speech (+)
  • pocketsphinx (+)
  • SpeechRecognition (+)
  • watson-developer-cloud (+)
  • wit (+)

برخی از این بسته‌ها - مانند wit و apiai - ویژگی‌های توکاری مانند «پردازش زبان طبیعی» (Natural Language Processing) برای تعیین نیت سخنران ارائه می‌کنند که از بازشناسی گفتار پایه‌ای کاری فراتر است. دیگر بسته‌ها، مانند google-cloud-speech، صرفا روی تبدیل گفتار به متن تمرکز می‌کنند. اما «SpeechRecognition» بسته‌ای محسوب می‌شود که سهولت کار با آن مثال زدنی و فوق‌العاده به شمار می‌آید. بازشناسی گفتار نیازمند ورودی صوتی است و بسته SpeechRecognition بازیابی این ورودی را بسیار آسان می‌کند. از سوی دیگر، به جای آنکه نیاز به ساخت اسکریپتی برای دسترسی به میکروفون و پردازش فایل صوتی از پایه باشد، SpeechRecognition این کارها را تنها در چند دقیقه انجام می‌دهد.

کتابخانه SpeechRecognition مانند پوششی برای چندین «رابط برنامه‌نویسی نرم‌افزارهای کاربردی» (API) محبوب عمل کرده و بنابراین بسیار انعطاف‌پذیر است. یکی از این موارد «Google Web Speech API» است که از کلید API پیش‌فرض که در کتابخانه SpeechRecognition هاردکد (hard-coded) شده، پشتیبانی می‌کند. این بدین معنا است که کاربر بدون نیاز به ثبت‌نام برای این سرویس می‌تواند از آن استفاده کند.

کتابخانه SpeechRecognition پایتون برای تشخیص گفتار
کتابخانه SpeechRecognition پایتون برای بازشناسی گفتار

انعطاف‌پذیری و سهولت کاربری بسته SpeechRecognition آن را به یک انتخاب فوق‌العاده برای هر پروژه پایتونی مبدل ساخته است. اگرچه، پشتیبانی از کلیه ویژگی‌های API‌هایی که این بسته پوششی برای آن‌ها است، تضمین نمی‌شود. کاربر باید زمانی را اختصاص داده و با جست‌و‌جو پیرامون گزینه‌های موجود اطمینان حاصل کند که بسته SpeechRecognition در مساله مورد نظر کاربر کار می‌کند یا خیر. به نظر می‌رسد آنچه پیش‌تر بیان شد توانسته در راستای استفاده از بسته SpeechRecognition متقاعد کننده واقع شود، بنابراین گام بعدی روش نصب این بسته خواهد بود.

نصب SpeechRecognition

SpeechRecognition با پایتون نسخه ۲.۶، ۲.۷ و ۳.۳ به بالا سازگار است اما نیاز به یک سری مراحل نصب افزوده برای پایتون ۲ دارد. در این راهنما، فرض می‌شود که کاربر از پایتون ۳.۳ به بالا استفاده می‌کند. بسته SpeechRecognition را می‌توان از ترمینال با pip نصب کرد.

1$ pip install SpeechRecognition

پس از انجام نصب، باید فرآیند نصب را با باز کردن یک «سشن» (session) مفسر و تایپ دستورات زیر تایید کرد.

1>>> import speech_recognition as sr
2>>> sr.__version__
3'3.8.1'

تذکر: کاربران گوناگون ممکن است از نسخه‌های متفاوتی از پایتون استفاده کنند. در هنگام نگارش این راهنما، آخرین نسخه موجود ۳.۸.۱ بوده است.

سشن موجود باید باز نگه داشته شود زیرا به زودی کارهای زیادی باید در آن انجام شود. SpeechRecognition به صورت «out of the box» (در زمینه نرم‌افزار این عبارت به معنای ویژگی یا کارکردی است که بلافاصله پس از نصب بدون پیکربندی یا دستکاری یا حتی بدون نصب کار می‌کند، همچنین به معنای آن است که برای کلیه کاربران به طور پیش‌فرض وجود دارد و نیاز به انجام کارهای اضافی برای استفاده یا پیکربندی این نرم‌افزارها یا فایل‌ها وجود ندارد.) با فایل‌های صوتی موجود کار می‌کند. شایان توجه است که به بسته PyAudio برای ثبت ورودی میکروفون نیاز وجود دارد. در ادامه، لیست «وابستگی‌هایی» (dependencies) که نیاز خواهند شد بیان می‌شوند. اکنون باید به اکتشاف در بسته نصب شده پرداخت.

کلاس Recognizer

همه کارهای جادویی بسته SpeechRecognition با کلاس Recognizer به وقوع می‌پیوندد. البته، هدف اولیه نمونه Recognizer بازشناسی گفتار است.

هر «نمونه» (instance) با تنظیمات و کارکردهای متنوعی برای بازشناسی گفتار از یک منبع صوتی همراه است. ساخت یک نمونه Recognizer آسان محسوب می‌شود. در این راستا کافی است در سشن مفسر موجود کد زیر وارد شود.

1>>> r = sr.Recognizer()

هر نمونه Recognizer دارای هفت متد برای بازشناسی گفتار از منبع صوتی با استفاده از API‌های متنوع است.

  • (+) recognize_bing(): Microsoft Bing Speech
  • (+) recognize_google(): Google Web Speech API
  • (+) recognize_google_cloud(): Google Cloud Speech - requires installation of the google-cloud-speech package
  • (+) recognize_houndify(): Houndify by SoundHound
  • (+) recognize_ibm(): IBM Speech to Text
  • (+) recognize_sphinx(): CMU Sphinx - requires installing PocketSphinx
  • (+) recognize_wit(): Wit.ai

در میان هفت مورد بیان شده در بالا، تنها ()recognize_sphinx به صورت آفلاین با موتور CMU Sphinx کار می‌کند و شش گزینه دیگر نیاز به اتصال اینترنت دارند. بحث کامل پیرامون ویژگی‌ها و مزایای هر API فراتر از موضوع این راهنما است. با توجه به آنکه SpeechRecognition با کلید API پیش‌فرض Google Web Speech API همراه است، می‌توان کار با آن را در لحظه آغاز کرد. به همین دلیل، از Web Speech API در این راهنما استفاده می‌شود. شش API دیگر نیاز به احراز هویت با یک کلید API یا نام‌کاربری/گذرواژه دارند. برای کسب جزئیات بیشتر، باید به مستندات SpeechRecognition رجوع کرد (+).

هشدار: کلید پیش‌فرض فراهم شده توسط SpeechRecognition به منظور تست است و امکان دارد گوگل هر زمانی آن را باطل کند. بنابراین استفاده از Google Web Speech API در تولید ایده خوبی نیست. حتی با یک کلید API معتبر نیز کاربر به تنها ۵۰ درخواست در روز محدود می‌شود و هیچ راهکاری برای افزایش این سهمیه وجود ندارد. خوشبختانه، رابط SpeechRecognition  تقریبا در کلیه API‌ها یکسان است، بنابراین استفاده از آنچه در این راهنما ارائه شده در پروژه‌های جهان واقعی آسان خواهد بود.

هر متد ()*ـrecognize در صورتی که API در دسترس نباشد، یک استثنای speech_recognition.RequestError راه‌اندازی می‌کند. برای ()recognize_sphinx این مساله در نتیجه نصب ناموجود، خراب یا ناسازگار Sphinx به وقوع می‌پیوندد. برای شش متد دیگر، در صورتی که به محدودیت API رسیده شود، سرور در دسترس نباشد و یا اتصال اینترنت وجود نداشته باشد RequestError راه‌اندازی می‌شود. اکنون در سشن مفسر ()recognize_google فراخونی می‌شود.

1r.recognize_google()

خروجی کد بالا چیزی شبیه زیر خواهد بود.

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: recognize_google() missing 1 required positional argument: 'audio_data'

برخی ممکن است حدس زده باشند که چنین اتفاقی به وقوع می‌پیوندد. اما چگونه ممکن است چیزی از هیچی تشخیص داده شود؟ همه هفت متد کلاس ()*ـrecognize نیازمند یک آرگومان audio_data هستند. در هر مورد، audio_data باید نمونه‌ای از کلاس AudioData بسته SpeechRecognition باشد. دو راه برای ساخت یک نمونه AudioData وجود دارد. راه اول، از یک فایل صوتی  و راه دوم صوت ضبط شده توسط یک میکروفون است. کار با فایل‌های صوتی اندکی آسان‌تر است، بنابراین ابتدا این مورد بررسی می‌شود.

کار با فایل‌های صوتی

پیش از ادامه دادن، نیاز به دانلود یک فایل صوتی وجود دارد. فایلی که در اینجا برای آغاز کار استفاده شده، «harvard.wav» (+) است. کاربر باید اطمینان حاصل کند که این فایل در دایرکتوری مشابه با آنچه مفسر پایتون در آن اجرا شده قرار دارد. SpeechRecognition با استفاده از کلاس مفید AudioFile کار با فایل‌های صوتی را آسان می‌سازد. این کلاس قابل مقداردهی اولیه با مسیر یک فایل صوتی و فراهم کردن رابط مدیریت زمینه برای خواندن و کار با محتوای این فایل‌های صوتی است.

نوع فایل‌های پشتیبانی شده

در حال حاضر، بسته SpeechRecognition از فرمت‌های فایل زیر پشتیبانی می‌کند.

  • WAV: باید در فرمت‌های PCM/LPCM باشد.
  • AIFF
  • AIFF-C
  • FLAC: باید در فرمت FLAC محلی باشد. OGG-FLAC پشتیبانی نمی‌شود.

افرادی که در لینوکس‌های برپایه x-86، ویندوز یا macOS کار می‌کنند، باید قادر به کار با فایل‌های FLAC بدون هیچ مشکلی باشند. در دیگر پلتفرم‌ها، نیاز به نصب «انکدر» (Encoder) خاص FLAC و حصول اطمینان از این است که به ابزارهای خط فرمان FLAC  دسترسی وجود دارد. جزئیات بیشتر در این رابطه در اینجا (+) وجود دارد.

استفاده از ()record برای ثبت داده‌ها از یک فایل

کد زیر به منظور پردازش محتوای فایل «harvard.wav» باید در سشن مفسر نوشته شود.

1>>> harvard = sr.AudioFile('harvard.wav')
2>>> with harvard as source:
3...    audio = r.record(source)
4...

مدیر زمینه فایل را باز کرده و محتوای آن را می‌خواند، سپس داده‌ها را در یک نمونه AudioFile که source نامیده می‌شود ذخیره می‌کند. پس از آن، متد ()record داده‌ها را از کل یک فایل در یک نمونه AudioData ذخیره می‌کند. این مورد را می‌توان با بررسی نوع یک audio تایید کرد.

1>>> type(audio)
2<class 'speech_recognition.AudioData'>

اکنون می‌توان ()recognize_google را در تلاش برای شناسایی هر گفتاری در فایل صوتی فراخوانی (invoke) کرد.

1>>> r.recognize_google(audio)
2'the stale smell of old beer lingers it takes heat
3to bring out the odor a cold dip restores health and
4zest a salt pickle taste fine with ham tacos al
5Pastore are my favorite a zestful food is the hot
6cross bun'

ممکن است این پرسش در ذهن برخی افراد نقش ببندد که «عبارات موجود در فایل harvard.wav از کجا آمده‌اند؟». این موارد مثال‌هایی از «Harvard Sentences» هستند. این عبارات توسط IEEE در سال ۱۹۶۵ به منظور تست قابلیت بازشناسی گفتار در خطوط تلفن منتشر شدند. این داده‌ها همچنان در تست سلولی و VOIP مورد استفاده قرار می‌گیرند.

Harvard Sentences متشکل از ۷۲ لیست از ده عبارت است. می‌توان رکوردهای رایگان از این عبارات را در وب‌سایت «Open Speech Repository» (+) پیدا کرد. موارد ضبط شده به زبان انگلیسی، چینی ماندارین، فرانسوی و هندی نیز موجود هستند و منبع فوق‌العاده‌ای از موارد رایگان برای ارزیابی کد را فراهم می‌کنند.

ثبت قطعات با offset و duration

پرسشی که امکان دارد در این لحظه برای برخی افراد مطرح شود آن است که اگر نیاز به ثبت یک بخش از گفتار روی فایل باشد چه باید کرد. متد ()record آرگومان کلیدواژه duration را می‌پذیرد که ضبط را پس از تعداد ثانیه‌های مشخص شده‌ای متوقف می‌کند. برای مثال، کد زیر هر گفتاری را در چهار ثانیه اول فایل ثبت می‌کند.

1>>> with harvard as source:
2...     audio = r.record(source, duration=4)
3...
4>>> r.recognize_google(audio)
5'the stale smell of old beer lingers'

متد ()record، هنگامی که درون یک بلوک with استفاده می‌شود، همیشه در جریان فایل به جلو حرکت می‌کند. این بدین معنا است که اگر یک بار برای ۴ ثانیه فایل ضبط شود و سپس دوباره برای ۴ ثانیه رکورد کردن آغاز شود، بار دوم چهار ثانیه از صوت پس از اولین چهارثانیه بازگردانده می‌شود.

1>>> with harvard as source:
2...     audio1 = r.record(source, duration=4)
3...     audio2 = r.record(source, duration=4)
4...
5>>> r.recognize_google(audio1)
6'the stale smell of old beer lingers'
7>>> r.recognize_google(audio2)
8'it takes heat to bring out the odor a cold dip'

شایان توجه است که audio2 شامل یک بخش از فاز سوم در فایل می‌شود. هنگام تعیین مدت زمان، رکورد کردن ممکن است mid-phrase یا حتی mid-word را متوقف کند که می‌تواند به صحت «رونویسی» (transcription) آسیب برساند. علاوه بر این، برای تعیین طول مدت ثبت، می‌توان به متد ()record با استفاده از آرگومان کلیدواژه offset یک نقطه شروع مشخص داد. این مقدار تعداد ثانیه‌ها از آغاز فایل که باید پیش از آغاز ضبط از آن‌ها چشم‌پوشی (ignore) شود را تعیین می‌کند. برای ثبت صرفا دومین عبارت در فایل، می‌توان با انحراف از ۴ ثانیه و ضبط برای مثلا ۳ ثانیه کار را آغاز کرد.

1>>> with harvard as source:
2...     audio = r.record(source, offset=4, duration=3)
3...
4>>> recognizer.recognize_google(audio)
5'it takes heat to bring out the odor'

آرگومان‌های کلیدواژه offset و duration برای بخش‌بندی یک فایل صوتی، اگر کاربر دانش پیشینی از ساختار گفتار در فایل را داشته باشد مفید هستند. اگرچه، استفاده شتاب‌زده از آن‌ها می‌تواند منجر به رونویسی ضعیفی شود. برای مشاهده این اثر، از کد زیر در مفسر می‌توان استفاده کرد.

1>>> with harvard as source:
2...     audio = r.record(source, offset=4.7, duration=2.8)
3...
4>>> recognizer.recognize_google(audio)
5'Mesquite to bring out the odor Aiko'

با آغاز ضبط از ثانیه ۴.۷، بخش «it t» از آغاز عبارت «it takes heat to bring out the odor» از دست می‌رود، بنابراین API فقط «akes heat» را دریافت می‌کند که با «Mesquite» مطابقت یافته است. به طور مشابه، در پایان ضبط «a co» ثبت می‌شود که آغاز سومین عبارت «a cold dip restores health and zest» است. این مورد با استفاده از API با «Aiko» تطبیق یافته.

دلیل دیگری نیز برای دریافت رونویسی اشتباه وجود دارد. «نویز» (Noise)! مثال بالا به این دلیل به خوبی عمل کرده که فایل صوتی به طرز منطقی تمییز است. در جهان واقعی، به جز حالتی که فرد فرصت پردازش فایل صوتی را پیش از داشته باشد، کاربر نمی‌تواند انتظار صوت بدون نویز را داشته باشد.

اثر نویز در بازشناسی گفتار

نویز یک واقعیت در زندگی بشر است. همه رکوردهای صوتی دارای درجاتی از نویز هستند و نویزهای مدیریت نشده می‌توانند صحت برنامه‌های کاربردی بازشناسی گفتار را مخدوش کنند. برای گرفتن احساس اینکه نویز چگونه می‌توان بازشناسی گفتار را متاثر کند، باید فایل «jackhammer.wav» را از اینجا (+) دانلود کرد.

همچون همیشه، باید اطمینان حاصل کرد که این فایل در دایرکتوری کار سشن‌های مفسر ذخیره شده است. این فایل حاوی عبارت «the stale smell of old beer lingers» است و در عین حال jackhammer که در پس زمینه با صدای بلند صحبت می‌کنم. در صورت تبدیل این فایل به رونویس چه اتفاقی خواهد افتاد؟

1>>> jackhammer = sr.AudioFile('jackhammer.wav')
2>>> with jackhammer as source:
3...     audio = r.record(source)
4...
5>>> r.recognize_google(audio)
6'the snail smell of old gear vendors'

پس چگونه می‌توان با این مشکل مواجه شد؟ یکی از مواردی که می‌توان آن را مورد آزمون قرار داد استفاده از متد ()adjust_for_ambient_noise برای کلاس Recognizer است.

1>>> with jackhammer as source:
2...     r.adjust_for_ambient_noise(source)
3...     audio = r.record(source)
4...
5>>> r.recognize_google(audio)
6'still smell of old beer vendors'

این کار کاربر را یک گام به عبارت واقعی نزدیک‌تر می‌کند، اما همچنان عالی نیست. همچنین، «the» از آغاز عبارت گم شده است. متد ()adjust_for_ambient_noise اول دوم جریان فایل را می‌خواند و تشخیص‌دهنده را برای سطح نویز فایل صوتی کالیبره می‌کند. از این رو، بخشی از جریان پیش از آنکه ()record برای ثبت داده‌ها فراخوانی شود، صرف شده است.

می‌توان «فرم زمانی» (time-frame) را که ()adjust_for_ambient_noise برای تحلیل استفاده می‌کند با آرگومان کلیدی duration تنظیم کرد. این آرگومان یک مقدار عددی را در ثانیه دریافت کرده و به طور پیش‌فرض روی ۱ قرار می‌دهد. در کد زیر تلاش شده این مقدار به ۰.۵ کاهش پیدا کند.

1>>> with jackhammer as source:
2...     r.adjust_for_ambient_noise(source, duration=0.5)
3...     audio = r.record(source)
4...
5>>> r.recognize_google(audio)
6'the snail smell like old Beer Mongers'

بسیار خب، این کار موجب می‌شود «the» در آغاز عبارت بیاید، اما اکنون باید به مشکلات جدیدی رسیدگی کرد. گاهی این امکان وجود ندارد که اثر نویز را حذف کرد، زیرا سیگنال بسیار نویزی‌تر از آن است که بتوان به شکل موفقیت‌آمیزی با آن س و کله زد. مساله این فایل نیز همین است.

به افرادی که زیاد با این مشکل مواجه می‌شوند توصیه می‌شود به انجام «پیش‌پردازش داده‌ها»  (pre-processing) اهتمام بورزند. این کار را می‌توان با نرم‌افزارهای ویرایش فایل صوتی (+) و یا بسته‌های پایتون (مانند SciPy) که می‌توانند فیلترهایی را به فایل اضافه کنند انجام داد. بحث تخصصی در این زمینه از حوصله این مطلب خارج است و در همین رابطه مطالعه کتاب «الن دونی» (Allen Downey) با نام «Think DSP» (+) توصیه می‌شود. در حال حاضر آگاهی از نویز محیط در فایل صوتی می‌تواند مشکلاتی را ایجاد کند و باید به منظور بیشینه کردن صحت تشخیص صدا به آن‌ها پرداخته شود.

هنگام کار با فایل‌های دارای نویز، مشاهده پاسخ API واقعی مفید خواهد بود. اغلب API‌ها یک رشته JSON باز می‌گردانند که دربرگیرنده رونویس‌های بسیاری است. متد ()recognize_google همیشه محتمل‌ترین رونویس را باز می‌گرداند مگر اینکه کاربر آن را مجبور به ارائه پاسخ کامل کند. می‌توان این کار را با تنظیم آرگومان کلیدواژه show_all برابر با مقدار True در متد ()recognize_google انجام داد.

1>>> r.recognize_google(audio, show_all=True)
2{'alternative': [
3  {'transcript': 'the snail smell like old Beer Mongers'}, 
4  {'transcript': 'the still smell of old beer vendors'}, 
5  {'transcript': 'the snail smell like old beer vendors'},
6  {'transcript': 'the stale smell of old beer vendors'}, 
7  {'transcript': 'the snail smell like old beermongers'}, 
8  {'transcript': 'destihl smell of old beer vendors'}, 
9  {'transcript': 'the still smell like old beer vendors'}, 
10  {'transcript': 'bastille smell of old beer vendors'}, 
11  {'transcript': 'the still smell like old beermongers'}, 
12  {'transcript': 'the still smell of old beer venders'}, 
13  {'transcript': 'the still smelling old beer vendors'}, 
14  {'transcript': 'musty smell of old beer vendors'}, 
15  {'transcript': 'the still smell of old beer vendor'}
16], 'final': True}

همانطور که مشهود است، ()recognize_google یک دیکشنری با کلید «alternative» باز می‌گرداند که به لیست رونویس‌های ممکن اشاره می‌کند. ساختار این پاسخ ممکن است از یک API به API دیگر متفاوت باشد و این موضوع برای «اشکال‌زدایی» (debugging) مفید است.

در حال حاضر یک ایده کلی پیرامون مبانی بسته SpeechRecognition شکل گرفت. تاکنون چگونگی ساخت یک نمونه AudioFile از فایل صوتی و استفاده از متد ()record برای ثبت داده‌ها از فایل بیان شد. همچنین، نحوه ثبت قطعات یک فایل با استفاده از آرگومان‌های کلیدواژه offset و duration از ()record و تاثیر مخربی که نویز بر صحت رونویس‌ها دارد تشریح شد. کم کم زمان انجام کارهای جالب فرا رسیده است. با گذر از مرحله رونویسی فایل‌های صوتی استاتیک، در ادامه به انجام پروژه تعاملی با پذیرش ورودی از یک میکروفون پرداخته می‌شود.

کار با میکروفون

برای دسترسی به میکروفون با SpeechRecognizer، باید بسته PyAudio (+) را نصب کرد. برای ادامه، سشن کنونی مفسر را بسته و نصب به صورتی که در زیر تشریح شده انجام می‌شود.

نصب PyAudio

فرآیند نصب PyAudio بسته به سیستم‌عامل متفاوت است.

گنو/لینوکس دبیان

افرادی که از سیستم‌عامل‌های مبتنی بر دبیان (مانند اوبونتو) استفاده می‌کنند، می‌توانند PyAudio را با استفاده از apt به صورت زیر نصب کنند.

1$ sudo apt-get install python-pyaudio python3-pyaudio

پس از نصب، ممکن است هنوز نیاز به اجرای pip install pyaudio باشد، به ویژه اگر کاربر با «محیط مجازی» (Virtual Environment) کار کند.

macOS

برای macOS، ابتدا نیاز به نصب PortAudio با Homebrew و سپس نصب PyAudio با pip است.

1$ brew install portaudio
2$ pip install pyaudio

ویندوز

در ویندوز می‌توان PyAudio را با pip نصب کرد.

1$ pip install pyaudio

تست نصب

پس از نصب PyAudio، می‌توان نصب را از کنسول تست کرد.

1$ python -m speech_recognition

اکنون کاربران باید اطمینان حاصل کنند که میکروفون روشن است و صدای آن بسته نیست. اگر نصب به طور صحیح انجام شده بود، کاربر باید چیزی شبیه آنچه در زیر آمده را مشاهده کند.

1A moment of silence, please...
2Set minimum energy threshold to 600.4452854381937
3Say something!

اکنون می‌توان با حرف زدن در میکروفون مشاهده کرد که SpeechRecognition چقدر خوب گفتار را رونویس می‌کند.

نکته: کاربرانی که از اوبونتو استفاده و خروجی‌های عجیبی مانند «ALSA lib … Unknown PCM» دریافت می‌کنند، می‌توانند به این صفحه (+) مراجعه کنند. این خروجی‌ها مربوط به بسته ALSA هستند که با اوبونتو نصب شده و ارتباطی با SpeechRecognition و PyAudio ندارد. در حقیقت، این پیام‌ها ممکن است خبر از مشکلی که در «پیکربندی» (configuration) بسته ALSA وجود دارد بدهند، اما بر اساس تجربه به نظر می‌رسد عملکرد کد را تحت تاثیر قرار نمی‌دهند و بیشتر حکم ایجاد مزاحمت دارند.

کلاس Microphone

اکنون باید یک سشن مفسر دیگر را باز کرد و یک نمونه از کلاس recognizer ساخت.

1>>> import speech_recognition as sr
2>>> r = sr.Recognizer()

اکنون، به جای استفاده از فایل صوتی به عنوان منبع، از میکروفون پیش‌فرض سیستم استفاده می‌شود. می‌توان به این میکروفون از طریق کلاس Microphone دسترسی داشت.

1>>> mic = sr.Microphone()

اگر سیستم هیچ میکروفون پیش‌فرضی ندارد (مثلا در زربری‌پای)، یا کاربر قصد دارد که از میکروفونی غیر از پیش‌فرض سیستم استفاده کند، نیاز به تغیین میکروفون مورد استفاده با دادن اندیس دستگاه است. می‌توان لیست نام میکروفون‌ها را با فراخوانی متد استاتیک ()list_microphone_names از کلاس Microphone دریافت کرد.

1>>> sr.Microphone.list_microphone_names()
2['HDA Intel PCH: ALC272 Analog (hw:0,0)',
3 'HDA Intel PCH: HDMI 0 (hw:0,3)',
4 'sysdefault',
5 'front',
6 'surround40',
7 'surround51',
8 'surround71',
9 'hdmi',
10 'pulse',
11 'dmix', 
12 'default']

توجه به این نکته لازم است که خروجی در سیستم‌های گوناگون امکان دارد با مثال بالا متفاوت باشد. اندیس دستگاه میکروفون، در واقع اندیس نام آن در لیست بازگردانده شده توسط ()list_microphone_names است. برای مثال، در خروجی بالا، برای استفاده از میکروفونی که «front» نامیده می‌شود و اندیس آن «3» است، باید یک نمونه از میکروفون به صورت زیر ساخته شود.

1>>> # This is just an example; do not run
2>>> mic = sr.Microphone(device_index=3)

در اغلب پروژه‌ها، کاربر احتمالا از میکروفون پیش‌فرض سیستم استفاده می‌کند.

استفاده از ()listen برای ثبت ورودی‌های میکروفون

اکنون که نمونه Microphone آماده است، زمان ثبت ورودی‌ها فرارسیده. درست مانند کلاس AudioFile ، نمونه Microphone نیز مدیر زمینه محسوب می‌شود. می‌توان ورودی‌ها را با میکروفون با استفاده از متد ()listen از کلاس Recognizer درون بلوک with ثبت کرد. این روش یک منبع صوتی را به عنوان اولین آرگومان خود دریافت کرده و ورودی را از منبع تا زمانی که سکوت تشخیص داده شود دریافت می‌کند.

1>>> with mic as source:
2...     audio = r.listen(source)
3...

پس از آنکه بلوک with اجرا شد، کاربر می‌تواند با گفتن «hello» امتحان و یک دقیقه برای اینکه خط مفسر (interpreter prompt) نمایش داده شود صبر کند. هنگامی که «>>>» باز می‌گردد، کاربر آماده بازشناسی گفتار است.

1>>> r.recognize_google(audio)
2'hello'

اگر خط مفسر باز نگردد، به احتمال زیاد میکروفون نویز زیادی از محیط دریافت کرده است. می‌توان با استفاده از کلیدهای ترکیبی «Ctrl + C» در فرآیند وقفه ایجاد کرد تا prompt بازگردد. برای مدیریت نویز محیط، نیاز به استفاده از متد ()adjust_for_ambient_noise از کلاس Recognizer است، از آنجا که ورودی از میکروفون کمتر از ورودی از فایل صوتی قابل پیش‌بینی محسوب می‌شود، بهتر است در هر بار استفاده از ورودی میکروفون از روش گفته شده استفاده شود.

1>>> with mic as source:
2...     r.adjust_for_ambient_noise(source)
3...     audio = r.listen(source)
4...

پس از اجرای کد بالا، باید یک ثانیه برای ()adjust_for_ambient_noise صبر کرد تا کارش را انجام دهد، سپس مجددا می‌توان در میکروفون «hello» گفت. پس از آن باید صبر کرد تا خط مفسر پیش از آنکه سعی کند گفتار را تشخیص دهد بازگردد. با فراخوانی ()adjust_for_ambient_noise منابع صوتی برای یک ثانیه آنالیز می‌شوند. اگر این زمان به نظر کاربر زیاد است، می‌تواند آن را با آرگومان کلیدواژه duration تنظیم کند.

در مستندات SpeechRecognition پیشنهاد شده که duration کمتر از ۰/۵ ثانیه نباشد. در برخی موارد، ممکن است کاربر تشخیص دهد که طول مدت بیشتر از یک ثانیه نتایج بهتری را تولید می‌کند. حداقل مقداری که کاربر نیاز دارد، بسته به محیط میکروفون است. متاسفانه، این اطلاعات اغلب در طول توسعه ناشناخته هستند. براساس تجربه نویسنده این مطلب، به نظر می‌رسد طول مدت پیش‌فرض برای اغلب کاربردها مناسب باشد.

مدیریت گفتار غیرقابل تشخیص

اکنون باید کد مثال پیشین را در مفسر  نوشته و نویزهای نامفهوم در میکروفون ایجاد شود.

در پاسخ باید پیامی شبیه آنچه در زیر آمده داده شود.

1Traceback (most recent call last):
2  File "<stdin>", line 1, in <module>
3  File "/home/david/real_python/speech_recognition_primer/venv/lib/python3.5/site-packages/speech_recognition/__init__.py", line 858, in recognize_google
4    if not isinstance(actual_result, dict) or len(actual_result.get("alternative", [])) == 0: raise UnknownValueError()
5speech_recognition.UnknownValueError

صوتی که نمی‌تواند توسط API تشخیص داده شود، منجر به نمایش پیام استثنای UnknownValueError می‌شود. کاربر باید همیشه فراخوانی‌های خود به API را با بلوک try and except پوشش دهد تا این استثناها را مدیریت کند.

تذکر: برای راه‌اندازی بلوک‌های «try and except» جهت مدیریت «استثناها» امکان دارد به تلاشی بیش از آنچه به نظر می‌رسد نیاز باشد. API برای رونویس هرگونه صوتی به شدت تلاش می‌کند. حتی خرخرهای اندک نیز به کلماتی مانند «how» رونویس می‌شوند. سرفه کردن، دست زدن و تپق‌های زبانی همواره استثنا را افزایش می‌دهند.

بازی «Guess the Word» با کد کامل

اکنون که مبانی بازشناسی گفتار با بسته SpeechRecognition به طور کامل بیان شد، از دانش جدید حاصل شده برای نوشن یک بازی که یک کلمه تصادفی را از یک لیست انتخاب می‌کند و به کاربر فرصت سه تلاش برای حدس زدن آن را می‌دهد استفاده می‌شود. اسکریپت کامل این بازی در زیر آمده است.

1import random
2import time
3
4import speech_recognition as sr
5
6
7def recognize_speech_from_mic(recognizer, microphone):
8    """Transcribe speech from recorded from `microphone`.
9
10    Returns a dictionary with three keys:
11    "success": a boolean indicating whether or not the API request was
12               successful
13    "error":   `None` if no error occured, otherwise a string containing
14               an error message if the API could not be reached or
15               speech was unrecognizable
16    "transcription": `None` if speech could not be transcribed,
17               otherwise a string containing the transcribed text
18    """
19    # check that recognizer and microphone arguments are appropriate type
20    if not isinstance(recognizer, sr.Recognizer):
21        raise TypeError("`recognizer` must be `Recognizer` instance")
22
23    if not isinstance(microphone, sr.Microphone):
24        raise TypeError("`microphone` must be `Microphone` instance")
25
26    # adjust the recognizer sensitivity to ambient noise and record audio
27    # from the microphone
28    with microphone as source:
29        recognizer.adjust_for_ambient_noise(source)
30        audio = recognizer.listen(source)
31
32    # set up the response object
33    response = {
34        "success": True,
35        "error": None,
36        "transcription": None
37    }
38
39    # try recognizing the speech in the recording
40    # if a RequestError or UnknownValueError exception is caught,
41    #     update the response object accordingly
42    try:
43        response["transcription"] = recognizer.recognize_google(audio)
44    except sr.RequestError:
45        # API was unreachable or unresponsive
46        response["success"] = False
47        response["error"] = "API unavailable"
48    except sr.UnknownValueError:
49        # speech was unintelligible
50        response["error"] = "Unable to recognize speech"
51
52    return response
53
54
55if __name__ == "__main__":
56    # set the list of words, maxnumber of guesses, and prompt limit
57    WORDS = ["apple", "banana", "grape", "orange", "mango", "lemon"]
58    NUM_GUESSES = 3
59    PROMPT_LIMIT = 5
60
61    # create recognizer and mic instances
62    recognizer = sr.Recognizer()
63    microphone = sr.Microphone()
64
65    # get a random word from the list
66    word = random.choice(WORDS)
67
68    # format the instructions string
69    instructions = (
70        "I'm thinking of one of these words:\n"
71        "{words}\n"
72        "You have {n} tries to guess which one.\n"
73    ).format(words=', '.join(WORDS), n=NUM_GUESSES)
74
75    # show instructions and wait 3 seconds before starting the game
76    print(instructions)
77    time.sleep(3)
78
79    for i in range(NUM_GUESSES):
80        # get the guess from the user
81        # if a transcription is returned, break out of the loop and
82        #     continue
83        # if no transcription returned and API request failed, break
84        #     loop and continue
85        # if API request succeeded but no transcription was returned,
86        #     re-prompt the user to say their guess again. Do this up
87        #     to PROMPT_LIMIT times
88        for j in range(PROMPT_LIMIT):
89            print('Guess {}. Speak!'.format(i+1))
90            guess = recognize_speech_from_mic(recognizer, microphone)
91            if guess["transcription"]:
92                break
93            if not guess["success"]:
94                break
95            print("I didn't catch that. What did you say?\n")
96
97        # if there was an error, stop the game
98        if guess["error"]:
99            print("ERROR: {}".format(guess["error"]))
100            break
101
102        # show the user the transcription
103        print("You said: {}".format(guess["transcription"]))
104
105        # determine if guess is correct and if any attempts remain
106        guess_is_correct = guess["transcription"].lower() == word.lower()
107        user_has_more_attempts = i < NUM_GUESSES - 1
108
109        # determine if the user has won the game
110        # if not, repeat the loop if user has more attempts
111        # if no attempts left, the user loses the game
112        if guess_is_correct:
113            print("Correct! You win!".format(word))
114            break
115        elif user_has_more_attempts:
116            print("Incorrect. Try again.\n")
117        else:
118            print("Sorry, you lose!\nI was thinking of '{}'.".format(word))
119            break

اکنون، کد بالا به قطعات کوچک شکسته و توضیحات مربوط به هر بخش آن ارائه می‌شود. تابع ()recognize_speech_from_mic نمونه‌های Recognizer و Microphone را به عنوان آرگومان دریافت کرده و یک دیکشنری با سه کلید باز می‌گرداند. اولین کلید، «success»، یک متغیر بولی است که نشان می‌دهد یک درخواست API موفقیت‌آمیز بوده یا نه. دومین کلید، «error»، یا «None» است و یا یک پیام خطا که نشان می‌دهد API در دسترس نیست یا گفتار نامفهوم بوده است. در نهایت، کلید «transcription» شامل رونویس از صوت رکورد شده توسط میکروفون می‌شود. تابع ابتدا بررسی می‌کند که آرگومان‌های recognizer و microphone از نوع صحیحی هستند و در صورتی که یکی و یا هر دوی آن‌ها نامعتبر باشد، TypeError داده می‌شود.

1if not isinstance(recognizer, sr.Recognizer):
2    raise TypeError('`recognizer` must be `Recognizer` instance')
3
4if not isinstance(microphone, sr.Microphone):
5    raise TypeError('`microphone` must be a `Microphone` instance')

متد ()listen سپس برای رکورد ورودی میکروفون مورد استفاده قرار می‌گیرد.

1with microphone as source:
2    recognizer.adjust_for_ambient_noise(source)
3    audio = recognizer.listen(source)

متد ()adjust_for_ambient_noise برای کالیبره کردن سازمان‌دهنده برای تغییر شرایط نویز هر بار که تابع ()recognize_speech_from_mic فراخوانی می‌شود مورد استفاده قرار می‌گیرد. سپس، ()recognize_google برای رونویس هر گفتاری در رکوردها فراخوانی می‌شود. یک بلوک try...except برای گرفتن استثناهای RequestError و UnknownValueError و مدیریت آن‌ها مورد استفاده قرار می‌گیرد. موفقیت درخواست API، هر گونه پیغام خطایی و گفتار رونویس شده در کلیدهای error ،success و transcription از دیکشنری response ذخیره می‌شوند که با تابع ()recognize_speech_from_mic بازگردانده می‌شود.

1response = {
2    "success": True,
3    "error": None,
4    "transcription": None
5}
6
7try:
8    response["transcription"] = recognizer.recognize_google(audio)
9except sr.RequestError:
10    # API was unreachable or unresponsive
11    response["success"] = False
12    response["error"] = "API unavailable"
13except sr.UnknownValueError:
14    # speech was unintelligible
15    response["error"] = "Unable to recognize speech"
16
17return response

می‌توان تابع ()recognize_speech_from_mic را با ذخیره‌سازی اسکریپت بالا در فایلی با نام «guessing_game.py» و اجرای دستوری که در ادامه می‌آید در یک سشن مفسر تست کرد.

1>>> import speech_recognition as sr
2>>> from guessing_game import recognize_speech_from_mic
3>>> r = sr.Recognizer()
4>>> m = sr.Microphone()
5>>> recognize_speech_from_mic(r, m)
6{'success': True, 'error': None, 'transcription': 'hello'}
7>>> # Your output will vary depending on what you say

خود بازی بسیار ساده است. ابتدا، یک لیست از کلمات، حداکثر تعداد حدس‌های قابل پذیرش، محدودیت prompt به صورت زیر تعیین می‌شود.

1WORDS = ['apple', 'banana', 'grape', 'orange', 'mango', 'lemon']
2NUM_GUESSES = 3
3PROMPT_LIMIT = 5

سپس، نمونه Recognizer و میکروفون ساخته می‌شوند و کلمه تصادفی از میان کلمات انتخاب می‌شود.

1recognizer = sr.Recognizer()
2microphone = sr.Microphone()
3word = random.choice(WORDS)

پس از پرینت کردن دستورالعمل‌ها و منتظر ماندن به مدت ۳ ثانیه، یک حلقه for برای مدیریت هر تلاش جهت حدس زدن و انتخاب کلمات استفاده می‌شود. اولین چیز درون حلقه for یک حلقه for دیگر است که کاربر را برای حداکثر زمان PROMPT_LIMIT به تلاش برای حدس زدن برمی‌انگیزد، و تلاش می‌کند که ورودی را هر بار با تابع ()recognize_speech_from_mic تشخیص دهد و دیکشنری بازگردانده شده به متغیر محلی guess را ذخیره کند.

اگر کلید transcription برای guess برابر با None باشد، گفتار کاربر رونویسی می‌شود و حلقه داخلی با break خاتمه پیدا می‌کند. اگر گفتار رونویسی نشود و مقدار کلید success برابر با False شود، خطای API به وقوع می‌پیوندد و حلقه مجددا با break خاتمه پیدا می‌کند. در غیر این صورت، درخواست API موفقیت‌آمیز اما گفتار غیر قابل تشخیص بوده است. به کاربر هشدار داده و حلقه for تکرار خواهد شد و به کاربر شانس دیگری در همان تلاش داده می‌شود.

1for j in range(PROMPT_LIMIT):
2    print('Guess {}. Speak!'.format(i+1))
3    guess = recognize_speech_from_mic(recognizer, microphone)
4    if guess["transcription"]:
5        break
6    if not guess["success"]:
7        break
8    print("I didn't catch that. What did you say?\n")

پس از آنکه حلقه for داخلی متوقف شد، دیکشنری guess از جهت خطاها مورد بررسی قرار می‌گیرد. اگر خطایی به وقوع بپیوندد، پیام خطا نمایش داده می‌شود و حلقه for بیرونی با دستور break متوقف می‌شود که این کار منجر به پایان اجرای برنامه می‌شود.

1if guess['error']:
2    print("ERROR: {}".format(guess["error"]))
3    break

اگر هیچ خطایی وجود نداشت، رونویس با کلمه‌ای که به طور تصادفی انتخاب شده مقایسه می‌شود. متد ()lower برای اشیای رشته برای حصول اطمینان از تطبیق بهتر کلمه انتخاب شده و حدس مورد استفاده قرار می‌گیرد. API ممکن است سخنرانی تطبیق یافته با کلمه «سیب» را به صورت «apple» یا «Apple» بازگرداند و پاسخ باید به عنوان صحیح در نظر گرفته شود.

اگر حدس صحیح باشد، کاربر پیروز می‌شود و بازی پایان می‌یابد. اگر کاربر اشتباه کرده باشد و تلاشی برای او باقی مانده باشد، حلقه for خارجی تکرار می‌شود و یک حدس جدید بازیابی می‌شود. در غیر این صورت، کاربر بازی را می‌بازد.

1guess_is_correct = guess["transcription"].lower() == word.lower()
2user_has_more_attempts = i < NUM_GUESSES - 1
3
4if guess_is_correct:
5    print('Correct! You win!'.format(word))
6    break
7elif user_has_more_attempts:
8    print('Incorrect. Try again.\n')
9else:
10    print("Sorry, you lose!\nI was thinking of '{}'.".format(word))
11    break

هنگام اجرا، خروجی چیزی شبیه زیر خواهد بود.

I'm thinking of one of these words:
apple, banana, grape, orange, mango, lemon
You have 3 tries to guess which one.

Guess 1. Speak!
You said: banana
Incorrect. Try again.

Guess 2. Speak!
You said: lemon
Incorrect. Try again.

Guess 3. Speak!
You said: Orange
Correct! You win!

بازشناسی گفتار در زبان‌های غیر انگلیسی

در این راهنما، بازشناسی گفتار در زبان انگلیسی انجام شد که زبان پیش‌فرض برای متدهای ()*_recognize از بسته SpeechRecognition است.

اگرچه، قطعا امکان بازشناسی گفتار در دیگر زبان‌ها وجود دارد و انجام آن ساده خواهد بود. برای بازشناسی گفتار در زبان‌های گوناگون، آرگومان کلیدواژه language از متد ()*_recognize باید روی رشته‌ای از زبان دلخواه قرار بگیرد. اغلب متدها تگ زبان BCP-47، مانند «en-US» برای انگلیسی آمریکایی یا «fr-FR» برای فرانسوی را می‌پذیرند. برای مثال، کد زیر گفتار فرانسوی را در یک فایل صوتی تشخیص می‌دهد.

1import speech_recognition as sr
2
3r = sr.Recognizer()
4
5with sr.AudioFile('path/to/audiofile.wav') as source:
6    audio = r.record(source)
7
8r.recognize_google(audio, language='fr-FR')

تنها متدهای زیر آرگومان کلیدواژه language را می‌پذیرند.

  • recognize_bing()
  • recognize_google()
  • recognize_google_cloud()
  • recognize_ibm()
  • recognize_sphinx()

برای آگاهی از اینکه کدام تگ‌های زبانی توسط API مورد استفاده کاربر پشتیبانی می‌شوند، مطالعه مستندات (+) مربوط به آن‌ها توصیه می‌شود. لیستی از تگ‌های پذیرفته شده توسط ()recognize_google در اینجا (+) موجود هستند.

خلاصه

در این راهنما، چگونگی نصب بسته SpeechRecognition و استفاده از کلاس Recognizer آن برای تشخیص آسان از هر دو فایل با استفاده از ()record و ورودی میکروفون با استفاده از ()listen بیان شد.

همچنین، چگونگی پردازش قطعات یک فایل صوتی با استفاده از آرگومان‌های کلیدواژه offset و duration از متد ()record مورد بررسی قرار گرفت.

تشخیص گفتار در پایتون
بازشناسی گفتار در پایتون

در ادامه مطلب، تاثیر نویز بر صحت رونویس‌ها و چگونگی تنظیم حساسیت نمونه‌های Recognizer برای نویز محیط با ()adjust_for_ambient_noise تشریح شد. در نهایت، استثناهای مورد استفاده و خطاهای ممکن در حالات گوناگون مورد بررسی قرار گرفت. در مجموع باید گفت، بازشناسی گفتار یک موضوع عمیق است و آنچه در اینجا بیان شد همچون کاهی در مقابل کوه است.

اگر مطلب بالا برای شما مفید بوده، آموزش‌های زیر نیز به شما پیشنهاد می‌شود:

^^

بر اساس رای ۱۹ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
realpython
۹ دیدگاه برای «بازشناسی گفتار (Speech Recognition) با پایتون — از صفر تا صد»

عالی و کامل!
تشکر فراوان از شما

سلام وقت بخیر
اگر امکانش هست لینک منبع این مطالب رو هم قرار بدید
ممنون

سلام، وقت شما بخیر؛

لینک منبع کلیه مطالب فرادرس در صورتیکه ترجمه یا تالیف باشند در انتهای آن‌ها و پس از بخش معرفی مطالب و آموزش‌های مرتبط آمده است.

از اینکه با مجله فرادرس همراه هستید از شما بسیار سپاسگزاریم.

سلام وقتتون بخیر
یه سوال داشتم چجوری فرمان های صوتی از راه دور روی کامپیوتر اجرا میشن
مثلا صد متر دور از کامپیوتر با میکروفون یه فرمان صوتی میدهیم و روی کامپیوتر اجرا میشن کردن چجوری این فرمان صوتی به کامپیوتر میرسه
ممنون میشم اگه بگید

تو cmd که این کد رو می زنم یک خطا عجیب میاد چه کار کنم؟
pip install pyaudio

سلام
خیلییی جامع و کامل بود همون چیزی بود که میخواستم
ممنون از نویسنده و سایت

فوق العاده بود
البته اگه با IDE pycharm
کارکنید نصب این کتابخونه ها خیلی راحت می شه
ممنون

سلام
یه چیزی رو یادتون رفته بود بگید اونم روش استفاده برای زبان فارسی بود :
(‘r.recognize_google(audio, language=’fa-ir)

دمت گرم من برای چیز دیگه ای اومده بودم این رو دیدم یک چیزی یاد گرفتم

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *