نموذج تحويل الصّوت إلى نصٍّ باستخدامِ لغة البايثون

Speech recognition
3- نموذج تحويل الصّوت إلى نصٍّ باستخدامِ لغة البايثون

انتشر استخدام  تطبيقات  المساعدة على الهواتف الذّكيّة، وأصبح من المألوف علينا إرسال طلباتنا بشكلٍ صوتيٍّ لنرى الاستجابة النّصية جاهزةً على أجهزتنا، فمثلاً نحن عندما نستيقظ صباحاً نودّ الاستعلام عن الطّقس فنقول لجهاز الموبايل عبر برنامج غوغل فويس Google Voice

“Hey Google. What’s the weather like today?”

فيقوم غوغل بكتابة نمطِ الطّقس الكامل، وهذا ما يوفّر لنا الكثيرَ من الوقت فيمكن إلقاء نظرةٍ سريعةٍ على الشّاشة، والعودة إلى العمل بدلاً من كتابة كامل الاستعلام عن الطّقس على محرّك البحث غوغل.

لكنّ السّؤال المثير للعجب، هو أنّه کیف لبرنامج غوغل أن يحوّل الاستعلاماتِ الصّوتیّة إلى نصوص؟؟

 إنّ غوغل یستخدم مزيجًا من تقنیّات التعلّم العميق ومعالجة اللّغات الطّبيعیّة (NLP)، لتحليل استعلامنا واسترداد الإجابة وتقديمها بشكلٍ نصّ.

يتمّ استخدام نفس مفهوم تحويل الكلام إلى نصٍّ في جميع تقنيّات التعرّف على الكلام الشائعة الأخرى ، مثل ألكسا Alexa من أمازون Amazon ، وسيري Siri من آبّل Apple ، وما إلى ذلك، وقد تختلف الدلالات من شركةٍ إلى أخرى، لكنّ الفكرة العامّة تظلّ كما هي.

والآن عزيزي القارئ كيف يمكننا بناء نموذج تحويل الكلام إلى نص خاص بنا باستخدام لغة بايثون ومهارات التعلّم العميق.

 علينا الاطّلاع أولاً على أساسيّات أنظمة التعرّف على الكلام، أي مقدّمة لمعالجة الإشارات فستكون معالجة الإشارة الصّوتيّة أمراً جوهريّاً عندما نطّبق نموذج تحويل الكلام إلى نصٍّ خاص بنا باستخدام لغة بايثون.

ما هي الإشارة الصّوتيّة؟

إنّ أيّ جسمٍ يهتزّ يُنتج موجاتٍ صوتيّة. هل فكرت يومًا كيف يمكننا سماع صوت شخصٍ ما؟ إنّه بسبب الموجات الصّوتيّة.

عندما يهتزّ جسم ما، تتأرجح جزيئات الهواء ذهاباً وإياباً عن موضعها وتنقل طاقتها إلى الجزيئات المجاورة، مما يؤدّي إلى انتقال الطّاقة من جزيء إلى آخر ينتج بدوره موجة صوتيّة.

الشكل-1 الموجة الصوتيــــة

معاملات الإشارة الصّوتيّة

المطال Amplitude : مقدار إزاحة الهواء عن وضعيّة الخمود، وهو صفة تميّز الصّوت المرتفع من الصوت المنخفض.

قمّة ومنخفض الموجة Crest and Trough: القمّة هي أعلى نقطة في الموجة،  بينما أسفل الموجة هو أدنى نقطة فيها.

الطّول الموجيّ Wavelength: يُعرّف الطّول الموجيّ بالمسافة بين قمّتين أو منخفضين متتاليين.

الدّورة Cycle: هي حركة الإشارة للقمّة والمنخفض مرّة واحدة، ولكلّ إشارة صوتيّة عدد من الدّورات.

تردّد الإشارة Frequency: يشير التردّد إلى سرعة تغيّر الإشارة عبر الزّمن، أي عدد المرّات التي تكررت فيها الإشارة نفسها خلال ثانية واحدة، ويكون تردّد الصّوت النّاعم أعلى من تردّد الصّوت الخشن.

الشكل-2 معاملات الإشارة الصّوتيّة

أنواع الإشارات

تنقسم الإشارات بشكل أساسي إلى نوعين: الإشارات الرّقميّة والإشارات التّشابهيّة.

الإشارات الرّقميّة:

