Моя простая нейронная сеть на java, зацените :)

Денис

Пользователь
#1
Итак как и обещал выставляю на всеобщее ̶о̶с̶м̶е̶я̶н̶и̶е̶ обозрение свою нейронную сеть на Java, которую написал сам, собирая информацию по крупицам в интернете, это моя первая НС, так что не бейте сильно, но если есть замечания по улучшению то буду рад услышать.

Классы ошибок выставлять не стал, они примитивные, можете просто создать пустой собственный.
При создании сети ей в качестве параметров даются количество сенсорных дендритов (входной слой) , вторым параметром будет массив чисел -
Количество чисел в массиве соответствует количеству слоёв включая выходной слой (последний).
Каждое число (массива) соответствует количеству нейронов в слое.
Сеть поддерживает любое количество выходных нейронов.
Тренирующий метод (trainNeuralNetwork(double[][] task, double[][] answ, double learnCoef, double shureness)) принимает на вход:
1. массив заданий.
2. массив ответов (правильных)
3. коефициент обучения.
4. уверенность сети.

Класс нейрона:
Java:
package neyralnetwork;
/**
*
* @author user
*/
public class Neuron implements Serializable {
  
    /**
     * Взвешенная сумма сигналов дендритов
     */
    private double e;
  
    /**
     * Вес дендритов
     */
    private final double[] dendritWeights;
  
    /**
     * Количество дендритов
     */
    private final int dendritCount;
  
    /**
     * Ошибка нейрона
     */
    private double error;
  
    /**
     * Сохраненные сигмоидные сигналы
     */
    private double[] sigmIn;
  
    /**
     * Входной сигнал нейрона смещения
     */
    private double biasIn;
    /**
     * Создаёт нейрон
     * @param dendCoun кількість дендритів з врахуванням нейрону зміщення
     */
    public Neuron(int dendCoun) {
        e=0.0;
        dendritCount = dendCoun;
        dendritWeights = new double[dendritCount];
        error=0.0;
        initiateDenritWeights();
    }
  
    /**
     * Инициирует вес нейронов
     */
    private void initiateDenritWeights(){
        for (int i = 0; i < dendritWeights.length; i++) {
            //dendritWeights[i] = Math.random()<0.5 ? Math.random()*0.3+0.6 : -Math.random()*0.3-0.6;
            dendritWeights[i] = Math.random()<0.5 ? Math.random()*0.3+(15/dendritCount) : -Math.random()*0.3-(15/dendritCount);
        }
    }
  
    /**
     * Получает сигналы на дендриты с нейронов предыдущего слоя
     * @param dendSygn сигмоидные сигналы на дендриты
     * @param bias сигнал нейрона смещения
     */
    public void takeDendSygnals(double[] dendSygn,double bias){
        //+1 тому що сигнали дендритів надсилаються без врахування нейрону зміщення
        if(dendSygn.length+1!=dendritCount)throw new NotMatchSygnDendCount();
        sigmIn=dendSygn;
        biasIn=bias;
        e=0.0;
        //важливо щоб перебирались вхідні сигнали
        for (int i = 0; i < dendSygn.length; i++) {
            e+=dendSygn[i]*dendritWeights[i];
        }
        e+=bias*dendritWeights[dendritCount-1];
    }
  
    /**
     * Сигмоидный сигнал
     * @return сигмоиду сигнала
     */
    public double giveSigmSignal(){
        return 1/(1+Math.exp(-e));
    }
  
    /**
     * Принимает ошибку
     * @param err ошибка
     */
    public void takeError(double err){
        error=err;
    }
  
    /**
     * Раздает ошибки
     * @return ошибки
     */
    public double[] giveErrors(){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        //-1 нейрону зміщення не потрібна помилка
        double[] errors = new double[dendritCount-1];
        //-1 нейрону зміщення не потрібна помилка
        for (int i = 0; i < dendritCount-1; i++) {
            errors[i] = error*dendritWeights[i];
        }
        return errors;
    }
  
