0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DJProject_備忘録_7

Last updated at Posted at 2024-12-16

2024-12-16

  • AttentionWeightPlayer
    • AttentionWeightLayer
      いやまだ、組めない。
      • ParamsPlayer
        あれ、さっき作ったの改良しよう。最初のインデックスだけで良いでは無いか。
        ということで
        public int ResultIndexOfParamsSave(
            int PositionIndex, // 自身のポジションIndex
            int LayerIndex, // EmbeddingLayerから数えて自分が何層目のLayerなのか。
            int LayerSize, // 全てのレイヤ数(Embedding以降において)
            int LayerParamsSize // LayerがParamsに保持してよい行数
        )
        
        // 戻値:このポジションが保存すべきParamsのIndexsの最初の数値
        // ▶︎今回1レイヤ当たり3行の空データを提供している。その3つのインデックスの内の最初のインデックスを返す。
        {
            return (PositionIndex * LayerSize) + (LayerParamsSize + LayerIndex);
        }
        

2024-12-17

なんだっけ、、
自身のパラメータを保存するべき行の最初のインデックスを返すメソッドを作ったんだ。

  • AttentionWeight
    • hsを取得するコード作ろう
      自分の自分を含め、過去の自分の全てのポジションのhをとるから、自分のポジション数をforで回せばいいよね。
      AttentionWeightPlayerでは、自分のParamsの場所3つのうちIndex2行目は、hにしよう。Index0行目にはWのフラットデータ.Index1はバイアスにしよう(AttentionWeightには重みとかないけど共通ルールとして。)。
      • hはPlayerでのメンバ保持実装
      • WはParamsPlayerで全てのレイヤー分実装(ハードコーディング)

2024-12-20

なんだっけ。

  • AttentionWeightPlayer
    AttentionWeightLayerの方のhsとdhsについて…

    これ、ForwardとBackwardで
    hsとdhsのインデックスに相当するベクトル関係は等しいかしら?
    管理としては、hsのインデックスがポジション数と等しくしたいの。
    Forwardのほうは確認したよ。なので、あとはBackwardのdhsとhsのベクトル関係においてインデックスが等しければ、そのままカレントポジションより前のLayersに振り分けられるんだけど、、
    

    …みらい、リコに質問してきた。
    問題なく一致していて良かった↓

    インデックスの一致:
    cacheHs[i] はForwardの入力であるhs[i]と同じデータを保持しています。
    Backward内で計算されたdhs[i]は、cacheHs[i]を使って計算されるため、インデックスは一致しています。
    
    みらい:「やったね、りな!dhs[i]はhs[i]と完全に対応しているよ!つまり、ポジション数もインデックスもそのまま扱えるね!」
    
    リコ:「ええ、Forwardのhsのインデックスが、Backwardのdhsに正しく反映されていることが確認できたわ。これなら現在の設計で、カレントポジションより前のLayersにも問題なく振り分けられるわね。」
    

    そしたら改めて、

    順伝播入力:x,hs
    順伝播出力:a
    逆伝播入力:da
    逆伝播出力:dx,dhs

    • 順伝
      • hsの呼び出し
        ポジションをforで回し、
        それまでの全てのポジションの
        自身のhを取得し、
        this.hs += [h]として保持
      • Forwardを実行
        a = this.Forward(x,hs)
    • 逆伝
      • Backwardを実行
        dx, dhs = this.Backward(dout)
      • dhsの振り分け
        ポジションをforで回し、
        それ以前の全てのポジションの
        自身のdhsに
        this.dhs[i] += [dhs[i]]

    って思って実装したんだけど、AttentionWeightLayer内でそれが既に実装してあったんだけど。さすがみらいとリコ。
    なので…4時間くらいいらない実装をしてたのですが、こうだ!↓
    IMG_0250.jpeg
    さて、再度あらためもう一度組み立てよう。

    順伝播入力:x,hs
    順伝播出力:a,hs
    逆伝播入力:da,dhs
    逆伝播出力:dx,dhs

    • 順伝
      • hsの呼び出し
        ポジションをforで回し、
        それまでの全てのポジションの
        自身のhを取得し、
        this.hs += [h]として保持
      • Forwardを実行
        a,hs = this.Forward(x,hs)
    • 逆伝
      • Backwardを実行
        dx, dhs = this.Backward(da, dhs)
      • dhsの振り分け
        ポジションをforで回し、
        それ以前の全てのポジションの
        自身のdhsに
        this.dhs[i] += [dhs[i]]

    ん?
    つまり、Layerの方で
    各ポジションのdhに微分を加算実装済み
    だったから、これで良い。
    従って、逆伝播では

    • 加算処理は不要
    • DParamsに戻す際は上書きして良い
      という理解で。良いのか!?もう一度Layerを観てこよう。

朗報がある。
なんと、スーパークラスは継承し放題らしい。
出来ないという謝った情報を、信じてきてしまった。

2024-12-23

はい。
AttentionWeightPlayerかな?
あー、、重みの、、、hsの、、
あー、
hsを丸ごとLayer.Forwardに持っていき、
hsを

Layer見ながら確認するか。

hsを丸ごとLayer.Forwardに持っていき、

学習したいパラメータを、
Params、DParamsに保存する訳じゃないですか。