الإشارة الرّقميّة هي تمثيل غير مترابط للإشارة عبر فترة من الزّمن. حيث يوجد عدد محدود من العيّنات بين أيّة فترتين زمنيّتين.

على سبيل المثال ، يشکّل متوسّط علامات طلّاب كليّة الهندسة من الرّتبة العليا والمتوسّطة على مدار السنوات الدراسيّة إشارة رقميّة، نظرًا لأنّه ينتج عنه عدد محدود من العيّنات.

الشكل-3 الإشارة الرقميّة

الإشارات التّشابهيّة

تُعرّف الإشارة التّشابهيّة بأنّها تمثيل مستمرّ للإشارة خلال مدّة زمنيّة، نلاحظ وجود عددٍ غير منتهٍ من العيّنات بين كلّ فترتين زمنيّتين في الإشارة التّشابهيّة على عكس الإشارة الرّقميّة التي تحوي عدداً محدداً من العيّنات.

على سبيل المثال، تشکّل إشارة الصّوت إشارة تشابهيّة لأنّها تمثيل مستمرّ للإشارة.

الشّكل-4 الإشارة التّشابهيّة

ما هو مفهوم أخذ العيّنات وما هي أهميّته؟

الإشارة الصّوتية تمثيل مستمرّ للمطالات التي تختلف وفقاً للزّمن، وتكون الفترات الزّمنيّة متقاربة جداً حيث يُقاس الزّمن بالـ بيكو ثانية.

إنّ التّعامل مع الإشارات التّشابهيّة يأخذ حجماً كبيراً من الذّاكرة، لأنّ الإشارة التّشابهيّة تحوي عدداً غير منتهٍ من العیّنات، وتتطلّب معالجة هذه العيّنات تعقيداتٍ حسابيّة كبيرة.

لذلك نحتاج إلى تقنيّة لتحويل الإشارة التّشابهيّة إلى إشارة رقميّة يمكن معالجتها بسهولة.

إنّ أخذ عيّنات الإشارة يعني تحويل الإشارة من إشارة تشابهيّة إلى إشارة رقمية، وذلك باختيار عددٍ محدّد من عيّنات الإشارة التّشابهيّة في الثّانية.

إذاً نستطيع تحويل الإشارة الصّوتيّة إلى إشارة رقميّة، من خلال أخذ العيّنات فيصبح تخزينها في الذّاكرة والتّعامل معها ومعالجتها أكثر فعاليّة.

عزيزي القارئ دعنا نتابع سويةً كيفيّة تخزين الإشارة الصّوتيّة في الذّاكرة من خلال أخذ العيّنات.

الشكل-5 مراحل تحويل الإشارة

يعرّف معدّل أخذ العیّنات أو تكرار أخذها على أنّه عدد العيّنات المختارة في الثّانية، فكلّما كان معدّل أخذ العیّنات كبيراً، كلّما ضمنّا عدم تماثل الإشارة الرّقمية النّاتجة عن الإشارة التّشابهيّة مع إشارة رقميّة ناتجة عن إشارة تشابهيّة أخرى.

تقانات استخلاص ميّزات الإشارة الصّوتيّة

إنّ الخطوة الأولى في التعرّف على الصّوت هي استخلاص الميزات التي ستشكل دخل نموذج التعرف عليھ ، لذلك سنتكلّم عن الطّرق المختلفة لاستخلاص الميّزات من الإشارة الصّوتيّة.

المجال الزّمنيّ

يتمّ تمثيل الإشارة الصّوتية في المجال الزّمنيّ كدالّة من المطالات بدلالة الزمن.

بتعبيرٍ بسيط يمكننا القول أنّ الإشارة في المجال الزّمنيّ هي رسم بياني بين المطال والزّمن.

وتكون الميّزات في هذه الحالة هي المطالات المأخوذة خلال فترات زمنيّة مختلفة.

الشّكل-6 تحليل الإشارة في المجال الزّمنيّ

إنّ تمثيل الإشارة في المجال الزّمنيّ يتجاهل معلومات معدّل الإشارة، مما يجعلنا نرغب في تمثيل الإشارة في المجال التردّدي.

المجال التردّدي

يتمّ تمثيل الإشارة الصّوتية في المجال التردّدي كدالّة من المطالات بدلالة التردّد، أي ببساطة يمكننا القول أنّ الإشارة الصّوتية في المجال التردّدي هي رسم بيانيّ بين المطال والتردّد. وتكون الميّزات في هذا التمثيل هي المطالات المسجلة عند تردّدات مختلفة.

