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_備忘録_6

Last updated at Posted at 2024-11-27

2024-11-28

次はTransformerを作るために、Affine,LeLU,Softmax,Normalization(逆伝播難しいんだよね…),AttentionWeight,WeightSum,CrossEntropyLoss
、、ぐらいかな。作っていこう。

えっと、前に書いた簡易Transformerの写真、写真、、、あった
あったけど、これAttentionLayerに1つ前のポジションのhs渡す矢印が足りない
IMG_0102.jpeg
ここで言う、FeedforwardLayerはAffineLayerとやってる事全く一緒らしい。
…ほんとに?
でもとりあえず、xW + bで良いってさ。
SigmoidLayerはReLULayerに置き換えよう。
そして、全てのLayerの手前にNormalizationLayerを挟み、爆発消失避けよう。

ちよっとまって、SwishLayerを過去の自分がUdonSharpで用意してくれてる。
ここのディレクトリ素敵、、。これ、今回使おう。
IMG_0103.png
中身が少し特殊だったので、それを訂正する形で、バージョンをアップさせよう。

IMG_0107.png

ここまで
用意できた。
CrossEntropyLossはSoftmaxWithLossとしてまとめた。

そしたら、、サーバー側のPythonにも同じレイヤーを作りましょうか…。

Pythonの方もできた。

2024-11-29

  • LiONにスケールダウン機能を加える。
    勾配爆発、消失した場合に、重み、バイアス全体のスケールダウンをすることで、限りなく勾配爆発、消失を教える試み。

  • スケジュールを作ろう

2024-11-30

スケジュールをつくろうと思ったけど、Layerを作っただけなので、各全てほLayerのPlayerを作ろう。

…土曜12時間出勤だるい今日、、、
とりあえずテンプレ…

using UdonSharp;
using UnityEngine;

public class AffinePlayer : SuperPlayer
{
    public string myName;
    public AffineLayer affineLayer;
    public InitAiTypesPlayer initAiTypesPlayer;
    
    // 初期化メソッド (Pythonの__init__に相当)
    public bool AffinePlayerReset()
    {
        myName = "AffinePlayer";
        return true;
    }

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

    public float[] Forward(float[] x)
    {
        float[] y = affineLayer.Forward(x);
        
        return y;
    }

    public float[] Backward(float[] dx)
    {
        float[] dout = affineLayer.Backward(dx)

        return dout;
    }
    
    // メイン処理を行うメソッド
    public override string ExecuteMain()
    {
        // ForwardPlayerでライブラリ的に使用するので
        // 実装今のところ不要
        return "Completed";
    }
}

レイヤーすべてにPlayerを用意した。LiON、もっと早い処理になるように改良できないかな、、
もう電池無くなる、、さよなら

2024-12-02

レイヤーのオブジェクト数は
UdonSharpの処理力的に、
各レイヤ1つずつとするため、
重み、バイアス、ベータ値
そして、それぞれの微分値は、
各ポジション分用意する必要がある。
IMG_0115.jpeg

  • レイヤーの作成
    • Params,DParamsLayerの作成
    • Xs,DXsLayerの作成

2024-12-05,2024-12-06

日付けが空いた。
なにしてたんだっけ、、
ああ、前回の画像みて思い出した。

  • レイヤーの作成
    • Params,DParamsLayerの作成
      さて、必要としてるのは…
      ・4次元arrayを持ったparams
      ・4次元arrayを持ったdparams
      ね。

…これじゃダメだ。C#知識不足の私に組み込めない。
パラメータ群は、ひとつの行列に収めることにした。
IMG_0146.jpeg
3行をひとつのLayer分の情報とし、
各重み、バイアス、ベータ値はフラットに…って、
あ、フラットにするのは重みだけで良いのか。
Layerでパラメータを呼び出す時は、reshapeして使うことにした。
これなら4次元データにならず、2次元行列で済む!

なので、えっと、次することは、、

  • Paramsプレイヤーは2次元ジャグ配列をもつオブジェクトとして作り直す。
  • DParamsプレイヤーも同様に。