    /**
     * Исправляет веса
     * @param learnCoef коефициент обучения
     */
    public void fixWeight(double learnCoef){
        //-1 тому що нейрон зміщення виправляється окремо
        for (int i = 0; i < dendritCount-1; i++) {
            dendritWeights[i]+=sigmIn[i]*learnCoef*giveSigmSignal()*(1-giveSigmSignal())*error;
        }
        dendritWeights[dendritCount-1]+=biasIn*learnCoef*giveSigmSignal()*(1-giveSigmSignal())*error;
    }
  
  
    /**
     * Раcпечатывает состояние нейрона
     */
    public void printNeyron(){
        System.out.println("Dendrit count - "+dendritCount);
        int cnt = 0;
        for (double dendritWeight : dendritWeights) {
            System.out.println("dnd #"+cnt+" - "+dendritWeight);
            cnt++;
        }
    }
}
 
Последнее редактирование:

Денис

Пользователь
#2
Класс слоя нейронов:
Java:
package neyralnetwork;

/**
*
* @author user
*/
public class Layer implements Serializable{
   
    /**
     * Массив нейронов слоя
     */
    private final Neuron[] neyrons;
   
    /**
     * Нейрон смещения
     */
    private final double bias;
   
    /**
     * Количество нейронов в слое
     */
    private final int neyronCount;
   
    /**
     * Количество нейронов в предыдущем слое
     */
    private final int prewNeuronCount;
    /**
     * Конструктор слоя
     * @param neuCount количество нейронов в слое
     * @param prewNeyCount количество нейронов в предыдущем слое
     */
    public Layer(int neuCount, int prewNeyCount) {
        neyronCount = neuCount;
        prewNeuronCount = prewNeyCount;
        neyrons = new Neuron[neyronCount];
        initiateNeyrons(prewNeyCount);
        bias = Math.random() < 0.5 ? -1.0 : 1.0;
    }
   
    /**
     * Инициализация нейронов
     * @param prewNeyCount количество нейронов в предыдущем слое
     */
    private void initiateNeyrons(int prewNeyCount){
        for (int i = 0; i < neyronCount; i++) {
            //+1 дендрит на нейрон зміщення
            neyrons[i] = new Neuron(prewNeyCount+1);
        }
    }
   
    /**
     * Отправляет сигналы нейронов слоя(текущего) в следующий слой
     * @return сигналы нейронов
     */
    public double[] giveSygnals(){
        double[] sygnals = new double[neyronCount];
        for (int i = 0; i < neyronCount; i++) {
            sygnals[i] = neyrons[i].giveSigmSignal();
        }
        /*int count=0;
        for (double sygnal : sygnals) {
            System.out.println("neyron #"+count+" sygn - "+sygnal);
            count++;
        }*/
        return sygnals;
    }
   
    /**
     * Принимает сигналы предыдущего слоя
     * @param sygnals сигналы предыдущего слоя
     */
    public void acceptSygnals(double[] sygnals){
        //if(sygnals.length!=neyrons.length) throw new NotMatchNeyronSygnCount();
        for (Neuron neyron : neyrons) {
            neyron.takeDendSygnals(sygnals, bias);
        }
    }
   
    /**
     * Принимает ошибки
     * @param errs ошибки
     */
    public void acceptErrors(double[] errs){
        if(neyrons.length!=errs.length) throw new NotMatchNeyronSygnCount();
        for (int i = 0; i < neyronCount; i++) {
            neyrons[i].takeError(errs[i]);
        }
    }
   
    /**
     * Передаёт ошибки следующему слою
     * @return ошибки
     */
    public double[] giveErrors(){
        /*double[][] layErr = new double[neyronCount][];
        for (int i = 0; i < neyronCount; i++) {
            layErr[i]=neyrons[i].giveErrors();
        }
        return layErr;*/
        double[] layErrs = new double[prewNeuronCount];
        for (int i = 0; i < prewNeuronCount; i++) {
            for (int j = 0; j < neyronCount; j++) {
                layErrs[i]+=neyrons[j].giveErrors()[i];
            }
        }
        return layErrs;
    }
   
    /**
     * Исправляет веса
     * @param learnCoef коефициент обучения
     */
    public void fixWeights(double learnCoef){
        for (Neuron neyron : neyrons) {
            neyron.fixWeight(learnCoef);
        }
    }
   
