Пример #1
0
    /// <summary>
    /// 保存したデータを基に学習開始
    /// </summary>
    public bool Learning(bool isNowTrain)
    {
        //データが無いなら学習しない
        if (situationDatas.Get().Count == 0 && isNowTrain == false)
        {
            return(false);
        }

        isTrain = isNowTrain;

        if (isNowTrain)
        {
            isTrain = nn.Train(epochs, learningRate, isNowTrain);
        }
        else
        {
            nn.InputData(situationDatas, teachDatas);

            //入っているデータを削除
            situationDatas = new NumYArray();
            teachDatas     = new NumYArray();

            isTrain = nn.Train(epochs, learningRate, isNowTrain);
        }

        if (!isTrain)
        {
            nn.SaveLearningData(charName + "/");
        }

        return(isTrain);
    }
Пример #2
0
    /// <summary>
    /// 意思決定
    /// </summary>
    public int DecideIntention()
    {
        NumYArray xData = new NumYArray();

        xData.Add(situation);
        //ニューラルネットワークによる結果表示
        NumYArray            resultArray = new NumYArray(nn.Predict(xData));
        List <List <float> > resultList  = resultArray.Get();

        //ランダムによる意思決定
        float n      = Random.Range(0.0f, NumY.Sum(resultArray).Get()[0][0]);
        float offset = 0.0f;

        for (int i = 0; i < resultList[0].Count; i++)
        {
            offset += resultList[0][i];
            if (n <= offset)
            {
                intention = i;
                break;
            }
        }

        return(this.intention);
    }
Пример #3
0
    //予測結果のデバッグ表示
    public void DisplayPredict(NumYArray data)
    {
        string[] name = new string[] { "立ち弱", "立ち強", "しゃがみ弱", "しゃがみ強", "波動", "昇竜",
                                       "ガード", "しゃがみガード", "前進", "後退", "ダッシュ", "ジャンプ", "前ジャンプ", "後ジャンプ" };

        for (int i = 0; i < name.Length; i++)
        {
            Debug.Log(name[i] + " : " + Mathf.Round(data.Get()[0][i] * 100) / 100);
        }
    }
Пример #4
0
    public NumYArray(NumYArray n)
    {
        array = new List <List <float> >();
        List <List <float> > nArray = n.Get();

        for (int i = 0; i < nArray.Count; i++)
        {
            array.Add(new List <float>());
            List <float> subList = nArray[i];
            for (int j = 0; j < subList.Count; j++)
            {
                array[i].Add(subList[j]);
            }
        }
    }
Пример #5
0
    /// <summary>
    /// 行列の積を求める
    /// </summary>
    /// <param name="a">自作行列</param>
    /// <param name="b">自作行列</param>
    /// <returns>計算された自作行列</returns>
    public static NumYArray Dot(NumYArray a, NumYArray b)
    {
        int[] sizeA = a.Size;
        int[] sizeB = b.Size;

        NumYArray copyA = new NumYArray(a);
        NumYArray copyB = new NumYArray(b);

        List <List <float> > arrayA = copyA.Get();
        List <List <float> > arrayB = copyB.Get();
        List <List <float> > array  = new List <List <float> >();

        //配列の要素確保
        for (int i = 0; i < sizeA[0]; i++)
        {
            array.Add(new List <float>());
            for (int j = 0; j < sizeB[1]; j++)
            {
                array[i].Add(0);
            }
        }

        //行列の内積計算
        if (sizeA[1] == sizeB[0])
        {
            for (int i = 0; i < array.Count; i++)
            {
                for (int j = 0; j < array[i].Count; j++)
                {
                    float term = 0;
                    for (int k = 0; k < sizeA[1]; k++)
                    {
                        term += arrayA[i][k] * arrayB[k][j];
                    }
                    array[i][j] = term;
                }
            }
        }
        else
        {
            //Debug.Log("Error : Argument size does not match.");
        }

        NumYArray returnArray = new NumYArray(array);

        return(returnArray);
    }