الشكل 7 تحليل الإشارة في المجال التردّدي

تكمن محدودیّة هذا التمثيل بأنّه يتجاهل ترتيب تسلسل الإشارة المأخوذ بعين الاعتبار في المجال الزّمنيّ.

ملاحظة: عزيزي القارئ لا بدّ أن ننتبه أنّ تحليل الإشارة في المجال الزّمنيّ يتجاهل تمامًا مكوّن التردّد، بينما تحليل الإشارة في المجال التردّدي لا يعطي اهتماماً لمكوّن الزّمن.

نريد أن نأخذ التردّدات المعتمدة على الزّمن وذلك بالاستعانة بمخطّط الطّيف.

مخطّط الطّيف

هل سمعتم بمخطّط الطّيف؟  يعرّف مخطّط الطّيف أنّه رسم ثنائيّ البعد بين الزّمن والتردّد، حيث تمثّل كلّ نقطة في هذا الرّسم مطال تردّد معيّن في زمن معيّن من حيث كثافة اللّون. 

إذاً يمكننا القول أنّ مخطّط  الطّيف يشكّل نطاقاً واسعاً من الألوان للتردّدات المختلفة مع الزّمن.

الششّل-8 مخطّط الطّيف

التعرّف على الكلام المنطوق

تقوم الشّركات البرمجيّة بتحديثات مستمرّة لتنتج واجهاتٍ جديدة على أجهزتنا الموبايل، لكنّ الشّاشة التي يحلم بها الجميع أن تكون شاشة متفاعلة مع كلامنا وليس فقط مع صورنا وكتاباتنا.

أصدرت مكتبة تنسر فلو tensorflow التي يمكن التعامل معها في لغة البايثون python مجموعةَ بيانات للأوامر الكلاميّة المنطوقة متضمّنة 65000 صوتاً مدّة كلّ صوت ثانية واحدة كما يتألّف كلّ صوت من 30 كلمة قصيرة مسجلّة لآلاف الأشخاص المختلفين. 

والآن حان الوقت لبناء نظام التعرّف على الكلام الذي يفهم الأوامر المنطوقة البسيطة.

تطبيق نموذج التعرّف على الكلام المنطوق بلغة البايثون

تضمين المكتبات:

تُستخدم مكتبة تحليل الصوت والموسيقى LibROSA  ومكتبة الحسابات العلمية SciPy لمعالجة الإشارات الصّوتيّة، ويمكن تضمينهم باستخدام تعليمة التّضمينimport وكذلك نحتاج لتضمين بعضَ المكتبات الأخرى، مثل مكتبة التّعامل مع نظام التّشغيل os ومكتبةُ بايثون العدديَّةُ  numpy  و مكتبة الإظهار display ومكتبة الرّسم البيانيّ matplotlib.

import os


import librosa  
import IPython.display as ٨ipd
import matplotlib.pyplot as plt
import numpy as np
from scipy.io import wavfile import warnings
warnings.filterwarnings("ignore")


يساعدنا استكشاف البيانات وإظهارها على فهم البيانات، وبالتّالي نستطيع إجراءَ المعالجة المُسبقة عليها بطريقةٍ أفضل.

إظهار الإشارة الصّوتيّة في المجال الزّمنيّ

نستخدم المكتبة ليبروسا librosa لتحميل الملف الصّوتيّ الذي يمثل الإشارة الصّوتيّة، ثمّ نرسم هذه الإشارة بالاستعانة بمكتبة الرّسم البيانيّ matplotlib.

نلاحظ في تعليمة librosa.load معامل sr وهو يعبر عن معدل أخذ العينات للإشارات الصوتية.

train_audio_path = '/content/train/audio'
samples, sample_rate = librosa.load('/content/train/audio/yes/0a7c2a8d_nohash_0.wav', sr = 16000)
fig = plt.figure(figsize=(14, 8))
ax1 = fig.add_subplot(211)
ax1.set_title('Raw wave of ' + '../input/train/audio/yes/0a7c2a8d_nohash_0.wav')
ax1.set_xlabel('time')
ax1.set_ylabel('Amplitude')
ax1.plot(np.linspace(0, sample_rate/len(samples), sample_rate), samples)

الشكل-9 الإشارة الصوتية في المجال الزمني

أخذ العیّنات

لنرَ معدّل أخذ العيّنات أي عدد العيّنات المأخوذة في الثّانية الواحدة نطبّق التّعليمات التّالية:

ipd.Audio(samples, rate=sample_rate)
print(sample_rate)

تغيير معدّل أخذ العیّنات

ممّا سبق يمكننا أن نفهم أنّ معدّل أخذ العيّنات للإشارة هو 16000 هرتز، لنغير معدّل أخذ العيّنات إلى  8000 هرتز لأنّ معظم التردّدات المتعلّقة بالكلام في مجموعة البيانات المستخدمة موجودة عند 8000 هرتز.

samples = librosa.resample(samples, sample_rate, 8000)
ipd.Audio(samples, rate=8000)

إنّ مجموعة البيانات التي نعمل عليها عبارة عن مجموعة أوامر مسجّلة صوتيّاً، لذلك دعونا نعرف عدد التّسجيلات الصّوتيّة لكلّ أمر command الموجودة في مجموعة البيانات وذلك برسم مخطّط بيانيّ بالاستفادة من مكتبة الرّسم matplotlib.

labels=os.listdir(train_audio_path)

#find count of each label and plot bar graph
no_of_recordings=[]
for label in labels:
    waves = [f for f in os.listdir(train_audio_path + '/'+ label) if f.endswith('.wav')]
    no_of_recordings.append(len(waves))
    
#plot
plt.figure(figsize=(30,5))
index = np.arange(len(labels))
plt.bar(index, no_of_recordings)
plt.xlabel('Commands', fontsize=12)
plt.ylabel('No of recordings', fontsize=12)
plt.xticks(index, labels, fontsize=15, rotation=60)
plt.title('No. of recordings for each command')
plt.show()

labels=["yes", "no", "up", "down", "left", "right", "on", "off", "stop", "go"]
الشكل-10 عدد التسجيلات الصوتية لكل أمر command

مدّة التّسجيلات الصّوتيّة

لنلقِ نظرةً على توزيع مدّة التّسجيلات من خلال رسم مخطّط الهستوغرام للتّسجيلات الصّوتيّة وذلك من خلال التّعليمات التّالية :

duration_of_recordings=[]
for label in labels:
    waves = [f for f in os.listdir(train_audio_path + '/'+ label) if f.endswith('.wav')]
    for wav in waves:
        sample_rate, samples = wavfile.read(train_audio_path + '/' + label + '/' + wav)
        duration_of_recordings.append(float(len(samples)/sample_rate))
    
plt.hist(np.array(duration_of_recordings))
الشكل-11 مخطّط الهستوغرام للتّسجيلات الصّوتيّة

المعالجة المُسبقة للإشارات الصّوتيّة

لاحظنا في فقرات عرض واستكشاف البيانات،  أنّ مدّة بعض التّسجيلات أقلّ من ثانية واحدة وأنّ معدّل أخذ العيّنات لبعض التّسجيلات مرتفع جداً. لذا  دعونا نقرأ الموجات الصّوتيّة ونعالجها من خلال:

إعادة أخذ العيّنات لتخفيض معدّل أخذها .

حذف الأوامر القصيرة التي تقلّ عن ثانية واحدة.

تتمثّل معالجة الإشارات الصّوتييّة بالشّفرة البرمجيّة التّالية:

train_audio_path = '/content/train/audio/'

all_wave = []
all_label = []
for label in labels:
    print(label)
    waves = [f for f in os.listdir(train_audio_path + '/'+ label) if f.endswith('.wav')]
    for wav in waves:
        samples, sample_rate = librosa.load(train_audio_path + '/' + label + '/' + wav, sr = 16000)
        samples = librosa.resample(samples, sample_rate, 8000)
        if(len(samples)== 8000) : 
            all_wave.append(samples)
            all_label.append(label)

ثمّ نقوم بتشفير أصناف الخرج إلى أرقام صحيحة كما في الشّفرة التّالية:

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y=le.fit_transform(all_label)
classes= list(le.classes_)

سنحوّل الرّقم الصّحيح المشفّر إلى شعاعٍ بطريقة تحويل one hot vector لأنّ المسألة تصنيف متعدّد multi classification.

from keras.utils import np_utils
y=np_utils.to_categorical(y, num_classes=len(labels))

نعيد تشكيلَ أبعاد المصفوفة بما يتناسب مع دخل conv1D ولذلك نجعل المصفوفة ثنائيّة البعد بثلاثة أبعاد من خلال التّعليمة التّالية.

all_wave = np.array(all_wave).reshape(-1,8000,1)

