Список работ

Нейронная сеть. Пример употребления

Ляпунов Т. А., ИТ-4-07

Содержание

Постановка задачи

Нейронная сеть применена для распознавания прописных букв русского алфавита.
Программа, реализующая алгоритм, является частью приложения, решающего задачи прогнозирования стоимости ценных бумаг. Приложение реализовано на языке FoxPro и основано на базе данных, описывающей предметную область.
Входные данные рассматриваемой задачи, как и в случае генетического алгоритма, поделены на две части. Первая часть содержит эталонные представления букв, а вторая, тестовая, – те же буквы, но с искажениями.
Эталонные буквы используются для обучения нейронной сети. Вторая часть используется для тестирования и оценки эффективности сформированной нейронной сети.
Каждая буква задается в матрице 7*8, как последовательность нулей и единиц. В наборе входных данных матрица представляется в виде последовательности ее строк. В качестве разделителя между строками использован символ *. Так, прописная буква А задается следующей строкой:

0011000*0011000*0100100*0100100*1111110*1000010*1000010*1000010

Табличное (матричное) представление этой буквы приведено на рис. 1. В пустых ячейках таблицы находятся нули.

Буква А как объект распознавания

Рис. 1. Эталонное и искаженное представление буквы А

Такие буквы, как Ж, М или Ф, занимают все столбцы таблицы.
Задача состоит в том, чтобы, зная эталонные представления букв, обучить нейронную сеть, а затем использовать ее для распознавания как эталонных, так и тестовых букв.
Для решения задачи обучения нейронной сети использован метод обратного распространения ошибки.

Структура нейронной сети

Используется 3-слойная нейронная сеть, структура которой приведена на рис. 2.

3-слойная нейронная сеть

Рис. 2. Структура примененной нейронной сети (n – число распознаваемых букв)

Третий слой образуют выходные нейроны.
В нейронной сети выбранной структуры каждый элемент младшего слоя передает свой выходной сигнал на входы всех элементов следующего слоя.
Число элементов в первом и втором слоях нейронной сети может варьироваться. В частности, в разбираемом примере второй слой содержит 8, а третий – 24 нейрона.

Входные данные

Обе части входных данных (эталонные и тестовые) хранятся в таблице Lttrs.dbf с двумя следующими символьными полями:
Nm (2 символа);
Lttr (63 символа).
В первом поле указывается буква, а во втором – ее представление.
Сначала следуют эталонные буквы, а затем тестовые. Записи в каждой части отсортированы по алфавиту. Буквы в тестовой части таблицы в поле Nm снабжены окончанием в виде цифры 2. Фрагмент таблицы Lttrs (конец эталонной и начало тестовой частей) приведен на рис. 3.

Кодировка эталонных и распознаваемых букв

Рис. 3. Таблица входных данных

И эталонная, и тестовые части таблицы имеют по 29 строк (отсутствуют буквы Ё, Й и Щ).
На вход программы распознавания подается номер nT строки тестовой части таблицы. Результатом работы программы является номер nM строки из эталонной части таблицы. Результат положителен, если nT – nM = 29. Так, если на вход подан номер nT = 31 строки, содержащей искаженное представление буквы Б, то правильным решением будет номер nM = 2 строки, содержащей эталонное представление буквы Б.
Программы обучения и распознавания работают с числовыми представлениями букв. Каждая буква – это набор из восьми цифр, отвечающих соответствующим строкам табличного описания буквы (см. рис. 1). В приводимой ниже программе эти цифры записываются в массив rrX0.
Минимальное число в строке табличного представления буквы равно нулю, максимальное – 127. При формировании массива rrX0 (выполняется процедурой GtLttr), число каждой строки табличного представления буквы уменьшается на 63. Таким образом, минимальное значение элемента массива rrX0 равно -63, а максимальное – 64.
Такое смещение обусловлено тем, что при вычислении выходного сигнала нейрона используется логистическая функция, возвращающая значение в диапазоне [-0.5, 0.5]. Смещение согласовывает входы и выходы нейронной сети.
Таким образом, на вход сети подаются 8 сигналов, описывающих распознаваемую букву. Так, в случае искаженной буквы Ж, на входе окажутся показанные на рис. 4 сигналы, уменьшенные на величину смещения.