    /**
     * Метод распечатывает слой
     */
    public void printLayer(){
        System.out.println("neyCount - "+neyronCount);
        System.out.println("bias - "+bias);
        int cnt=0;
        for (Neuron neyron : neyrons) {
            System.out.println("");
            System.out.println("Neyron #"+cnt);
            neyron.printNeyron();
            cnt++;
        }
    }
   
}
 
Последнее редактирование:

Денис

Пользователь
#3
Главный класс
Java:
package neyralnetwork;

import java.io.Serializable;
import java.util.ArrayList;
import javafx.concurrent.Task;
/**
 *
 * @author user
 */
public class NeuralNetwork extends Task<Void> implements Serializable {
   
    private double[][] taskSave;
   
    private double[][] answerSave;
   
    private double learnCoefSave;
    
    private double shurenessSave;
   
    /**
     * Количество слоёв
     */
    private final int layersCount;
   
    /**
     * Количество сенсорных дендритов
     */
    private double[] sensors;
   
    /**
     * Массив слоёв
     */
    private final Layer[] layers;
   
    //private final Label label;
    /**
     * Конструктор нейронной сети
     * @param sens количество сенсорных нейронов
     * @param networkMap карта нейронной сети
     */
    public NeuralNetwork(int sens,int[] networkMap/*, Label lbl*/) {
        sensors=new double[sens];
        layersCount=networkMap.length;
        layers = new Layer[networkMap.length];
        initiateLayers(networkMap);
        //label = lbl;
    }
    /**
     * Инициализирует слои
     * @param networkMap карта слоёв
     */
    private void initiateLayers(int[] networkMap) {
        layers[0] = new Layer(networkMap[0], sensors.length);//винести окремо змінну?
        for (int i = 1; i < layersCount; i++) {
            layers[i] = new Layer(networkMap[i], networkMap[i-1]);
        }
    }
   
    /**
     * Получает ответ сети по указанному заданию
     * @param task задание
     * @return відповідь
     */
    public double[] getAnswer(double[] task){
        if(task.length!=sensors.length) throw new NotMatchNeyronSygnCount();
        sensors=task;
        /*for (int i = 0; i < sensors.length; i++) {//винести окремо змінну?
            sensors[i]=task[i];
        }*/
        return getAnswer();
    }
   
    /**
     * Получает ответ сети по предустановленному заданию(вопросу)
     * @return ответ
     */
    public double[] getAnswer(){
        layers[0].acceptSygnals(sensors);
        for (int i = 1; i < layersCount; i++) {
            layers[i].acceptSygnals(layers[i-1].giveSygnals());
        }
        return layers[layers.length-1].giveSygnals();
    }
   
    /**
     * Тренировка нейронной сети
     * @param task подборка заданий
     * @param answ подборка ответов
     * @param learnCoef коефициент обучения
     * @param shureness уверенность сети
     */
    public void trainNeuralNetwork(double[][] task, double[][] answ, double learnCoef, double shureness){
        if(task.length!=answ.length) throw new NotMatchTaskAnswCount();
        boolean glError;
        //int cykles = 0;
        double totalErr;
        do{
            totalErr=0;
            glError=false;
            for (int i = 0; i < task.length; i++) {
                if(task[i].length!=sensors.length) throw new NotMatchTaskAnswCount();
                double[] errors = getErrors(answ[i], getAnswer(task[i]));
                totalErr+=getTotalError(errors);
                if(isError(shureness, errors)){
                    backpropagateAndFix(errors,learnCoef);
                    glError=true;
                }
            }
            System.out.println("total error - "+totalErr);
            updateMessage("number - "+totalErr);
        }while(glError);
    }
   
    /**
     * Устанавливает параметры обучения сети
     * @param ts задания
     * @param an ответы
     * @param sh уверенность сети
     * @param lc коефициент обучения
     */
    public void setParameters(double[][] ts, double[][] an, double lc, double sh){
        taskSave = ts;
        answerSave = an;
        shurenessSave = sh;
        learnCoefSave = lc;
    }
   
