Добрый день уважаемые форумчане... Разбираюсь с нейронными сетями, нашел сгенерированный код не могу понять что он делает , если есть у кого пара минут помогите .. объясните задача написать нейронную сеть для игры например в кости представленный фрагмент выбрасывает всегда или 6 или 1) Код (Delphi): type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); end; TNeuralNetwork = class FWeights: array[0..1] of Double; FLearningRate: Double; function Sigmoid(x: Double): Double; function SigmoidDerivative(x: Double): Double; constructor Create(LearningRate: Double); function Predict(Input: array of Double): Double; // Предсказание результата procedure Train(Input: array of Double; Target: Double); // Обучение function RollDice: Integer; // Эмуляция броска кубика end; var Form1: TForm1; implementation {$R *.dfm} constructor TNeuralNetwork.Create(LearningRate: Double); begin Randomize; FWeights[0] := Random; // Инициализация веса FWeights[1] := Random; // Инициализация веса FLearningRate := LearningRate; end; function TNeuralNetwork.Sigmoid(x: Double): Double; begin Result := 1 / (1 + Exp(-x)); end; function TNeuralNetwork.SigmoidDerivative(x: Double): Double; begin Result := x * (1 - x); end; function TNeuralNetwork.Predict(Input: array of Double): Double; var Sum: Double; begin Sum := FWeights[0] * Input[0] + FWeights[1] * Input[1]; Result := Round(Sigmoid(Sum) * 6); // Умножаем на 6 для предсказания от 1 до 6 if Result < 1 then Result := 1; // Ограничиваем минимум if Result > 6 then Result := 6; // Ограничиваем максимум end; procedure TNeuralNetwork.Train(Input: array of Double; Target: Double); var Output, Error, Delta: Double; begin Output := Predict(Input); // Получаем предсказание Error := Target - Output; // Вычисляем ошибку // Корректируем веса for var i := 0 to High(Input) do begin Delta := Error * SigmoidDerivative(Output); FWeights[i] := FWeights[i] + FLearningRate * Delta * Input[i]; end; end; function TNeuralNetwork.RollDice: Integer; begin Result := Random(6) + 1; // Возвращаем случайное число от 1 до 6 end; procedure TForm1.Button1Click(Sender: TObject); var NN: TNeuralNetwork; Input: array of Double; Target: Integer; Prediction, Prediction1: Integer; Roll: Integer; begin // Создаем нейронную сеть NN := TNeuralNetwork.Create(0.1); // скорость обучения 0.1 // Обучаем сеть на 10 произвольных бросках for var i := 1 to 10000 do begin Roll := NN.RollDice; // Эмулируем бросок Input := [i, Roll]; // Пример входа: номер броска и результат NN.Train(Input, Roll); // Обучение на результате броска end; // Прогнозирование Input := [11, 0.0]; // Пример входа: номер броска и результат 0.0 Prediction :=trunc(NN.Predict(Input)); // Предсказываем результат Prediction1:=round(Prediction); Button2.Caption:='Predicted dice roll: ' + IntToStr(Prediction1); {ReadLn;} // Ожидаем нажатия клавиши end;
Код (Delphi): unit Neural; type NeuralSystem = record countInputNeural: integer; x: array of real; w: array of real; y: real; err: real; procedure Init(countInputNeural: integer); begin Randomize; self.countInputNeural := countInputNeural; x := new real[countInputNeural]; w := new real[countInputNeural]; for var i := 0 to countInputNeural - 1 do w[i] := random(-1, 1); end; function Learn(xInput: array of real; yInput: real): real; begin var yCopy: real; self.err := 0; yCopy := 0; for var i := 0 to countInputNeural - 1 do yCopy += xInput[i] * w[i]; yCopy := 1 / (1 + exp(-yCopy)); self.err := yInput - yCopy; for var i := 0 to countInputNeural - 1 do w[i] += (err * 0.5 * xInput[i]); result := err; end; function Activate(xInput: array of real): real; begin self.y := 0; self.x := xInput; for var i := 0 to countInputNeural - 1 do self.y += self.x[i] * self.w[i]; self.y := 1 / (1 + exp(-self.y)); result := y; end; end; begin end.
Ребзя вопрос Код (Delphi): type TLayer = array of Double; var InputData: array of TLayer; SetLength(InputData, 1000); InputData[I] := [Random(6) + 1, Random(6) + 1]; InputData[I][0] + InputData[I][1] Инпутдата динамический массив к примеру for I :=0 to 1200 InputData[0] и InputData[1] он двухмерный ? я не пойму вроде он одномерный но [0] и InputData[1] это что ? --- Сообщение объединено, 13 окт 2024 --- одномерный вещественный числа в нем представлены [Random(6) + 1, Random(6) + 1] как тогда обработать данные к примеру вывести floatti string / ToString(InputData[nm1] вызывают ругань у компилятора
Двумерный динамический массив вещественных чисел. Для старых версий Delphi код выглядел бы примерно вот так: Код (Delphi): var InputData: array of array of Double; begin SetLength(InputData,1200,2); for i:=Low(InputData) to High(InputData) do begin InputData[i][0]:=Random(6)+1; InputData[i][1]:=Random(6)+1; end; А тут код для версии XE7+ (появились новые возможности для работы с динамическимим массивами) . По этому обрывку ничего непонятно.
FWeightsInputHidden: array of array of Double; FWeightsHiddenOutput: array of array of Double; можно оформить проще как FWeightsInputHidden: array of TLayer; FWeightsHiddenOutput: array of TLayer; ?
Так я понял директива создания двух мерного массива array of array, почему же array of TLayer; создаёт тоже двух мерный? --- Сообщение объединено, 13 окт 2024 --- И объясните плз что возвращает метод nn. Forward
1) Для этого есть отладчик. Просто переключитесь на Debug версию 2) У вас в EnergyNN.pas Код (Pascal): function TNeuralNetwork.Train(Input: DynAR2; Expected: array of Double; EPOCHS:Integer): Double; var HiddenOutputs: array of Double; // Объявлен динамический массив (размерность не определена; нужен SetLength) i, j : Integer; TotalError: Double; begin TotalError := 0; for j := 0 to EPOCHS - 1 do begin TotalError := 0; for i := 0 to High(Input) do begin // Прямой проход for var k := 0 to HIDDEN_NEURONS - 1 do HiddenOutputs[k] := FHiddenLayer[k].FeedForward(Input[i]); // Обращаетесь к k-ому элементу, но у массива нету SetLength
Простите вы правы, не создан массив HiddenOutputs. ... --- Сообщение объединено, 28 окт 2024 --- Помоги плз, немного переделал с математикой что то почему то на выходе числа меньше 0, максимум 1, а должны быть >1000 --- Сообщение объединено, 28 окт 2024 --- я так понимаю все дело в функции активации , но что же делать ? сменить ее ? на какую ?
Не совсем. Чтобы числа были > 1000 можно так же оставить сигмоиду Код (Text): OutputFinal[k] := Sigmoid(OutputFinal[k] + FBiasO[k]); Cyber_Mozg, чтобы числа были > 1000 на выходном слое не надо применять функции активации.
Убрал... OutputFinal[k] := OutputFinal[k] + FBiasO[k]; все равно, мало, Маштабировал Result := OutputFinal[0]*10; результаты чет не очень проверять буду --- Сообщение объединено, 29 окт 2024 --- Ребят, подскажите к примеру у меня сеть с 4 входами, данные у каждого входа отличаются по ращмерности, к примеру время в часа 0-23х, темп от-50 до +50в градусах ,и тд, нужна ли мне нормализация входных данных? --- Сообщение объединено, 29 окт 2024 --- Те выполнить маштабирование, чтобы по каждому входы данные были от 0 до 1
Ты пытаешься обучить НС на типе array of array of Double, проблема из за этого. Это как начать строить дом с чердака
Cyber_Mozg, сначала Inputs, Outputs: Double; Если все работает: Inputs, Outputs: array of Double; Код (Delphi): type NeuralNet = record CInp: integer; InL: array of Double; W1: array of Double; Err: Double; OutL: Double; end; const learning_rate = 0.025; var NN: NeuralNet; procedure UpdateNN(var NN: NeuralNet; InputArr: array of Double); var i: integer; Gradient: double; begin for i := 0 to NN.CInp - 1 do begin Gradient := NN.err * learning_rate * InputArr[i]; NN.W1[i] := NN.W1[i] + Gradient; end; end; //UpdateNN procedure LearnNetwork(var NN: NeuralNet; InputArr: array of Double; Etalon: Double); var i: integer; Output: Double; begin Output := 0; for i := 0 to NN.CInp - 1 do begin Output := Output + InputArr[i] * NN.W1[i]; end; NN.Err := Etalon - Output; UpdateNN(NN, InputArr); Writeln(NN.Err:0:5); end; //LearnNetwork function Predict(var NN: NeuralNet; InputArr: array of Double): Double; var i: integer; begin for i := 0 to NN.CInp - 1 do begin NN.InL[i] := InputArr[i]; end; NN.OutL := 0; for i := 0 to NN.CInp - 1 do begin NN.OutL := NN.OutL + NN.InL[i] * NN.W1[i]; end; Result := NN.OutL; end; //Predict procedure OutputW1(NN: NeuralNet); var i: Integer; begin WriteLn('Weights 1: '); for i := 0 to High(NN.W1) do begin WriteLn(NN.W1[i]:0:5); end; Writeln(''); end; //OutputW1 Сначала делаешь без Biases. Если все нормально, добавляешь Biases, скрытые слои, например. Еще надо следить за весами, чтобы избежать переполнения. Для этого есть L1, L2 регуляризация.