Буква Ж на входе нейронной сети

Рис. 4. Буква Ж и ее представление на входе нейронной сети

Число выходов нейронной сети равно числу букв в обучающей выборке. В примере формируется нейронная сеть, способная распознавать первые 10 букв русского алфавита.
Значения выходных сигналов находятся в диапазоне [-0.5, 0.5].
После обработки сигнала выбирается выход с максимальным сигналом. По номеру этого выхода в эталонной части таблицы Lttrs находится решение задачи. Так, в случае буквы Ж абсолютно верным решением будет вектор y, в котором 7-й элемент равен 0.5, а все прочие элементы имеют значение -0.5.

Обучение нейронной сети

Сигнал, подаваемый на вход элемента нейронной сети слоя k, определяется, как взвешенная сумма его входных сигналов:

skj = ∑mi=1yiwkij,  j = 1, nk, где

m – число элементов (нейронов) в слое k – 1. В случае первого слоя m = 8, а yi – это входные сигналы (yi = xi);
nk – число элементов в слое k;
wkij – соответствующий весовой коэффициент.
Выход каждого элемента рассчитывается по следующей формуле:

yjk = f(sjk), где

f(x) = -0.5 + 1 / (1 + e-αx) (в нижеприводимой программе α = 1.0) .

Функция f называется логистической, ее график приведен на рис. 5.

График логистической функции

Рис. 5. Использованная в примере логистическая функция

Задача обучения нейронной сети состоит в нахождении весовых коэффициентов wkij, обеспечивающих правильное распознавание образов (в нашем случае букв).
Эта задача решается методом обратного распространения ошибки, следующим образом:

  1. Взять произвольную эталонную букву.
  2. Подать на вход сети ее числовое представление и рассчитать значения yj выходных сигналов нейронной сети.
  3. Вычислить параметр коррекции δj каждого элемента нейронной сети

    δj = (yj - dj)dyj/dsj (в случае выходных нейронов), где dj – ожидаемое значение на j-м выходе,
    или
    δjk = [∑iδik+1wijk+1]dyj/dsj (для нейронов первого и второго слоев, k = 1 или k = 2).
    Производная логистической функции равна αe-αx / (1 + e-αx)2, в программе α = 1.0.

  4. Рассчитать величину коррекции весовых коэффициентов выходных элементов

    Δwkij = -ηδkjyijk-1 (в случае выходного слоя k = 3). В программе η = 0.5.

  5. Выполнить корректировку весовых коэффициентов элементов каждого слоя

    wkij = wkij + Δwkij.

  6. Повторить процедуру обучения, подав на вход описание иной эталонной буквы.

Приведенная процедура неоднократно выполняется для всего множества эталонных букв, образующих обучающую выборку. Процесс обучения завершается либо при получении весовых коэффициентов, обеспечивающих распознавание всех букв обучающей выборки, либо после превышения заданного порогового числа итераций.
Начальные значения весовых коэффициентов всех нейронов, формируемые перед первой итерацией, задаются случайным образом в диапазоне [0.0, 1.0].
Обучающая выборка формируется в примере из 10 первых букв таблицы Lttrs.

Распознавание

На вход нейронной сети подается вектор x (размер вектора 8), содержащий числовое представление распознаваемой буквы. На выходе сети, по известным, найденным в процессе обучения весовым коэффициентам вычисляется вектор y (размер вектора 10).
Решение дает выходной нейрон с максимальным значением yj: по номеру j этого нейрона из таблицы Lttrs извлекается и предъявляется в качестве ответа буква.

Таблица весовых коэффициентов

Весовые коэффициенты хранятся в таблице Wghts.dbf, имеющей следующие поля:
Lr (тип Integer) – номер слоя;
D (тип Integer) – номер нейрона в слое;
D2 (тип Integer) – номер подходящей к нейрону связи;
W (тип Numeric 18, 10) – значение весового коэффициента.
Фрагмент таблицы показан на рис. 6.

