Меню
Бесплатно
Главная  /  Любовь  /  Построение обученных логических нейронных сетей. Распознавание букв латинского алфавита Распознавание букв

Построение обученных логических нейронных сетей. Распознавание букв латинского алфавита Распознавание букв

Требуется создать нейронную сеть для распознавания 26 букв латинского алфавита . Будем считать, что имеется система считывания символов, которая каждый символ представляет в виде матрицы . Например, символ A может быть представлен, как показано на рис. 2.22.

Рис. 2.22. Представление символа

Реальная система считывания символов работает не идеально, а сами символы отличаются по начертанию. Поэтому, например, для символа A единицы могут располагаться не в тех клетках, как показано на рис. 2.22. Кроме того, вне контура символа могут возникать ненулевые значения. Клетки, соответствующие контуру символа, могут содержать значения, отличные от 1. Будем называть все искажения шумом.

В MATLAB имеется функция prprob , возвращающая матрицу , каждый столбец которой представляет записанную в виде вектора матрицу , описывающую соответствующую букву (первый столбец описывает букву A, второй - букву B и т. д.). Функция prprob возвращает также целевую матрицу размером , каждый столбец которой содержит одну единицу в строке, соответствующей номеру буквы при нулевых остальных элементах столбца. Например, первый столбец, соответствующий букве A, содержит 1 в первой строке.

Пример . Определим шаблон для буквы A (программа Template_A.m ).

% Пример формирования шаблона для буквы A

Prprob;

i=1; % номер буквы A

v=alphabet(:,i); % вектор, соответствующий букве A

template=reshape(v, 5,7)";

Кроме уже описанной функции prprob в программе использованы функции reshape , которая формирует матрицу , а после транспонирования - (убедитесь, что невозможно сразу сформировать матрицу ), и функция plotchar , которая рисует 35 элементов вектора в виде решетки . После выполнения программы Template_A.m получим матрицу template и шаблон буквы A, как показано на рис. 2.23.

Рис. 2.23. Сформированный шаблон буквы A

Для распознавания букв латинского алфавита необходимо построить нейронную сеть с 35 входами и 26 нейронами в выходном слое. Примем число нейронов скрытого слоя равным 10 (такое число нейронов выбрано экспериментально). Если при обучении возникнут затруднения, то можно увеличить количество нейронов этого уровня.



Сеть распознавания образов строится функцией patternnet. Обратите внимание, что при создании сети не задается число нейронов входного и выходного слоев. Эти параметры неявно задаются при обучении сети.

Рассмотрим программу распознавания букв латинского алфавита Char_recognition.m

% Программа распознавания букв латинского алфавита

Prprob; % Формирование входных и целевых векторов

Size(alphabet);

Size(targets);

% Создание сети

Train(net,P,T);

% Обучение в присутствии шума

P = ;

Train(netn,P,T);

Train(netn,P,T);

% Тестирование сети