その後で、どのようにForwardPlayerでの処理をするか、考えよう。流れは大まかに出来てる…
IMG_0147.jpeg

…ので、後で考えても大丈夫。

  • AiSettingsPlayer の作成
    このプレイヤーに、HiddenSizeやXSizeのパラメータ設定をメンバ変数として持たせよう。

2024-12-09

  • ParamsPlayer を作らなきゃ

2024-12-11

まってまず、EmbeddingLayerの改良から始めよう。

殴り書き紙の備忘録
大まかな流れ
IMG_0173.jpeg
IMG_0172.jpeg

なので、

  • EmbeddingPlayerの改良
    あ、Tokenizerクラス作らなきゃ
    EmbeddingLayerの重み定義できないや。
    あいや、設定パラメータは全てAiSettingsPlayerから取得するようにしよう。仮定義としてEmbeddingLayerを先に作ろう。
    • RinaNumpyに
      • Append_FloatArray()
      • Append_StringArray()
        を追加。
      • …あと色々追加。

2024-12-12

EmbeddingLayerあとBackwardだけ
えっとEmbeddingLayerの次のレイヤーは、レイヤー群になる。
なので、レイヤー群の最初のレイヤー(LayerNormalizationPlayer)は、
なので、次のレイヤーはEmbeddingのthis.SampleIdVerをforで回して取得することになる。

そのため、AiFlagsPlayerを作成し、その時学習中のポジションのインデックスをこのプレイヤーに保持させることにした。
ほか、ほかの処理でフラグが必要になった場合、このプレイヤーに書き込み使用していく。

EmbeddingPlayerできた。
ついでに、「予定スケジュール.md」も作成した。中身は次の通り。

# Forward
## Xのフロートベクトル化まで
- InitAiTypesPlayer # モード変数の初期化
- ChangeAiModePlayer # TrainまたはPredictのトグルスイッチ
- ChangeTravelModePlayer # ForwardまたはBackwardのトグルスイッチ
- AiSettingsPlayer # 入力データ、隠れ層等の設定
- EmbeddingPlayer # Xを1次元ベクトル化
## フロートベクトルをlossに変換するまで
- PositionsParamsPlayer # このポジションのパラメータを、各レイヤーにペーストする
- NormalizationPlayer # 各ポジション毎回、EmbeddingPlayerのSampleVecVerから取り出してくる。
- SkipAddPlayer
- AffinPlayer
- NormalizationPlayer
- SwishPlayer
- NormalizationPlayer
- AttentionWeightPlayer
- NormalizationPlayer
- WeightSumPlayer
- NormalizationPlayer
- AffinPlayer
- NormalizationPlayer
- SoftmaxWithLossPlayer
---
# Backward
## Backwardモードに移行
- ChangeTravelModePlayer # ForwardまたはBackwardのトグルスイッチ
## EmbeddingPlayer直前まで逆伝播
- SoftmaxWithLossPlayer
- NormalizationPlayer
- AffinPlayer
- NormalizationPlayer
- WeightSumPlayer
- NormalizationPlayer
- AttentionWeightPlayer
- NormalizationPlayer
- SwishPlayer
- NormalizationPlayer
- AffinPlayer
- SkipAddPlayer
- NormalizationPlayer # 各ポジション毎回、EmbeddingPlayerのdSampleVecVerに入れ込んでいく。
- PositionsParamsPlayer # Layerのパラメータを、自身の変数に保持
## EmbeddingPlayerのbackwardで、dWの完成
- EmbeddingPlayer

プレイヤーの実行順番が記載されている。新しいプレイヤーも定義した。