Пример #6
0
    /// <summary>
    /// シグモイド関数による計算
    /// </summary>
    /// <param name="a">自作配列</param>
    /// <returns>計算された自作配列</returns>
    public static NumYArray Sigmoid(NumYArray a)
    {
        NumYArray            copyArray = new NumYArray(a);
        List <List <float> > array     = copyArray.Get();

        for (int i = 0; i < array.Count; i++)
        {
            for (int j = 0; j < array[i].Count; j++)
            {
                array[i][j] = 1 / (1 + Mathf.Exp(-array[i][j]));
            }
        }

        NumYArray returnArray = new NumYArray(array);

        return(returnArray);
    }
Пример #7
0
    public static NumYArray operator /(NumYArray a, NumYArray b)
    {
        int[] sizeA = a.Size;
        int[] sizeB = b.Size;

        NumYArray copyA = new NumYArray(a);
        NumYArray copyB = new NumYArray(b);

        List <List <float> > arrayA = copyA.Get();
        List <List <float> > arrayB = copyB.Get();

        //行列の割り算(配列の要素がすべて同じの場合)
        if (sizeA[0] == sizeB[0])
        {
            for (int i = 0; i < sizeA[0]; i++)
            {
                for (int j = 0; j < sizeA[1]; j++)
                {
                    arrayA[i][j] /= arrayB[i][j];
                }
            }
        }
        //(配列の要素の1次元目のみ違う場合)
        else if (sizeA[1] == sizeB[1])
        {
            for (int i = 0; i < sizeA[0]; i++)
            {
                for (int j = 0; j < sizeA[1]; j++)
                {
                    arrayA[i][j] /= arrayB[0][j];
                }
            }
        }
        else
        {
            Debug.Log("Error : Argument size does not match.");
        }

        NumYArray array = new NumYArray(arrayA);

        return(array);
    }
Пример #8
0
    public static NumYArray operator /(float a, NumYArray b)
    {
        int[] sizeB = b.Size;

        NumYArray copyB = new NumYArray(b);

        List <List <float> > arrayB = copyB.Get();

        for (int i = 0; i < sizeB[0]; i++)
        {
            for (int j = 0; j < sizeB[1]; j++)
            {
                arrayB[i][j] = a / arrayB[i][j];
            }
        }

        NumYArray array = new NumYArray(arrayB);

        return(array);
    }
Пример #9
0
    public static NumYArray operator /(NumYArray a, float b)
    {
        int[] sizeA = a.Size;

        NumYArray copyA = new NumYArray(a);

        List <List <float> > arrayA = copyA.Get();

        for (int i = 0; i < sizeA[0]; i++)
        {
            for (int j = 0; j < sizeA[1]; j++)
            {
                arrayA[i][j] /= b;
            }
        }

        NumYArray array = new NumYArray(arrayA);

        return(array);
    }
Пример #10
0
    public static void SaveCSVData(NumYArray array, string csvName)
    {
        StreamWriter sw = new StreamWriter(@"Assets/Resources/AIData/" + csvName + ".csv", false, Encoding.GetEncoding("Shift_JIS"));

        //ヘッダー書き込み
        sw.WriteLine(csvName);
        string[] data = new string[array.Size[1]];
        //データ書き込み
        for (int i = 0; i < array.Size[0]; i++)
        {
            for (int j = 0; j < array.Size[1]; j++)
            {
                data[j] = array.Get()[i][j].ToString();
            }
            string str = string.Join(",", data);
            sw.WriteLine(str);
        }
        sw.Flush();
        sw.Close();
    }