Таблица весовых коэффициентов нейронной сети

Рис. 6. Таблица весовых коэффициентов (фрагмент)

Программная реализация

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

Процедуры общего назначения

* Возвращает значение логистической функции
FUNCTION sgmd
 LPARAMETERS x, a
 a = IIF(PARAMETERS() = 1, 1.0, a)
 DO CASE
 CASE x > 10.0
  f = 0.5
 CASE x < -10.0
  f = -0.5
 OTHERWISE
  f = 1.0 / (1.0 + EXP(-a * x)) - 0.5
 ENDCASE
 RETURN f
ENDFUNC
* Расчет выходных значений нейронов
PROCEDURE fndX(rrXPrv, rrW, rrXNn, nRsltM, jc, prn, rrPrn)
 LOCAL k, k2
 nn = ALEN(rrW, 1)
 nPrv = ALEN(rrW, 2)
 FOR k = 1 TO nn
  s = 0.0
  FOR k2 = 1 TO nPrv
   s = s + rrW[k, k2] * rrXPrv[k2]
  NEXT
  rrXNn[k] = sgmd(s)
 NEXT
 * Подготовка массива rrXNn для последующей печати
 IF prn
  mVl = rrXNn[1]
  kM = 1
  FOR k = 1 TO nn
   IF mVl < rrXNn[k]
    mVl = rrXNn[k]
    kM = k
   ENDIF
  NEXT
  tptVls = ''
  FOR k = 1 TO nn
   tptVls = tptVls + ' ' + TRANSFORM(ROUND(rrXNn[k], 2), '99.99')
  NEXT
  lttrTst = lttrs.Nm
  GO kM IN lttrs
  rrPrn[jc] = IIF(kM = jc, ‘+ ’, ‘- ‘) + lttrTst + ' : ' + lttrs.Nm + ' : ';
   + TRANSFORM(ROUND(rrXNn[kM], 2), '99.99') + ' : ' + tptVls
  nRsltM = nRsltM + IIF(kM = jc, 1, 0)
 ENDIF
ENDPROC
* Формирует массив rrX с числовым представлением буквы
* Элементы массива – суть вектор, подаваемый на вход нейронной сети
PROCEDURE gtLttr
 LPARAMETERS rrX, xM
 LOCAL k, j
 mLlttr = lttrs.Lttr
 FOR k = 1 TO 8
  wrd = GETWORDNUM(mLlttr, k, "*")
  vl = 0
  FOR j = 1 TO 7
   p = SUBSTR(wrd, j, 1)
   vl = vl + IIF(p = '1', 2^(j - 1), 0)
  NEXT
  rrX(k) = (-0.5 * xM + vl) / xM
 NEXT
ENDPROC
* Выводит в файл d:1.txt результат работы программы
* Параметр rCntLrn – это число распознаваемых букв
* Массив rrFnd имеет rCntLrn элементов, каждый из которых содержит
* плюс, если результат верен, и минус – в противном случае,
* исходную букву, букву – ответ, значение выходного сигнала,
* соответствующего ответу, последовательность всех выходных значений
* После вывода массива печатаются процент распознавания и время работы программы
PROCEDURE prntRsltNN(rCntLrn, rrPrn, nRsltM, tStrt)
 SET SAFETY OFF
 SET ALTERNATE TO d:1.txt
 SET ALTERNATE ON
 SET CONSOLE OFF
 FOR k = 1 TO rCntLrn
  ? rrPrn[k]
 NEXT
 ? "Success = " + TRANSFORM(ROUND(100.0 * nRsltM / rCntLrn, 2)) + "%"
 ? 'Time = ' + TRANSFORM(SECONDS( ) - tStrt)
 SET ALTERNATE TO
 MODIFY FILE d:1.txt
ENDPROC

Процедуры обучающей программы

* Возвращает значение производной логистической функции
FUNCTION sgmdD
 LPARAMETERS x, a
 a = IIF(PARAMETERS() = 1, 1.0, a)
 f = EXP(-a * x)
 f2 = 1.0 + f
 f2 = f2 * f2
 fD = a * f / f2
 RETURN fD
