Участник:Anton goy/Самоорганизующиеся карты Кохонена

Материал из Алговики
Перейти к навигации Перейти к поиску


Автор: Гой Антон, 617 группа.

Свойства и структура алгоритмов

Общее описание алгоритма

Рисунок 1. Структура самоогранизующейся карты Кохонена с шестиугольной решеткой

Самоорганизующаяся карта Кохонена (англ. Self-Organizing Map или сокращено SOM) - это разновидность нейронных сетей, относящаяся к алгоритмам обучения без учителя. Основная цель - найти скрытые закономерности в данных по средством снижения размерности исходного пространства. Важным свойством карт Кохонена является то, что они строят отображение в пространство низкой размерности (обычно двумерное) таким образом, что топология исходного пространства сохраняется. Результат данного отображения - правильная решетка из обученных нейронов - называется "картой" исходного пространства. Алгоритм был разработан известным финским учёным, заслуженным академиком Финской Академии Наук Теуво Кохоненом в 1984(2) году. Карты Кохенана находят успешное применение в задачах кластеризации и визуализации, а также для снижения размерности и детектирования аномалий в данных.

Карты Кохонена и по своей архитектуре, и по методу обучения отличаются от обычных нейронных сетей прямого распространения. C точки зрения метода обучения, карты Кохонена не используют градиентные методы для минимизации ошибки (как это делается в сетях прямого распространения), поскольку являются алгоритмом обучения без учителя и никак не могут учитывать информацию и метках классов. Поэтому нейронная сеть обучается через соревнование между нейронами: на каждом шаге алгоритма для случайного объекта из обучающей выборки выбирается нейрон-победитель (best matching unit, BMU), который в определенном смысле наиболее похож на данный объект.

Рисунок 2б. Топология слоя Кохонена с прямоугольными ячейками
Рисунок 2а. Топология слоя Кохонена с шестиугольными ячейками

А архитектура карты Кохонена (Рис. 1) представляет два слоя: первый слой состоит из входных нейронов (их количество равно размерности исходного пространства), второй слой (его называют слоем Кохонена) представляет собой строго упорядоченную решетку, в узлах которой расположены нейроны-сумматоры, соедененные со всеми входами сети. Для визуализации топологии слоя Кохонена (Рис. 2) используют либо шестиугольные (Рис. 2а), либо прямоугольные (Рис. 2б) ячейки, в которых распологаются нейроны. Шестиугольные ячейки часто являются более предпочтительными, так как расстояние от центра выбранной ячейки до ее соседей одинаково.

Каждый нейрон [math]\displaystyle{ n_j }[/math] слоя Кохонена описывается вектором весов [math]\displaystyle{ \mathbf{w}_j }[/math], размерность которого совпадает с размерностью исходного пространства, и координатами нейрона на двумерной плоскости - [math]\displaystyle{ \mathbf{r}_j }[/math].

Процесс обучения состоит в настройке векторов весов [math]\displaystyle{ \mathbf{w}_j }[/math].

Математическое описание алгоритма

Пусть [math]\displaystyle{ \mathcal{L} = \left\{ \mathbf{x}_i \right\}_{i=1}^{N} }[/math] - некоторое подмножество точек пространства [math]\displaystyle{ \mathbb{R}^D }[/math], [math]\displaystyle{ \mathbf{x}_i = \left( x_{i}^{(1)}, \dots, x_{i}^{(D)} \right) \in \mathbb{R}^D }[/math]. В машинном обучении множество [math]\displaystyle{ \mathcal{L} }[/math] называют обучающей выборкой.

Пусть задано [math]\displaystyle{ L = X \times Y }[/math] общее количество нейронов в слое Кохонена. И каждому нейрону [math]\displaystyle{ n_j }[/math] поствлен в соответствие вектор весов [math]\displaystyle{ \mathbf{w}_{j} = \left( w_{j}^{(1)}, \dots, w_{j}^{(D)} \right) \in \mathbb{R}^D }[/math] и вектор [math]\displaystyle{ \mathbf{r}_j \in \mathbb{R}^2 }[/math], определющий его положение на двумерной плоскости.