Пример #11
0
    public static NumYArray Sum(NumYArray a, int axis = -1)
    {
        int[] sizeA = a.Size;

        NumYArray copyArray = new NumYArray(a);

        List <List <float> > copyList = copyArray.Get();
        List <List <float> > list     = new List <List <float> >();

        //全ての数値を足す
        if (axis == -1)
        {
            float sumNum = 0;
            for (int i = 0; i < sizeA[0]; i++)
            {
                for (int j = 0; j < sizeA[1]; j++)
                {
                    sumNum += copyList[i][j];
                }
            }
            list.Add(new List <float>());
            list[0].Add(sumNum);
        }
        //指定された計算方法による加算
        else
        {
            //列の和を求める
            if (axis == 0)
            {
                list.Add(new List <float>());
                for (int i = 0; i < sizeA[1]; i++)
                {
                    float sumNum = 0;
                    for (int j = 0; j < sizeA[0]; j++)
                    {
                        sumNum += copyList[j][i];
                    }
                    list[0].Add(sumNum);
                }
            }
            //行の和を求める
            else if (axis == 1)
            {
                for (int i = 0; i < sizeA[0]; i++)
                {
                    list.Add(new List <float>());
                    float sumNum = 0;
                    for (int j = 0; j < sizeA[1]; j++)
                    {
                        sumNum += copyList[i][j];
                    }
                    list[i].Add(sumNum);
                }
            }
            else
            {
                Debug.Log("Error : Argument size does not match.");
            }
        }

        NumYArray returnArray = new NumYArray(list);

        return(returnArray);
    }
Пример #12
0
    /// <summary>
    /// 入力されたデータを元にトレーニング
    /// </summary>
    /// <param name="epochs">トレーニング回数</param>
    /// <param name="learningRate">学習率</param>
    /// <returns></returns>
    public bool Train(int epochs, float learningRate, bool isTrainNow)
    {
        if (!isTrainNow)
        {
            NumYArray layerZ1 = new NumYArray();
            NumYArray layerA1 = new NumYArray();
            NumYArray layerZ2 = new NumYArray();
            NumYArray layerA2 = new NumYArray();

            NumYArray dlayerZ1 = new NumYArray();
            NumYArray dlayerZ2 = new NumYArray();
            NumYArray dw1      = new NumYArray();
            NumYArray db1      = new NumYArray();
            NumYArray dw2      = new NumYArray();
            NumYArray db2      = new NumYArray();

            totalTrainNum = 0;
            maxTrainNum   = Mathf.RoundToInt(100 / xData.Get().Count);
            if (maxTrainNum <= 0)
            {
                maxTrainNum = 1;
            }
            learnSpeed = 1;
        }

        nowTrainNum = 0;

        //規定回数学習させ、他処理のために途中で抜ける
        while (nowTrainNum < maxTrainNum * learnSpeed)
        {
            //許容値を超えているか判定する用出力結果
            //Array  a = Predict(xData);

            int m = xData.Get()[0].Count;

            //順伝播・フォワードプロパゲーション
            layerZ1 = NumY.Dot(xData, this.w1) + this.b1;
            layerA1 = NumY.Sigmoid(layerZ1);
            layerZ2 = NumY.Dot(layerA1, this.w2) + this.b2;
            layerA2 = NumY.Sigmoid(layerZ2);

            //誤差逆伝播法・バックプロパゲーション
            dlayerZ2 = (layerA2 - yData) / m;
            dw2      = NumY.Dot(layerA1.T, dlayerZ2);
            db2      = NumY.Sum(dlayerZ2, 0);

            dlayerZ1 = NumY.Dot(dlayerZ2, w2.T) * NumY.SigmoidDerivative(layerZ1);
            dw1      = NumY.Dot(xData.T, dlayerZ1);
            db1      = NumY.Sum(dlayerZ1, 0);

            //パラメータ更新
            w2 -= learningRate * dw2;
            b2 -= learningRate * db2;
            w1 -= learningRate * dw1;
            b1 -= learningRate * db1;

            nowTrainNum++;
            totalTrainNum++;

            if (totalTrainNum >= epochs)
            {
                this.xData    = new NumYArray();
                this.yData    = new NumYArray();
                totalTrainNum = 0;
                nowTrainNum   = 0;
                return(false);
            }
        }

        nowTrainNum = 0;
        return(true);
    }