Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

Проблема с нейронной сетью Хопфилда (анализ текста)

#delphi #нейронные_сети #neuralbase


Здравствуйте, товарищи!    

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

Нейронная сеть Хопфилда обучается словам, которые хранятся в ini-файле (слова разбиваются
на буквы, каждая буква представляется уникальной шестизначной последовательностью 1 и 0) 
Каждая буква слова, которое нужно распознать, разбивается на уникальную шестизначную
последовательность 1 и 0
Эти коды букв распознаваемого слова соединяются в кучу и подаются на выходы нейронной
сети хопфилда 
дальше, в идеале, выходные данные должны анализироваться, после чего, нейро сеть
должна выдать наиболее похожий результат из тех, что она "знает" 
Заранее обученная нейронная сеть обратного распространения просматривает, выданные
нейро сетью хапфилда, коды символов и преобразует их в буквы

Однако что-то у меня с сетью  хопфилда не так. Она выбирает одно, какое-то, слово
из обучающей выборки и всегда подставляет его. Чувствую, что я где-то накосячил =/
критику, типа "зачем так мудрить, зачем использовать нейро сеть, бла-бла-бла" фтопку.
собственно код
// Очистить сведения о примерах
NeuralNetHopf1.ResetPatterns;
// Устанавливаем размер вектора для Хопфилда
SetLength(zInputVector, 36);
// Создаем стринглист
Slova:= TStringList.Create;
// Создаем ини файл
IniFile1:= TIniFile.Create('G:\Neural\Project 1\HopfData.ini');
// Заносим слова в стринглист
IniFile1.ReadSection('слова', Slova);

// Пробегаем все слова
for i := 0 to Slova.Count - 1 do
 begin
  f:= 0; // обнуляем элемент вектора
  // Пробегаем каждую букву в слове
  for h := 1 to Length(Slova[i]) do //количество букв в слове
    begin
      // смотрим код буквы и заносим его в вектор
      for z := 0 to 5 do  // z - количество символов буквы. всего 6
        begin
          if Array1[ord(Slova[i][h]), z] = 1 then // в этом массиве хранятся коды
букв. например: буква "а" с анси кодом 1072 имеет личный код 100000
            zInputVector[f]:= 1
          else
            zInputVector[f]:= -1;
          // Переходим на следущее поле вектора
          inc(f); // переходим на след. элемент вектора
        end;
    end;

  // Добавляем пример для выборки
  NeuralNetHopf1.AddPattern(zInputVector);

 end;

// Инициализируем веса
NeuralNetHopf1.InitWeights;

Memo.Lines.Clear;

// подаем сигналы на выходы сети хопфилда
z:= 0;
for I := 1 to Length(Edit1.Text) do
 for h := 0 to 5 do
  begin
    // в массиве коды символов
    if Array1[ord(Edit1.Text[i]), h] = 1 then
      NeuralNetHopf1.Layers[1].Neurons[z].Output := 1
    else
      NeuralNetHopf1.Layers[1].Neurons[z].Output := -1;
  end;

// Запуск процесса распознования
NeuralNetHopf1.Calc;

// получаем результат
for i := 0 to Length(zInputVector) - 1 do
 if NeuralNetHopf1.Layers[1].Neurons[i].Output = -1 then
   Memo.Lines.Add(FloatToStr(0))
 else
   Memo.Lines.Add(FloatToStr(1));

// устанавливаем размер вектора входа для сети обратного распространения
SetLength(xInputVector, NeuralNetExtended1.InputFieldCount);

// считаем, сколько у нас букв в слове (выпендрился)
simbols:= NeuralNetHopf1.Layers[1].NeuronCount / NeuralNetExtended1.InputNeuronCount;

// счетчик строк
h:= 0;
// Вывод результата
for z := 0 to StrToInt(FloatToStr(simbols)) - 1 do
  begin
    // заполняем вектор входа кодом буквы
    for I := 0 to 5 do
      begin
        xInputVector[i] := StrToInt(Memo.Lines[h]);
        inc(h);
      end;
    // Просчитываем
    NeuralNetExtended1.ComputeUnPrepData(xInputVector);
    // Выводим результат
    res:= FloatToStr(NeuralNetExtended1.Output[0]);

    // округляем полученный код буквы
    if (res[6] = '8') or (res[6] = '9') or (res[6] = '7') or (res[6] = '6')then
      res:= IntToStr(StrToInt(copy(res, 1, 4)) + 1)
    else
      res:= copy(res, 1, 4);

    // выводим букву в мемо
    Memo.Lines.Add(chr(strtoint(res)));
  end;
    


Ответы

Ответ 1



А какого типа у вас zInputVector? Если это класс или массив, то это является указателем, т.е. во время первого цикла, где добавляется пример для выборки при изменении значения zInputVector[f], меняются также значения тех, что уже добавлены. Попробуйте после f:= 0; // обнуляем элемент вектора // Пробегаем каждую букву в слове Выделить новую память для zInputVector. Если класс, то zInputVector:=Classname.Create, если другое то New, или getMem, смотря по ситуации. Вроде так. Но не уверен, с нейро сетью Хопфилда не приходилось общяться.

Комментариев нет:

Отправить комментарий