    /**
     * Начинает обучение сети если данные загружены
     */
    public void startLearn(){
        if(taskSave==null&&answerSave==null)return;// доповнити перевіркою коефіціенту навчання і впевненості !!!!!!!!!!!!!!!!!!!!!!!!!!!!
        trainNeuralNetwork(taskSave, answerSave, learnCoefSave, shurenessSave);
    }
   
    @Override
    protected Void call() {
        startLearn();
        return null;
    }
    /**
     * Возвращает ошибки
     * @param rigthAnswers правильные ответы
     * @param answers ответы сети
     * @return ошибки
     */
    public double[] getErrors(double[] rigthAnswers, double[] answers){
        if(rigthAnswers.length!=answers.length) throw new NotMatchTaskAnswCount();
        double[] errs = new double[rigthAnswers.length];
        for (int i = 0; i < rigthAnswers.length; i++) {
            errs[i] = rigthAnswers[i]-answers[i];
        }
        return errs;
    }
   
    /**
     * Подсчитывает суммарную ошибку эпохи
     * @param err все ошибки
     * @return суммарная ошибка
     */
    public double getTotalError(double[] err){
        double totalErr=0;
        for (double d : err) {
            totalErr+=Math.abs(d);
        }
        return totalErr;
    }
   
    /**
     * Проверяет есть ли ошибка в ответе сети
     * @param shureness уверенность сети
     * @param errors ошибки
     * @return ответ есть ли ошибка
     */
    public boolean isError(double shureness,double[] errors){
        boolean isErr=false;
        for (double error : errors) {
            isErr = isErr ? true : Math.abs(error)>shureness;
        }
        return isErr;
    }
   
    /**
     * Обратное распространение ошибок
     * @param errs ошибки
     */
    private void backPropagateErrors(double[] errs){
        layers[layersCount-1].acceptErrors(errs);
        for (int i = layersCount-1; i > 0; i--) {
            layers[i-1].acceptErrors(layers[i].giveErrors());
        }
    }
   
    /**
     * Исправление весов
     * @param learnCoef коефициент обучения
     */
    private void fixWeights(double learnCoef){
        for (int i = layers.length-1; i > -1; i--) {
            layers[i].fixWeights(learnCoef);
        }
    }
   
    /**
     * Обратное распространение ошибок и исправление весов
     * @param errs ошибки
     * @param learnCoef коефициент обучения
     */
    private void backpropagateAndFix(double[] errs, double learnCoef){
        backPropagateErrors(errs);
        fixWeights(learnCoef);
    }
   
    /**
     * Распечатывает слой нейронов
     */
    public void printNN(){
        System.out.println("Layers count - "+layersCount);
        System.out.println("sensors count - "+sensors.length);
        int count = 0;
        for (Layer layer : layers) {
            System.out.println("");
            System.out.println("Layer #"+count);
            layer.printLayer();
            count++;
        }
    }
   
}
Извиняюсь за сумбурность, если есть вопросы - задавайте.
 
Последнее редактирование:

CMTV

Администратор
Команда форума
#5
Правда, лучше вам еще раз перепроверить, правильно ли сохранился код. Возможно, при редактировании сообщений что-то могло испортиться.
 
#6
Главный класс
Java:
package neyralnetwork;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
    *
    * @author user
    */