ENDFUNC
* Формирует начальные значения весовых коэффициентов
PROCEDURE ntW(nPrv, nn, rrW, lrVl, prn)
 FOR k = 1 TO nn
  wVl = ''
  FOR k2 = 1 TO nPrv
   rrW[k, k2] = RAND()
   * Подготовка печати весовых коэффициентов
   IF lrVl = 1
    wVl = wVl + ' ' + TRANSFORM(ROUND(rrW[k, k2], 4))
   ENDIF
  NEXT
  * Печать весовых коэффициентов
  IF lrVl = 1 AND prn
   ? wVl
  ENDIF
 NEXT
ENDPROC
* Формирует данные (массивы rrChW и rrNP), необходимые для пересчета
* весовых коэффициентов текущего слоя нейронной сети
PROCEDURE nxtLr(kL, nPrv, n, nn, rrX, rrN, rrW, rrXP, rrNP, rrChW)
 LOCAL k, k2
 FOR k = 1 TO n
  smR = 0
  FOR k2 = 1 TO nn
   smR = smR + rrN[k2] * rrW[k2, k]
  NEXT
  rrVl = smR * sgmdD(rrX[k])
  FOR k2 = 1 TO nPrv
   rrChW[k, k2] = -kL * rrVl * rrXP[k2]
  NEXT
  rrNP[k] = rrVl
 NEXT
ENDPROC
* Выполняет пересчет весовых коэффициентов текущего слоя нейронной сети
PROCEDURE crW(nPrv, nn, rrW, rrChW)
 LOCAL k, k2
 FOR k = 1 TO nn
  FOR k2 = 1 TO nPrv
   rrW[k, k2] = rrW[k, k2] + rrChW[k, k2]
  NEXT
 NEXT
ENDPROC
* Записывает в таблицу Wghts полученные в результате обучения весовые коэффициенты
PROCEDURE wVlSv(nPrv, nn, rrW, lrVl, prn)
 DIMENSION rrWNsrt[4]
 rrWNsrt[1] = lrVl
 SELECT wghts
 IF lrVl = 1
  DELETE ALL
  PACK
 ENDIF
 FOR k = 1 TO nn
  rrWNsrt[2] = k
  wVl = ''
  FOR k2 = 1 TO nPrv
   rrWNsrt[3] = k2
   rrWNsrt[4] = rrW[k, k2]
   APPEND FROM ARRAY rrWNsrt
   IF prn
    wVl = wVl + ' ' + TRANSFORM(ROUND(rrW[k, k2], 4))
   ENDIF
  NEXT
  IF prn
   ? wVl
  ENDIF
 NEXT
ENDPROC

Процедуры тестовой программы

* Формирует массив из двух элементов, содержащий число элементов
* текущего и последующего слоев нейронной сети
PROCEDURE rrDmnsn(lrVl, rrD, prn)
 SELECT wghts
 CALCULATE CNT() FOR lr = lrVl TO rrCnt
 CALCULATE CNT() FOR lr = lrVl AND d = 1 TO dVl
 rrD[1] = rrCnt / dVl
 rrD[2] = dVl
 IF prn
  ? TRANSFORM(rrD[1]) + ', ' + TRANSFORM(rrD[2])
 ENDIF
ENDPROC
* Заполняет массивы весовых коэффициентов нейронной сети
PROCEDURE wVlRd(rrW, lrVl, prn)
 SELECT wghts
 SCAN FOR wghts.Lr = lrVl
  rrW[wghts.D, wghts.D2] = wghts.W
 ENDSCAN
 * Печать весовых коэффициентов при prn = .T.
 IF prn
  nn = ALEN(rrW, 1)
  nPrv = ALEN(rrW, 2)
  FOR k = 1 TO nn
   wVl = ''
   FOR k2 = 1 TO nPrv
    wVl = wVl + ' ' + TRANSFORM(ROUND(rrW[k, k2], 4))
   NEXT
   ? wVl
  NEXT
 ENDIF