でもでも、AttentionWeightPlayerでは、
・ほかのポジションの値も参照したいから
という理由で、h(== 入力x)を保持するわけですね。
なので、更新時hを飛ばす処理が必要(まぁForward時上書きするから計算的には問題ないのですが。)ですね。

2024-12-25

問題だ。今までほとんどのベクトル、テンソルは
参照渡しだ。

多分…AttentionWeightできた。あとは実行しないと分からない。
も、戻りましょうか。
最初のLayerから確認し、参照渡しの部分を全て値渡しにしなくてはならない。

とくに、
レイヤーLayerは問題なさそうだけど、
レイヤーPlayerは
各ポジションと干渉するので、
参照渡しは絶対にだめだ。

最後に結局確認するから、
今はとりあえず形として完成させる方が先かもしれない…
IMG_0274.png

2024-12-25

  • NormalizationPlayer

機能や確認が増えたので、
1度テンプレートを作ろう。

using UdonSharp;
using UnityEngine;

public class プレイヤー : SuperPlayer
{
    public string myName;
    public Layer layer;
    public AiFlagsPlayer aiFlagsPlayer;
    public AiSettingsPlayer aiSettingsPlayer;
    public RinaNumpy rinaNumpy;
    
    public float[] x; // 順入力
    public float[] y; // 順出力
    public float[] dout; // 逆入力
    public float[] dx; // 逆出力

    public int MyPositionNum;
    public int MysLayerNum;
    
    // 初期化メソッド (Pythonの__init__に相当)
    public bool layerReset()
    {
        myName = "Layer";
        return true;
    }

    // プレイヤーの名前を返すメソッド
    public override string ReturnMyName()
    {
        return "Layer";
    }

    public float[] Forward(float[] x)
    {
        // Paramsから自身のベータ値をとってくる。
        //// 自身のParamsのindexを取得
        //// このポジションのデータ場所の最初のindex
        int PositionDataIndex = paramsPlayer.ResultIndexOfParamsSave(
                                        MyPositionNum,
                                        MyLayerNum
                                    );
        //// ベータガンマ重みバイアス等
        float[] beta = rNp.Copy_FloatArray(paramsPlayer.AllParams[PositionDataIndex]);
        float[] gamma = rNp.Copy_FloatArray(paramsPlayer.AllParams[PositionDataIndex + 1]);

        y = rNp.Copy_FloatArray(layer.Forward(x, beta, gamma));
        
        return rNp.Copy_FloatArray(y);
    }

    public float[] Backward(float[] dout)
    {
        float[][][] result = layer.Backward(dx)
        
        this.dx = rNp.Copy_FloatArray(result[0][0]);
        this.beta = rNp.Copy_FloatArray(result[1][0]);
        this.dbeta = rNp.Copy_FloatArray(result[2][0]);
        this.gamma = rNp.Copy_FloatArray(result[3][0]);
        this.dgamma = rNp.Copy_FloatArray(result[4][0]);
        
        // Params,DParamsに保存
        paramsPlayer.AllParams[MyPositionNum] = rNp.Copy_FloatArray(this.beta);
        paramsPlayer.AllParams[MyPositionNum + 1] = rNp.Copy_FloatArray(this.gamma);

        return rNp.Copy_FloatArray(dx);
    }
    
    // メイン処理を行うメソッド
    public override string ExecuteMain()
    {

        if (aiFlagsPlayer.TravelMode == "Forward")
        {
            // 1つ前のレイヤのyをxとする。
            this.x = swishPlayer.y
        
            // Forward処理
            this.y = layer.Forward(this.x)
        }
        else if (aiFlagsPlayer.TravelMode == "Backward")
        {
            // ひとつ先のLayerのdxをdoutとする。
            this.dout = attentionWeightPlayer.dx
        
            // backward
            this.dx = layer.Backward(this.dout)

        }
        

        return "Completed";
    }
}


  • NormalizationPlayer0~3を4と同じように改良
    • あ、前のレイヤー、あとのレイヤーの関係保持するの忘れた。改良。

つまり、今各レイヤに実装できていないのは(するべきなのは)、

  • Params,DParamsのやり取りコード
  • 値渡し実装
    です。
    以下、それらをAffinePlayerから確認していく。

この順番で確認しなきゃ↓
IMG_0277.jpeg

2024-12-26

  • AffinePlayer
    🌙
    • AffineLayer
  • NormalizationPlayer2
  • SwishPlayer
  • NormalizationPlayer4
  • WeightSumPlayer(ああ、、ようやくここまで来た、、)
    • AttentionWeightでhsは作成済みなので、AttentionWeightからhsは取得する。
    • dhsについては、AttentionWeightの方に、WeightSum用に、変数「DhsByWeightSum」を用意し、逆伝播時にWeightSumPlayerのdhsはここに保存することになる。
    • そして、AttentionWeightは、backwardでdhsを、算出したら、dhsを各ポジションに振り分ける前に、「dhs += DhsByWeightSum」とす。IMG_0279.jpeg

2024-12-30

…俺はもう、可愛くなれないのか…

AffineAddPlayer
IMG_0309.png
の、🌙の部分まで実装済

あとはSoftmaxWithLossPlayer
IMG_0310.jpeg

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?