public class NeyralNetworkApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction((ActionEvent event) -> {
            System.out.println("Hello World!");
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        /*Neuron n1 = new Neuron(5);
    n1.printNeyron();

    Layer lr1 = new Layer(4, 5);

    lr1.printLayer();*/

        NeuralNetwork nn1 = new NeuralNetwork(4, new int[]{3,2,1});

        nn1.printNN();

        //выборка с определённой логикой (я уже забыл условия но сеть всеравно даёт правильный ответ :)))
        //МОЖЕТЕ ЗАКОММЕНТИРОВАТЬ НА СВОЙ ВКУС ЛЮБЫЕ ОДНУ ИЛИ ДВЕ ПАРЫ (ОТВЕТ-ВОПРОС), СЕТЬ СПРАВЛЯЕТСЯ.
        double[][] task1 = {
            {1.0,0.0,0.0,0.0},
            {0.0,1.0,0.0,0.0},
            {1.0,1.0,0.0,0.0},
            {0.0,0.0,1.0,0.0},
            {1.0,0.0,1.0,0.0},
            {0.0,1.0,1.0,0.0},
            {1.0,1.0,1.0,0.0},
            {0.0,0.0,0.0,1.0},
            //тестовые вопросы намеренно изымаются из обучающей выборки
            //чтобы создать ситуацию в которой сеть будет сама делать выводы
            //{1.0,0.0,0.0,1.0},
            //{0.0,1.0,0.0,1.0},
            {1.0,1.0,0.0,1.0},
            {0.0,0.0,1.0,1.0},
        };

        //ответы
        double[][] answ1 = {
            {1.0},
            {0.0},
            {0.0},
            {0.0},
            {0.0},
            {1.0},
            {1.0},
            {1.0},
            //ответы сеть должна угадать сама
            //{1.0},//ожидаемый ответ 1
            //{0.0},//ожидаемый ответ 2
            {0.0},
            {0.0},
        };


        nn1.trainNeuralNetwork(task1, answ1, 0.5, 0.05);

        System.out.println("Ожидаемый ответ 1 - 1");
        System.out.println("Ожидаемый ответ 2 - 0");
        System.out.println("Ответ 1 - "+nn1.setTask(new double[]{1.0,0.0,0.0,1.0})[0]);
        System.out.println("Ответ 2 - "+nn1.setTask(new double[]{0.0,1.0,0.0,1.0})[0]);

        /*nn1.printNN();

    NeuralNetwork nn2 = new NeuralNetwork(2, new int[]{3,1});

    double[][] task2 = {
    {0.0,0.0},
    {0.0,1.0},
    {1.0,0.0},
    {1.0,1.0},
    };

    double[][] answ2 = {
    {0.0},
    {1.0},
    {1.0},
    {0.0},
    };

    nn2.trainNeuralNetwork(task2, answ2, 0.9, 0.2);

    System.out.println("nn2 - "+nn2.setTask(task2[0])[0]);
    System.out.println("nn2 - "+nn2.setTask(task2[1])[0]);
    System.out.println("nn2 - "+nn2.setTask(task2[2])[0]);
    System.out.println("nn2 - "+nn2.setTask(task2[3])[0]);*/

        /*NeuralNetwork nn3 = new NeuralNetwork(7, new int[]{5,1});

    double[][] task3 = {
    {0.0,0.4,0.0,0.1,0.0,0.0,0.8},
    {0.7,0.0,0.4,0.0,0.1,0.0,0.0},
    {0.0,0.7,0.0,0.4,0.0,0.1,0.0},
    {1.0,0.0,0.7,0.0,0.4,0.0,0.1},
    {0.0,1.0,0.0,0.7,0.0,0.4,0.0},
    {0.0,0.0,1.0,0.0,0.7,0.0,0.4},
    {0.3,0.0,0.0,1.0,0.0,0.7,0.0},
    {0.0,0.3,0.0,0.0,1.0,0.0,0.7},
    {0.6,0.0,0.3,0.0,0.0,1.0,0.0},
    {0.0,0.6,0.0,0.3,0.0,0.0,1.0},
    {0.9,0.0,0.6,0.0,0.3,0.0,0.0},
    {0.0,0.9,0.0,0.6,0.0,0.3,0.0},
    {0.0,0.0,0.9,0.0,0.6,0.0,0.3},
    {0.2,0.0,0.0,0.9,0.0,0.6,0.0},
    {0.0,0.2,0.0,0.0,0.9,0.0,0.6},
    {0.5,0.0,0.2,0.0,0.0,0.9,0.0},
    {0.0,0.5,0.0,0.2,0.0,0.0,0.9},
    {0.8,0.0,0.5,0.0,0.2,0.0,0.0},
    {0.0,0.8,0.0,0.5,0.0,0.2,0.0},
    {0.0,0.0,0.8,0.0,0.5,0.0,0.2},
    {0.1,0.0,0.0,0.8,0.0,0.5,0.0},
    {0.0,0.1,0.0,0.0,0.8,0.0,0.5},
    {0.4,0.0,0.1,0.0,0.0,0.8,0.0},
    };

    double[][] answ3 = {
    {0.0},{0.8},{0.0},{0.0},{0.1},{0.0},{0.4},{0.0},{0.7},{0.0},{1.0},{0.0},{0.0},{0.3},{0.0},{0.6},{0.0},{0.9},{0.0},{0.0},{0.2},{0.0},{0.5}
    };


    nn3.trainNeuralNetwork(task3, answ3, 0.6, 0.02);

    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[0])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[1])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[2])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[3])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[4])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[5])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[6])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[7])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[8])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[9])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[10])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[11])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[12])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[13])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[14])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[15])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[16])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[17])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[18])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[19])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[20])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[21])[0]));
    System.out.println("time is 12 hours "+takeTime(nn3.setTask(task3[22])[0]));*/


        launch(args);
    }
    public static String takeTime(double d){
        int tm = (int)Math.round(d*10);
        if(tm==0)return "no events";
        return ""+(6*tm)+" min";
    };
}
Извиняюсь за сумбурность, если есть вопросы - задавайте.

