Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Готовые отчеты (2021) / Лабораторная работа 5

.pdf
Скачиваний:
98
Добавлен:
05.06.2021
Размер:
654.45 Кб
Скачать

Федеральное агентство связи ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ

ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М. А. БОНЧ-БРУЕВИЧА» (СПбГУТ)

Факультет инфокоммуникационных сетей и систем Кафедра программной инженерии и вычислительной техники

ЛАБОРАТОРНАЯ РАБОТА №5 по дисциплине «Системы искусственного интеллекта»

Выполнил: студент 3-го курса дневного отделения группы ИКПИ-85

Коваленко Леонид Александрович Преподаватель:

доцент кафедры ПИиВТ Белая Татьяна Иоанновна

Санкт-Петербург

2021

Цель работы Изучение способа прогнозирования временного ряда с помощью

нейронной сети.

Задание Индивидуальное задание согласно варианту представлено в табл. 1.

Таблица 1 — Индивидуальное задание

№ вв.

Вид функции

Промежуток нахождения решения

 

 

 

14

cos(t−0.5)×|t|

t ( 0 , 10 ] ; t (0 , 20 ] ; t (0 , 30 ]

 

 

 

Теоретические сведения

Ряд наблюдений x(t1), x(t2), ..., x (tN ) анализируемой величины x(t) , произведенных в последовательные моменты времени t1 , t2 ,... , t N , называется временным рядом. В общем виде моменты наблюдений могут быть произвольными, но классически считается, что во временных рядах равноотстоящие моменты наблюдений.

При решении задачи прогнозирования требуется найти значение Y (или несколько значений) в будущий момент времени на основе известных предыдущих значений.

Для прогнозирования временного ряда может быть использован многослойный персептрон. Причем в таком случае нет необходимости в числе скрытых слоев больше одного. Достаточно 3-х слоев: входной (число нейронов зависит от размера входных данных), скрытый (от 10 до 100 нейронов) и выходной (1 нейрон).

Практическая часть Для построения программы, решающей задачу прогнозирования, будем

считать, что временной ряд изменяется по определенному закону, представленному таблицей вариантов, на который влияют случайные помехи. В таком случае алгоритм будет состоять из следующих этапов:

2

1.Построить временной ряд, который представляет собой функцию. (Вид функции определяется по варианту задания.)

2.К полученному временному ряду добавить шум в размере максимум 20% от амплитуды сигнала.

3.Разделить временной ряд на 2 части — для обучения сети и для прогнозирования. Число точек первой части должно относиться к числу точек второй как 3:1.

4.Построить выборку для обучения (первую часть временного ряда). Для этого на основе временного ряда строится 5 рядов с задержкой от 1 до 5 (глубина выборки: 5 лагов). Для построения ряда с задержкой 5 берутся от 1 до M-5 элементы выборки, с задержкой 4 берутся от 2 до M-4 элементы выборки, с задержкой 3 берутся от 3 до M-3 элементы выборки, с задержкой 2 берутся от 4 до M-2 элементы выборки, с задержкой 1 берутся от 5 до M-1 элементы выборки, где M — число точек обучающей выборки.

5.Построить нейронную сеть для прогнозирования. Число слоев (кроме входного) — 2. Активационная функция скрытого слоя — гиперболический тангенс, выходного — линейная. Число нейронов скрытого слоя взять достаточным для удовлетворительного прогнозирования (10-100), число нейронов выходного слоя — 1.

6.Произвести обучение сети на обучающем множестве.

7.Произвести прогнозирование второй части временного ряда на обученной сети.

8.Рассчитать среднеквадратическую ошибку прогнозирования (MSE). Код программы, моделирующей, обучающей и тестирующей работу

нейронной сети, на языке MATLAB с использованием функций Neural Network Toolbox представлен в табл. 2.

Таблица 2 — Код на MATLAB (Neural Network Toolbox)

program1.m

