/*{ * return Task.CompletedTask; * }*/ // установка безусловного рефлекса, будем проводить тупо по прямой от начальной точки до конечной (ставим макс вес если связи нет то создадим ее) // надо подумать хорошо ли так. с одной стороны максимальная скрость реакции с другой очень сложно подавить такой рефлекс условным // договоримся безусловный рефлекс проводить по всем слоям от начальной точки до конечной. при таком варианте получаем возможность подавить на любом уровне // и при желании можно увеличить скорость реакции прокачав более короткую связь (через несколько слоев) обучением // в теории, таким способом мы можем задать очень медленный безусловный рефлекс задав более длинный путь (попетляв по слоям туда сюда) public void SetUnconditionedReflex(List <NCoords> path) { if (!checkNeurons()) { return; } for (var i = 1; i < path.Count; i++) { var beginN = Neurons[path[i - 1].Z][path[i - 1].Y][path[i - 1].X]; var destN = path[i].ToSingle(LenX, LenY); var founded = false; foreach (var output in beginN.Output) { if (output.Neuron == destN) // связь нашли усилим ее до макс и свалим { output.Weight = UNCONDITIONED_REFLEX_WEIGHT; founded = true; break; } } if (!founded) { var o = new NRelation() { Neuron = destN, Weight = UNCONDITIONED_REFLEX_WEIGHT }; o.SetNeuron(Neurons[path[i].Z][path[i].Y][path[i].X]); beginN.Output.Add(o); } } }
// создаем выходные связи для нейрона (рандомно) private List <NRelation> _createOutputForNeuron(int x, int y, int z) { if (NEED_STAT_WEIGHT) { MinWeight = 0; MaxWeight = 0; } var output = new List <NRelation>(); // по оси Z распределение норм тут не надо замыкать последний слой на первый var minZ = z - MAX_DEEP_RELATIONS_Z; if (minZ < 1) { minZ = 1; } var maxZ = z + MAX_DEEP_RELATIONS_Z; if (maxZ > LenZ - 1) { maxZ = LenZ - 1; } // а вот по икс и игрек хотелось бы замкнуть первые нейроны на последние var minY = y - maxDeepRelationsY; /*if (minY < 0) minY = 0;*/ var maxY = y + maxDeepRelationsY; // if (maxY > LenY - 1) maxY = LenY - 1; var minX = x - maxDeepRelationsX; /*if (minX < 0) minX = 0;*/ var maxX = x + maxDeepRelationsX; // if (maxX > LenX - 1) maxX = LenX - 1; /*if (z==0 && y==1 && x==2) * _logger.LogInformation(2111, "NNet _createOutputForNeuron {x}-{xx} {y}-{yy} {z}-{zz}", minX, maxX, minY, maxY, minZ, maxZ); * /**/ for (var zz = minZ; zz <= maxZ; zz++) // первый слой входы (входы исключительно на другие слои) { for (var yy = minY; yy <= maxY; yy++) { for (var xx = minX; xx <= maxX; xx++) { // замыкания по оси икс и игрек var yyy = yy; var xxx = xx; if (yy < 0) { yyy = LenY + yy; } if (yy > LenY - 1) { yyy = yy - (LenY); } if (xx < 0) { xxx = LenX + xx; } if (xx > LenX - 1) { xxx = xx - (LenX); } // связь на себя не допускаем, тока косвенная - через другие нейроны if (x == xxx && yyy == y && z == zz) { continue; } var coords = new NCoords(xxx, yyy, zz); var o = new NRelation() { Neuron = coords.ToSingle(LenX, LenY), Weight = _rand.NextFloat(MIN_INIT_WEIGHT, MAX_INIT_WEIGHT), WeightChange = 0 }; if (NEED_STAT_WEIGHT) { // здесь не надо юзать WeightSum так как WeightChange==0 if (MinWeight > o.Weight) { MinWeight = o.Weight; } if (MaxWeight < o.Weight) { MaxWeight = o.Weight; } } /*if (z == 0 && y == 1 && x == 2) * { * _logger.LogInformation(1111, "NNet _createOutputForNeuron for ({x}, {y}, {z}) => {n} ({xx}, {yy}, {zz})", x, y, z, (new NCoords(xxx, yyy, zz)).ToSingle(LenX, LenY), xxx, yyy, zz); * }/**/ o.SetNeuron(Neurons[zz][yyy][xxx]); output.Add(o); } } } return(output); }