private color_prior ChangeColorDropout(GameObject neuron, color_prior cp)
    {
        LineRenderer curlr;
        float        no_dropouted_links_perc = 0;
        Vector3      mid_color = new Vector3(0, 0, 0);

        for (int j = 0; j < neuron.transform.childCount; j++)
        {
            curlr = neuron.transform.GetChild(j).GetComponent <LineRenderer>();
            if (curlr.startColor.a > 0.5)
            {
                no_dropouted_links_perc++;
                cp.color         = curlr.startColor;
                cp               = GetNewColor(cp);
                curlr.startColor = cp.color;
                curlr.endColor   = cp.color;
            }
        }
        //neuron's color change depends on it's dropouted links num
        no_dropouted_links_perc /= neuron.transform.childCount;
        //cp.color = curlr.startColor;
        cp.rate = no_dropouted_links_perc;
        cp      = GetNewColor(cp);
        // neuron.GetComponent<Renderer>().material.color = cp.color;
        return(cp);
    }
    private color_prior ChangeColorNeuronsRemoving(GameObject neuron, color_prior cp)
    {
        LineRenderer curlr;
        Color        col;

        if (neuron.transform.childCount > 0)
        {
            if (Random.Range(1, 100) % 3 == 0)
            {
                col = Color.red;
                neuron.GetComponent <Renderer>().material.color = col;
            }
            else
            {
                col = Color.black;
            }
            for (int j = 0; j < neuron.transform.childCount; j++)
            {
                curlr            = neuron.transform.GetChild(j).GetComponent <LineRenderer>();
                curlr.startColor = col;
                curlr.endColor   = col;
            }
        }
        cp.continue_proc = false;
        return(cp);
    }
    private IEnumerator SendNeuronSignalBack(GameObject neuron, int layer_id, float explosing_k, bool is_gradient_exploding = false)
    {
        //cp.color start_color, end_color=1-startcolor, delta=0.1f
        LineRenderer curlr;
        Color        c2             = Color.black;
        color_prior  cp             = new color_prior(Color.black, 0, true, 1);
        float        delta          = 0.1f;
        float        max_brightness = 1;

        explosing_k = Mathf.Pow(explosing_k, layer_id);

        while (cp.continue_proc)
        {
            yield return(new WaitForSeconds(0.1f));

            for (int j = 0; j < neuron.transform.childCount; j++)
            {
                curlr = neuron.transform.GetChild(j).GetComponent <LineRenderer>();

                switch (cp.prior)
                {
                case (0):
                    if (cp.color.r < max_brightness)
                    {
                        cp.color.r += delta;
                    }
                    else
                    {
                        cp.prior = 1;
                    }
                    break;

                case (1):

                    if (cp.color.r > 0)
                    {
                        cp.color.r -= delta * explosing_k;
                        c2.r       += delta * explosing_k;
                    }
                    else
                    {
                        if (!is_gradient_exploding)
                        {
                            curlr.startColor = Color.black;
                            curlr.endColor   = Color.black;
                            cp.color         = Color.black;
                        }
                        cp.continue_proc = false;
                    }

                    break;
                }

                curlr.endColor   = cp.color;
                curlr.startColor = c2;
            }
        }
    }
    private IEnumerator SendNeuronSignalFront(GameObject neuron, int layer_id, float vanishing_k = 0)
    {
        //cp.color start_color, end_color=1-startcolor, delta=0.1f
        LineRenderer curlr;
        Color        c2              = Color.black;
        color_prior  cp              = new color_prior(Color.black, 0, true, 1);
        float        delta_g         = 0.1f;
        float        brightness_perc = Mathf.Pow((1 - vanishing_k), layer_id);
        float        max_brightness  = brightness_perc;

        while (cp.continue_proc)
        {
            yield return(new WaitForSeconds(0.1f));

            for (int j = 0; j < neuron.transform.childCount; j++)
            {
                curlr = neuron.transform.GetChild(j).GetComponent <LineRenderer>();

                switch (cp.prior)
                {
                case (0):
                    if (cp.color.g < max_brightness)
                    {
                        cp.color.g += delta_g * max_brightness;
                    }
                    else
                    {
                        cp.prior = 1;
                    }
                    break;

                case (1):

                    if (cp.color.g > 0)
                    {
                        cp.color.g -= delta_g * max_brightness;
                        c2.g       += delta_g * max_brightness;
                    }
                    else
                    {
                        cp.color         = Color.black;
                        c2               = Color.black;
                        cp.continue_proc = false;
                    }
                    break;
                }


                curlr.startColor = cp.color;
                curlr.endColor   = c2;
            }
        }
    }
    private color_prior ChangeColorUsual(GameObject neuron, color_prior cp)
    {
        LineRenderer curlr;

        cp = GetNewColor(cp);
        //change neuron color the same way as links??
        //neuron.GetComponent<Renderer>().material.color = cp.color;
        for (int j = 0; j < neuron.transform.childCount; j++)
        {
            curlr            = neuron.transform.GetChild(j).GetComponent <LineRenderer>();
            curlr.startColor = cp.color;
            curlr.endColor   = cp.color;
        }
        return(cp);
    }
    public color_prior GetNewColor(color_prior cp)
    {
        switch (cp.prior)
        {
        case (0):
            if (cp.color.r > learning_rate * cp.rate)
            {
                cp.color.r -= learning_rate * cp.rate;
                cp.color.b -= learning_rate * cp.rate;
            }
            else
            {
                cp.prior = 1;
            }
            return(cp);

        case (1):
            if (cp.color.r < (1 - learning_rate * cp.rate))
            {
                cp.color.r += learning_rate * cp.rate;
            }
            else
            {
                cp.prior = 2;
            }
            return(cp);

        case (2):
            if (cp.color.g > learning_rate * cp.rate)
            {
                cp.color.g -= learning_rate * cp.rate;
                cp.color.b -= learning_rate * cp.rate;
            }
            else
            {
                cp.prior = 3;
            }
            return(cp);

        default:
            cp.continue_proc = false;
            return(cp);
        }
    }
    private color_prior ChangeColorWeightDecay(GameObject neuron, color_prior cp)
    {
        LineRenderer curlr;
        Color        col;

        for (int j = 0; j < neuron.transform.childCount; j++)
        {
            curlr = neuron.transform.GetChild(j).GetComponent <LineRenderer>();
            if (Random.Range(1, 100) % 3 == 0)
            {
                col = Color.red;
            }
            else
            {
                col = Color.black;
            }

            curlr.startColor = col;
            curlr.endColor   = col;
        }
        cp.continue_proc = false;
        return(cp);
    }
    public IEnumerator ChangeColor(GameObject neuron)
    {
        if (neuron)
        {
            color_prior cp = new color_prior(Color.gray, 0, true, 1);
            while (cp.continue_proc)
            {
                yield return(new WaitForSeconds(0.1f));

                switch (change_mode)
                {
                case (MODE.USUAL):
                    cp = ChangeColorUsual(neuron, cp);
                    break;

                case (MODE.NEURONSADDING):
                    cp = ChangeColorUsual(neuron, cp);
                    break;

                case (MODE.NEURONSREMOVING):
                    cp = ChangeColorNeuronsRemoving(neuron, cp);
                    break;

                case (MODE.DROPOUT):
                    // cp = ChangeColorDropout(neuron, cp);
                    break;

                case (MODE.WEIGHTDECAY):
                    cp = ChangeColorWeightDecay(neuron, cp);
                    break;

                default:
                    break;
                }
            }
        }
    }