%Для MATLAB R2018b (9.5.0.944444) Pro

%Программа, написанная с использованием функций Neural Network Toolbox clear all; close all; clc;

%=== Исходные данные ===

%Число точек

n = 100;

% Число лагов

3

b =

5;

 

% Генерация вектора

X

X = linspace(0.001,

10, n);

%

Генерация вектора

Y на основе вектора X

Y

= cos(X - 0.5) .*

abs(X) + rand(size(X)) * 0.2; % "Шуманизация"

%Обучающая выборка k = fix(n * 3 / 4); Xt = X(1, 1:k);

Yt = Y(1, 1:k);

%Проверочная выборка Xv = X(1, k+1:n);

Yv = Y(1, k+1:n); vs = size(Xv, 2);

%Глубина прогноза

m = k - b;

%Горизонт прогноза (по умолчанию 1) g = 1;

%Минимальные и максимальные значения координат min_x = min(X);

max_x = max(X); min_y = min(Y); max_y = max(Y);

%=== Прогнозирование временного ряда ===

%Построение обучающих "подвыборок" km = k - m;

if (m <= g)

error('Горизонт прогноза слишком большой.'); elseif (g ~= 1 && isprime(km))

error('Измените значение глубины прогноза (либо горизонта прогноза в 1).'); elseif (mod(km, g) ~= 0)

error('Горизонт прогноза указан неверно.\n(%d mod g) должно быть равно 0.', km);

end

q = fix(km / g + 1);

Yq = zeros(m, q); for i=1:q

Yq(:, i) = Yt(1, 1+g*(i-1):m+g*(i-1));

end

%Настройка минимальных и максимальных значений

mmx = zeros(size(Yq, 1), 2); mmx(:, 1) = min_y - min_y; mmx(:, 2) = max_y + max_y;

%Создание нейронной сети обратного распространения с прямой связью

%2 скрытых слоя

%Передаточные функции: гиперболический тангенс и линейная функция net = newff(mmx, [100 1], {'tansig' 'purelin'}, 'trainlm');

%Скорость обучения

net.trainParam.lr = 0.01;

%Максимальное число эпох net.trainParam.epochs = 100;

%Цель (внимание: возможно переобучение) net.trainParam.goal = 0.01;

%Обучение сети

fprintf('> Обучение сети началось\n');

[net, ~, ~, E] = train(net, Yq(:, 1:q-1), Yq(end, 2:q)); train_mse = max(E);

fprintf('> Обучение сети закончилось\n');

% Моделирование работы сети

fprintf('> Моделирование работы сети началось\n');

Yp = Yq(:, q);

Yr = zeros(1, vs); forecast_mse = 0; for i=1:vs

Yr(1, i) = sim(net, Yp);

Yp = vertcat(Yp(2:size(Yp, 1), 1), Yr(1, i)); forecast_mse = forecast_mse + (Yr(1, i)-Yv(1, i)) ^ 2;

end

forecast_mse = forecast_mse / vs;

fprintf('> Моделирование работы сети закончилось\n');

% Построение графика

plot(Xt, Yt, 'b*'); % Построение обучающей выборки hold on;

plot(Xv, Yv, 'gs'); % Построение проверочной выборки

4

plot(Xv, Yr, 'rx'); % Построение прогноза

tx = (max_x - min_x) / 20; ty = (max_y - min_y) / 20;

text(min_x + tx, min_y + ty, sprintf("Train MSE: %s", train_mse)); text(min_x + tx, min_y + ty * 2, sprintf("Forecast MSE: %s", forecast_mse)); xlim([min_x max_x]); % Установка границы по X

ylim([min_y max_y]); % Установка границы по Y xlabel('X'); % Метка оси X

ylabel('Y'); % Метка оси Y grid on; % Сетка

Ключевыми параметрами являются:

1.Число точек n ;

2.Число лагов b ;

