Е.С.Борисов
суббота, 27 сентября 2003 г.
К задаче классификации можно свести много прикладных задач : от оптического распознавания текста до выявление фальшивых кредитных карт и медицинской диагностики. Существует несколько подходов к построению классификаторов. В данной статье рассмотрен классификатор на основе искусственной нейронной сети [1]. При большой размерности нейронной сети, возникает потребность в высокопроизводительных многопроцессорных вычислительных системах [2]. Это особенно важно для классификаторов реального времени, где необходимо получать результат сразу, без существенных задержек. Для многопроцессорных вычислительных систем необходимо создавать специальные программы. В тексте такой программы определяются части (ветки), которые могут выполнятся параллельно, а также алгоритм их взаимодействия. Целью данной работы является построение классификатора для эффективного использования на многопроцессорных вычислительных системах.
Задача, которую мы будем рассматривать в данной статье, это классификация бинарных образов (черно-белых видеоизображений).
Постановку задачи можно сформулировать так : разработать параллельную программу классификации бинарных образов, способную одновременно обрабатывать несколько образов.
Для реализации классификатора будем использовать модели искусственных нейронных сетей.
Искусственная нейронная сеть это совокупность нейронных элементов (рис. 1) и связей между ними [3].
Множество всех нейронов нейронной сети можно разделить на подмножества - т.н. слои. Слой искусственной нейронной сети это множество нейронов на которые в каждый такт времени параллельно поступают сигналы от других нейронов данной сети [3]. Взаимодействие нейронов происходит послойно.
(2) |
На вход классификатора подаются бинарные картинки (рис. 3) размером точек с изображением цифр (), т.е. всего входов. На выходе получаем слово , , т.е. всего 10 выходов. Номер , для которого выход , соответствует номеру класса входного образца.
Важной особенностью искусственной нейронной сети есть возможность её обучения. Процесс обучения сводится к процедуре корректировки весовых коэффициентов. В качестве метода обучения используется правило Видроу-Хоффа [4]:
Таким образом, прежде чем классификатор начнет работать его необходимо обучить на множестве учебных примеров, которое представляет собой множество пар - (картинка, выход сети).
Цикл обучения выглядит так :
Соответственно представленной выше модели, на языке MC# [5][6][7] написан параллельный классификатор бинарных образов.
''Память'' сети это матрица весовых коэффициентов . На этапе инициализации программы порождается начальная сеть. Эта сеть обучается на множестве пар [образ,выход_сети], которые содержатся в двух текстовых файлах : patterns.dat - обучающая выборка, targets.dat - верные выходы для обучающей выборки. Создается рабочая матрица весов, соответствующая [patterns.dat, targets.dat], которая используется, динамически создаваемыми, классификаторами для одновременного распознавания образов из файла tests.dat Таким образом, полученная система может ''читать'' словами.
Классификатор реализуется тремя классами :
// однослойная сеть
class OneLayerNet { . . . }
// персептрон, пороговая функция активации
class Perceptron : OneLayerNet { . . . }
// классификатор, 35 входов, 10 выходов
// распознает бинарные картинки 5x7 точек
class Classificator : Perceptron { . . . }
ParClassificator - класс, реализующий параллельный классификатор. На этапе инициализации программы при помощи конструктора ParClassificator(), на основе содержимого patterns.dat и targets.dat, создается рабочая матрица весов m_weight. Собственно, механизм распараллеливания заключен в двух методах recognize и Get :
Параллельный классификатор ParClassificator осуществляет одновременное распознавание бинарных образов из tests.dat при помощи метода makeTestPar. Этот метод для каждого образа из tests.dat вызывает movable метод recognize и собирает результаты методом Get.
class ParClassificator {
. . .
protected double[,] m_weight;
public ParClassificator() {
Classificator nnet=new Classificator(N);
nnet.teach("patterns.dat","targets.dat");
m_weight=nnet.weight();
. . .
}
. . .
public void makeTestPar(string file) {
. . .
for(i=0;(loadPattern()==1);i++) {
recognize(m_weight,Copy(m_pattern), m_channel );
}
for(int j=0;j<i;j++) { Get(); }
. . .
}
public movable recognize(double [,] W, sbyte[] I, Channel( NeuralIO ) c ) {
Classificator nnet=new Classificator(N);
NeuralIO n=new NeuralIO(IN_SIZE,OUT_SIZE);
n.I(I);
nnet.I(I);
nnet.weight(W);
nnet.step();
n.O(nnet.O());
c(n);
}
public void Get() & Channel m_channel( NeuralIO n ) {
printIn(n.I());
printOut(n.O());
}
}
Данная программа реализует модель распараллеливания по данным - все множество данных для обработки делится на части и распределяется между вычислительными узлами, которые независимо друг от друга по единому алгоритму обрабатывают свои части.
При увеличении количества процессоров, предполагается ускорение
близкое к линейному. Ускорение[8] на процессорах это отношение
Текст программы на MC# [ здесь ]