Содержание
Цель работы.. 3
Индивидуальное задание. 3
Выполнение работы.. 4
1. Описание реализованной модели нейронной сети и процедуры ее обучения. 4
Описание нейронной сети. 4
Описание процедуры обучения. 6
2. Описание обучающих данных. 11
3. Численные значения, характеризующие начальное состояние, ход обучения и его результат. 12
4. Графическое представление результатов обучения нейрона. 18
5. Исходный текст программы. 19
Цель работы
Создание программы, реализующей искусственную нейронную сеть; разработка процедуры обучения сети; использование полученных результатов для решения тестовых задач сжатия данных, классификации и аппроксимации.
Индивидуальное задание
Тип нейронной сети: Сеть с самоорганизацией на основе конкуренции
Назначение сети: Классификация данных по алгоритму нейронного газа
Выполнение работы
Описание нейронной сети
Сетями с самоорганизацией называются сети, не требующие для своего обучения «учителя» и самостоятельно адаптирующие свои веса под обучающие данные. Такие сети строятся из нейронов типа WTA и подобных им. Как правило, это однослойные сети, в которых каждый нейрон получает все компоненты входного вектора X размерностью N. На рис. 1 представлена структурная схема такой сети.
Рис. 1. Структурная схема однослойные сети на базе нейронов типа WTA
Основу самоорганизации нейронных сетей составляет закономерность, что глобальной упорядочение сети становится возможным в результате самоорганизации операций, независимо происходящих в различных локальных сегментах сети. В соответствии с поданными на вход сигналами осуществляется активация нейрона, который вследствие изменения значений синоптических весов адаптируется к поступающим обучающим выборкам.
Для сетей с самоорганизацией, основу обучения которых составляет конкуренция между нейронами, обязательным является наличие связей для каждого нейрона со всеми компонентами входного вектора. При активации сети вектором X в конкурентной борьбе побеждает тот нейрон, веса которого в наименьшей степени отличаются от соответствующих компонентов этого вектора.
Для j-того нейрона-победителя соотношение:
d- расстояние между вектором X и . Вокруг нейрона-победителя образуется топологическая окрестность. Все нейроны в пределах этой окрестности подвергаются адаптации по правилу Хопфилда:
Процесс самоорганизации предполагает определение победителя каждого этапа. При инициализации весов сети случайным образом, часть нейронов может оказаться в области правила, в котором отсутствуют данные или их количество ничтожно мало. Эти нейроны имеют мало шансов на победу и адаптацию своих весов, поэтому они остаются мертвыми. Для активации всех нейронов сети в алгоритме обучения необходимо предусмотреть учет побед каждого нейрона с использование либо соседства гауссовского типа, либо так называемого механизма утомления. Также используется механизм штрафов для самых активных нейронов.
Алгоритм нейронного газа
В этом алгоритме на каждой итерации все нейроны сортируются в зависимости от их расстояния до вектора x. После сортировки нейроны размечаются в последовательности, соответствующей увеличению удалённости.
где dk=|x-wm(i)| обозначает удалённость i-того нейрона, занимающего в результате сортировки m-ю позицию в последовательности, возглавляемой нейроном-победителем, которому сопоставлена удаленность d0. Значение функции соседства для i-того нейрона G(i,x) определяется по формуле:
в которой m(i) обозначает очерёдность, полученную в результате сортировки (m(i)=1,2, 3,…,n-1), а лямбда - параметр, аналогичный уровню соседства в алгоритме Кохонена, уменьшающийся с течением времени. При лямбда =0 адаптации подвергается только нейрон-победитель, и алгоритм превращается в обычный алгоритм WTA, но при уточнению подлежат веса многих нейронов, причём уровень уточнения зависит от величины G(i,x).
Для достижения хороших результатов самоорганизации процесс обучения должен начинаться с большого значения лямбда, однако с течением времени его величина уменьшается до нуля.
Описание процедуры обучения
Расширяющийся нейронный газ строит граф, пытаясь приблизить распределение данных. Не связанные подграфы этого графа — это наши искомые кластеры. Он строится по следующему алгоритму:
Рассмотрим этот итерационный алгоритм на примере со следующими данными:
В самом начале построения графа случайным образом задаются первые два нейрона s1 и s2.
После этого начинается итерационный процесс:
2. Выбирается два ближайших нейрона. Они перемещаются на r1 и r2 соответственно ближе к данному элементу, где r1 > r2.
3. Следующие три итерации s2 поменяет свое местоположение сильнее, чем s1. Значит в окрестности s2 большая плотность данных, и нужно создать новый нейрон s3 посередине между s2 и его ближайшим соседом s1. Связь между s1 и s2 удаляется.
4. После еще 3 итераций нейрон s1 никаким образом не изменит своего положения. Значит он не помогает приблизить распределение наших данных. Сначала удаляется его связь с s3, а потом и он сам
5. За следующие 3 итерации мы столкнемся с такой же проблемой, как в пункте 3 и нам понадобится создать s4. В результате получится граф s2-s3-s4, приближающий распределение наших данных
В результате получается граф с несколькими не связанными подграфами, повторяющие распределение наших данных.
В качестве тестовых наборов данных будем рассматриватьсСтандартный набор данных sklearn c двумя полумесяцами:
В результате обучения расширяющийся нейронный газ точно сохранил форму данных всего лишь с 500 элементами, хотя изначальный набор данных состоял из 10000, и точно определил, что здесь два кластера.
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_moons
data, _ = make_moons(10000, noise=0.06, random_state=0)
plt.scatter(*data.T)
plt.show()
import copy
from neupy import algorithms, utils
def draw_image(graph, show=True):
for node_1, node_2 in graph.edges:
weights = np.concatenate([node_1.weight, node_2.weight])
line, = plt.plot(*weights.T, color='black')
plt.setp(line, linewidth=0.2, color='black')
plt.xticks([], [])
plt.yticks([], [])
if show:
plt.show()
def create_gng(max_nodes, step=0.2, n_start_nodes=2, max_edge_age=50):
return algorithms.GrowingNeuralGas(
n_inputs=2,
n_start_nodes=n_start_nodes,
shuffle_data=True,
verbose=True,
step=step,
neighbour_step=0.005,
max_edge_age=max_edge_age,
max_nodes=max_nodes,
n_iter_before_neuron_added=100,
after_split_error_decay_rate=0.5,
error_decay_rate=0.995,
min_distance_for_update=0.01,
)
def extract_subgraphs(graph):
subgraphs = []
edges_per_node = copy.deepcopy(graph.edges_per_node)
while edges_per_node:
nodes_left = list(edges_per_node.keys())
nodes_to_check = [nodes_left[0]]
subgraph = []
while nodes_to_check:
node = nodes_to_check.pop()
subgraph.append(node)
if node in edges_per_node:
nodes_to_check.extend(edges_per_node[node])
del edges_per_node[node]
subgraphs.append(subgraph)
return subgraphs
tils.reproducible()
gng = create_gng(max_nodes=500)
for epoch in range(20):
gng.train(data, epochs=1)
draw_image(gng.graph)
print("Found {} clusters".format(len(extract_subgraphs(gng.graph))))