noise_rage=0:0.05:0.5; % Массив уровней шума (стандартных отклонений шума

for noiselevel=noise_rage

for i=1:max_test

% Тест для сети 1

% Тест для сети 2

title("Погрешность сети");

xlabel("Уровень шума");

ylabel("Процент ошибки");

Оператор = prprob ; формируют массив векторов входа alphabet размера с шаблонами символов алфавита и массив целевых векторов targets .

Сеть создается оператором net=patternnet. Примем параметры сети по умолчанию. Обучение сети производится сначала в отсутствии шума. Затем сеть обучается на 10 наборах идеальных и зашумленных векторов. Два набора идеальных векторов используются, чтобы сеть сохранила способность классифицировать идеальные векторы (без шума). После обучения сеть "забыла", как классифицировать некоторые векторы, свободные от шума. Поэтому сеть следует снова обучить на идеальных векторах.

Следующий фрагмент программы производит обучение в отсутствие шума:

% Обучение сети в отсутствие шума

Train(net,P,T);

disp("Обучение сети в отсутствие шума завершено. Нажмите Enter");

Обучение в присутствии шума проводится с применением двух идеальных и двух зашумленных копий входных векторов. Шум имитировался псевдослучайными нормально распределенными числами с нулевым средним значением и стандартным отклонением 0.1 и 0.2. Обучение в присутствии шума производит следующий фрагмент программы:

% Обучение в присутствии шума

netn = net; % сохранение обученной сети

T = ;

P = ;

Train(netn,P,T);

disp("Обучение сети в присутствии шума завершено. Нажмите Enter");

Поскольку сеть обучалась в присутствии шума, то имеет смысл повторить обучение без шума, чтобы гарантировать правильную классификацию идеальных векторов:

% Повторное обучение в отсутствии шума

Train(netn,P,T);

disp("Повторное обучение сети в отсутствии шума завершено. Нажмите Enter");

Тестирование сети проводилось для двух структур сети: сети 1, обученной на идеальных векторах, и сети 2, обученной на зашумленных последовательностях. Шум со средним значением 0 и стандартным отклонением от 0 до 0.5 с шагом 0.05 добавлялся к векторам входа. Для каждого уровня шума формировалось 10 зашумленных векторов для каждого символа, и вычислялся выход сети (желательно увеличить число зашумленных векторов, но это заметно увеличит время работы программы). Сеть обучается так, чтобы сформировать единицу в единственном элементе выходного вектора, позиция которого соответствует номеру распознанной буквы, и заполнить остальную часть вектора нулями. Никогда на выходе сети не будет формировать вектор выхода, состоящий точно из 1 и 0. Поэтому в условиях действия шумов выходной вектор обрабатывается функцией compet , которая преобразует выходной вектор так, что самый большой выходной сигнал получает значение 1, а все другие выходные сигналы получают значение 0.

Соответствующий фрагмент программы имеет вид:

% Выполнение теста для каждого уровня шума

for noiselevel=noise_rage

for i=1:max_test

P=alphabet+randn(35, 26)*noiselevel;

% Тест для сети 1

errors1=errors1+sum(sum(abs(AA-T)))/2;

% Тест для сети 2

errors2=errors2+sum(sum(abs(AAn-T)))/2;

% Средние значения ошибок (max_test последовательностей из 26 векторов целей)

network1=;

network2=;

plot(noise_rage, network1*100, noise_rage, network2*100);

title("Погрешность сети");

xlabel("Уровень шума");

ylabel("Процент ошибки");

legend("Идеальные входные векторы","Зашумленные входные векторы");

disp("Тестирование завершено");

При вычислении погрешности распознавания, например, errors1=errors1+sum(sum(abs(AA-T)))/2, учтено, что при неправильном распознавании не совпадают два элемента выходного вектора и вектора цели, поэтому при подсчете погрешности производится деление на 2. Сумма sum(abs(AA-T)) вычисляет число не совпавших элементов для одного примера. Сумма sum(sum(abs(AA-T))) вычисляет число не совпавших элементов по всем примерам.

Графики погрешности распознавания сетью, обученной на идеальных входных векторах, и сетью, обученной на зашумленных векторах, представлены на рис. 2.24. Из рис. 2.24 видно, что сеть, обученная на зашумленных образах, дает небольшую погрешность, а на идеальных входных векторах сеть обучить не удалось.

Рис. 2.24. Погрешности сети в зависимости от уровня шума

Проверим работу обученной сети (в рабочем пространстве MATLAB должна присутствовать обученная сеть). Программа Recognition_J.m формирует зашумленный вектор для буквы J и распознает букву. Функция randn формирует псевдослучайное число, распределенное по нормальному закону с нулевым математическим ожиданием и единичным среднеквадратичным отклонением. Случайное число с математическим ожиданием m и среднеквадратическим отклонением d получается по формуле m+randn*d (в программеm=0, d=0.2 ).

noisyJ = alphabet(:,10)+randn(35,1) * 0.2;

plotchar(noisyJ);

disp("Зашумленный символ. Нажмите Enter");

A2 = netn(noisyJ);

A2 = compet(A2);

ns = find(A2 == 1);

disp("Распознан символ");

plotchar(alphabet(:,ns));

Программа выводит номер распознанной буквы, зашумленный шаблон буквы (рис. 2.25) и шаблон распознанной буквы (2.26).

Рис. 2.25. Зашумленный шаблон буквы

Рис. 2.26. Шаблон распознанной буквы

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

Задания

1. Проделайте все приведенные примеры.

2. Испытайте распознавание различных букв

3. Исследуйте влияние шума в программах на точность распознавания символов.

Аппроксимация функций

Упражнение на распознание букв. Различные уровни сложности. На букву накладывается маска с шумом. Иногда требуется проявить сообразительность, чтобы методом исключения понять, что за буква была в задании.

Обучение детей чтению и буквам русского алфавита. Какая буква изображена? Выбери правильный ответ справа.

Какая буква спряталась. Онлайн игра для раннего развития детей. Распознавание букв русского алфавита

Как учить буквы русского алфавита

Часто буквы русского алфавита начинают учить по порядку, так как это написано в в букваре. На самом деле, буквы нужно учить в порядке их частоты употребления. Дам небольшую подсказку - буквы в центре клавиатуры используются чащще чем те, что на перефирии. Поэтому, сначала нужно запоминать А, П, Р, О.... и на закуску оставлять такие, как Й, Х, Ж, Щ...

Что лучше - учить ребенка читать по буквам или слогами

Многие преподаватели учат сразу слогами. Я предлагаю обойти эту небольшую проблему и вместо того, чтобы учить слоги, играть в онлайн игры. Так ребенок одновременно учится и играет. Вернее, ему кажется что он играет и при этом непроизвольно повторяет нужные звуки.

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

Помогают ли учить буквы буквари. Почему бумажные буквари еще используются в практике обучения

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

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

Помогают ли онлайн упражнения запоминать буквы

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

С какого возраста следует отдавать ребенка в образовательные центры

Скорость взросления разная. Обычно. девочки до определенного возраста опережают в развитии мальчиков. Девочки начинают раньше говорить, они более социально ориентированы и больше поддаются обучению. мальчики же наоборот, часто являются большими аутистами - которые гуляют сами по себе. Из этого моно сделать вывод, что девочки обучаются чтению чуть раньше чем мальчики. Но, это лишь внешняя схема. Каждый ребенок индивидуален и готовность его к обучению можно проверить на практике. Нравится ли ребенку посещать занятия? остается ли что либо в его сознании после того, как он отучился?

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

Что делать, если ребенок не запоминает буквы

Учиться трудно. И, то не зависит от того, взрослый это человек или малыш. Обучаться очень и очень трудно. К тому же дети обучаются только в игре. Другой факт состоит в том, что для того чтобы обучиться чему либо, нужно применять на практике или повторять множество раз. Поэтому ничего нет удивительного в том, что дети очень плохо запоминают буквы.

Есть отдельный ряд детей, которые поздно начинают говорить и при этом путают не только буквы, но и звуки. с такими ребятами нужно рисовать буквы вместе использовать для этого все возможны материалы, и крупы, и спички, и камешки, карандаши - все что есть под руками. Нарисуйте вы - попросите ребенка повторить.

Можно выполнять графические диктанты, можно играть в нарисуй и повтори.

Что делать, если малыш путает буквы, например, Д и Т

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

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

повторение - мать учения. Повторяйте буквы в словах, повторяйте буквы в слогах, пробуйте отгадывать буквы. пусть ребенок напишет букву, а вы попробуйте отгадать. А, можно наоборот - попробуйте сложить букву из зерен риса, а сынишка или дочка путь отгадают, что это за буква. Можно писать палочкой на песке.

Почему буквы не произносит правильно. Как научить ребенка произносить буквы четко и ясно?

Пробелы могут быть на уровне физиологии. Человек не правильно себя слышит. или ему кажется, что он говорит правильно. проверить это очень легко - достаточно записать разговор на диктофон и дать послушать как ребенок читает.

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

Что нужно еще отметить, так это то, что детей любить нужно и заниматься с ними периодически. Не запускать процессы.

Как заниматься с ребенком алфавитом для подготовки к школе

Заниматься с детьми нужно в игровой форме. Как раз так, как указано на этом сайте. Еще один секрет обучения состоит в том, что заниматься нужно малыми порциями. Дети не могут удерживать внимание дольше 5 минут. Поэтому заниматься дольше просто бесполезно.

С каких букв нужно начинать запоминание алфавита

Начинать запоминание букв нужно с общеупотребительных букв. Второй секрет - это запоминать буквы из которых состоит имя ребенка, имя мамы и папы, можно к этим словам добавить имена брата и сестры, бабушки и дедушки. Это самые любимые имена.

Кстати, если вы учитесь печатать в слепую, то первое слово, с которого нужно начать тренировки по набору - это опять таки ваше имя и фамилия.

Нужно ли запоминать малышу буквы английского алфавита

Знание английского алфавита не повредит. В школе не изучают, алфавит, а сразу начинают читать оставляя алфавит на откуп родителям. стоит так же отметить то, что большие и маленькие английские буквы выглядят по разному и их нужно обязательно запоминать. Если ваш ребенок начал поздно говорить, то скорее всего, запоминание латинских букв для него будет представлять проблему.

Можно ли научить ребенка читать сразу словами

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

Как запомнить цифры дошкольнику

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

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

Почему малыш - дошкольник забывает буквы. Обучение чтению в играх

Почему малыш забывает буквы, хотя учил их еще вчера

Обычно, ребенок легко запоминает одни буквы, и не очень другие. Роль взрослого в том, чтобы отмечать то, что не получается у его подопечного и давать дополнительные задания.

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

Эббингауз (почитайте больше об этом в Википедии) изучал как быстро забывается бессмысленная для этого человека информация и пришел к выводу, что за первые двадцать минут забывается 40% информации. А, если невозможно точно сказать что обозначает та или иная буква, то это равносильно тому, что буква незнакома вовсе. Должно быть однозначное 100% узнавание.

Повторять, повторять, повторять

Например, вы тренируете склады (слог, сочетание букв) НА , и ребенок более менее научился распознавать и читать сочетание. Добавьте к заданиям слог НО, и попросите читать слова помогая читать незнакомые еще ребенку буквы. Впрочем, ребенок может сам нажимать на слоги и слушать, как компьютер читает.

Пусть перед нами экран, разбитый на двенадцать клеток, 4 x 3. Клетки отображают дискретность элементов изображения. При фокусировании изображения клетка либо засвечивается, либо нет. "Засветка" определяет единичное значение величины ее возбуждения, "не засветка" - нулевое. Так, буква О определяет засветку клеток, определяемую на рис.2.1 . Буква А засвечивает экран, как показано на рис.2.2 .

Что надо сделать, чтобы некий конструируемый нами прибор мог сказать, какая это буква?

Очевидно, надо все сигналы возбуждения клеток экрана, засвечиваемые буквой О, подать на конъюнктор , реализующий схему И. Единичный сигнал на выходе конъюнктора , как показано на рис.2.1 , сформируется тогда и только тогда, когда засветятся все клетки экрана, на которое ложится изображение буквы О. Наличие единичного сигнала на выходе конъюнктора и определит ответ: "Это буква О".


Рис. 2.1. Обучение букве "О"


Рис. 2.2. Обучение букве "А"

То же необходимо сделать и для буквы А.

Пометим каждую клетку экрана ее координатами. Тогда на языке математической логики сделанное нами можно записать в виде логических высказываний - предикатов :

Эти предикаты определяют "электронное" воплощение методами схемотехники.

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

А если на экран подать букву К? Тогда ни один из двух конъюнкторов не выработает единичное значение, так как не произойдет полное совпадение засветки соответствующих им клеток экрана. Чтобы "научить" систему букве К, необходимо ввести еще один конъюнктор и проделать те же построения, что и выше.

Таким образом, мы можем говорить, что построили систему распознавания двух "правильно" заданных букв.

Но что делать, если буквы на экране пишутся дрожащей рукой? Тогда мы должны разрешить альтернативную засветку каких-то соседних клеток экрана и учитывать это с помощью операции дизъюнкции , ИЛИ. Как известно, в результате выполнения этой операции формируется единичный сигнал в том случае, если на входе есть хоть один единичный сигнал.

Рассмотрим возможность распознавания буквы О, допустив возможность засветки клеток (1,1), (1,3), (4,1), (4,3). Тогда ранее построенный предикат примет вид:

Аналогично, для буквы А допустим засветку клеток (4,1) и (4,3):


Рис. 2.3. Совместное обучение буквам "О" и "А"

Объединив оба предиката, получим схему на рис.2.3 .

Таким образом, мы реализовали для обучения и распознавания "схемотехнический" подход, основанный на применении булевых функций и оперирующий булевыми переменными 0, 1.

Построение логической нейронной сети, обученной распознаванию букв

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

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

Значит, надо уйти от вполне определенных булевых переменных (0, 1, "да - нет", "белое - черное" и т.д.) в сторону неопределенности, достоверности или других оценок информации, - в сторону действительных переменных.

Но тогда необходимо уйти и от булевой алгебры , так как понятия конъюнкции и дизъюнкции для действительных переменных не определены. Тут и приходит на помощь анализ и применение принципов природной реализации - принципов нейронной сети , воплощенных в нашем мозге.

Преобразуем полученную нами обученную схему в нейронную сеть (рис.2.4).

Каждая клетка экрана - это нейрон -рецептор, который в результате засветки обретает некоторую величину возбуждения, принимающую значение между нулем и единицей. Рецепторы , заменившие экран, образуют входной, или рецепторный, слой нейросети. Каждый конъюнктор и дизъюнктор заменим единой для всей сети моделью нейрона . Введем выходной слой сети, состоящий в нашем примере из двух нейронов , возбуждение которых определяет результат распознавания. Назовем нейроны выходного слоя по названиям букв - О и А.

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


Рис. 2.4. Нейронная сеть для распознавания букв "О" и "А"

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

Первоначально находим

Затем положим

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

Знакомство с эйлеровой характеристикой изображения.

Основная идея состоит в том, что берется черно белое изображение, и считая, что 0 это белый пиксель, а 1 это черный пиксель, тогда все изображение будет представлять из себя матрицу из нулей и единиц. В таком случае, черно-белое изображение можно представить как набор фрагментов размером 2 на 2 пикселя, все возможные комбинации представлены на рисунке:

На каждом изображение pic1, pic2, ... изображен красный квадрат шага подсчёта в алгоритме, внутри которого один из фрагментов F с рисунка выше. На каждом шаге происходит суммирование каждого фрагмента, в результате для изображения Original получим набор: , далее он будет называть эйлеровой характеристикой изображения или характеристическим набором.


ЗАМЕЧАНИЕ: на практике значение F0 (для изображения Original это значение 8) не используется, поскольку является фоном изображения. Поэтому будут использоваться 15 значений, начиная с F1 до F15.

Свойства эйлеровой характеристики изображения.

  1. Значение характеристического набора является уникальным, иными словами не существует два изображения с одинаковой эйлеровой характеристикой.
  2. Нет алгоритма преобразования из характеристического набора в исходное изображение, единственный способ - это перебор.

Каков алгоритм распознания текста?

Идея распознания букв заключается в том, что мы заранее вычисляем эйлеровую характеристику для всех символов алфавита языка и сохраняем это в базу знаний. Затем для частей распозноваемого изображения будем вычислять эйлеровую характеристику и искать её в базе знаний.

Этапы распознавания:

  1. Изображение может быть как черно-белым так и цветным, поэтому первым этапом происходит аппроксимация изображения, то есть получение из него черно белого.
  2. Производим попиксельный проход по всему изображению с целью нахождения черных пикселей. При обнаружении закрашенного пикселя запускается рекурсивная операция по поиску всех закрашенных пикселей прилегающий к найденному и последующим. В результате мы получим фрагмент изображения, который может быть как симвом целиком так и часть его, либо "мусором", которые следует отбросить.
  3. После нахождения всех не связанных частей изображения, для каждого вычисляется эйлеровая характеристика.
  4. Далее в работу вступает анализатор, который проходя по каждому фрагменту определяет, есть ли значение его эйлеровой характеристики в базе знаний. Если значение находим, то считаем, что это распознанный фрагмент изображения, иначе оставляем его для дальнейшего изучения.
  5. Нераспознанные части изображения подвергаются эвристическому анализу, то есть я пытаюсь по значению эйлеровой характеристики найти наиболее подходящее значение в базе знаний. Если же найти не удалось, то происходит попытка "склеить" находящиеся неподалеку фрагменты, и уже для них провести поиск результата в базе знаний. Для чего делается "склеивание"? Дело в том, что не все буквы состоят из одного непрерывного изображения, допустим "!" знак восклицания содержит 2 сегмента (палочка и точка), поэтому перед тем как его искать в базе знаний, требуется вычислить суммарное значение эйлеровой характеристики из обоих частей. Если же и после склейки с соседними сегментами приемлемый результат найти не удалось, то фрагмент считам мусором и пропускаем.

Состав системы:

  1. База знаний - файл или файлы изначально созданные мной, либо кем то ещё, содержащие характеристические наборы символов и требуемые для распознования.
  2. Core - содержит основные функции, выполняющие распознавание
  3. Generator - модуль для создания базы знаний.

ClearType и сглаживание.

Итак, на вход мы имеем распозноваемое изображение, и цель из него сделать черно-белое, подходящее для начала процесса распознавания. Казалось бы, чего может быть проще, все белые пиксели считаем за 0, а все остальные остальные 1, но не все так просто. Текст на изображении может быть сглаженным и не сглаженным. Сглаженные символы смотрятся плавными и без углов, а не сглаженные будут выглядеть на современным мониторах с заметными глазу пикселями по контуру. С появлением LCD (жидкокристаллических) экранов были созданы ClearType (для Windows) и другие виды сглаживания, которые пользуясь особенностями матрицы монитора. Меняют цвета пиксели изображения текста, после чего он выглядит намного "мягче". Что бы увидеть результат сглаживания, можно напечатать какую то букву (или текст) к примеру в mspaint , увеличить масштаб, и ваш текст превратилась в какую то разноцветную мозаику.

В чем же дело? Почему на маленьком масштабе мы видим обычный символ? Неужели глаза нас обманываю? Дело в том, что пиксель LCD монитора состоит не из единого пикселя, который может принимать нужный цвет, а из 3 субпикселей 3 цветов, которых хватает для получения нужного цвета. Поэтому цель работы ClearType получить наиболее приятный глазу текст используя особенность матрицы LCD монитора, а это достигается с помощью субпиксельного рендеринга. У кого есть "Лупа" можете, с целью эксперимента, увеличить любое место включенного экрана и увидеть матрицу как на картинке ниже.

На рисунке показан квадрат из 3х3 пикселей LCD матрицы.

Внимание! Данная особенность усложняет получение черно белого изображения и очень сильно влияет на результат, поскольку не всегда даёт возможность получить такое же изображение, эйлеровая характеристика которого сохранена в базу знаний. Тем самым различие изображений заставляет выполнять эвристический анализ, которые не всегда может быть удачным.


Получение черно-белого изображения.

Найденные в интернете алгоритмы преобразования цветного в черно-белое меня не устроили качеством. После их применения, образы символов подвергнутых сублепиксельному рендеренгу, становились разными по ширине, появлялись разрывы линий букв и непонятный мусор. В итоге решил получать черно-белого изображения путем анализа яркости пикселя. Черным считал все пиксели ярче (больше величины) 130 единиц, остальные белые. Данный способ не идеален, и все равно приводит к получению неудовлетворительного результата если меняется яркость текста, но он хотя бы получал схожие со значениями в базе знаний изображения. Реализацию можно посмотреть в классе LuminosityApproximator.

База знаний.

Изначальная задумка наполнения базы знаний была такая, что я для каждой буквы языка подсчитаю эйлеровую характеристику получаемого изображения символа для 140 шрифтов, которые установлены у меня на компьтере (C:\Windows\Fonts), добавлю ещё все варианты типы шрифтов (Обычный, Жирный , Курсив ) и размеры с 8 до 32, тем самым покрою все, или почти все, вариации букв и база станет универсальной, но к сожалению это оказалось не так хорошо как кажется. С такими условиями у меня получилось вот что:

  1. Файл базы знаний получился достаточно большим (около 3 мегабайт) для русского и английского языка. Не смотря на то, что эйлеровая характеристика хранится в виде простой строки из 15 цифр, а сам файл представляет из себя сжатый архив (DeflateStream), который потом распаковывается в памяти.
  2. Около 10 секунд у меня занимает десериализация базы знаний. При этом страдало время сравнения характеристических наборов. Функцию для вычисления GetHashCode() подобрать не получилось, поэтому пришлось сравнивать поразрядно. И по сравнению с базой знаний из 3-5 шрифтов, время анализа текста с базой в 140 шрифтов увеличиволось в 30-50 раз. При этом в базу знаний не сохраняются одинаковые характеристические наборы, не смотря на то, что некоторые символы в разных шрифтах могут выглядеть одинаково и быть схожими даже есть это к примеру 20 и 21 шрифт.

Поэтому пришлось создать небольшую базу знаний, которая идет внутри Core модуля, и даёт возможность проверить функционал. Есть очень серьезная проблема при наполнении базы. Не все шрифты отображают символы небольшого размера корректно. Допустим символ "e" при отрисовке 8 размером шрифта по имени "Franklin Gothic Medium" получается как:

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

Алгоритм поиска символов.

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

Но это идеальная ситуация, мне же в ходе распознования приходилось иметь дело с разобрванными изображениями, которые помимо всего могли иметь и огромное количество мусора, располагаемого рядом с текстом:


На этом изображении слова "yes" попытаюсь объяснить сложность анализа. Будем считать, что это полная строка, но при этом b13 и i6 это фрагменты мусора в результате апроксимации. У символа "y" не хватает точки, и при этом ни один из символов не присутсвует в базе знаний, что бы с уверенностью сказать, что мы имеет дело со строкой текста от "c" до "i" строки. А высота строки нам очень важна, так как для склейки нам нужно знать насколько ближайшие фрагменты стоит "склеивать" и анализировать. Ведь может быть ситуация, что мы нечаянно начнём склеивать символы двух строк и результаты такого распознования будут далеки от идеальных.

Эвристика при анализе образов.


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

  1. Нахожу все характеристические наборы в базе знаний, у которых наибольшее количество значений F фрагментов совпадает с распозноваемым изображением.
  2. Далее выбираю только те характеристические наборы, у которых с распозноваемым изображением по не равным значеним F фрагмента, разница не больше чем на +- 1 единицу: -1 < F < 1. И это все подсчитывается для каждой буквы алфавита.
  3. Затем нахожу символ, который имеет наибольшее число вхождений. Считая его резульатом эвристического анализа.
Этот алгоритм даёт не лучшие результаты на маленьких изображений символов (7 - 12 размер шрифта). Но может быть связанно с тем, что в базе знаний присутсвуют характеристические наборы для схожих изображений разных символов.

Пример использования на языке C#.

Пример начала распознования изображения image. В переменной result будет текст:

var recognizer = new TextRecognizer (container); var report = recognizer.Recognize(image); // Raw text. var result = report.RawText(); // List of all fragments and recognition state for each ones. var fragments = report.Symbols;

Демо проект.

Для наглядной демонстарции работы я написал WPF приложение. Запускается оно из проекта с именем "Qocr.Application.Wpf ". Пример окна с результатом распознования ниже:

Что бы распознать изображение потребуется:

  • Нажимает "New Image" выбирает изображение для распознания
  • Используя режим "Black and White " можно увидить какое изображение будет подвергаться анализу. Если вы видите крайне низкого качества изображение, то не ждите хороших результатов. Что бы улучшить результаты можете попробовать сами написать конвертер цветного изображения в черно белое.
  • Выбираем язык "Language" .
  • Нажимает распознать "Recognize" .
Все фрагменты изображения должны стать помеченными оранжевой или зелёной рамкой.
Пример распознования анлоязычного текста:

Книги Майкла Нильсона "Neural Networks and Deep Learning".


Перевод я разбил на несколько статей на хабре, чтобы было удобнее читать:
Часть 1) Введение в нейронные сети
Часть 2) Построение и градиентный спуск
Часть 3) Реализация сети для распознавания цифр
Часть 4) Немного о глубоком обучении