Алгоритм обучения (online version):

  1. Задать начальные приближение весов [math]\displaystyle{ \mathbf{w}_{j} }[/math], [math]\displaystyle{ \forall j=1, \dots, L }[/math].
  2. Выбрать случайно номер объекта [math]\displaystyle{ i \sim Unif[1, N] }[/math].
  3. Найти расстояние между объектом [math]\displaystyle{ \mathbf{x}_i }[/math] и всеми векторами весов [math]\displaystyle{ \mathbf{w}_{j} }[/math]: [math]\displaystyle{ \rho(\mathbf{x}_i, \mathbf{w}_{j}) = \left\| \mathbf{x}_i - \mathbf{w}_{j} \right\|^2, \quad \forall j=1, \dots, L }[/math]
  4. Найти нейрон-победитель [math]\displaystyle{ n_b }[/math], [math]\displaystyle{ b = \arg \min_{\forall j \in \{1, \dots, L\}} \rho(\mathbf{x}_i, \mathbf{w}_{j}) }[/math], наиболее близкий к текущему объекту [math]\displaystyle{ \mathbf{x}_i }[/math].
  5. Для всех неронов [math]\displaystyle{ n_j }[/math] пересчитать их веса по следующей формуле: [math]\displaystyle{ \mathbf{w}_{j} \leftarrow \mathbf{w}_{j} + \alpha(t)h_{b, j}(t)(\mathbf{x}_i - \mathbf{w}_{j}) }[/math], где [math]\displaystyle{ \alpha(t) }[/math] - темп обучения (learning rate), монотонно убывающая функция от номера итерации [math]\displaystyle{ t }[/math], [math]\displaystyle{ h_{b, j}(t) }[/math] - функция определяющая "меру соседства" нейронов [math]\displaystyle{ n_b }[/math] и [math]\displaystyle{ n_j }[/math].
  6. Проверить критерий останова. При необходмости перейти на шаг 2.

Данное выше описание является довольно общим и не раскрывает некоторых деталей:

  • Начальное приближение для [math]\displaystyle{ \mathbf{w}_j }[/math]
    • Инициализация случайными значениями. Самый простой способ - [math]\displaystyle{ w_j^{(d)} \sim Unif[0, 1] }[/math]. Данный подход может потребовать большое количество итераций, так как вектора весов неупорядочены и могут находится на значительном расстоянии от точек обучающей выборки.
    • Инициализация объектами обучающей выборки. Данный способ может позволить уменьшить количество итераций, так как вектора весов будут изначально находятся в области пространства, в которой расположены объекты выборки. Но проблема с неупорядоченностью остается.
    • Инициализация при помощи PCA. При помощи PCA находятся первые две главные компоненты [math]\displaystyle{ e_1, e_2 }[/math]. Затем в плоскости натянутой на ветора [math]\displaystyle{ e_1, e_2 }[/math] выбирается регулярная сетка точек, которыми и инициализируются вектора [math]\displaystyle{ \mathbf{w}_j }[/math]. Этот способ является наиболее предпочтительным и на практике показывает хорошие результаты.
  • Задание [math]\displaystyle{ \alpha(t) }[/math]
    • [math]\displaystyle{ \alpha(t) = \alpha_0 \exp \left\{ -\frac{t}{\lambda} \right\} }[/math]
    • [math]\displaystyle{ \alpha(t) = \frac{1}{t} }[/math]
    • [math]\displaystyle{ \alpha(t) = \lambda^{\frac{t}{T}}, \lambda \in (0, 1) }[/math]
  • Задание [math]\displaystyle{ h_{b,j}(t) }[/math]
    • Наиболее популярный способ: [math]\displaystyle{ h_{b,j}(t) = \exp \left\{ - \frac{\| \mathbf{r}_b -\mathbf{r}_j \|^2}{2\sigma(t)^2} \right\} }[/math], где [math]\displaystyle{ \sigma(t) }[/math] - убывающая функция.

Кроме онлайн алгоритма обучения часто на практике применяют более эффективную с точки зрения вычислений batch-версию. Пусть выбрано [math]\displaystyle{ B \in \mathbb{N} }[/math]. Тогда batch-версия алгоритма описывается следующим образом:

Алгоритм обучения (batch version):

  1. Задать начальные приближение весов [math]\displaystyle{ \mathbf{w}_{j} }[/math], [math]\displaystyle{ \forall j=1, \dots, L }[/math].
  2. Случайно выбрать множество [math]\displaystyle{ \mathcal{B} \subset \{1, \dots, N \} }[/math] размера [math]\displaystyle{ B }[/math].
  3. Для каждого объекта [math]\displaystyle{ \mathbf{x}_i }[/math], [math]\displaystyle{ i \in \mathcal{B} }[/math], найти нейрон-победитель [math]\displaystyle{ n_{b(i)} }[/math], где [math]\displaystyle{ b(i) = \arg \min_{\forall j \in \{1, \dots, L\}} \rho(\mathbf{x}_i, \mathbf{w}_{j}) }[/math]
  4. Пересчитать веса для всех нейронов [math]\displaystyle{ \mathbf{w}_j \leftarrow \frac{\sum_{i \in \mathcal{B}}h_{b(i),i}\mathbf{x}_i}{\sum_{i \in \mathcal{B}}h_{b(i),i}} }[/math], [math]\displaystyle{ \forall j=1, \dots, L }[/math].
  5. Проверить критерий останова. При необходимости перейти на шаг 2.