ENDPROC

Обучающая программа

tStrt = SECONDS( )
CLEAR
IF USED('lttrs')
 USE IN lttrs
ENDIF
IF USED('wghts')
 USE IN wghts
ENDIF
USE lttrs IN 1
USE wghts IN 2
SELECT lttrs
* Предельное число обучающих итераций
nLrn = 300
kL = 0.75
* Размер обучающей выборки
rCntLrn = 10
* Число букв в эталонной части таблице Lttrs
lttrsLL = 29
* Число входных сигналов и элементов в слоях нейронной сети
n0 = 8
n1 = 8
n2 = 24
n3 = rCntLrn
* Величина смещения в описании буквы
xM = 2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5   && 63
* Массив с описание распознаваемой буквы
DIMENSION rrX0(n0)
* Массивы весовых коэффициентов и поправочных данных
DIMENSION rrW1(n1, n0), rrX1(n1), rrChW1(n1, n0), rr1(n1)
DIMENSION rrW2(n2, n1), rrX2(n2), rrChW2(n2, n1), rr2(n2)
DIMENSION rrW3(n3, n2), rrX3(n3), rrChW3(n3, n2), rr3(n3)
* Массив выходных сигналов, отвечающих абсолютно верному решению
DIMENSION rrX3Rght(n3)
* Массив с выводимыми на печать данными
DIMENSION rrPrn(rCntLrn)
* Инициализация массивов поправочных данных
rrChW1 = 0
rrChW2 = 0
rrChW3 = 0
* Генерация начальных весовых коэффициентов
ntW(n0, n1, @rrW1, 1, .F.)
ntW(n1, n2, @rrW2, 2)
ntW(n2, n3, @rrW3, 3)
* Формируем начальные значения выходных сигналов (массив rrX3)
* (иными словами, рассчитываем нейронную сеть)
jc = 1
GO jc
gtLttr(@rrX0, xM)
fndX(@rrX0, @rrW1, @rrX1)
fndX(@rrX1, @rrW2, @rrX2)
fndX(@rrX2, @rrW3, @rrX3)
* Обучение
FOR jc0 = 1 TO nLrn
 FOR jc = 1 TO rCntLrn
  rrX3Rght = 0.5
  rrX3Rght[jc] = 0.5
  FOR jc2 = 1 TO 2
   GO jc
   * Формируем числовое представление текущей буквы
   * Рассчитываем нейронную сеть
   gtLttr(@rrX0, xM)
   fndX(@rrX0, @rrW1, @rrX1)
   fndX(@rrX1, @rrW2, @rrX2)
   fndX(@rrX2, @rrW3, @rrX3)
   * Получаем корректирующие значения выходных нейронов
   FOR k = 1 TO n3
    s3 = rrX3[k]
    rrVl = (s3 - rrX3Rght[k]) * sgmdD(s3)
    FOR k2 = 1 TO n2
     rrChW3[k, k2] = -kL * rrVl * rrX2[k2]
    NEXT
    rr3[k] = rrVl
   NEXT
   * Получаем корректирующие значения нейронов прочих уровней сети
   nxtLr(kL, vrnt, kMu, kMu2, n1, n2, n3, @rrX2, @rr3, @rrW3, @rrX1, @rr2, @rrChW2)
   nxtLr(kL, vrnt, kMu, kMu2, n0, n1, n2, @rrX1, @rr2, @rrW2, @rrX0, @rr1, @rrChW1)
   * Корректировка весовых коэффициентов
   crW(n0, n1, @rrW1, @rrChW1)
   crW(n1, n2, @rrW2, @rrChW2)
   crW(n2, n3, @rrW3, @rrChW3)
  NEXT
 NEXT
 * Расчет нейронной сети для всех букв обучающей выборки
 * с целью оценки качества обучения (nRsltM - число точных решений)
 nRsltM = 0
 FOR jc = 1 TO rCntLrn
  GO jc
  gtLttr(@rrX0, xM)
  fndX(@rrX0, @rrW1, @rrX1)
  fndX(@rrX1, @rrW2, @rrX2)
  fndX(@rrX2, @rrW3, @rrX3, @nRsltM, jc, .F., 2)
 NEXT
 * Завершаем обучение, если сеть узнает все буквы обучающей выборки
 IF nRsltM = rCntLrn
  EXIT
 ENDIF
