LSTM
آموزش‌های پایه‌ای هوش مصنوعیآموزش‌های پیشرفته هوش مصنوعیپردازش گفتارکاربردهای هوش مصنوعیکتابخانه‌ های یادگیری عمیق

تولید موسیقی به کمک لایه‌های Conv LSTM: هوش مصنوعی قطعات موسیقی تولید می‌کند

    0
    مدت زمان مطالعه: ۶ دقیقه

    در این پروژه، ما از LSTM به جای GAN برای تولید موسیقی استفاده خواهیم کرد. در نتیجه استفاده از LSTM ها، مدل سریع‌تر آموزش می‌بیند و می‌توانیم عملکرد مدل را بر مبنای یک خروجی عینی ارزیابی کنیم.

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

    قطعه موسیقی زیر بخشی از موسیقی‌ ساخته شده توسط هوش مصنوعی است:

    نکته جالب در مورد قطعه موسیقی LSTM 2 این است که پایان این قطعه موسیقی به گونه‌ای است که شنونده احساس می‌کند قرار است یک کادانس کامل، آکورد درجه چهار، درجه پنج، درجه یک (IV-V-I) شروع شود. آکوردهایی قبلی هم جالب به نظر می‌رسند.

    LSTM

    پیش‌پردازش داده‌

    اولین مرحله در پروژه‌های یادگیری ماشین، پیش‌پردازش داده است. در پروژه پیش‌رو، عملیات پیش‌پردازش داده‌ها شامل دو مرحله است:

    دسترسی به فایل‌های Midi:

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

    تبدیل فایل‌های midi به تصویر

    من در GitHub صفحه‌ای پیدا کردم که دو برنامه (program) دارد و با استفاده از کتابخانه music21 فایل‌های midi را به تصویر و تصاویر را به فایل‌های midi تبدیل می‌کند.

    هر نُت را می‌توان به صورت یک بلوک سفید نشان داد. ارتفاع بلوک نشان‌دهنده نواک (pitch) و طول بلوک نشان‌دهنده مدت زمان اجرای نُت است.

    من برای اینکه این دو برنامه را با یکدیگر و با فایل‌های midi ادغام کنم و در یک دایرکتوری دیگر تصاویر جدیدی ایجاد کنم یک کد نوشتم:

    این کد ما را به مسیر دایرکتوری midi می‌برد و مسیر تمامی فایل‌های midi را به یک لیست اضافه می‌کند تا بتوانیم به آن‌ها دسترسی داشته باشیم:

     

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

    این کد با استفاده از تابع midi2image (که در همان صفحه GitHub قرار دارد) و با توجه به مسیر دسترسی به فایل‌های midi، فایل‌ها را به تصویر تبدیل می‌کند. از آنجایی‌که طول برنامه ۱۰۶ است و تعداد نت‌هایی موجود در یک فایل midi نیز ۱۰۶ نُت است، شکل فایل‌های midi به (۱۰۶، ۱۰۶) تغییر می‌کند. علاوه بر این، در عملیات transposed convolution کار کردن با مربعات آسان‌تر است.

    ایجاد دیتاست

    این کد ما به دایرکتوری می‌برد و تمامی داده‌های تصویری را ثبت می‌کند. توجه داشته باشید که تمامی تصاویر باید ۹۰ درجه چرخش (۹۰۰ rotation) داشته باشند، در این صورت تایع getdata می‌تواند به جای نواک (pitch)، بر اساس ترتیب زمانی به داده‌ها دسترسی پیدا کند.
    این کد بر مبنای داده‌های سری زمانی، لیست‌های x و y را می‌سازد. متغیر mini_x مجموعه‌های ۹ عضوی از نت‌ها را یک به یک به لیست‌ X اضافه می‌کنند و لیست Y نیز حاوی نت‌هایی است که روی هر یک از مجموعه‌های ۹تایی نگاشت شده‌اند.
    اگر لیست‌های x و y را به آرایه‌های Numpy تبدیل کنیم، زمانی‌که داده‌ها را به مدل وارد می‌کنیم با هیچ خطایی مواجه نمی‌شویم.
    این کد شکل آرایه‌های x و y را تغییر می‌دهد تا لایه Conv LSTM را برازش کند. مقدار این لیست‌ها برابر با ۱۰۶ یک (۱) و صفر (۰) خواهد بود. منظور از ۱  این است که نُت در این نواک اجرا خواهد شد و منظور از ۰ این است که هیچ نُتی با این نواک در این گام زمانی اجرا نمی‌شود.

    ساخت لایه Conv LSTM

    این کد، کلِ معماری مدل است که از آن استفاده می‌شود. به نظر من این مدل بسیار کارآمد و انعطاف‌پذیر است. پیش از این نیز از این مدل برای پیش‌بینی قیمت سهام بر مبنای داده‌های تاریخی استفاده کرده بودم. تنها تفاوت این دو مدل در این است که لایه آخر این مدل از تابع سیگموید با ۱۰۶ گره استفاده می‌کند، چرا که هر گام زمانی باید به صورت ۱۰۶ نُت تعریف شود و مشخص شود اینا این نُت اجرا می‌شود یا خیر.
    زمانی‌که این تابع را فراخوانی می‌کنیم تا معماری مدل را مشاهده کنیم، گزارشی بدین شکل به دست می‌آوریم:
    شما می‌توانید پارامترهای مدل را تغییر دهید و تأثیر هر یک از آن‌ها را  بر روی نتیجه نهایی مدل مشاهده کنید.
    این کد مدل را برای ۱۰۰   آموزش می‌دهد. توجه داشته باشید که در این مدل به داده‌ اعتبارسنجی نیاز نداریم، زیرا لازم نیست مدل نُت بعدی را ۱۰۰ درصد درست پیش‌بینی کند. در اینجا ما فقط می‌خواهیم مدل الگوی موسیقی اصلی را یاد بگیرد و نُت احتمالی بعدی را ایجاد کند.

    نتایج صوتی

    مدل با استفاده از این تابع می‌تواند موسیقی تولید کند. نحوه عملکرد این مدل بدین صورت است:

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

    در مرحله بعد، تصویر را ۹۰ درجه به عقب می‌چرخانیم تا تابع image2midi به خوبی عمل کند:

    سپس تصویر را به فایل midi تبدیل می‌کنیم و برای گوش دادن به قطعه موسیقی تولیدشده کد زیر را اجرا می‌کنیم:

    حالا می‌توانیم به موسیقی اولیه گوشی دهیم:

    چیزی نیست!

    هیچ موسیقی تولید نشده است.

    تغییر نتایج به صورت مصنوعی

    در زمان بررسی نتایج متوجه می‌شویم که مدل نمی‌تواند مقادیر بّزرگ‌تر از ۶/۰ را تولید کند. و با توجه به اینکه Numpy هم مقایر کمتر از ۶/۰ را رُند می‌کند، هیچ نُتی برای اجرا کردن وجود ندارد. من تمام تلاشم را کردم تا راهی برای تغییر معماری مدل پیدا کنم اما بر روی اینترنت چیزی پیدا نکردم.

    البته ایده‌ای به ذهنم رسید که نامتعارف است: اینکه نتایج را به صورت دستی تغییر دهیم.

    مشکلی که شبکه دارد این است که مقادیر پیش‌بینی شده خیلی کوچک هستند. اگر یک مقدار خاص به پیش‌بینی‌ها اضافه کنیم، شبکه می‌تواند نُت‌های واقعی را نمایش دهد.

    چگونه ممکن است که این تغییرات بر روی پیش‌بینی‌های مدل تأثیر نگذارند؟ زیرا ما می‌توانیم پیش‌بینی‌های مدل را مصور کنیم: البته نه به عنوان نُت اجرا شده یا نُت اجرا نشده، بلکه به این صورت که آیا این نُت مناسب این گام زمانی است یا خیر. در واقع مدل بر روی تابع زیان MSE آموزش می‌بیند: به عبارت دیگر، تفاضل میان مقدار پیش‌بینی شده و مقادیر واقعی معنادار است. با توجه به اینکه مقادیری که مدل در آغاز پیش‌بینی کرده، مجدداً آموزش می‌بینند، پیش‌بینی‌های مدل بزرگ می‌شوند.

    تابع تولید موسیقی را ارتقا دادیم:

    در این تابع دو متغیر جدید به نام‌های vanish_proof و vanish_inc داریم. Vanish_proof مقداری است که به تمامی پیش‌بینی‌ها اضافه می‌شود و vanish_inc نرخ افزایش vanish_proof است. با توجه به اینکه هر یک از پیش‌بینی‌های شبکه بر مبنای پیش‌بینی‌های قبلی خواهند بود، وجود این دو متغیر لازم و ضروری است. کوچک‌ بودن پیش‌بینی‌ها بر عملیات انتشار رو به جلو (forward propogation) تأثیر می‌گذارد و باعث می‌شود موسیقی به آرامی خاموش شود.

    در نتیجه  موسیقی بهتری ساخته می‌شود. من این قطعه موسیقی را دوست دارم:

    نتیجه‌گیری

    به نظر من جالب‌ترین قسمت این مقاله همان تغییر دستی نتایج بود. تا جایی که اطلاع دارم کسی قبلاً این کار را انجام نداده و مطمئنم نیستم این تمرین چقدر نتیجه‌بخش است. شما می‌توانید متغیرهای vanish_proof و vanish_inc را تغییر دهید و نتایج آن را مشاهده کنید.

    من بهنام هستم
    این مطلب چه میزان برای شما مفید بوده است؟
    [کل: ۰ میانگین: ۰]

    دستاورد جدید پژوهشی در زمینه هوش مصنوعی توسط عضو علمی دانشگاه پیام نور مرکز اردکان به چاپ رسید

    مقاله قبلی

    تحلیل فیلم اکس ماشین با آزمایش تورینگ

    مقاله بعدی

    شما همچنین ممکن است دوست داشته باشید

    نظرات

    پاسخ دهید

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