نقسّم البيانات إلى بيانات تدريب بنسبة 80% وبيانات تحقّق بنسبة 20% من خلال التّعليمات التّالية:

from sklearn.model_selection import train_test_split
x_tr, x_val, y_tr, y_val = train_test_split(np.array(all_wave),np.array(y),stratify=y,test_size = 0.2,random_state=777,shuffle=True)

بنية النّموذج

سنبني نموذج تحويل الصّوت إلى نصّ باستخدام شبكة الطّي العصبونيّة Conv1d التي تنجز عملية الطّي على امتداد ذي  بعد واحد.

الشكل 12- بنية النموذج

بناء النّموذج 

سيتمّ بناء النّموذج باستخدام مكتبة كيراس.

يكون شكل الدّخل في النّموذج 8000*1 لأن معدّل العيّنات في الإشارة الصّوتيّة هو 8000 ، يتألّف النّموذج من أربع طبقات طيّ كما في الشّكل (9) ولكلّ طبقة طيّ طبقة تجمِيعٌ وفقَ القيمةِ الكُبرى max pooling.

from keras.layers import Dense, Dropout, Flatten, Conv1D, Input, MaxPooling1D
from keras.models import Model
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras import backend as K
K.clear_session()

inputs = Input(shape=(8000,1))

#First Conv1D layer
conv = Conv1D(8,13, padding='valid', activation='relu', strides=1)(inputs)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)

#Second Conv1D layer
conv = Conv1D(16, 11, padding='valid', activation='relu', strides=1)(conv)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)

#Third Conv1D layer
conv = Conv1D(32, 9, padding='valid', activation='relu', strides=1)(conv)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)

#Fourth Conv1D layer
conv = Conv1D(64, 7, padding='valid', activation='relu', strides=1)(conv)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)

#Flatten layer
conv = Flatten()(conv)

#Dense Layer 1
conv = Dense(256, activation='relu')(conv)
conv = Dropout(0.3)(conv)

#Dense Layer 2
conv = Dense(128, activation='relu')(conv)
conv = Dropout(0.3)(conv)
outputs = Dense(len(labels), activation='softmax')(conv)

model = Model(inputs, outputs)
model.summary()


عند بناء النّموذج الموضّح بالشّفرة البرمجيّة سيكون ملخّص النّموذج كما يلي :

 

Model: “model”

_________________________________________________________________

Layer (type)                 Output Shape              Param #   

===============================================================

input_1 (InputLayer)         [(None, 8000, 1)]         0         

_________________________________________________________________

conv1d (Conv1D)              (None, 7988, 8)           112       

_________________________________________________________________

max_pooling1d (MaxPooling1D) (None, 2662, 8)           0         

_________________________________________________________________

dropout (Dropout)            (None, 2662, 8)           0         

_________________________________________________________________

conv1d_1 (Conv1D)            (None, 2652, 16)          1424      

_________________________________________________________________

max_pooling1d_1 (MaxPooling1 (None, 884, 16)           0         

_________________________________________________________________

dropout_1 (Dropout)          (None, 884, 16)           0         

_________________________________________________________________

conv1d_2 (Conv1D)            (None, 876, 32)           4640      

_________________________________________________________________

max_pooling1d_2 (MaxPooling1 (None, 292, 32)           0         

_________________________________________________________________

dropout_2 (Dropout)          (None, 292, 32)           0         

_________________________________________________________________

conv1d_3 (Conv1D)            (None, 286, 64)           14400     

_________________________________________________________________

max_pooling1d_3 (MaxPooling1 (None, 95, 64)            0         

_________________________________________________________________

dropout_3 (Dropout)          (None, 95, 64)            0         

_________________________________________________________________

flatten (Flatten)            (None, 6080)              0         

_________________________________________________________________

dense (Dense)                (None, 256)               1556736   

_________________________________________________________________

dropout_4 (Dropout)          (None, 256)               0         

_________________________________________________________________

dense_1 (Dense)              (None, 128)               32896     

_________________________________________________________________

dropout_5 (Dropout)          (None, 128)               0         

_________________________________________________________________

dense_2 (Dense)              (None, 10)                1290      

================================================================

Total params: 1,611,498

Trainable params: 1,611,498

Non-trainable params: 0

سنختار تابعَ التّكلفة الانتروبيا المتقاطعة الفئويّة categorecal cross entropy لأنّ المسألة هي تصنيف متعدّد الأصناف multi classificaton.

model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])

التوقّف المبکّر والنّقاط العلاّمة checkpoints هي عملیّات لإيقاف تدريب الشّبكة العصبونیّة في الوقت المناسب وحفظ أفضل نموذج بعد كلّ دورة epoch.

es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10, min_delta=0.0001) 
mc = ModelCheckpoint('best_model.hdf5', monitor='val_acc', verbose=1, save_best_only=True, mode='max')

