Министерство образования и науки Российской Федерации Калужский филиал федерального государственного бюджетного образовательного учреждения высшего профессионального образования "Московский государственный технический университет имени Н.Э. Баумана" (КФ МГТУ им. Н.Э. Баумана) О Т Ч Е Т ДОМАШНЕЕ ЗАДАНИЕ №2 ДИСЦИПЛИНА:"Нейрокомпьютеры"ТЕМА:" Сеть Кохонена. Деление на кластеры методом к-ближних соседей. " Выполнил: студент гр. ЭВМ-91Салтыков В.С. ____________________ Проверил:Комарцова Л.Г. ____________________ Дата сдачи (защиты) лабораторной работы: Результаты сдачи (защиты): Калуга, 2013 г. Теория Задача классификации заключается в разбиении объектов на классы, причем основой разбиения служит вектор параметров объекта. Сами классы часто бывают неизвестны заранее, а формируются динамически. Назовем прототипом класса объект, наиболее типичный для своего класса. Один из самых простых подходов к классификации состоит в том, чтобы предположить существование определенного числа классов и произволным образом выбрать координаты прототипов. Затем каждый вектор из набора данных связывается с ближайшим к нему прототипом, и новыми прототипами становятся центроиды всех векторов, связанных с исходным прототипом. В качестве меры близости двух векторов обычно выбирается евклидово расстояние: На этих принципах основано функционирование сети Кохонена, обычно используемой для решения задач классификации. Данная сеть обучается без учителя на основе самоорганизации. По мере обучения вектора весов нейронов становятся прототипами классов- групп векторов обучающей выборки. На этапе решения информационных задач сеть относит новый предъявленный образ к одному из сформированных классов. Рассмотрим архитектуру сети Кохонена и правила обучения подробнее. Сеть Кохонена состоит из одного слоя нейронов. Число входов каждого нейрона n равно размерности вектора параметров объекта. Количество нейронов m совпадает с требуемым числом классов, на которые нужно разбить объекты(меняя число нейронов, можно динамически менять число классов). Обучение начинается с задания небольших случайных значений элементам весовой матрицы W. В дальнейшем происходит процесс самоорганизации, состоящий в модификации весов при предъявлении на вход векторов обучающей выборки. Каждый столбец весовой матрицы представляет собой параметры соответствующего нейрона-классификатора. Для каждого j-го нейрона определяется расстояние от него до входного вектора Далее выбирается нейрон с номером k, 1 ≤ k ≤ m , для которого это расстояние минимально(то есть сеть отнесла входной вектор к классу с номером k). На текущем шаге обучения N будут модифицироваться только веса нейронов из окрестности нейрона k: Первоначально в окрестности любого из нейронов находятся все нейроны сети, но с каждым шагом эта окрестность сужается. В конце этапа обучения подстраиваются только веса только нейрона с номером k. Темп обучения с течением времени также уменьшается. Образы обучающей выборки предъявляются последовательно, и каждый раз происходит подстройка весов. Программа. В данной лабораторной работе необходимо решить задачу кластеризации. Отнести точки к существующим областям. Для это рисуем три области и называем их А, В, С Рисунок 1. Рисование областей. Далее рисуем точку. И программа, вычислив расстояние, от точки до центров из каждой областей относит эту точку к области, расстояние между которой является минимальным. Рисунок 2. Отнесение точки к соответствующей области. Исходный код: using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.IO; using System.Linq; namespace Персептрон { public partial class MainWindow { private const int Size = 19; SimpleCell[,] _sensors; private List<AreaParams> _areas; public MainWindow() { InitializeComponent(); } private void WindowLoaded(object sender, RoutedEventArgs e) { _sensors = new SimpleCell[Size, Size]; _areas = new List<AreaParams>(); for (int i = 0; i < Size; i++) { for (int j = 0; j < Size; j++) { var sensor = new SimpleCell(); table.Children.Add(sensor); sensor.SetValue(Canvas.LeftProperty, (double)i * 26 + 3.5); sensor.SetValue(Canvas.TopProperty, (double)j * 26 + 3.5); _sensors[i, j] = sensor; } } } private void ClearButClick(object sender, RoutedEventArgs e) { for (int i = 0; i < Size; i++) { for (int j = 0; j < Size; j++) { _sensors[i, j].Selected = false; } } } private void CheckClick(object sender, RoutedEventArgs e) { if (_areas.Count == 0) { MessageBox.Show("Сначала укажите области!"); return; } int x = 0, y = 0; bool pointFound = false; for (int i = 0; i < Size; i++) { for (int j = 0; j < Size; j++) { if (_sensors[i, j].Selected) { x = i; y = j; pointFound = true; break; } } if (pointFound) break; } if (!pointFound) { MessageBox.Show("Сначала укажите точку!"); return; } ClearButClick(null, null); double minDist = double.MaxValue; AreaParams areaThatThePointBelongsTo = null; foreach (var area in _areas) { double dist = CalculateDistance(x, y, area); if (dist < minDist) { minDist = dist; areaThatThePointBelongsTo = area; } } CalculateDistance(x, y, areaThatThePointBelongsTo); if (areaThatThePointBelongsTo != null) MessageBox.Show("Точка принадлежит области " + areaThatThePointBelongsTo.Name); RecalculateAreasCenter(x, y, areaThatThePointBelongsTo); } private void SaveAreaClick(object sender, RoutedEventArgs e) { if (string.IsNullOrEmpty(AreaName.Text)) { MessageBox.Show("Сначала укажите название области!"); return; } if (_areas.FirstOrDefault(area => area.Name == AreaName.Text) != null) { MessageBox.Show("Область с указанным именем уже существует!"); return; } int minX = Size; int minY = Size; int maxX = 0; int maxY = 0; var xs = new List<int>(); var ys = new List<int>(); for (int i = 0; i < Size; i++) { for (int j = 0; j < Size; j++) { if (_sensors[i, j].Selected) { if (i < minX) minX = i; if (j < minY) minY = j; if (i > maxX) maxX = i; if (j > maxY) maxY = j; xs.Add(i); ys.Add(j); } } } int centerX = (int)xs.Average() + minX; int centerY = (int)ys.Average() + minY; _areas.Add(new AreaParams { Name = AreaName.Text, CenterX = centerX, CenterY = centerY, RadiusX = maxX - minX, RadiusY = maxY - minY }); ClearButClick(null, null); } double CalculateDistance(int x, int y, AreaParams area) { if (area == null) return double.MaxValue; return Math.Sqrt(Math.Pow(x - area.CenterX, 2) + Math.Pow(y - area.CenterY, 2)); } void RecalculateAreasCenter(int x, int y, AreaParams area) { if (area == null) return; if (Math.Abs(x - area.CenterX) > area.RadiusX) { area.CenterX += 2*Math.Sign(x - area.CenterX); area.RadiusX += 1; } if (Math.Abs(y - area.CenterY) > area.RadiusY) { area.CenterY += 2 * Math.Sign(y - area.CenterY); area.RadiusY += 1; } } } public class AreaParams { public string Name; public int CenterX; public int CenterY; public int RadiusX; public int RadiusY; }}
1/--страниц