Интерпретация шага 2 состоит в следующем: веса нейронов преставляют собой выпуклую комбинацию объектов с номерами из [math]\displaystyle{ \mathcal{B} }[/math].

Вычислительное ядро алгоритма

Рассмотрим batch-версию алгоритма. Основные вычисления приходятся на шаг 2, где необходимо вычислять расстояния между всеми [math]\displaystyle{ \mathbf{x}_i }[/math], [math]\displaystyle{ i \in \mathcal{B} }[/math] и весами нейронов [math]\displaystyle{ \mathbf{w}_j }[/math], [math]\displaystyle{ j \in \{ 1, \dots, L \} }[/math] и затем искать минимум:

[math]\displaystyle{ d_{ij} = \left\| \mathbf{x}_i - \mathbf{w}_j \right\|^2 = \left\|\mathbf{x}_i\right\|^2 - 2 \mathbf{x}_i^{T}\mathbf{w}_j + \left\|\mathbf{w}_j\right\|^2 }[/math]

Так как нас будет интересовать минимум по [math]\displaystyle{ j }[/math], то первое слагаемое [math]\displaystyle{ \left\|\mathbf{x}_i\right\|^2 }[/math] можно не учитывать. Тогда все что нам нужно это вычислить матрицу квази-расстояний [math]\displaystyle{ \mathbf{D} = \| \hat{d}_{ij} \|_{B \times L} }[/math], где [math]\displaystyle{ \hat{d}_{ij} = \left\|\mathbf{w}_j\right\|^2 - 2 \mathbf{x}_i^{T}\mathbf{w}_j }[/math]

Сложность вычисления [math]\displaystyle{ \mathbf{D} }[/math] составляет [math]\displaystyle{ O\left(L D B \right) }[/math], учитывая что [math]\displaystyle{ \left\|\mathbf{w}_j\right\|^2 }[/math] можно вычислить за один проход по всем нейронам.

Далее поиск минимум в каждой строке матрицы [math]\displaystyle{ \mathbf{D} }[/math] занимает [math]\displaystyle{ O(LB) }[/math]

Макроструктура алгоритма

Пусть [math]\displaystyle{ \mathbf{X}_{\mathcal{B}} }[/math] - матрица, строками которой являются объекты [math]\displaystyle{ \mathbf{x}_i }[/math] таких, что [math]\displaystyle{ i \in \mathcal{B} }[/math], а [math]\displaystyle{ \mathbf{W} }[/math] - матрица, строками которой являются веса нейронов.

Тогда на макроуровне можно выделить следующие операции:

  1. [math]\displaystyle{ \mathbf{D} \leftarrow ComputePairwiseDistances(\mathbf{X}_{\mathcal{B}}, \mathbf{W}) }[/math]
  2. [math]\displaystyle{ \mathbf{b} \leftarrow FindClosestNeurons(\mathbf{D}) }[/math]
  3. [math]\displaystyle{ \mathbf{W} \leftarrow ComputeWeightedSumsAcrossObjects(\mathbf{X}_{\mathcal{B}}, \mathbf{b}_{*}) }[/math]

Здесь мы дали описание макроопераций в терминах функций, возвращающих соответствующии значения.

Функция [math]\displaystyle{ ComputePairwiseDistances }[/math] вычисляет квазирасстояния между объектами и нейронами и возвращает матрицу [math]\displaystyle{ \mathbf{D} \in \mathbb{R}^{B \times L} }[/math].

Функция [math]\displaystyle{ FindClosestNeurons }[/math] в каждой строке матрицы [math]\displaystyle{ \mathbf{D} }[/math] находит минимальное значение и возвращает вектор [math]\displaystyle{ \mathbf{b} \in \mathbb{R}^B }[/math], такой что элемент в позиции [math]\displaystyle{ i }[/math] соответствует номеру нейрона-победителя для объекта [math]\displaystyle{ \mathbf{x}_i }[/math].

Функция [math]\displaystyle{ ComputeWeightedSumsAcrossObjects }[/math] вычисляет новые значения весов для каждого нейрона, суммируя строки матрицы [math]\displaystyle{ \mathbf{X}_{\mathcal{B}} }[/math] с весами пропорциональными их мере соседства с соответствующим нейроном-победителем.