Нейронная сеть в Экселе (MS Excel) на VBA (исходный код)
Данная нейронная
сеть предназначена для прогнозирования. Опробовалась для котировок ROSNEFT и
LUCKOIL ММВБ (Для Форекса не пробывал). За код просьба не ругать –
главная задача показать студентам «на пальцах» как и куда
идут сигналы при подсчете и обучении нейросети, а инструмент лучше Экселя для
работы с таблицами трудно найти. Собственно можно транслировать в Excel котировки
из Quik и обсчитывать данные нейросетью, только надо дописать
некоторые моменты.
На вход сети подаются сигналы Open[i] – Open[i-1], Low[i] – Low[i-1], High[i] – High[i-1], Close[i-1]
– Close[i], на выходе снимается сигнал Close[i+1]
– Close[i]. Обращаю внимание, что в приложенном примере у
котировок сверху вниз по листу дата убывает (соответственно i инвертировано).
Также хочу отметить, что «классически» необходимо подавать скользящее окно за
несколько периодов, для этого необходимо
либо доделать функцию SetIO(),
либо добавлять столбцы необходимых разностей в листе с выборкой.
Основные функции:
NNet() - итоговая процедура (типа
main()), которая
собирает сеть, инициализирует ее, запускает обучение. Можно набросать в нее
свой набор функций.
Test() – для подачи тестового сигнала. Основная проблема при написании –
чтобы матрицы на матрицы с векторами правильно перемножались:)
SetParams() – устанавливает параметры нейросети
(здесь нужно ручками прописывать скорость обучения, начало и конец
валидационной выборки и т д).
CreateNet()
- создать сеть по указанным параметрам.
InitNet() – инициализировать веса связей GMatrix случайными числами от -1 до 1.
SetIO() – установка входов и выходов при подаче конкретного примера в
сеть (если нужно менять принцип подающихся входных данных, то менять здесь).
Calc() – расчет выходов сети при подаче конкретного примера.
Backpropagation() – обучение нейросети, пока ошибка не
станет меньше заданной (метод обратного распространения ошибки). Желательно
добавить несколько строчек обучения по расписанию, то есть снижать скорость
обучения (коэффициенты Nu1
и Nu2) при подходе к
заданной ошибке, либо после выхода на заданную
отшлифовать малыми значениями Nu1
и Nu2.
CountError() – подсчет ошибки правильней делать
через проценты, но сделано через относительную ошибку. Переделать не трудно:)
PrintList() – вывести в лист «0» текущие значения
всех матриц, промежуточных векторов, входов – выходов. По сути деббугер, для
просмотра, что да как в нейросети творится.
ClearList() – очистить лист «0».
Preprocess() - предобработка данных, нейроны работают с
сигналами от -1 до 1, если не растягивать тангенсоиду. Поэтому лучше загнать
входные примеры в этот интервал.
PlotSuccessResult() – после успешного обучения, в лист
«0» выводятся показатели ошибок на валидационной выборке и чуть ниже на
примерах, которые сеть вообще не видела. Что куда выводится см
ниже на рисунке.
SaveNet() – сохранить сеть (толком не тестировалась).
LoadNet() – загрузить сохраненную сеть (толком не тестировалась).
Описание
глобальных переменных см. в начале листинга программы.
Укажу основные матрицы:
GInputs() – входы нейросети. Это столбцы с листа под переменной list. Например, GInputs(5,6,7,8) указывает
сети, что входы берутся со столбцов 5, 6, 7, 8.
GOutputs() – выходы нейросети. Аналогично GInputs .
GNeuro() – указывает сколько слоев в сети и количество нейронов в них.
Например, объявление GNeuro(4, 8, 6, 1) – указывает, что в
сети 4 слоя (т.е. по размеру массива) – вместе с входным и выходным слоями. И
при этом 4, 8, 6, 1 – указывает, что в сети 4 входа (защиту от дурака на
совпадение первого элемента GNeuro
и размером GInputs не
ставил!!), в 1-м скрытом слое 8 нейронов, во 2-м скрытом слое 6 нейронов и один
выход.
GMatrix() – собственно матрицы весов. Сделано таким громоздким способом,
потому – что так легче. А также гдето у авторитетов
прочитал, что сеть с более чем двумя скрытыми слоями не возможно обучить (если
только это не сверточные нейросети). Оказалось, что и 5 скрытых слоев нормально
обучаются.
Можно делать
свои процедуры (типа NNet()
и Test()), куда
последовательно записывать нужные функции (Примечание – Процедура в VBA запускается
по F5, а функция нет).
Сеть в основном гонялась с 2-5 скрытыми слоями, 4 входа (OLHC) и 1 выход. Подозреваю, что много
ошибок, если отходить от данных параметров, но со временем исправится.
После
обработки напильником можно использовать для других целей, например
классификации.
Рисунок объясняющий,
что и куда выводит сеть в листе «0» -
Для запуска
необходимо войти в редактор макросов, выбрать Module3, встать мышкой на тело процедуры
NNet() и нажать F5 (или Run сверху на
панели). Сеть может бесконечно долго обучаться, если не выходит на заданную
ошибкуJ Для прерывания, необходимо нажать Ctrl+Break, либо убить процесс в диспетчере
задач.
Собственно
несколько поражен результатами работы – нейросеть
конечно ошибается в абсолютных значениях, но знаки Роснефти угадывает о-о-очень
хорошо! Можно перекинуть код в Metatrader,
но там придется с шкалированием входов – выходов бороться. Если здесь я просто
делил на максимальное значение ряда, то там врядли так просто будет.
Если сеть
кому-то понравилась или принесла ощутимую пользу, не откажусь от благодарностей
на WMR
R398365873120 :)
По всем
вопросам использования нейросети пишите на apsheronka@mail.ru .
Возможна разработка нейросети на заказ.
Ниже дан
исходный код нейросети. Лучше скачивать приаттаченный архив с примером – там
последняя версия исходников.
Нейронная сеть обновлена 10.10.10 - спасибо коллеге по нелегкому делу исследования и написания нейросетей Хамиту!
Добавлены функция предобработки данных - ускорился процесс обучения, добавлен график ошибки и некоторые другие моменты
Сайт автора >>
Скачать исходный
код нейросети с примером в Excel:
ссылка
=====================================================================
' Нейронная сеть на VBA (Visual Basic for
Application). Исходный код
' PhD(eng) Shumkov Eugene. KubSTU (Krasnodar).
' march 2010
' Реализован многослойный персептрон и алгоритм обратного распространения ошибки (BackProp, Back Propogation)
' Нейронная сеть в Excel
Dim inp
As Integer
Dim NEU As
Integer
Dim OUT As Integer
Dim GInputs()
As Variant ' номера столбцов входов
Dim GOutputs()
As Variant ' номера столбцов выходов
Dim GMatrix()
As Double ' трехмерный массив весов
Dim Matrix1() As Double ' не используется
Dim Matrix2() As Double ' не используется
Dim GNeuro() As Variant ' количество нейронов
в слоях, размер массива определяет количество слоев (вместе с входным и
выходным)
Dim GError() As Double ' здесь ошибка по
выходам
Dim GDelta() As Double ' здесь дельты по слоям
Dim GOut() As Variant ' выходные значения
слоев (размерность на 1 меньше, чем число num_layers)
Dim GSum() As Variant ' здесь то что до функции активации, то есть сумма входов * на веса
Dim num_layers As Integer ' количество слоев,
вместе с входным и выходным
Dim InpVector() As Double ' входной вектор на
текущей итерации
Dim OutVector() As Double ' выходной вектор на
текущей итерации
Dim RealOut() As Double ' не используется
Dim Layer1_out()
As Double 'не используется
Dim list As String ' имя листа для данных. Обучающая и валидационная
выборка
Dim savelist As String ' имя листа в который сохранять матрицы
Dim Alpha As Double ' параметр наклона в
тангенсоиде и сигмоиде
Dim Error As Double ' заданная ошибка
Dim CurError As
Double ' текущая ошибка
Dim MaxStep As Long ' максимальное количество итераций обучения
Dim MaxSample As Long ' количество примеров
выборки на листе list
Dim Nu2 As Double ' скорость обучения для
второго слоя
Dim Nu1 As Double ' скорость обучения для
первого слоя
Dim num_error As Long ' позиция для вывода
ошибки в нулевой лист
Dim BINARY As Integer ' если 1 то входы-выходы
0-1, если 0 то входы выход float, если 2 то входы float, выходы 0-1
Dim TANGENSOID As Integer ' если 1 то
тангенсоид, 2 сигмоид, 0 порог
Dim TEST_SIGNAL As Boolean ' если тестовый сигнал,
то обнуляем весовые матрицы и на входы подаем 1
Dim LINE_SIGNAL As Boolean ' если true, то подаем линию, если false, то подаем (i - (i-1))
Dim Mx As Integer ' максимальный размер матрицы GMatrix - ножно, что
выводить PrintList
Dim start_valid_pos As Integer ' начальная
позиция валидационной выборки
Dim end_valid_pos As Integer ' конечная
позиция валидационной выборки
Dim start_test As Integer ' начало выборки,
которую сеть вообще не видела при обучении
Dim end_test As Integer ' конец выборки, которуб
сеть не видела при обучении
Dim learning_number_example As Integer ' количество примеров для обучения (идут сразу после end_valid_pos)
Dim MaxValue As
Double
'-----------------------------------------------------------------------------------------------------------------------------------
Sub NNet()
Application.ScreenUpdating = False ' отключаем автоматический пересчет
формул и обновление листов
Application.EnableEvents = False
Application.Calculation =
xlCalculationManual
TEST_SIGNAL = False ' подаем в нормальном режиме
tmp = SetParams()
tmp =
Preprocess()
tmp =
ClearList()
tmp =
CreateNet()
tmp =
InitNet()
tmp =
Backpropagation()
tmp =
PrintList()
tmp =
PlotSuccessResult()
Application.ScreenUpdating =
True ' обратно включаем пересчет формул
Application.EnableEvents = True
Application.Calculation =
xlCalculationAutomatic
End Sub
'-----------------------------------------------------------------------------------------------------------------------------------
Sub Test()
' для тестовой проверки правильности
перемножения матриц и векторов
Worksheets("0").Cells(2,
3).Value = 3
tmp =
SetParams()
TEST_SIGNAL = True
tmp =
ClearList()
tmp =
CreateNet()
tmp =
InitNet()
tmp =
Calc(10)
tmp =
CountError()
tmp =
Backpropagation()
tmp =
PrintList()
End Sub
'-----------------------------------------------------------------------------------------------------------------------------------
Function SetParams()
' Функция установки основных параметров
нейронной сети
GInputs = Array(5, 6, 7, 8) ' номера
столбцов входов
GOutputs = Array(8) ' номера столбцов
выходов
GNeuro = Array(4, 8, 8, 1)
num_layers = 3 ' на единицу меньше т к с нуля массивы
start_valid_pos = 13
end_valid_pos = 23
learning_number_example = 150 ' количество примеров для обучения
start_test = 4
end_test = 13
LINE_SIGNAL = False
inp =
4
NEU = 10
OUT = 1
list
= "2"
savelist
= "save"
Alpha = 0.5
MaxStep = 1000000
Nu1 = 0.05
Nu2 = 0.05
num_error = 10
BINARY = 0 ' вход/выход = 0/1
TANGENSOID = 1
If BINARY = 1 Or BINARY = 2 Then
Error = 3 ' заданная ошибка обучения
Else
Error = 0.03 ' ## ВОТ ЗДЕСЬ МЕНЯТЬ
ЗАДАННУЮ ОШИБКУ ОБУЧЕНИЯ!!!!
End If
Worksheets(list).Activate ' активируем лист с входными и выходными данными
ActiveCell.SpecialCells(xlLastCell).Select
MaxSample = ActiveCell.Row
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function CreateNet()
As Integer
' Создание сети (многослойный
персептрон)
ReDim Matrix1(NEU,
inp)
ReDim Matrix2(OUT,
NEU)
ReDim InpVector(inp)
ReDim OutVector(OUT)
ReDim RealOut(OUT)
ReDim Layer1_out(NEU)
'ReDim GNeurons(num_layers)
' определяем количество нейронов в слоях
num_layers = UBound(GNeuro)
Mx = 0
For i = 0 To num_layers Step 1 ' ищем максимальную размерность в
количестве нейронов
If GNeuro(i)
> Mx Then
Mx = GNeuro(i)
End If
Next i
ReDim GMatrix(num_layers
- 1, Mx, Mx) ' задаем глобальный массив весов
ReDim GOut(num_layers - 1, Mx) ' выходные значения внутренних слоев
ReDim GSum(num_layers - 1, Mx) ' входные
значения внутренних слоев
ReDim GDelta(num_layers - 1, Mx) ' значения
дельт по слоям
ReDim GError(GNeuro(num_layers))
'UBound(GNeuro,1)
CreateNet = 0
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function InitNet()
' Инициализация сети
Randomize
For i = 0 To num_layers - 1 Step 1 ' слоев
на один меньше, чем размерность GNeuro
For j = 0 To GNeuro(i + 1) - 1 Step 1
For z = 0 To GNeuro(i) - 1 Step 1
tmp
= Rnd
GMatrix(i,
j, z) = tmp * 2 - 1
Next z
Next j
Next i
' Если тестовый сигнал
If TEST_SIGNAL = True Then
For i =
0 To num_layers - 1 Step 1 ' слоев на один меньше, чем размерность GNeuro
For j = 0 To GNeuro(i + 1) - 1 Step 1
For z = 0 To GNeuro(i) - 1 Step 1
GMatrix(i, j, z) = 1
Next z
Next j
Next i
End If
InitNet = 0
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function SetIO(num As Integer)
' для ускорения работы сети
можно предварительно массив валидационной выборки готовить
tmp = 0
If BINARY = 1 Then ' входы выходы 0 и 1
sz
= UBound(GInputs)
For i = 0 To sz Step 1
If LINE_SIGNAL = False
Then
tmp
= Cells(num, GInputs(i)).Value - Cells(num - 1, GInputs(i)).Value
Else
tmp
= Cells(num, GInputs(i)).Value
End If
If tmp > 0 Then
InpVector(i)
= 1
Else
InpVector(i)
= 0
End If
Next i
sz
= UBound(GOutputs)
' выходы
For i = 0 To sz Step 1
If LINE_SIGNAL = False
Then
tmp
= Cells(num - 1, GOutputs(i)).Value - Cells(num - 2, GOutputs(i)).Value
Else
tmp
= Cells(num - 1, GOutputs(i)).Value
End If
If tmp > 0 Then
OutVector(i)
= 1
Else
OutVector(i)
= 0
End If
Next i
ElseIf BINARY = 0 Then ' вход\выход = float
sz
= UBound(GInputs)
For i = 0 To sz Step 1
If LINE_SIGNAL = False Then
InpVector(i)
= (Cells(num, GInputs(i)).Value - Cells(num - 1, GInputs(i)).Value) / MaxValue
Else
InpVector(i)
= Cells(num, GInputs(i)).Value / MaxValue
End If
Next i
sz =
UBound(GOutputs)
' выходы
For i = 0 To sz Step 1
If LINE_SIGNAL = False
Then
OutVector(i)
= (Cells(num - 1, GOutputs(i)).Value - Cells(num - 2, GOutputs(i)).Value) /
MaxValue
Else
OutVector(i)
= Cells(num - 1, GOutputs(i)).Value / MaxValue
End If
Next i
ElseIf BINARY = 2 Then ' вход = float, выход = 0/1
sz
= UBound(GInputs)
For i = 0 To sz Step 1
If LINE_SIGNAL = False
Then
InpVector(i)
= (Cells(num, GInputs(i)).Value - Cells(num - 1, GInputs(i)).Value) / MaxValue
Else
InpVector(i)
= Cells(num, GInputs(i)).Value / MaxValue
End If
Next i
' выходы
sz
= UBound(GOutputs)
For i = 0 To sz Step 1
If LINE_SIGNAL = False
Then
tmp
= Cells(num - 1, GOutputs(i)).Value - Cells(num - 2, GOutputs(i)).Value
Else
tmp
= Cells(num - 1, GOutputs(i)).Value
End If
If tmp > 0 Then
OutVector(i)
= 1
Else
OutVector(i)
= 0
End If
Next i
End If
' TEST
SIGNAL
If TEST_SIGNAL = True Then
InpVector(0)
= 1
InpVector(1)
= 1
InpVector(2)
= 1
InpVector(3)
= 1
OutVector(0)
= 0
End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function Calc(num As Integer) As Double
' вычисляем выход сети по
примеру num
SetIO (num)
Dim temp
As Double
' Считаем по GMatrix
For i = 0 To num_layers - 1 Step 1 ' слоев
на один меньше, чем размерность GNeuro
For j = 0 To GNeuro(i + 1) - 1 Step 1
temp
= 0
For z = 0 To GNeuro(i) - 1 Step 1
If i = 0 Then
temp = temp + GMatrix(i, j, z) * InpVector(z)
Else
temp = temp + GMatrix(i, j, z) * GOut(i - 1, j)
End If
Next z
GSum(i, j) = temp
' то что входит в нейрон
If TANGENSOID = 0 Then
' порог
GOut(i,
j) = Porog(temp)
ElseIf TANGENSOID = 1
Then 'тангенсоида
GOut(i,
j) = Tang(temp)
Else ' сигмоида
GOut(i, j)
= Sigm(temp)
End If
Next j
Next i
Calc = 0
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function Backpropagation()
' Алгоритм обратного распространения ошибки (BackProp, Back Propogation Algorithm)
If BINARY > 0 Or TANGENSOID = 0 Then
Exit Function
End If
num_error = Mx + 10 ' номер строки в 0м листе куда выводить ошибку
ttt = 0 ' смещение столбцов с ошибкой по
вертикали, если количество примеров больше длины листа
Randomize
For i = 0 To
MaxStep Step 1
num
= Rnd * learning_number_example + end_valid_pos
If CountError() < Error Then ' если ошибка меньше
заданной, то прерываем обучение
lkl =
PlotSuccessResult()
Exit For
End If
Calc (num)
tmp
= GDeltaToNull() ' обнуляем матрицы дельт
' писать все НЕ ПОД ОДИН ВЫХОД, под
GNeuro(num_layers)!!!!
' считаем дельту для выходного слоя
For j = 0 To GNeuro(num_layers) - 1 Step 1
GError(j)
= GOut(num_layers - 1, j) - OutVector(0)
GDelta(num_layers
- 1, j) = GError(j) * Derivative(GSum(num_layers - 1, j)) ' отсчет в GDelta от последнего к первому по первому измерению
Next j
' изменяем веса последнего слоя
For j = 0 To GNeuro(num_layers) - 1 Step 1
For z = 0 To GNeuro(num_layers - 1) - 1 Step 1
GMatrix(num_layers
- 1, j, z) = GMatrix(num_layers - 1, j, z) - Nu1 * GDelta(num_layers - 1, j) *
GOut(num_layers - 2, z)
If Abs(GMatrix(num_layers - 1, j, z)) > 2 Then
tmp = Rnd
GMatrix(num_layers - 1, j, z) = tmp * 2 - 1
End If
Next z
Next j
' считаем дельту слоев кроме последнего и изменяем
веса соотвествующих матриц
For j = num_layers - 2 To 0
Step -1 ' цикл по слоям
For z = 0 To GNeuro(j + 1) - 1 Step 1 ' цикл по
количеству нейронов в непосчитанных слоях
For k = 0 To GNeuro(j + 2) - 1
Step 1 ' цикл по последующему слою
GDelta(j, z) = GDelta(j, z)
+ GDelta(j + 1, k) * Derivative(GSum(j, z)) ' посчитали дельты j-го слоя
Next k
Next z
' изменяем веса
For z = 0 To GNeuro(j) - 1 Step 1
For k = 0 To GNeuro(j + 1) - 1 Step 1
If j > 0
Then
GMatrix(j, k, z) = GMatrix(j, k, z) - Nu1 * GDelta(j, k) *
GOut(j - 1, z)
Else
GMatrix(j, k, z) = GMatrix(j, k, z) - Nu1 * GDelta(j, k) *
InpVector(z)
End If
If Abs(GMatrix(j, k, z)) > 2 Then
tmp = Rnd
GMatrix(j, k, z) = tmp * 2 - 1
End If
Next k
Next z
Next j
num_error = num_error + 1 ' номер строки куда ошибку выводить
If num_error > 63000 Then
num_error = Mx + 10
ttt
= ttt + 5
End If
Worksheets("0").Cells(num_error,
ttt + 1).Value = i
Worksheets("0").Cells(num_error,
ttt + 2).Value = num
Worksheets("0").Cells(num_error,
ttt + 3).Value = CurError
'str1 = "" ' выводим то
что подавалось в сеть
'For w = 0 To UBound(InpVector) - 1 Step 1
' str1 = str1 + CStr(Round(InpVector(w),
4)) + " "
'Next w
'Worksheets("0").Cells(num_error,
ttt + 5).Value = str1
tmp = PrintList()
Next i
Backpropagation = 0
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function CountError()
' расчет ошибки на выходах нейросети
If BINARY = 1 Or BINARY = 2 Then ' выходы бинарные
CurError = 10 ' если выходы бинарные, то наоборот
отнимаем, т к считаем количество правильно угаданных
примеров
Else
CurError = 0 ' если выходы float то как обычно плючуем ошибку
End If
If end_valid_pos > 0 Then
end_point = end_valid_pos ' конечная точка если
валидационной выборки нет, то есть проверяется на всем наборе примеров
Else
end_point =
learning_number_example
End If
For k = 0 To GNeuro(num_layers) - 1 Step 1 ' по всем выходам
For i = start_valid_pos To end_point Step 1 ' цикл по примерам валидационной выборки
Calc (i)
If BINARY = 1 Or BINARY = 2 Then ' выходы бинарные
If GOut(num_layers - 1, k) > 0 And OutVector(0) > 0 Then
CurError =
CurError - 1
ElseIf GOut(num_layers - 1, k) = 0 And OutVector(0) = 0 Then
CurError =
CurError - 1
End If
Else
CurError = CurError + Abs(GOut(num_layers
- 1, k) - OutVector(0))
End If
Next i
Next k
CurError = CurError /
(end_point - start_valid_pos)
CountError = CurError
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function Tang(sea As Double) As Double
Tang = (Exp(Alpha
* sea) - Exp((-1) * Alpha * sea)) / (Exp(Alpha * sea) + Exp((-1) * Alpha *
sea))
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function Sigm(sea As Double) As Double
Sigm = 1 / (1 - Exp((-1) * Alpha * sea))
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function Porog(sea As Double) As Double
If sea > 0 Then
Porog = 1
Else
Porog = 0
End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function Derivative(inp As Variant) As Double
If TANGENSOID = 1 Then ' гиперболический тангенс
Derivative = (1 - inp * inp)
ElseIf TANGENSOID = 2 Then ' сигмоида
Derivative = inp / (1 - inp)
End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function PrintList()
Worksheets("0").Activate
' выводим матрицы
sm = 0 ' смещение между выводом матриц
For i = 0 To num_layers - 1 Step 1 ' слоев
на один меньше, чем размерность GNeuro
For j = 0 To GNeuro(i + 1) - 1 Step 1
For z = 0 To GNeuro(i) - 1 Step 1
Cells(j
+ 1, z + 1 + sm).Value = GMatrix(i, j, z)
Next z
Next j
sm
= sm + GNeuro(i) + 1 ' +1 чтобы разрыв между матрицами был
Next i
sm =
sm + 1
' Выводим Input
For i = 0 To
inp - 1 Step 1
Cells(i + 1,
sm).Value = InpVector(i)
Next i
sm =
sm + 2
' Выводим OUT
For i = 0 To GNeuro(num_layers) - 1 Step 1
Cells(i
+ 1, sm).Value = OutVector(i)
Cells(i
+ 1, sm + 1).Value = GOut(num_layers - 1, i)
Cells(i
+ 1, sm + 2).Value = GError(i)
Next i
' выводим GOut скрытых слоев
k = 0
For i = 0 To
num_layers - 2 Step 1
For j = 0 To GNeuro(i + 1) Step 1
Cells(j + Mx + 4, 14 + i + k).Value = GSum(i, j) '
первый столбец то, что до функции активации
Cells(j + Mx + 4, 15 + i + k).Value
= GOut(i, j) ' то что после функции активации
Cells(j + Mx + 4, 16 + i
+ k).Value = GDelta(i, j) ' GDelta
Next j
k = k + 3
Next i
' выводим GDelta
Worksheets(list).Activate
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function ClearList()
' очищаем нулевой лист
Worksheets("0").Activate
Cells.Select
Selection.ClearContents
Range("A1").Select
Worksheets(list).Activate
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function GDeltaToNull()
Erase GDelta
ReDim GDelta(num_layers - 1, Mx) ' значения дельт по слоям
End Function
Function Preprocess()
' функция предварительной
обработки входных столбцов для поиска наибольшего значения, чтобы на него потом
поделить
MaxValue = 0
Worksheets(list).Activate
For i = start_valid_pos To end_valid_pos + learning_number_example Step 1
sz
= UBound(GInputs)
For j = 0 To sz Step 1
If LINE_SIGNAL = False
Then
tmp
= Abs(Cells(i, GInputs(j)).Value - Cells(i - 1, GInputs(j)).Value)
Else
tmp
= Cells(i, GInputs(j)).Value
End If
If MaxValue < tmp
Then
MaxValue = tmp
End If
Next j
Next i
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function PlotSuccessResult()
' выводим в нулевой лист
разницу между действительными значениями и желаемыми на валидационной выборке при
достижении заданного значения ошибки
pos1 = 0
For i = start_valid_pos To end_valid_pos Step 1 ' печатаем валидационную выборку
Calc (i)
ll
= GNeuro(num_layers)
For k = 0 To GNeuro(num_layers) - 1 Step 1 ' по всем выходам
pos1 = Mx * 2 + i * ll
+ k
Worksheets("0").Cells(pos1,
19) = i
Worksheets("0").Cells(pos1,
20).Value = OutVector(k)
Worksheets("0").Cells(pos1,
21).Value = GOut(num_layers - 1, k)
Worksheets("0").Cells(pos1,
22).Value = OutVector(k) - GOut(num_layers - 1, k)
Next k
Next i
pos1 = pos1 + 2
' печатаем те примеры, которые сеть вообще не видела
z = 0
For i = start_test To end_test Step 1 ' печатаем валидационную выборку
Calc (i)
ll
= GNeuro(num_layers)
For k = 0 To GNeuro(num_layers) - 1 Step 1 ' по всем выходам
Worksheets("0").Cells(pos1
+ k, 19) = i
Worksheets("0").Cells(pos1
+ k, 20).Value = OutVector(k)
Worksheets("0").Cells(pos1
+ k, 21).Value = GOut(num_layers - 1, k)
Worksheets("0").Cells(pos1
+ k, 22).Value = OutVector(k) - GOut(num_layers - 1, k)
Next k
z = z + 1
pos1 = pos1 + GNeuro(num_layers)
Next i
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function SaveNet()
k = 1 ' счетчик выведенных строк в savelist
Worksheets(savelist).Activate
Cells(k,
1).Value = "Sheet"
Cells(k, 2).Value = list ' лист
откуда брались данные по обучению
k = k + 1
Cells(k,
1).Value = "Alpha"
Cells(k,
2).Value = Alpha ' коэффициент в тангенсоиде и сигмоиде
k = k + 1
Cells(k,
1).Value = "Type_fa" ' тип функции активации
Cells(k,
2).Value = TANGENSOID
k = k + 1
Cells(k,
1).Value = "IO type"
Cells(k,
2).Value = BINARY
k = k + 1
' входы
s = UBound(GInputs)
Cells(k, 1).Value = "Inputs"
Cells(k, 2).Value = s + 1 ' указываем
реальное количество слоев, без учета 0-го элемента
k = k + 1
For i = 0 To s Step 1
Cells(k,
2).Value = GInputs(i)
k = k + 1
Next i
' выходы
s = UBound(GOutputs)
Cells(k,
1).Value = "Outputs"
Cells(k,
2).Value = s + 1
k = k + 1
For i = 0 To s Step 1
Cells(k,
2).Value = GOutputs(i)
k = k + 1
Next i
' количество слоев
s = UBound(GNeuro)
Cells(k,
1).Value = "Layers"
Cells(k,
2).Value = s + 1
k = k + 1
For i = 0 To s Step 1
Cells(k,
2).Value = GNeuro(i)
k = k + 1
Next i
' выводим матрицы
sm = 0 ' смещение между выводом матриц
For i = 0 To num_layers - 1 Step 1 '
слоев на один меньше, чем размерность GNeuro
For j = 0 To GNeuro(i + 1) - 1 Step 1
For z = 0 To GNeuro(i) - 1 Step 1
Cells(k + j + 1 + sm, z + 1).Value = GMatrix(i, j, z)
Next z
Next j
sm
= sm + GNeuro(i + 1) + 1 ' +1 чтобы разрыв между матрицами был
Next i
End Function
'-----------------------------------------------------------------------------------------------------------------------------------
Function LoadNet()
' функция загрузки параметров
уже обученной сети
Worksheets(savelist).Activate
k = 0 ' позиция последней прочитанной
строки
list = Cells(1,
2).Value
Alpha = Cells(2,
2).Value
TANGENSOID = CInt(Cells(3, 2).Value)
BINARY = CInt(Cells(4,
2).Value)
' входы
s = Cells(5,
2).Value
k = 6
ReDim GInputs(s - 1)
For i = 0 To
s - 1 Step 1
GInputs(i) = Cells(6
+ i, 2).Value
k = k + 1
Next i
' выходы
s = Cells(k,
2).Value
k = k + 1
ReDim GOutputs(s - 1)
For i = 0 To
(s - 1) Step 1
GOutputs(i)
= Cells(k, 2).Value
k = k + 1
Next i
' слои и количество нейронов в них
s = Cells(k, 2).Value
k = k + 1
ReDim GNeuro(s - 1)
For i = 0 To
(s - 1) Step 1
GNeuro(i)
= Cells(k, 2).Value
k = k + 1
Next i
' читаем матрицы весов
sm = 0 ' смещение между выводом матриц
num_layers = UBound(GNeuro)
k = k + 1
For i = 0 To num_layers - 1 Step 1 ' слоев на один меньше, чем
размерность GNeuro
For j = 0 To GNeuro(i + 1) - 1 Step 1
For z = 0 To GNeuro(i) - 1 Step 1
GMatrix(i,
j, z) = Cells(k + j + sm, z + 1).Value
Next z
Next j
sm = sm + GNeuro(i + 1) + 1 ' +1 чтобы
разрыв между матрицами был
Next i
' дополнительные параметры
start_valid_pos = 13
end_valid_pos = 23
start_test = 3
end_test = 13
learning_number_example = 150
' количество примеров для обучения
LINE_SIGNAL = False
TEST_SIGNAL = False
savelist
= "save"
MaxStep = 1000000
Nu1 = 0.05
Nu2 = 0.05
num_error = 10
If BINARY = 1 Or BINARY = 2 Then
Error = 3 ' заданная ошибка обучения
Else
Error = 0.006
End If
Mx = 0
For i = 0 To num_layers Step 1 ' ищем
максимальную размерность в количестве нейронов
If GNeuro(i)
> Mx Then
Mx = GNeuro(i)
End If
Next i
ReDim GOut(num_layers
- 1, Mx) ' выходные значения внутренних слоев
ReDim GSum(num_layers
- 1, Mx) ' входные значения внутренних слоев
ReDim GDelta(num_layers - 1, Mx) ' значения дельт по слоям
ReDim GError(GNeuro(num_layers))
Worksheets(list).Activate
End Function
Нейросети (много взято у Шумского и
Короткого).
Нейронная сеть для прогнозирования котировок forex, акций.
Нейросети (основная страница)