美文网首页Unity-机器学习
神经网络算法之神经元案例一:制作计算或与运算的神经元

神经网络算法之神经元案例一:制作计算或与运算的神经元

作者: veinsvx | 来源:发表于2018-07-15 08:03 被阅读0次
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
/*有时候我们会自定义一些单独的class/struct, 
 由于这些类并没有从 MonoBehavior 派生所以默认并不被Unity3D识别为可以Serialize的结构。
 自然也就不会在Inspector中显示。
 我们可以通过添加 [System.Serializable]这个Attribute使Unity3D检测并注册这些类为可Serialize的类型。*/
public class TraingSet
{
    public double[] input;
    public double output;
}

public class PercePtron : MonoBehaviour
{
    public TraingSet[] ts;
    double[] weights = { 0, 0 };//输入端的参数
    double bias = 0;//偏差参数
    double totalError = 0;//输出端的错误差值
    /// <summary>
    /// 计算他们的公式
    /// f(x)={1  if w*x+b>0
    ///       0  else
    ///input1*weight1+input2*weight2+bias
    /// </summary>
    /// <param name="v1">输入端参数</param>
    /// <param name="v2">输入端</param>
    /// <returns></returns>
    double DotProductBias(double[] v1, double[] v2)
    {
        if (v1 == null || v2 == null)
            return -1;
        if (v1.Length != v2.Length)
            return -1;
        double d = 0;
        //d=input1*weight1+input2*weight2+bias
        for (int x = 0; x < v1.Length; x++)
        {
            d += v1[x] * v2[x];
        }
        d += bias;
        return d;
    }
    /// <summary>
    /// 计算输出端
    /// </summary>
    /// <param name="i">当前计算的or表达式</param>
    /// <returns></returns>
    double CalcOutPut(int i)
    {
        double dp = DotProductBias(weights, ts[i].input);
        if (dp > 0) return (1);
        return (0);
    }

    /// <summary>
    /// 初始化输入端的参数和偏差参数
    /// </summary>
    void InitialiseWeights()
    {
        for (int i = 0; i < weights.Length; i++)
        {
            weights[i] = Random.Range(-1.0f, 1.0f);
        }
        bias = Random.Range(-1.0f, 1.0f);
    }

    void UpdateWeights(int j)
    {
        double error = ts[j].output - CalcOutPut(j);
        totalError += Mathf.Abs((float)error);
        for (int i = 0; i < weights.Length; i++)
        {
            //根据error的差值信息更新参数的值
            weights[i] = weights[i] + error * ts[j].input[i];
        }
        bias += error;
    }

    void Train(int epochs)
    {
        InitialiseWeights();
        for (int e = 0; e < epochs; e++)
        {
            totalError = 0;
            for (int t = 0; t < ts.Length; t++)
            {
                UpdateWeights(t);
                Debug.Log("W1" + (weights[0]) + "W2" + (weights[1]) + "B:" + bias);
            }
            Debug.Log("TOTAL ERROR:" + totalError);
        }
    }
    void Start()
    {
        Train(8);
    }
}

将上面的脚本添加到场景内的空物体,
然后再将属性栏面板里的数值改成如下形式(此为计算或运算):


属性面板数值.png

然后点击运行按钮,可以看到控制台有类似的输出:


控制台输出结果.png
因为我们是最开始是随机生成的三个参数,所以数值显示可能不同,但是当TOTALERROT为0的时候,即表示最优的三个参数已经得到了,此时可以在
脚本Start()回调函数中,加上如下一句话
        Debug.Log("Test:0 0" + "结果" + CalcOutput(0, 0));
        Debug.Log("Test:0 1" + "结果" + CalcOutput(0, 1));
        Debug.Log("Test:1 0" + "结果" + CalcOutput(1, 0));
        Debug.Log("Test:1 1" + "结果" + CalcOutput(1, 1));

如果你用的是VisualStudio,此时应该会报错,所以你需要写一个CalcOutput()的重载,
和上面代码的差不过,最后应该是这样的。


CalcOutPut的两种重载.png
Start函数中输入数值测试训练结果.png
控制台输出结果.png

目前案例一已经结束了,有点抽象,理解起来可能有些困难。�但是他的核心意思已经表达清楚了。
通过一部分训练数据,训练出最优的参数,当训练出最优的参数之后,这个神经元就可以处理想过的问题了。
目前这还只是一个神经元,并没有组成神经网络,下一个案例将带给大家一个具体点的例子,但是还是只有一个单一的神经元。
今天的内容就是这些,希望能帮助到需要的各位。

相关文章

网友评论

    本文标题:神经网络算法之神经元案例一:制作计算或与运算的神经元

    本文链接:https://www.haomeiwen.com/subject/ucgupftx.html