Нейронная сеть в Экселе (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, акций.
Нейросети (основная страница)


Рейтинг@Mail.ru

 
 
Апшеронск Спорт VBA Форекс Сочи-2014 Нейросети Студентам
Связь с Администратором сайта, E-mail: apsheronka@mail.ru
Апшеронск, Краснодарский край

Размещение рекламы на сайте
Карта сайта

При перепечатке материалов сайта - обязательная активная гиперссылка на сайт!