NEXT
* Проверка качества сети на буквах обучающей выборки
SELECT lttrs
nRsltM = 0
FOR jc = 1 TO rCntLrn
 GO jc
 gtLttr(@rrX0, xM)
 fndX(@rrX0, @rrW1, @rrX1)
 fndX(@rrX1, @rrW2, @rrX2)
 fndX(@rrX2, @rrW3, @rrX3, @nRsltM, jc, .T., @rrPrn)
NEXT
* Печать результатов проверки
prntRsltNN(rCntLrn, @rrPrn, nRsltM, tStrt)
wVlSv(n0, n1, @rrW1, 1, .F.)
wVlSv(n1, n2, @rrW2, 2, .F.)
wVlSv(n2, n3, @rrW3, 3, .F.)

Заметим, что обучение можно продолжить и при достижении условия nRsltM = rCntLrn, добавив значимое число итераций.
После завершения поиска весовых коэффициентов нейронной сети обучающая выборка вновь подается на вход сети для оценки результатов обучения.
В примере распознаются все элементы обучающей выборки:

+ A : A : 0.42 : 0.42 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50
+ Б : Б : 0.48 : -0.44 0.48 -0.50 -0.48 -0.48 -0.47 -0.50 -0.50 -0.49 -0.49
+ B : B : 0.47 : -0.44 -0.50 0.47 -0.49 -0.46 -0.50 -0.49 0.18 -0.48 -0.49
+ Г : Г : 0.41 : -0.50 -0.47 -0.50 0.41 -0.48 -0.50 -0.50 -0.45 -0.50 -0.46
+ Д : Д : 0.46 : -0.48 -0.50 -0.49 -0.49 0.46 -0.50 -0.50 -0.47 -0.50 -0.50
+ E : E : 0.38 : -0.50 -0.50 -0.50 -0.50 -0.50 0.38 -0.49 -0.50 -0.50 -0.50
+ Ж : Ж : 0.47 : -0.50 -0.50 -0.50 -0.50 -0.50 -0.48 0.47 -0.50 -0.50 -0.49
+ З : З : 0.04 : -0.50 -0.50 -0.49 -0.50 -0.50 -0.50 -0.50 0.04 -0.50 -0.50
+ И : И : 0.48 : -0.41 -0.49 -0.43 -0.50 -0.50 -0.48 -0.50 -0.40 0.48 -0.43
+ K : K : 0.44 : -0.50 -0.50 -0.50 -0.48 -0.50 -0.47 -0.50 -0.38 -0.50 0.44
Success = 100%
Time = 31.11

Время, затраченное на обучение, выводится в секундах.

Тестовая программа

tStrt = SECONDS( )
CLEAR
SET TALK OFF
* Если параметр frmTst = .T., то оценка сети будет выполнена по тестовой выборке,
* то есть буквы будут взяты из тестовой части таблицы Lttrs
frmTst = .T.
IF USED('lttrs')
 USE IN lttrs
ENDIF
IF USED('wghts')
 USE IN wghts
ENDIF
USE lttrs IN 1
USE wghts IN 2
* Величина смещения в описании буквы
xM = 2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5   && 63
* Получаем размеры нейронной сети (число входов и число элементов в каждом ее слое)
SELECT lttrs
DIMENSION rrD(2)
rrDmnsn(1, @rrD, .F.)
n0 = rrD[2]
n1 = INT(rrD[1])
rrDmnsn(2, @rrD, .F.)
n2 = INT(rrD[1])
rrDmnsn(3, @rrD, .F.)
n3 = INT(rrD[1])
DIMENSION rrX0(n0)
DIMENSION rrW1(n1, n0), rrX1(n1)
DIMENSION rrW2(n2, n1), rrX2(n2)
DIMENSION rrW3(n3, n2), rrX3(n3)
DIMENSION rrPrn(n3)
* Записываем весовые коэффициенты нейронной сети в массивы
wVlRd(@rrW1, 1, .F.)
wVlRd(@rrW2, 2, .F.)
wVlRd(@rrW3, 3, .F.)
* Проверка
SELECT lttrs
nRsltM = 0
FOR jc = 1 TO n3
 GO jc + IIF(frmTst, 29, 0)
 gtLttr(@rrX0, xM)
 fndX(@rrX0, @rrW1, @rrX1)
 fndX(@rrX1, @rrW2, @rrX2)
 fndX(@rrX2, @rrW3, @rrX3, @nRsltM, jc, .T., @rrPrn)