Введение

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

Простую интуицию - "у 9-тки есть петля сверху, и вертикальный хвост внизу" не так просто реализовать алгоритмически. Нейронные сети используют примеры, выводят некоторые правила и учатся на них. Более того чем больше примеров мы покажем сети, тем больше она узнает о рукописных цифрах, следовательно классифицирует их с большей точностью. Мы напишем программу в 74 строчки кода, которая будет определять рукописные цифры с точностью >99%. Итак, поехали!

Персептрон

Что такое нейронная сеть? Для начала объясню модель искусственного нейрона. Персептрон был разработан в 1950 г. Фрэнком Розенблатом , и сегодня мы будем использовать одну из основных его моделей - сигмоидный персептрон. Итак, как он работает? Персепрон принимает на вход вектор и возвращает некоторое выходное значение .



Розенблат предложил простое правило для вычисления выходного значения. Он ввел понятие "значимости", далее "веса" каждого входного значения . В нашем случае будет зависеть от того, будет ли больше или меньше некоторого порогового значения .



И это все, что нам нужно! Варьируя и вектор весов , можно получить совершенно разные модели принятия решения. Теперь вернемся к нейронной сети.



Итак, мы видим, что сеть состоит из нескольких слоев нейронов. Первый слой называется входным слоем или рецепторами (), следующий слой - скрытый (), и последний - выходной слой (). Условие довольно громоздко, давайте заменим на скалярное произведение векторов . Далее положим , назовем его смещением персептрона или и перенесем в левую часть. Получим:


Проблема обучения

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



Если бы это было возможно, то мы могли бы манипулировать весами в выгодную нам сторону и постепенно обучать сеть, но проблема состоит в том, что при некотором изменение веса конкретного нейрона - его выход может полностью "перевернуться" с 0 на 1. Это может привести к большой ошибке прогноза всей сети, но есть способ обойти эту проблему.

Сигмоидный нейрон

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



Казалось бы, совершенно разные случаи, но я вас уверяю, что персептрон и сигмоидный нейрон имеют много общего. Допустим, что , тогда и, следовательно . Верно и обратное, если , то и . Очевидно, что работая с сигмоидным нейроном мы имеем более сглаженный персептрон. И действительно:


Архитектура нейронных сетей

Проектирование входных и выходных слоев нейросети - достаточно просто занятие. Для примера, предположим, что мы пытаемся определить, изображена ли рукописная "9" на изображении или нет. Естественным способом проектирования сети является кодирование интенсивностей пикселей изображения во входные нейроны. Если изображение имеет размер , то мы имеем входных нейрона. Выходной слой имеет один нейрон, который содержит выходное значение, если оно больше, чем 0.5, то на изображении "9", иначе нет. В то время как проектирование входных и выходных слоев - достаточно простая задача, выбор архитектуры скрытых слоев - искусство. Исследователи разработали множество эвристик проектирования скрытых слоев, например такие, которые помогают скомпенсировать количество скрытых слоев против времени обучения сети.


До сих пор мы использовали нейронные сети, в которых выход из одного слоя - использовался как сигнал для следующего, такие сети называются прямыми нейронными сетями или сетями прямого распространения(). Однако существуют и другие модели нейронных сетей, в которых возможны петли обратной связи. Эти модели называются рекуррентными нейронными сетями (). Рекуррентные нейронные сети были менее влиятельными, чем сети с прямой связью, отчасти потому, что алгоритмы обучения для рекуррентных сетей (по крайней мере на сегодняшний день) менее эффективны. Но рекуррентные сети по-прежнему чрезвычайно интересны. Они гораздо ближе по духу к тому, как работает наш мозг, чем сети с прямой связью. И вполне возможно, что повторяющиеся сети могут решать важные проблемы, которые могут быть решены с большим трудом с помощью сетей прямого доступа.


Итак, на сегодня все, в следующей статье я расскажу о градиентом спуске и обучении нашей будущей сети. Спасибо за внимание!