3.Скорость обучения lr ;

4.Цель обучения goal .

Именно они определяют, какой результат будет на выходе.

Для первого промежутка нахождения решения (0 ,10 ] получим следующие возможные результаты1 (рис. 1, 2, 3, 4, 5).

Рисунок 1 — 100 точек, 5 лагов, (0 ,10 ] , цель 0.01 (1)

Рисунок 2 — 100 точек, 5 лагов, (0 ,10 ] , цель 0.01 (2)

1Приведены 5 графиков после нескольких запусков одного и того же сценария. Синие точки — обучающая выборка, зеленые точки — ожидаемый результат, красные точки — полученный результат.

5

Рисунок 3 — 100 точек, 5 лагов, (0 ,10 ]

Рисунок 4 — 100 точек, 5 лагов, (0 ,10 ]

, цель 0.01 (3)

, цель 0.01 (4)

Рисунок 5 — 100 точек, 5 лагов, (0 ,10 ] , цель 0.01 (5)

Графики сильно отличаются, хотя параметры и код никак не изменялись. Тому есть несколько причин:

1. На интервале (0 ,10 ] приведенная в задании функция не может быть аппроксимирована достаточно точно. (Поведение функции не может быть достаточно точно определено на малой совокупности данных.)

6

2. Число точек n и число лагов b слишком малы для обучения сети. Для второго промежутка нахождения решения (0 ,20 ] получим

следующие возможные результаты (рис. 6, 7, 8).

Рисунок 6 — 100 точек, 5 лагов, (0 ,20 ] , цель 0.01 (1)

Рисунок 7 — 100 точек, 5 лагов, (0 ,20 ] , цель 0.01 (2)

Рисунок 8 — 100 точек, 5 лагов, (0 ,20 ] , цель 0.01 (3)

В данных случаях функция аппроксимируется точнее, т. к. диапазон увеличился в 2 раза — поведение функции прогнозировать легче. Однако

7

число точек и число лагов остались прежними, а значит могут быть редкие исключения (рис. 9).

Рисунок 9 — 100 точек, 5 лагов, (0 ,20 ] , цель 0.01 (4)

Для третьего промежутка нахождения решения (0 ,30 ] получим следующие возможные результаты (рис. 10, 11, 12).

Рисунок 10 — 100 точек, 5 лагов, (0 ,30 ] , цель 0.01 (1)

Рисунок 11 — 100 точек, 5 лагов, (0 ,30 ] , цель 0.01 (2)

8

Рисунок 12 — 100 точек, 5 лагов, (0 ,30 ] , цель 0.01 (3) Аппроксимация стала немного точнее.

Теперь поменяем число лагов b=50 и цель goal=0.000001 .

Для первого промежутка нахождения решения (0 ,10 ] получим следующие возможные результаты (рис. 13, 14).

Рисунок 13 — 100 точек, 50 лагов, (0 ,10 ] , цель 1e-6 (1)

Рисунок 14 — 100 точек, 50 лагов, (0 ,10 ] , цель 1e-6 (2)

9

(0 ,30 ]

Для второго промежутка нахождения решения (0 ,20 ] получим следующий возможный результат (рис. 15).

Рисунок 15 — 100 точек, 50 лагов, (0 ,20 ] , цель 1e-6

Для третьего промежутка нахождения решения (0 ,30 ] получим следующий возможный результат (рис. 16).

Рисунок 16 — 100 точек, 50 лагов, , цель 1e-6

Результат аппроксимации стал точнее, хоть и имеются редкие исключения (рис. 14).

Код программы, моделирующей, обучающей и тестирующей работу нейронной сети, на языке Python с использованием библиотеки Neurolab представлен в табл. 3.

Таблица 3 — Код на Python (Neurolab)

program2.py

"""

Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)] on win32

-neurolab version is 0.3.5

-matplotlib version is 3.3.4

-numpy version is 1.19.5

10