NEXT
* Печать результатов проверки
prntRsltNN(n3, @rrPrn, nRsltM, tStrt)

При работе с тестовыми (искаженными) буквами процент распознавания снижается:

+ A2 : A : 0.50 : 0.50 0.50 0.48 -0.50 0.49 0.50 0.17 -0.49 0.50 0.44
– Б2 : З : -0.50 : -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50
+ B2 : B : 0.29 : -0.49 -0.50 0.29 -0.50 -0.49 -0.50 -0.50 0.06 -0.50 -0.50
+ Г2 : Г : 0.42 : -0.50 -0.47 -0.50 0.42 -0.48 -0.50 -0.50 -0.45 -0.50 -0.46
+ Д2 : Д : 0.47 : -0.40 -0.46 -0.50 -0.36 0.47 -0.50 -0.50 -0.44 -0.50 -0.35
+ E2 : E : 0.34 : -0.50 -0.50 -0.50 -0.50 -0.50 0.34 -0.49 -0.50 -0.50 -0.49
+ Ж2 : Ж : 0.45 : -0.50 -0.50 -0.50 -0.49 -0.50 -0.41 0.45 -0.50 -0.50 -0.49
+ З2 : З : -0.45 : -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.45 -0.50 -0.50
– И2 : З : -0.49 : -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.49 -0.50 -0.50
+ K2 : K : -0.46 : -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.50 -0.46
Success = 80%
Time = 0.015

Эталонные и тестовые данные

В примере таблица Lttrs содержит следующие 58 строк:

A  0011000*0011000*0100100*1000010*1111110*1000010*1000010*1000010
Б  1111100*1000000*1000000*1111100*1000010*1000010*1000010*1111100
B  1111100*1000010*1000010*1111100*1000010*1000010*1000010*1111100
Г  1111100*1000010*1000000*1000000*1000000*1000000*1000000*1000000
Д  0011000*0100100*0100100*0100100*0100100*0100100*1111110*1000010
E  1111110*1000000*1000000*1111100*1000000*1000000*1000000*1111110
Ж  1101011*0101010*0101010*0011100*0011100*0101010*0101010*1101011
З  0111100*1000010*0000010*0011100*0000010*0000010*1000010*0111100
И  1000010*1000010*1000110*1001010*1010010*1100010*1000010*1000010
K  1000010*1000100*1001000*1010000*1110000*1001000*1000100*1000010
Л  0000110*0001010*0010010*0010010*0010010*0010010*0100010*1000010
M  1000001*1100011*1010101*1001001*1000001*1000001*1000001*1000001
H  1000010*1000010*1000010*1111110*1000010*1000010*1000010*1000010
O  0111100*1000010*1000010*1000010*1000010*1000010*1000010*0111100
П  1111110*1000010*1000010*1000010*1000010*1000010*1000010*1000010
P  1111100*1000010*1000010*1111100*1000000*1000000*1000000*1000000
C  0111100*1000010*1000000*1000000*1000000*1000000*1000010*0111100
T  1111100*0010000*0010000*0010000*0010000*0010000*0010000*0010000
У  1000010*1000010*1000010*0111110*0000010*0000010*1000010*0111100
Ф  0001000*0111110*1001001*1001001*0111110*0001000*0001000*0001000
X  1000001*0100010*0010100*0001000*0001000*0010100*0100010*1000001
Ч  1000010*1000010*1000010*0111110*0000010*0000010*0000010*0000010
Ш  1001001*1001001*1001001*1001001*1001001*1001001*1001001*1111111
Ъ  1100000*0100000*0100000*0111100*0100001*0100001*0100001*0111110
Ы  1000001*1000001*1000001*1111001*1000101*1000101*1000101*1111001
Ь  0100000*0100000*0100000*0111100*0100001*0100001*0100001*0111110
Э  0111100*1000010*0000010*0011110*0000010*0000010*1000010*0111100
Ю  1001110*1010001*1010001*1110001*1010001*1010001*1010001*1001110
Я  0111110*1000010*1000010*0111110*0001010*0010010*0100010*1000010
A2 0011000*0010000*0100100*1000010*1111110*1000010*1000010*1000001
Б2 1111110*1000000*1000000*1111100*1000010*1000010*1000010*1111100
B2 1111100*1000010*1000010*1111100*1000010*1000010*1000010*0111100
Г2 1111100*1000010*1000000*1000000*0000000*1000000*1000000*1000000
Д2 0011000*0100100*0100100*0100100*0100100*0100100*1110110*1000010
E2 1111110*1000000*1000000*1101100*1000000*1000000*1000000*1111110
Ж2 1101011*0101010*0101010*0011100*0010100*0101010*0101010*0100011
З2 0111100*1000010*0000010*0011100*0000010*0000010*1000010*0110100
И2 1000010*1000010*1000110*1000010*1010010*1100010*1000010*1000010
K2 1000001*1000100*1001000*1010000*1110000*1001000*1000100*1000010
Л2 0000110*0001010*0010010*0010010*0010010*0010010*0100010*1000000
M2 1000001*1100011*1010101*1001001*1000001*1000001*1000001*1000000
H2 1000010*1000010*1000010*1101110*1000010*1000010*1000010*1000010
O2 0110100*1000010*1000010*1000010*1000010*1000010*1000010*0111100
П2 1111110*1000010*1000010*1000010*1000010*1000010*1000010*1000000
P2 1101100*1000010*1000010*1111100*1000000*1000000*1000000*1000000
C2 0110100*1000010*1000000*1000000*1000000*1000000*1000010*0111100
T2 1111111*0010000*0010000*0010000*0010000*0010000*0010000*0010000
У2 1000010*1000010*1000010*0111010*0000010*0000010*1000010*0111100
Ф2 0001000*0111110*1001001*1001001*0110110*0001000*0001000*0001000
X2 1000001*0100010*0010100*0001000*0001000*0010100*0100010*1001001
Ч2 1000010*1000010*1000010*0111110*0000010*0000010*0000010*0000000
Ш2 1001001*1001001*1001001*1001001*1001001*1001001*1001001*1110111
Ъ2 1100000*0000000*0100000*0111100*0100001*0100001*0100001*0111110
Ы2 1000001*1000001*1000001*1111001*1000101*1000101*1000100*1111001
Ь2 0100000*0100000*0100000*0111100*0100001*0100001*0100001*0110110
Э2 0111110*1000010*0000010*0011110*0000010*0000010*1000010*0111100
Ю2 1001110*1010001*1010001*1110001*1010001*1010001*1010001*1001011
Я2 0111110*1000010*1000010*0111110*0001010*0010010*0100010*1000000

Заключение

Приведенная программа содержит около 300 строк, что несколько больше, чем в случае генетического алгоритма.
Совсем необязательно обучать сеть распознавать все буквы. Проще (с позиции обучения) иметь, например, три сети, каждая из которых обучена распознаванию своего подмножества букв алфавита. Образ поочередно подается на вход каждой сети. В качестве решения берется буква, отвечающая нейрону с максимальным значением выходного сигнала.

Литература

  1. Калан Роберт. Основные концепции нейронных сетей. М.: Издательский дом "Вильямс", 2001. - 288 с.
  2. Люгер Джорж Ф. Искусственный интеллект: стратегии и методы решения сложных проблем. М.: Издательский дом "Вильямс", 2005. - 864 с.

Список работ

Рейтинг@Mail.ru