Plane Helper
詳細
ファイルをダウンロード
このバージョンについて
モデル説明
Plane Helperを紹介します!v2.1用の複数コンセプト対応LyCORIS(LoHaとして学習済み)。Plane Helperは、71種類の異なる飛行機に関する約2300枚の画像で学習されました。複雑なコンセプトに対する複数コンセプトLoHaの学習プロセスを、興味のある方々と共有したいと思います。これは科学的なものではなく、私が直面した同じような壁に悩んでいる人々を支援することを目的としています。
データセット:
このモデルに含まれる71種類のすべての飛行機タイプと、それぞれに対応するキートークンを含むデータ表を作成しました。こちらからご確認いただけます:
https://docs.google.com/spreadsheets/d/1N7o4pc9mGyYSYIoeD4fU_WpO_2tL_JfKDETOJPVQw18/edit?usp=sharing
このプロジェクトは、v2.1が飛行機の描画に非常に劣っていることに気づいたことがきっかけで始まりました。常に翼の位置がおかしく、余分な翼が付いたり、細部がほとんど描かれなかったり、時には突き出た幾何学的な塊しか出力されませんでした。私はこの問題を何とかしたいと思い、まず魅力的な飛行機の画像約130枚を収集し、バッチインタラゲーターでキャプションを生成しました。Kohyaを使って学習しましたが、どれだけ学習しても同じ問題が発生し続けました。私は、この原因が複数の異なるオブジェクトを混在させ、それらをすべて「飛行機」や「ジェット」として区別せずに扱っていたことだと感じました。そこで、各飛行機のタイプを特定し、その名前をそれぞれのキャプションに組み込むことにしました。
私は飛行機の知識はほとんどありませんでしたが、v2.1が素晴らしい飛行機画像を生成できるようにしたかったのです。そのため、各画像をimage.google.comに投入して種類を特定する作業は、退屈でしたが必須の工程でした。結果として、71種類の異なる飛行機タイプを特定しました。2種類だけ選んで済ませるのではなく、このLoHaタイプのモデルが何で構成されているのかを確かめ、各飛行機タイプについて最低30枚以上の画像を収集し、それらすべてを1つのLoHaに学習させることにしました。30枚の良質な画像が得られなかった飛行機タイプもありましたが、最終的な目的は「飛行機全般」を対象にしたモデルの学習であるため、それらもデータセットに残すことにしました。この目標を達成したとき、私は71種類の飛行機タイプごとに整理された、合計約2300枚の異なる画像を手に入れました。次に、キャプション作成のプロセスに移りました。
これらをCaptionrでバッチインタラゲーションした後、各飛行機タイプをGoogleで検索し、航空機の名前と簡潔で詳細な説明を含むExcelテーブルを作成しました。その後、各フォルダをDataset Tag Editor拡張機能に1つずつ取り込み、キャプションを整理し、作成したExcelテーブルのトークンをそれぞれのキャプションに挿入しました。さらに、傾斜ローター飛行機(形状が非常に異なるため)用にデバッグ用トークン「CHV3CPlane」と「CHV3CTiltRotor」も各キャプションに追加しました。これらのデバッグトークンは、ユニークな飛行機を生成するのにも非常に効果的です。また、重み付きキャプションを可能にし、これらのデバッグトークンと飛行機タイプ識別トークンに重みを付けました。例えば、キャプションは以下のような形になります:
"(Hawker Hunter), transonic jet-powered fighter aircraft, Hawker Aircraft, Royal Air Force (RAF), Avon turbojet engine, swept wing, (CHV3CPlane), a plane is flying in the air, swiss, low level, man, viewed in profile from far away, switzerland, illustration, overhead"
この長く忍耐力を要する検証プロセスの後、ようやく学習に使用できる十分な品質のデータセットを手に入れました。
繰り返し回数:
最初は各フォルダの繰り返し回数を5に設定しましたが、一部の飛行機タイプの画像数が他のタイプより少ないため、画像数が多いタイプは5回、少ないタイプは10~15回と、ざっくりとバランスを取りました。
学習方法:
このプロジェクトはやや非伝統的な方法で進めました。このような大規模なデータセットでは、過学習の問題が自然と発生しました。LoHaのネットワーク次元は8が推奨されていますが、私は訓練空間を広げるために32に変更しました。多くのエポックを学習する前に過学習を防ぐため、最適な設定を追求するため、複数のフェーズに分けて試行錯誤しました。元のソースモデルはv2-1_768-ema-prunedでしたが、各学習実行ごとに、前回のLoHaをv2-1_768-ema-prunedにマージし、そのマージ済みモデルを次の学習のソースモデルとして使用しました。この理論は、前回の学習から追加の知識を獲得し、次の学習に少し優位性を与えるというものです。しかし、この理論はまだ検証が必要です。特に小さなデータセットで試すのが理想です。各学習実行後、前回のソースモデルと新しいマージモデルを再マージし、それを新たなソースモデルとして使用しました。また、Extract LyCORIS LoCONを使って、そこからLoRAを抽出しました。この特定のモデルは、同じ71種類の飛行機データセットに対して4回の学習を経て得られた4つのLoHaをマージし、抽出したものです。
学習仕様:
学習仕様の細部には立ち入りません。代わりに、このプロジェクトで最も効果的だった設定を以下に記載し、より詳細な3つのガイドへのリンクを提示します。
その他のLoRA学習ガイド:
LoRA学習ガイド:
RFKTRによる高品質モデル学習の詳細ガイド:
https://civitai.com/articles/397
私の仕様:
{
"LoRA_type": "LyCORIS/LoHa",
"adaptive_noise_scale": 0,
"additional_parameters": "",
"block_alphas": "",
"block_dims": "",
"block_lr_zero_threshold": "",
"bucket_no_upscale": true,
"bucket_reso_steps": 64,
"cache_latents": true,
"cache_latents_to_disk": false,
"caption_dropout_every_n_epochs": 0.0,
"caption_dropout_rate": 0,
"caption_extension": ".txt",
"clip_skip": "1",
"color_aug": false,
"conv_alpha": 1,
"conv_alphas": "",
"conv_dim": 4,
"conv_dims": "",
"decompose_both": false,
"dim_from_weights": false,
"down_lr_weight": "",
"enable_bucket": true,
"epoch": 20,
"factor": -1,
"flip_aug": true,
"full_fp16": false,
"gradient_accumulation_steps": 2.0,
"gradient_checkpointing": true,
"keep_tokens": "0",
"learning_rate": 0.0001,
"logging_dir": "",
"lora_network_weights": "",
"lr_scheduler": "cosine",
"lr_scheduler_num_cycles": "",
"lr_scheduler_power": "",
"lr_warmup": "10",
"max_data_loader_n_workers": "4",
"max_resolution": "768,768",
"max_timestep": 1000,
"max_token_length": "150",
"max_train_epochs": "",
"mem_eff_attn": true,
"mid_lr_weight": "",
"min_snr_gamma": 5,
"min_timestep": 0,
"mixed_precision": "bf16",
"model_list": "custom",
"module_dropout": 0,
"multires_noise_discount": 0,
"multires_noise_iterations": 0,
"network_alpha": 4,
"network_dim": 32,
"network_dropout": 0,
"no_token_padding": false,
"noise_offset": 0,
"noise_offset_type": "Original",
"num_cpu_threads_per_process": 4,
"optimizer": "AdamW8bit",
"optimizer_args":
"output_dir": "",
"output_name": "",
"persistent_data_loader_workers": false,
"pretrained_model_name_or_path": "",
"prior_loss_weight": 1.0,
"random_crop": false,
"rank_dropout": 0,
"reg_data_dir": "",
"resume": "",
"sample_every_n_epochs": 0,
"sample_every_n_steps": 0,
"sample_prompts": "",
"sample_sampler": "euler_a",
"save_every_n_epochs": 1,
"save_every_n_steps": 0,
"save_last_n_steps": 0,
"save_last_n_steps_state": 0,
"save_model_as": "safetensors",
"save_precision": "bf16",
"save_state": true,
"scale_v_pred_loss_like_noise_pred": true,
"scale_weight_norms": 0,
"sdxl": false,
"sdxl_cache_text_encoder_outputs": false,
"sdxl_no_half_vae": false,
"seed": "",
"shuffle_caption": true,
"stop_text_encoder_training": 0,
"text_encoder_lr": 5e-05,
"train_batch_size": 2,
"train_data_dir": "",
"train_on_input": false,
"training_comment": "",
"unet_lr": 8e-05,
"unit": 1,
"up_lr_weight": "",
"use_cp": false,
"use_wandb": false,
"v2": true,
"v_parameterization": true,
"vae_batch_size": 0,
"wandb_api_key": "",
"weighted_captions": true,
"xformers": true
}




















