I have an error in this code and the error is () Is there anyone who can help me I would be grateful for that
% إضافة مسار مكتبة WFDB Toolbox إلى Matlab
addpath("C:wfdbwfdb-app-toolbox-0-10-0mcode"); % استبدل هذا المسار بموقع مكتبة WFDB على جهازك
% قائمة بالتسجيلات من قاعدة البيانات
records = {‘100’, ‘101’, ‘102’, ‘103’, ‘104’, ‘105’, ‘106’, ‘107’, ‘108’, ‘109’, …
‘111’, ‘112’, ‘113’, ‘114’, ‘115’, ‘116’, ‘117’, ‘118’, ‘119’, ‘121’, …
‘122’, ‘123’, ‘124’, ‘200’, ‘201’, ‘202’, ‘203’, ‘205’, ‘207’, ‘208’, …
‘209’, ‘210’, ‘212’, ‘213’, ‘214’, ‘215’, ‘217’, ‘219’, ‘220’, ‘221’, …
‘222’, ‘223’, ‘228’, ‘230’, ‘231’, ‘232’, ‘233’, ‘234’};
% تحديد نسبة البيانات للتدريب
train_ratio = 0.7;
% ترتيب السجلات عشوائيًا لضمان توزيع عشوائي
shuffled_indices = randperm(length(records));
records = records(shuffled_indices);
% حساب عدد السجلات للتدريب والاختبار
num_train = round(train_ratio * length(records));
num_test = length(records) – num_train;
% تقسيم السجلات إلى مجموعتي التدريب والاختبار
train_records = records(1:num_train);
test_records = records(num_train+1:end);
% دالة لقراءة ومعالجة بيانات ECG
function data = read_and_process_ecg(recordName)
[ECG, Fs] = rdsamp(recordName, 1); % قراءة البيانات
ECG = ECG – mean(ECG); % إزالة ضوضاء التيار المستمر
[b, a] = butter(4, [0.5 45] / (Fs / 2), ‘bandpass’); % مرشح رقمي
filtered_ECG = filtfilt(b, a, ECG); % تطبيق المرشح بتمرير صفري
normalized_ECG = 2 * (filtered_ECG – min(filtered_ECG)) / (max(filtered_ECG) – min(filtered_ECG)) – 1; % تطبيع
qrs_peaks = panTompkinsQRS(normalized_ECG, Fs); % اكتشاف قمم QRS
data.segments = segmentHeartBeats(normalized_ECG, qrs_peaks, Fs); % تجزئة نبضات القلب
data.Fs = Fs;
end
% معالجة بيانات التدريب
train_data = cell(length(train_records), 1);
for i = 1:length(train_records)
recordName = train_records{i};
fprintf(‘Processing training record %s…n’, recordName);
train_data{i} = read_and_process_ecg(recordName);
end
% معالجة بيانات الاختبار
test_data = cell(length(test_records), 1);
for i = 1:length(test_records)
recordName = test_records{i};
fprintf(‘Processing test record %s…n’, recordName);
test_data{i} = read_and_process_ecg(recordName);
end
% توحيد البيانات في مصفوفة 3D (عينات، ميزات، قنوات)
function [X, Y] = prepare_data(data, fixed_segment_length)
% حساب عدد العينات
num_samples = sum(cellfun(@(d) length(d.segments), data));
% تهيئة مصفوفة البيانات
X = zeros(num_samples, fixed_segment_length, 1); % إضافة بُعد القنوات
Y = zeros(num_samples, 1);
sample_idx = 1;
for i = 1:length(data)
for j = 1:length(data{i}.segments)
segment = data{i}.segments{j};
segment_length = length(segment);
% إذا كان المقطع أطول من الطول الثابت، نقوم بتقليمه
if segment_length > fixed_segment_length
segment = segment(1:fixed_segment_length);
% إذا كان المقطع أقصر، نقوم بتعبئته بالأصفار
elseif segment_length < fixed_segment_length
segment = [segment; zeros(fixed_segment_length – segment_length, 1)];
end
% تعيين المقطع إلى مصفوفة X
X(sample_idx, :, 1) = segment’; % تعيين مع إضافة بُعد القناة
% تعيين التسمية
Y(sample_idx) = i; % استخدام رقم السجل كتصنيف مبدئي
sample_idx = sample_idx + 1;
end
end
% تحويل X إلى الشكل المطلوب (طول السلسلة، عدد العينات، عدد القنوات)
% X = permute(X, [2, 3, 1]); % ليس هناك حاجة لإعادة الترتيب هنا
end
% تعيين الطول الثابت للمقاطع
fixed_segment_length = 625; % يمكنك ضبط هذا الطول بناءً على تحليل البيانات
% تجهيز بيانات التدريب والاختبار
[xTrain, yTrain] = prepare_data(train_data, fixed_segment_length);
[xTest, yTest] = prepare_data(test_data, fixed_segment_length);
disp([‘Size of xTrain: ‘, num2str(size(xTrain))]);
disp([‘Size of xTest: ‘, num2str(size(xTest))]);
% تحويل التسميات إلى مصفوفات دلالية (Categorical)
numClasses = numel(unique(yTrain));
yTrain = categorical(yTrain);
yTest = categorical(yTest);
% % تحويل التسميات إلى مصفوفات دلالية (Categorical)
% yTrain = cellfun(@(x) categorical(x, 1:length(train_records)), num2cell(yTrain), ‘UniformOutput’, false);
% yTest = cellfun(@(x) categorical(x, 1:length(test_records)), num2cell(yTest), ‘UniformOutput’, false);
% حصول على القيم الممكنة للتصنيفات
labels = unique(yTrain);
% تحويل `yTrain` و `yTest` إلى مصفوفة خلية من المتجهات النمطية
yTrain = cellfun(@(x) categorical(x, labels), num2cell(yTrain), ‘UniformOutput’, false);
yTest = cellfun(@(x) categorical(x, labels), num2cell(yTest), ‘UniformOutput’, false);
% تحويل الأبعاد إلى الصيغة الصحيحة إذا لزم الأمر
xTrain = permute(xTrain, [2, 3, 1]);
xTest = permute(xTest, [2, 3, 1]);
% 2. بناء نموذج 1D-CNN
layers = [
sequenceInputLayer([fixed_segment_length 1]) % طبقة الإدخال مع حجم البيانات وعدد القنوات
convolution1dLayer(3, 32, ‘Padding’, ‘same’) % طبقة الالتفاف
batchNormalizationLayer % طبقة تطبيع الدفعات
reluLayer % طبقة التنشيط ReLU
maxPooling1dLayer(2, ‘Stride’, 2) % طبقة التجميع
dropoutLayer(0.5) % طبقة الإسقاط لتقليل الإفراط في التكيف
convolution1dLayer(3, 64, ‘Padding’, ‘same’)
batchNormalizationLayer
reluLayer
maxPooling1dLayer(2, ‘Stride’, 2)
dropoutLayer(0.5)
flattenLayer % تحويل البيانات إلى مصفوفة مسطحة
fullyConnectedLayer(128) % طبقة الاتصال الكاملة
reluLayer
dropoutLayer(0.5)
fullyConnectedLayer(numClasses) % طبقة الخرج بعدد الفئات
softmaxLayer % طبقة سوفت ماكس
classificationLayer]; % طبقة التصنيف
% 3. تجميع النموذج
options = trainingOptions(‘adam’, …
‘InitialLearnRate’, 0.001, …
‘MaxEpochs’, 20, …
‘MiniBatchSize’, 32, …
‘ValidationData’, {xTest, yTest}, …
‘Plots’, ‘training-progress’, …
‘Verbose’, false);
% 4. تدريب النموذج
net = trainNetwork(xTrain, yTrain, layers, options);
% 5. تقييم النموذج
yPred = classify(net, xTest);
accuracy = sum(yPred == yTest) / numel(yTest);
disp([‘Test Accuracy: ‘, num2str(accuracy * 100), ‘%’]);
% طباعة تقرير التصنيف
confusionchart(yTest, yPred);
% الدالة: تطبيق خوارزمية Pan-Tompkins لاكتشاف قمم QRS
function qrs_peaks = panTompkinsQRS(ecg, fs)
% تطبيق خوارزمية Pan-Tompkins لاكتشاف قمم QRS في إشارات ECG
% سيتم تنفيذ عدة خطوات: الاشتقاق، التربيع، التنعيم، وإيجاد القمم
% المشتقة
diff_ecg = diff(ecg);
% التربيع
squared_ecg = diff_ecg .^ 2;
% التنعيم باستخدام نافذة متحركة
window_size = round(0.12 * fs); % 120ms نافذة
smoothed_ecg = conv(squared_ecg, ones(1, window_size) / window_size, ‘same’);
% إيجاد القمم
max_value = max(smoothed_ecg); % الحصول على القيمة العظمى للإشارة المربعة المنعمة
min_peak_height = 0.02 * max_value; % تعيين MinPeakHeight كنسبة مئوية من القيمة العظمى
[~, qrs_peaks] = findpeaks(smoothed_ecg, ‘MinPeakHeight’, min_peak_height, ‘MinPeakDistance’, round(0.6 * fs));
end
% الدالة: تجزئة إشارات نبضات القلب الفردية بناءً على مواقع قمم QRS
function segments = segmentHeartBeats(ecg, qrs_peaks, fs)
% تجزئة إشارات نبضات القلب الفردية بناءً على مواقع قمم QRS
% سنقوم بتحديد أجزاء الإشارة حول كل قمة QRS
num_beats = length(qrs_peaks);
segments = cell(num_beats, 1);
% طول كل مقطع حول QRS (مثلاً 0.6 ثانية)
segment_length = round(0.6 * fs);
for i = 1:num_beats
start_idx = max(qrs_peaks(i) – segment_length, 1);
end_idx = min(qrs_peaks(i) + segment_length, length(ecg));
segments{i} = ecg(start_idx:end_idx);
end
end% إضافة مسار مكتبة WFDB Toolbox إلى Matlab
addpath("C:wfdbwfdb-app-toolbox-0-10-0mcode"); % استبدل هذا المسار بموقع مكتبة WFDB على جهازك
% قائمة بالتسجيلات من قاعدة البيانات
records = {‘100’, ‘101’, ‘102’, ‘103’, ‘104’, ‘105’, ‘106’, ‘107’, ‘108’, ‘109’, …
‘111’, ‘112’, ‘113’, ‘114’, ‘115’, ‘116’, ‘117’, ‘118’, ‘119’, ‘121’, …
‘122’, ‘123’, ‘124’, ‘200’, ‘201’, ‘202’, ‘203’, ‘205’, ‘207’, ‘208’, …
‘209’, ‘210’, ‘212’, ‘213’, ‘214’, ‘215’, ‘217’, ‘219’, ‘220’, ‘221’, …
‘222’, ‘223’, ‘228’, ‘230’, ‘231’, ‘232’, ‘233’, ‘234’};
% تحديد نسبة البيانات للتدريب
train_ratio = 0.7;
% ترتيب السجلات عشوائيًا لضمان توزيع عشوائي
shuffled_indices = randperm(length(records));
records = records(shuffled_indices);
% حساب عدد السجلات للتدريب والاختبار
num_train = round(train_ratio * length(records));
num_test = length(records) – num_train;
% تقسيم السجلات إلى مجموعتي التدريب والاختبار
train_records = records(1:num_train);
test_records = records(num_train+1:end);
% دالة لقراءة ومعالجة بيانات ECG
function data = read_and_process_ecg(recordName)
[ECG, Fs] = rdsamp(recordName, 1); % قراءة البيانات
ECG = ECG – mean(ECG); % إزالة ضوضاء التيار المستمر
[b, a] = butter(4, [0.5 45] / (Fs / 2), ‘bandpass’); % مرشح رقمي
filtered_ECG = filtfilt(b, a, ECG); % تطبيق المرشح بتمرير صفري
normalized_ECG = 2 * (filtered_ECG – min(filtered_ECG)) / (max(filtered_ECG) – min(filtered_ECG)) – 1; % تطبيع
qrs_peaks = panTompkinsQRS(normalized_ECG, Fs); % اكتشاف قمم QRS
data.segments = segmentHeartBeats(normalized_ECG, qrs_peaks, Fs); % تجزئة نبضات القلب
data.Fs = Fs;
end
% معالجة بيانات التدريب
train_data = cell(length(train_records), 1);
for i = 1:length(train_records)
recordName = train_records{i};
fprintf(‘Processing training record %s…n’, recordName);
train_data{i} = read_and_process_ecg(recordName);
end
% معالجة بيانات الاختبار
test_data = cell(length(test_records), 1);
for i = 1:length(test_records)
recordName = test_records{i};
fprintf(‘Processing test record %s…n’, recordName);
test_data{i} = read_and_process_ecg(recordName);
end
% توحيد البيانات في مصفوفة 3D (عينات، ميزات، قنوات)
function [X, Y] = prepare_data(data, fixed_segment_length)
% حساب عدد العينات
num_samples = sum(cellfun(@(d) length(d.segments), data));
% تهيئة مصفوفة البيانات
X = zeros(num_samples, fixed_segment_length, 1); % إضافة بُعد القنوات
Y = zeros(num_samples, 1);
sample_idx = 1;
for i = 1:length(data)
for j = 1:length(data{i}.segments)
segment = data{i}.segments{j};
segment_length = length(segment);
% إذا كان المقطع أطول من الطول الثابت، نقوم بتقليمه
if segment_length > fixed_segment_length
segment = segment(1:fixed_segment_length);
% إذا كان المقطع أقصر، نقوم بتعبئته بالأصفار
elseif segment_length < fixed_segment_length
segment = [segment; zeros(fixed_segment_length – segment_length, 1)];
end
% تعيين المقطع إلى مصفوفة X
X(sample_idx, :, 1) = segment’; % تعيين مع إضافة بُعد القناة
% تعيين التسمية
Y(sample_idx) = i; % استخدام رقم السجل كتصنيف مبدئي
sample_idx = sample_idx + 1;
end
end
% تحويل X إلى الشكل المطلوب (طول السلسلة، عدد العينات، عدد القنوات)
% X = permute(X, [2, 3, 1]); % ليس هناك حاجة لإعادة الترتيب هنا
end
% تعيين الطول الثابت للمقاطع
fixed_segment_length = 625; % يمكنك ضبط هذا الطول بناءً على تحليل البيانات
% تجهيز بيانات التدريب والاختبار
[xTrain, yTrain] = prepare_data(train_data, fixed_segment_length);
[xTest, yTest] = prepare_data(test_data, fixed_segment_length);
disp([‘Size of xTrain: ‘, num2str(size(xTrain))]);
disp([‘Size of xTest: ‘, num2str(size(xTest))]);
% تحويل التسميات إلى مصفوفات دلالية (Categorical)
numClasses = numel(unique(yTrain));
yTrain = categorical(yTrain);
yTest = categorical(yTest);
% % تحويل التسميات إلى مصفوفات دلالية (Categorical)
% yTrain = cellfun(@(x) categorical(x, 1:length(train_records)), num2cell(yTrain), ‘UniformOutput’, false);
% yTest = cellfun(@(x) categorical(x, 1:length(test_records)), num2cell(yTest), ‘UniformOutput’, false);
% حصول على القيم الممكنة للتصنيفات
labels = unique(yTrain);
% تحويل `yTrain` و `yTest` إلى مصفوفة خلية من المتجهات النمطية
yTrain = cellfun(@(x) categorical(x, labels), num2cell(yTrain), ‘UniformOutput’, false);
yTest = cellfun(@(x) categorical(x, labels), num2cell(yTest), ‘UniformOutput’, false);
% تحويل الأبعاد إلى الصيغة الصحيحة إذا لزم الأمر
xTrain = permute(xTrain, [2, 3, 1]);
xTest = permute(xTest, [2, 3, 1]);
% 2. بناء نموذج 1D-CNN
layers = [
sequenceInputLayer([fixed_segment_length 1]) % طبقة الإدخال مع حجم البيانات وعدد القنوات
convolution1dLayer(3, 32, ‘Padding’, ‘same’) % طبقة الالتفاف
batchNormalizationLayer % طبقة تطبيع الدفعات
reluLayer % طبقة التنشيط ReLU
maxPooling1dLayer(2, ‘Stride’, 2) % طبقة التجميع
dropoutLayer(0.5) % طبقة الإسقاط لتقليل الإفراط في التكيف
convolution1dLayer(3, 64, ‘Padding’, ‘same’)
batchNormalizationLayer
reluLayer
maxPooling1dLayer(2, ‘Stride’, 2)
dropoutLayer(0.5)
flattenLayer % تحويل البيانات إلى مصفوفة مسطحة
fullyConnectedLayer(128) % طبقة الاتصال الكاملة
reluLayer
dropoutLayer(0.5)
fullyConnectedLayer(numClasses) % طبقة الخرج بعدد الفئات
softmaxLayer % طبقة سوفت ماكس
classificationLayer]; % طبقة التصنيف
% 3. تجميع النموذج
options = trainingOptions(‘adam’, …
‘InitialLearnRate’, 0.001, …
‘MaxEpochs’, 20, …
‘MiniBatchSize’, 32, …
‘ValidationData’, {xTest, yTest}, …
‘Plots’, ‘training-progress’, …
‘Verbose’, false);
% 4. تدريب النموذج
net = trainNetwork(xTrain, yTrain, layers, options);
% 5. تقييم النموذج
yPred = classify(net, xTest);
accuracy = sum(yPred == yTest) / numel(yTest);
disp([‘Test Accuracy: ‘, num2str(accuracy * 100), ‘%’]);
% طباعة تقرير التصنيف
confusionchart(yTest, yPred);
% الدالة: تطبيق خوارزمية Pan-Tompkins لاكتشاف قمم QRS
function qrs_peaks = panTompkinsQRS(ecg, fs)
% تطبيق خوارزمية Pan-Tompkins لاكتشاف قمم QRS في إشارات ECG
% سيتم تنفيذ عدة خطوات: الاشتقاق، التربيع، التنعيم، وإيجاد القمم
% المشتقة
diff_ecg = diff(ecg);
% التربيع
squared_ecg = diff_ecg .^ 2;
% التنعيم باستخدام نافذة متحركة
window_size = round(0.12 * fs); % 120ms نافذة
smoothed_ecg = conv(squared_ecg, ones(1, window_size) / window_size, ‘same’);
% إيجاد القمم
max_value = max(smoothed_ecg); % الحصول على القيمة العظمى للإشارة المربعة المنعمة
min_peak_height = 0.02 * max_value; % تعيين MinPeakHeight كنسبة مئوية من القيمة العظمى
[~, qrs_peaks] = findpeaks(smoothed_ecg, ‘MinPeakHeight’, min_peak_height, ‘MinPeakDistance’, round(0.6 * fs));
end
% الدالة: تجزئة إشارات نبضات القلب الفردية بناءً على مواقع قمم QRS
function segments = segmentHeartBeats(ecg, qrs_peaks, fs)
% تجزئة إشارات نبضات القلب الفردية بناءً على مواقع قمم QRS
% سنقوم بتحديد أجزاء الإشارة حول كل قمة QRS
num_beats = length(qrs_peaks);
segments = cell(num_beats, 1);
% طول كل مقطع حول QRS (مثلاً 0.6 ثانية)
segment_length = round(0.6 * fs);
for i = 1:num_beats
start_idx = max(qrs_peaks(i) – segment_length, 1);
end_idx = min(qrs_peaks(i) + segment_length, length(ecg));
segments{i} = ecg(start_idx:end_idx);
end
end % إضافة مسار مكتبة WFDB Toolbox إلى Matlab
addpath("C:wfdbwfdb-app-toolbox-0-10-0mcode"); % استبدل هذا المسار بموقع مكتبة WFDB على جهازك
% قائمة بالتسجيلات من قاعدة البيانات
records = {‘100’, ‘101’, ‘102’, ‘103’, ‘104’, ‘105’, ‘106’, ‘107’, ‘108’, ‘109’, …
‘111’, ‘112’, ‘113’, ‘114’, ‘115’, ‘116’, ‘117’, ‘118’, ‘119’, ‘121’, …
‘122’, ‘123’, ‘124’, ‘200’, ‘201’, ‘202’, ‘203’, ‘205’, ‘207’, ‘208’, …
‘209’, ‘210’, ‘212’, ‘213’, ‘214’, ‘215’, ‘217’, ‘219’, ‘220’, ‘221’, …
‘222’, ‘223’, ‘228’, ‘230’, ‘231’, ‘232’, ‘233’, ‘234’};
% تحديد نسبة البيانات للتدريب
train_ratio = 0.7;
% ترتيب السجلات عشوائيًا لضمان توزيع عشوائي
shuffled_indices = randperm(length(records));
records = records(shuffled_indices);
% حساب عدد السجلات للتدريب والاختبار
num_train = round(train_ratio * length(records));
num_test = length(records) – num_train;
% تقسيم السجلات إلى مجموعتي التدريب والاختبار
train_records = records(1:num_train);
test_records = records(num_train+1:end);
% دالة لقراءة ومعالجة بيانات ECG
function data = read_and_process_ecg(recordName)
[ECG, Fs] = rdsamp(recordName, 1); % قراءة البيانات
ECG = ECG – mean(ECG); % إزالة ضوضاء التيار المستمر
[b, a] = butter(4, [0.5 45] / (Fs / 2), ‘bandpass’); % مرشح رقمي
filtered_ECG = filtfilt(b, a, ECG); % تطبيق المرشح بتمرير صفري
normalized_ECG = 2 * (filtered_ECG – min(filtered_ECG)) / (max(filtered_ECG) – min(filtered_ECG)) – 1; % تطبيع
qrs_peaks = panTompkinsQRS(normalized_ECG, Fs); % اكتشاف قمم QRS
data.segments = segmentHeartBeats(normalized_ECG, qrs_peaks, Fs); % تجزئة نبضات القلب
data.Fs = Fs;
end
% معالجة بيانات التدريب
train_data = cell(length(train_records), 1);
for i = 1:length(train_records)
recordName = train_records{i};
fprintf(‘Processing training record %s…n’, recordName);
train_data{i} = read_and_process_ecg(recordName);
end
% معالجة بيانات الاختبار
test_data = cell(length(test_records), 1);
for i = 1:length(test_records)
recordName = test_records{i};
fprintf(‘Processing test record %s…n’, recordName);
test_data{i} = read_and_process_ecg(recordName);
end
% توحيد البيانات في مصفوفة 3D (عينات، ميزات، قنوات)
function [X, Y] = prepare_data(data, fixed_segment_length)
% حساب عدد العينات
num_samples = sum(cellfun(@(d) length(d.segments), data));
% تهيئة مصفوفة البيانات
X = zeros(num_samples, fixed_segment_length, 1); % إضافة بُعد القنوات
Y = zeros(num_samples, 1);
sample_idx = 1;
for i = 1:length(data)
for j = 1:length(data{i}.segments)
segment = data{i}.segments{j};
segment_length = length(segment);
% إذا كان المقطع أطول من الطول الثابت، نقوم بتقليمه
if segment_length > fixed_segment_length
segment = segment(1:fixed_segment_length);
% إذا كان المقطع أقصر، نقوم بتعبئته بالأصفار
elseif segment_length < fixed_segment_length
segment = [segment; zeros(fixed_segment_length – segment_length, 1)];
end
% تعيين المقطع إلى مصفوفة X
X(sample_idx, :, 1) = segment’; % تعيين مع إضافة بُعد القناة
% تعيين التسمية
Y(sample_idx) = i; % استخدام رقم السجل كتصنيف مبدئي
sample_idx = sample_idx + 1;
end
end
% تحويل X إلى الشكل المطلوب (طول السلسلة، عدد العينات، عدد القنوات)
% X = permute(X, [2, 3, 1]); % ليس هناك حاجة لإعادة الترتيب هنا
end
% تعيين الطول الثابت للمقاطع
fixed_segment_length = 625; % يمكنك ضبط هذا الطول بناءً على تحليل البيانات
% تجهيز بيانات التدريب والاختبار
[xTrain, yTrain] = prepare_data(train_data, fixed_segment_length);
[xTest, yTest] = prepare_data(test_data, fixed_segment_length);
disp([‘Size of xTrain: ‘, num2str(size(xTrain))]);
disp([‘Size of xTest: ‘, num2str(size(xTest))]);
% تحويل التسميات إلى مصفوفات دلالية (Categorical)
numClasses = numel(unique(yTrain));
yTrain = categorical(yTrain);
yTest = categorical(yTest);
% % تحويل التسميات إلى مصفوفات دلالية (Categorical)
% yTrain = cellfun(@(x) categorical(x, 1:length(train_records)), num2cell(yTrain), ‘UniformOutput’, false);
% yTest = cellfun(@(x) categorical(x, 1:length(test_records)), num2cell(yTest), ‘UniformOutput’, false);
% حصول على القيم الممكنة للتصنيفات
labels = unique(yTrain);
% تحويل `yTrain` و `yTest` إلى مصفوفة خلية من المتجهات النمطية
yTrain = cellfun(@(x) categorical(x, labels), num2cell(yTrain), ‘UniformOutput’, false);
yTest = cellfun(@(x) categorical(x, labels), num2cell(yTest), ‘UniformOutput’, false);
% تحويل الأبعاد إلى الصيغة الصحيحة إذا لزم الأمر
xTrain = permute(xTrain, [2, 3, 1]);
xTest = permute(xTest, [2, 3, 1]);
% 2. بناء نموذج 1D-CNN
layers = [
sequenceInputLayer([fixed_segment_length 1]) % طبقة الإدخال مع حجم البيانات وعدد القنوات
convolution1dLayer(3, 32, ‘Padding’, ‘same’) % طبقة الالتفاف
batchNormalizationLayer % طبقة تطبيع الدفعات
reluLayer % طبقة التنشيط ReLU
maxPooling1dLayer(2, ‘Stride’, 2) % طبقة التجميع
dropoutLayer(0.5) % طبقة الإسقاط لتقليل الإفراط في التكيف
convolution1dLayer(3, 64, ‘Padding’, ‘same’)
batchNormalizationLayer
reluLayer
maxPooling1dLayer(2, ‘Stride’, 2)
dropoutLayer(0.5)
flattenLayer % تحويل البيانات إلى مصفوفة مسطحة
fullyConnectedLayer(128) % طبقة الاتصال الكاملة
reluLayer
dropoutLayer(0.5)
fullyConnectedLayer(numClasses) % طبقة الخرج بعدد الفئات
softmaxLayer % طبقة سوفت ماكس
classificationLayer]; % طبقة التصنيف
% 3. تجميع النموذج
options = trainingOptions(‘adam’, …
‘InitialLearnRate’, 0.001, …
‘MaxEpochs’, 20, …
‘MiniBatchSize’, 32, …
‘ValidationData’, {xTest, yTest}, …
‘Plots’, ‘training-progress’, …
‘Verbose’, false);
% 4. تدريب النموذج
net = trainNetwork(xTrain, yTrain, layers, options);
% 5. تقييم النموذج
yPred = classify(net, xTest);
accuracy = sum(yPred == yTest) / numel(yTest);
disp([‘Test Accuracy: ‘, num2str(accuracy * 100), ‘%’]);
% طباعة تقرير التصنيف
confusionchart(yTest, yPred);
% الدالة: تطبيق خوارزمية Pan-Tompkins لاكتشاف قمم QRS
function qrs_peaks = panTompkinsQRS(ecg, fs)
% تطبيق خوارزمية Pan-Tompkins لاكتشاف قمم QRS في إشارات ECG
% سيتم تنفيذ عدة خطوات: الاشتقاق، التربيع، التنعيم، وإيجاد القمم
% المشتقة
diff_ecg = diff(ecg);
% التربيع
squared_ecg = diff_ecg .^ 2;
% التنعيم باستخدام نافذة متحركة
window_size = round(0.12 * fs); % 120ms نافذة
smoothed_ecg = conv(squared_ecg, ones(1, window_size) / window_size, ‘same’);
% إيجاد القمم
max_value = max(smoothed_ecg); % الحصول على القيمة العظمى للإشارة المربعة المنعمة
min_peak_height = 0.02 * max_value; % تعيين MinPeakHeight كنسبة مئوية من القيمة العظمى
[~, qrs_peaks] = findpeaks(smoothed_ecg, ‘MinPeakHeight’, min_peak_height, ‘MinPeakDistance’, round(0.6 * fs));
end
% الدالة: تجزئة إشارات نبضات القلب الفردية بناءً على مواقع قمم QRS
function segments = segmentHeartBeats(ecg, qrs_peaks, fs)
% تجزئة إشارات نبضات القلب الفردية بناءً على مواقع قمم QRS
% سنقوم بتحديد أجزاء الإشارة حول كل قمة QRS
num_beats = length(qrs_peaks);
segments = cell(num_beats, 1);
% طول كل مقطع حول QRS (مثلاً 0.6 ثانية)
segment_length = round(0.6 * fs);
for i = 1:num_beats
start_idx = max(qrs_peaks(i) – segment_length, 1);
end_idx = min(qrs_peaks(i) + segment_length, length(ecg));
segments{i} = ecg(start_idx:end_idx);
end
end ecg, 1d-cnn, proprocessing MATLAB Answers — New Questions