各レイヤーの中に、またプレイヤーとしてまとめていないもの、さらにレイヤーとして未完成なものがほとんどなので、1プレイヤー1プレイヤー、完成させていこう

  • NormalizationPlayer,NormalizationLayer
    んー、、LayerとPlayerを交互に見て疲れる…しんどい…パソコンでやりたい…
    NormalizationPlayerは(NormalizationPlayerに限らず)何度か使用してるので、NormalizationPlayer2とか作ってかなきゃね。
    あ、、githubだと
    IMG_0182.png
    みたいに左しか見えないから
    2_Normalizationとかにしなきゃ、、。
    うーん、基本的にプレイヤーのExecuteMainは
    // メイン処理を行うメソッド
    public override string ExecuteMain()
    {
    
        if (initAiTypesPlayer. TravelMode == "Forward")
        {
            // 1つ前のレイヤから、xを取ってくる
            this.x = embeddingPlayer.SampleVecVer[aiFlagsPlayer.NowPositionIndex]
        
            // Forward処理
            this.y = normalizationLayer.Forward(this.x)
        }
        else if (initAiTypesPlayer. TravelMode == "Backward")
        {
            // ひとつ先のLayerから、doutを取ってくる
            this.dout = skipAddPlayer.dx
        
            // backward
            this.dx = normalizationLayer.Backward(this.dout)
            
            // このポジション終了したので+=1
            aiFlagsPlayer.NowPositionIndex += 1;
        }
    
    1つ前のプレイヤーから取って来る感じでいいかな、、。
    Pythonみたいにインスタンスをリストで管理できないから、if分岐で実行する処置をとった。U#はオブジェクト指向プログラミングがやりにくいですね…。

2024-12-13

  • SkipAddPlayer, SkipAddLayer
    • Player
      • ExecuteMain
        ifでForward分岐
    • Layer
      ForwardとBackwardの機能がなんか逆だったから訂正。
      Skip先はAffineLayer2とし、AffineLayer2自身でSkipAddPlayerにアクセスしてyを取得して加算させることにする。
  • AffinePlayer(1つ目)
    • プレイヤー

はい。
あ、PlayerのPlayerResetメソッドで
Layerの初期化してないや。
やろう。
(邪心発散:上京アフロ田中の次のシリーズってあるのかな…見たい)
(邪心発散:ぁぁ、、UdonSharpはふたつ先のスーパーレイヤ取れないっていう噂だし、、とりあえずハードコーディングするしかないよね…全部で10超過位のレイヤ数だし、すぐだよ、すぐ。)

…なんだっけ
ああ、初期かね。
いいや。

  • NormalizationPlayer2
  • SwishPlayer
  • NormalizationPlayer3

2024-12-16

  • NormalizationPlayer3
  • AttentionWeightPlayer
    • AttentionLayer
      さて。そうですね、Forwardで、1つ前のポジションと、自身のhをまとめhsにしなければならない。
      ポジションの順伝逆伝が1つ終わると、レイヤのパラメータはParamsPlayerの2次元ベクトルに
      わー、、
入力は、int型。
出力は、
って、、ああ、なんか出来ちゃったよ、笑

ちょっとベクトルの書き方が数学的にやったことないから(園芸科学科の専門高校だったから…線形代数習わなかったの…悔しい)あれだけど、
[y1,y2,y3] = 3x + [0,1,2]
で出来そうね。
y=ax+bで考えてみたよ。バイアスが個々のインデックスのズレだとすれば、あとは3かけるだけでいけるよね。傾きが3なのね、この式は。

だから、、

def result_index_of_paramssave(x=None):
    y = []
    bs = [0, 1, 2]
    a = self.LayersParamSize * self.LayerSize
    for b in bs:
        y.append(a * x + b)
    return y

として保存しよう
chatGPTに変換させて、さらに細かいところの修正、ほかプレイヤーからの引き継ぎ

    public int[] ResultIndexOfParamsSave(int x)
    // 引数:処理中のposition数
    // 戻値:このポジションが保存すべきParamsのIndexs
    {
        // 結果を格納する配列を初期化
        int[] y = new int[3];
        int[] bs = { 0, 1, 2 };
        int[] a = aiSettingsPlayer.LayerParamsSize * aiSettingsPlayer.LayerSize

        // bsの各要素に3 * xを加算してyに格納
        for (int bi = 0; bi < bs.Length;bi++)
        {
            y = rinaNumpy.Append_FloatArray(y, bs[bi] + 3 * x);
        }

        return y;
    }

じゃぁAttentionWeightPlayerでは、、
・現在のPositionをforで回す
・ResultIndexOfParamsSaveにiを入れて保存すべき

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?