دعنا ندرّب النّموذج بتقسيم عیّنات التّدريب إلى دفعاتٍ كلّ دفعة بحجم 32.

history=model.fit(x_tr, y_tr ,epochs=100, callbacks=[es,mc], batch_size=32, validation_data=(x_val,y_val))

لقد تمّ التّوقف عند الدّورة 39

Epoch 00039: early stopping

سنعتمد على الرّسوم البيانیّة لفهم أداء النّموذج خلال فترة زمنیّة معيّنة برسم منحني تابع الخسارة لكل من عينات التدريب والاختبار.

from matplotlib import pyplot 
pyplot.plot(history.history['loss'], label='train') 
pyplot.plot(history.history['val_loss'], label='test') 
pyplot.legend() 
pyplot.show()
الشكل 13- منحنيات تابع الخسارة لبيانات التدريب والاختبار

نلاحظ أن منحنيات الخسارة لبيانات التدريب والاختبار متقاربة مما يدلّ على أنّ النموذج تدّرب وأصبح جاهزاً.

بعد حفظ النموذج نستخدم التعليمة التالية لتحميله.

from keras.models import load_model
model=load_model('best_model.hdf5')

والآن لنعرّف التابع الذي يعطي النّص من أجل تسجيلٍ صوتيٍّ ما.

def predict(audio):
    prob=model.predict(audio.reshape(1,8000,1))
    index=np.argmax(prob[0])
    return classes[index]

يمكنكم الاطلاع على كامل الشيفرة البرمجية في مستودع  الجت هب  الخاص بموقع الذكاء الاصطناعي باللغة العربية

الخلاصــــة

قدّمنا في هذه المقالة كيفیّة بناء نموذج تعلّم عميق للتعرّف على الصّوت وتحويله إلى نصٍّ وذلك خطوةً بخطوة.

حيث عرضنا خصائصَ الإشارات الصّوتيّة وطرقَ معالجتها في المجال الزّمنيّ والتردّدي ثمّ انتقلنا إلى بناء نموذج شبكة الطّيّ العصبونيّة وضبطنا معاملاته بحيث حصلنا على أفضل النّتائج في تحويل الصّوت إلى نصٍّ على مجموعة بيانات معياريّة من موقع كاغل kaggle.

يسرّني أن أرى تعليقاتكم حول هذا المقال في  عرض التعليقات  في الأسفل.

المراجــــــع

1-Learn how to Build your own Speech-to-Text Model (using Python)

2- https://www.kaggle.com/c/tensorflow-speech-recognition-challenge.

0 Shares:
9 تعليقات
    1. اهلا بك
      أولا تحصلل مجموعة بياناتك يعني يجب أن تعرف معدل العينات في إشارتك الصوتية بنفس الطريقة التي استخدمتها.
      ثم تجعل شكل الدخل للنموذج متوافق مع عدد العينات التي في مثالنا 8000
      و تقسم بياناتك الى بيانات تدريب وبيانات اختبار كما فعلنا في مثالنا في هذا المقال. وباتباع نفس الخطوات وصولا الى تعليمة fit المعبرة عن التدريب تخصل على النتيجة لكن يجب أن تراعي أن عدد الفلاتر وحجمها هو بارامتر تجريبي وفقا لبياناتك فقد تغير في قيم هذه البارامترات.
      بالتوفيق..

  1. السلام عليكم

    هل من ثمة خطأ في الشيفرة البرمجية في الفقرة: “إظهار الإشارة الصّوتيّة في المجال الزّمنيّ” ؟
    بالضبط في هذا السطر:
    “ax1.plot(np.linspace(0, sample_rate/len(samples), sample_rate), samples)”

    أعتقد بأن الصواب يجب أن يكون كالتالي:
    “ax1.plot(np.linspace(0, len(samples)/sample_rate, len(samples)), samples)”

    صحيح؟

  2. السلام عليكم
    وجزاك الله خير
    هل مدة التعرف فقط ثانية واحدة!
    وهل استطيع تمديدها بحيث اتكلم وقت ما اريد ولا اتقيد بالثانية

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

You May Also Like