Готовые отчеты (2021) / Лабораторная работа 5
.pdfФедеральное агентство связи ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ
ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М. А. БОНЧ-БРУЕВИЧА» (СПбГУТ)
Факультет инфокоммуникационных сетей и систем Кафедра программной инженерии и вычислительной техники
ЛАБОРАТОРНАЯ РАБОТА №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 ,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