Не могу понять, что именно делает эта НС
 

Денис

Пользователь
#7
Не могу понять, что именно делает эта НС
Говоря простыми словами, она делает выводы, это простейшая feed forward нейронная сеть - скармливаешь ей кучу примеров с правильными ответами, даёшь ей вопрос (задание которое она не знала заранее) получаешь ответ (вывод на основе загруженных в неё ранее примеров.
Такие НС могут предсказывать колебания курсов валют, распознавать изображения, в комбинации с генетическим алгоритмом могут управлять например мышцами скелета для хотьбы, проходить игры, водить автомобиль, и т. д.
 
Последнее редактирование:

JaT

Новичок
#9
Вы уверены что код корректен?
dendritWeights = Math.random()<0.5 ? Math.random()*0.3+(15/dendritCount) : -Math.random()*0.3-(15/dendritCount);
Тут, например, ты пытаешься присвоить массиву double числовое значение. Может должно быть так: "dendritWeights[ i ]"?

double[] errors = getErrors(answ, setTask(task));
Тут пытаешься вызвать "setTask" передав ему двумерный массив "task", хотя "setTask" должен принимать одномерный массив.

И по ходу кода много таких мелких проблем, в итоге компилировать и запустить не выйдет.
Очень заинтересовала такая простая и лаконичная реализация, хочу опробовать на деле. Есть возможность получить ссылку с корректным кодом, например, на github?

P.S. Пока печатал обнаружил, что форум обрезает "[ ]", тогда причина проблем с отображением кода ясна.
 

CMTV

Администратор
Команда форума
#10
P.S. Пока печатал обнаружил, что форум обрезает "[ ]", тогда причина проблем с отображением кода ясна.
Скорее всего это из-за того, что изначально код был выложен без обрамления в тег [code]. Получается, что он принимал эти скобки за теги сообщения форума.
 

JaT

Новичок
#11
Скорее всего это из-за того, что изначально код был выложен без обрамления в тег [code]. Получается, что он принимал эти скобки за теги сообщения форума.
Да, тут целая цепочка действий, которая к этому привела. Подождем автора, надеюсь поправит)
 

Денис

Пользователь
#12
Да, тут целая цепочка действий, которая к этому привела. Подождем автора, надеюсь поправит)
Спасибо за замечание, поправлю на ближайших выходных. Действительно, когда я выкладывал код – текстового редактора как сейчас не было.
 

Денис

Пользователь
#13
Да, тут целая цепочка действий, которая к этому привела. Подождем автора, надеюсь поправит)
Скорее всего это из-за того, что изначально код был выложен без обрамления в тег [code]. Получается, что он принимал эти скобки за теги сообщения форума.
Исправил. Выпилил из него интерфейс за ненадобностью, следовательно он стал "чище", добавил возможность следить за прогрессом обучения через интерфейс, сейчас работаю над сетью анализирующей текст и создающей собственный, подробности здесь:
Как нейросети пишут стихи?