訓練diffusion模型

訓練擴散模型


無條件圖像生成是擴散模型的一種流行應用,它生成的圖像與用於訓練的數據集中的圖像相似。通常,最好的結果是通過在特定數據集上微調預訓練模型來獲得的。您可以在 Hub 上找到許多這樣的檢查點,但如果您找不到您喜歡的檢查點,您可以隨時訓練自己的檢查點!

本教程將教您如何在 Smithsonian Butterflies 數據集的子集上從頭開始訓練 UNet2DModel,以生成您自己的 🦋 蝴蝶 🦋。

💡 本培訓教程基於 🧨 擴散器筆記本進行培訓。有關擴散模型的更多詳細信息和背景(例如它們的工作原理),請查看筆記本!

在開始之前,請確保您安裝了🤗數據集來加載和預處理圖像數據集,並安裝了🤗加速,以簡化在任意數量的 GPU 上的訓練。以下命令還將安裝 TensorBoard 以可視化訓練指標(您還可以使用權重和偏差來跟踪您的訓練)。

我們鼓勵您與社區分享您的模型,為此,您需要登錄您的 Hugging Face 帳戶(如果您還沒有帳戶,請在此處創建一個!)。您可以從筆記本登錄並在出現提示時輸入您的令牌:

Copied>>> from huggingface_hub import notebook_login >>> notebook_login()

或者從終端登錄:

Copiedhuggingface-cli login

由於模型檢查點非常大,因此安裝 Git-LFS 來對這些大文件進行版本控制:

Copied!sudo apt -qq install git-lfs !git config –global credential.helper store

訓練配置

為了方便起見,創建一個包含訓練超參數的 TrainingConfig 類(隨意調整它們):

Copied>>> from dataclasses import dataclass >>> @dataclass … class TrainingConfig: … image_size = 128 # the generated image resolution … train_batch_size = 16 … eval_batch_size = 16 # how many images to sample during evaluation … num_epochs = 50 … gradient_accumulation_steps = 1 … learning_rate = 1e-4 … lr_warmup_steps = 500 … save_image_epochs = 10 … save_model_epochs = 30 … mixed_precision = “fp16” # `no` for float32, `fp16` for automatic mixed precision … output_dir = “ddpm-butterflies-128” # the model name locally and on the HF Hub … push_to_hub = True # whether to upload the saved model to the HF Hub … hub_private_repo = False … overwrite_output_dir = True # overwrite the old model when re-running the notebook … seed = 0 >>> config = TrainingConfig()

加載數據集

您可以使用 🤗 數據集庫輕鬆加載史密森尼蝴蝶數據集:

Copied>>> from datasets import load_dataset >>> config.dataset_name = “huggan/smithsonian_butterflies_subset” >>> dataset = load_dataset(config.dataset_name, split=”train”)

💡 您可以從 HugGan 社區活動中找到其他數據集,也可以通過創建本地 ImageFolder 來使用自己的數據集。如果數據集來自 HugGan 社區活動,則將 config.dataset_name 設置為數據集的存儲庫 ID;如果您使用自己的圖像,則將 imagefolder 設置為。

🤗 Datasets 使用 Image 功能自動解碼圖像數據並將其加載為我們可以可視化的 PIL.Image :

Copied>>> import matplotlib.pyplot as plt >>> fig, axs = plt.subplots(1, 4, figsize=(16, 4)) >>> for i, image in enumerate(dataset[:4][“image”]): … axs[i].imshow(image) … axs[i].set_axis_off() >>> fig.show()

不過,這些圖像的尺寸各不相同,因此您需要先對它們進行預處理:

  • Resize 將圖像大小更改為 config.image_size 中定義的大小。
  • RandomHorizontalFlip 通過隨機鏡像圖像來擴充數據集。
  • Normalize 對於將像素值重新縮放到 [-1, 1] 範圍非常重要,這是模型所期望的。

Copied>>> from torchvision import transforms >>> preprocess = transforms.Compose( … [ … transforms.Resize((config.image_size, config.image_size)), … transforms.RandomHorizontalFlip(), … transforms.ToTensor(), … transforms.Normalize([0.5], [0.5]), … ] … )

使用 🤗 數據集的 set_transform 方法在訓練期間動態應用 preprocess 函數:

Copied>>> def transform(examples): … images = [preprocess(image.convert(“RGB”)) for image in examples[“image”]] … return {“images”: images} >>> dataset.set_transform(transform)

請隨意再次可視化圖像以確認它們已調整大小。現在您已準備好將數據集包裝在 DataLoader 中進行訓練!

Copied>>> import torch >>> train_dataloader = torch.utils.data.DataLoader(dataset, batch_size=config.train_batch_size, shuffle=True)

創建 UNet2D 模型

🧨 Diffusers 中的預訓練模型可以使用您想要的參數輕鬆地從其模型類創建。例如,要創建 UNet2DModel:

Copied>>> from diffusers import UNet2DModel >>> model = UNet2DModel( … sample_size=config.image_size, # the target image resolution … in_channels=3, # the number of input channels, 3 for RGB images … out_channels=3, # the number of output channels … layers_per_block=2, # how many ResNet layers to use per UNet block … block_out_channels=(128, 128, 256, 256, 512, 512), # the number of output channels for each UNet block … down_block_types=( … “DownBlock2D”, # a regular ResNet downsampling block … “DownBlock2D”, … “DownBlock2D”, … “DownBlock2D”, … “AttnDownBlock2D”, # a ResNet downsampling block with spatial self-attention … “DownBlock2D”, … ), … up_block_types=( … “UpBlock2D”, # a regular ResNet upsampling block … “AttnUpBlock2D”, # a ResNet upsampling block with spatial self-attention … “UpBlock2D”, … “UpBlock2D”, … “UpBlock2D”, … “UpBlock2D”, … ), … )

快速檢查樣本圖像形狀與模型輸出形狀是否匹配通常是個好主意:

Copied>>> sample_image = dataset[0][“images”].unsqueeze(0) >>> print(“Input shape:”, sample_image.shape) Input shape: torch.Size([1, 3, 128, 128]) >>> print(“Output shape:”, model(sample_image, timestep=0).sample.shape) Output shape: torch.Size([1, 3, 128, 128])

偉大的!接下來,您需要一個調度程序來向圖像添加一些噪聲。

創建調度程序

根據您使用模型進行訓練還是推理,調度程序的行為會有所不同。在推理過程中,調度器根據噪聲生成圖像。在訓練期間,調度程序從擴散過程中的特定點獲取模型輸出(或樣本),並根據噪聲調度和更新規則將噪聲應用於圖像。

讓我們看一下 DDPMScheduler,並使用 add_noise 方法向之前的 sample_image 添加一些隨機噪聲:

Copied>>> import torch >>> from PIL import Image >>> from diffusers import DDPMScheduler >>> noise_scheduler = DDPMScheduler(num_train_timesteps=1000) >>> noise = torch.randn(sample_image.shape) >>> timesteps = torch.LongTensor([50]) >>> noisy_image = noise_scheduler.add_noise(sample_image, noise, timesteps) >>> Image.fromarray(((noisy_image.permute(0, 2, 3, 1) + 1.0) * 127.5).type(torch.uint8).numpy()[0])

模型的訓練目標是預測添加到圖像中的噪聲。這一步的損失可以通過下式計算:

Copied>>> import torch.nn.functional as F >>> noise_pred = model(noisy_image, timesteps).sample >>> loss = F.mse_loss(noise_pred, noise)

 訓練模型

到目前為止,您已經掌握了開始訓練模型的大部分內容,剩下的就是將所有內容組合在一起。

首先,您需要一個優化器和一個學習率調度器:

Copied>>> from diffusers.optimization import get_cosine_schedule_with_warmup >>> optimizer = torch.optim.AdamW(model.parameters(), lr=config.learning_rate) >>> lr_scheduler = get_cosine_schedule_with_warmup( … optimizer=optimizer, … num_warmup_steps=config.lr_warmup_steps, … num_training_steps=(len(train_dataloader) * config.num_epochs), … )

然後,您需要一種評估模型的方法。為了進行評估,您可以使用 DDPMPipeline 生成一批樣本圖像並將其保存為網格:

Copied>>> from diffusers import DDPMPipeline >>> from diffusers.utils import make_image_grid >>> import math >>> import os >>> def evaluate(config, epoch, pipeline): … # Sample some images from random noise (this is the backward diffusion process).# The default pipeline output type is `List[PIL.Image]` … images = pipeline( … batch_size=config.eval_batch_size, … generator=torch.manual_seed(config.seed), … ).images … # Make a grid out of the images … image_grid = make_image_grid(images, rows=4, cols=4) … # Save the images … test_dir = os.path.join(config.output_dir, “samples”) … os.makedirs(test_dir, exist_ok=True) … image_grid.save(f”{test_dir}/{epoch:04d}.png”)

現在,您可以使用 🤗 Accelerate 將所有這些組件包裝在一個訓練循環中,以輕鬆進行 TensorBoard 日誌記錄、梯度累積和混合精度訓練。要將模型上傳到 Hub,請編寫一個函數來獲取存儲庫名稱和信息,然後將其推送到 Hub。

💡 下面的訓練循環可能看起來令人生畏且漫長,但是當您僅用一行代碼啟動訓練時,這一切都是值得的!如果您迫不及待地想要開始生成圖像,請隨意複製並運行下面的代碼。您可以隨時返回並更仔細地檢查訓練循環,例如當您等待模型完成訓練時。 🤗

Copied>>> from accelerate import Accelerator >>> from huggingface_hub import HfFolder, Repository, whoami >>> from tqdm.auto import tqdm >>> from pathlib import Path >>> import os >>> def get_full_repo_name(model_id: str, organization: str = None, token: str = None): … if token is None: … token = HfFolder.get_token() … if organization is None: … username = whoami(token)[“name”] … return f”{username}/{model_id}” … else: … return f”{organization}/{model_id}” >>> def train_loop(config, model, noise_scheduler, optimizer, train_dataloader, lr_scheduler): … # Initialize accelerator and tensorboard logging … accelerator = Accelerator( … mixed_precision=config.mixed_precision, … gradient_accumulation_steps=config.gradient_accumulation_steps, … log_with=”tensorboard”, … project_dir=os.path.join(config.output_dir, “logs”), … ) … if accelerator.is_main_process: … if config.push_to_hub: … repo_name = get_full_repo_name(Path(config.output_dir).name) … repo = Repository(config.output_dir, clone_from=repo_name) … elif config.output_dir is not None: … os.makedirs(config.output_dir, exist_ok=True) … accelerator.init_trackers(“train_example”) … # Prepare everything# There is no specific order to remember, you just need to unpack the# objects in the same order you gave them to the prepare method. … model, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( … model, optimizer, train_dataloader, lr_scheduler … ) … global_step = 0 … # Now you train the model … for epoch in range(config.num_epochs): … progress_bar = tqdm(total=len(train_dataloader), disable=not accelerator.is_local_main_process) … progress_bar.set_description(f”Epoch {epoch}”) … for step, batch in enumerate(train_dataloader): … clean_images = batch[“images”] … # Sample noise to add to the images … noise = torch.randn(clean_images.shape).to(clean_images.device) … bs = clean_images.shape[0] … # Sample a random timestep for each image … timesteps = torch.randint( … 0, noise_scheduler.config.num_train_timesteps, (bs,), device=clean_images.device … ).long() … # Add noise to the clean images according to the noise magnitude at each timestep# (this is the forward diffusion process) … noisy_images = noise_scheduler.add_noise(clean_images, noise, timesteps) … with accelerator.accumulate(model): … # Predict the noise residual … noise_pred = model(noisy_images, timesteps, return_dict=False)[0] … loss = F.mse_loss(noise_pred, noise) … accelerator.backward(loss) … accelerator.clip_grad_norm_(model.parameters(), 1.0) … optimizer.step() … lr_scheduler.step() … optimizer.zero_grad() … progress_bar.update(1) … logs = {“loss”: loss.detach().item(), “lr”: lr_scheduler.get_last_lr()[0], “step”: global_step} … progress_bar.set_postfix(**logs) … accelerator.log(logs, step=global_step) … global_step += 1 … # After each epoch you optionally sample some demo images with evaluate() and save the model … if accelerator.is_main_process: … pipeline = DDPMPipeline(unet=accelerator.unwrap_model(model), scheduler=noise_scheduler) … if (epoch + 1) % config.save_image_epochs == 0 or epoch == config.num_epochs – 1: … evaluate(config, epoch, pipeline) … if (epoch + 1) % config.save_model_epochs == 0 or epoch == config.num_epochs – 1: … if config.push_to_hub: … repo.push_to_hub(commit_message=f”Epoch {epoch}”, blocking=True) … else: … pipeline.save_pretrained(config.output_dir)

唷,那是相當多的代碼!但您終於準備好使用 🤗 Accelerate 的 notebook_launcher 函數啟動訓練了。向函數傳遞訓練循環、所有訓練參數和進程數(您可以將此值更改為可用的 GPU 數量)以用於訓練:

Copied>>> from accelerate import notebook_launcher >>> args = (config, model, noise_scheduler, optimizer, train_dataloader, lr_scheduler) >>> notebook_launcher(train_loop, args, num_processes=1)

訓練完成後,查看擴散模型生成的最終 🦋 圖像 🦋!

Copied>>> import glob >>> sample_images = sorted(glob.glob(f”{config.output_dir}/samples/*.png”)) >>> Image.open(sample_images[-1])

下一步

無條件圖像生成是可訓練任務的一個示例。您可以訪問🧨 擴散器培訓示例頁面來探索其他任務和培訓技術。以下是您可以學到的一些示例:

  • 文本反轉,一種向模型傳授特定視覺概念並將其集成到生成圖像中的算法。
  • DreamBooth,一種在給定主題的多個輸入圖像的情況下生成主題的個性化圖像的技術。
  • 在您自己的數據集上微調穩定擴散模型的指南。
  • LoRA 使用指南,這是一種內存高效技術,可以更快地微調大型模型。

如何訓練穩定的擴散模型:初學者指南

掌握訓練穩定擴散模型的基礎知識。通過簡單的分步說明,我們將立即將初學者轉變為自信的模型訓練師。一起來學習吧!

近年來,人工智能 (AI) 和機器學習 (ML) 徹底改變了數據分析、預測建模和決策領域。其中一個發展就是穩定擴散模型,它是一種基於歷史數據生成圖像和預測結果的強大工具。

在這份內容廣泛的指南中,我們將深入研究穩定擴散模型的訓練過程,為您提供掌握這一迷人技術必不可少的步驟、最佳實踐和策略。

穩定擴散模型簡介

穩定擴散模型包含一種機器學習算法類型,該算法使用歷史數據來預測特定結果或事件的概率。這些模型採用一種稱為擴散過程的技術,其中包括向輸入圖像添加噪聲,然後隨著時間的推移逐漸減少噪聲以生成最終圖像。此過程產生的圖像比傳統深度學習 (DL) 模型更詳細、更真實。

穩定擴散模型因其處理複雜和抽象文本描述的能力而特別引人注目,這要歸功於一種稱為穩定訓練的新方法。該技術使模型能夠生成與文本輸入一致的高質量圖像,使其比以前的文本到圖像模型有了顯著改進。

穩定擴散模型的數據準備

在訓練穩定擴散模型之前,準備用於訓練模型的數據至關重要。該過程涉及以下步驟:

Data collection 數據採集

收集與您期望的結果相關的準確且最新的數據。確保數據準確地代表您希望模型解決的問題。

Data cleaning 數據清洗

消除數據集中的任何異常值、缺失數據或不一致之處,以最大限度地提高模型的準確性。這可能涉及填充缺失值、糾正錯誤或將數據轉換為更可用的格式。

Data preprocessing 數據預處理

應用各種技術來提高模型的準確性和性能。這可能包括歸一化、標準化或降維。

模型設計和算法選擇

準備好數據後,下一步就是設計穩定擴散模型。這涉及為模型選擇適當的算法、架構和參數。穩定擴散模型中使用的一些流行算法包括:

深度卷積神經網絡(DCNN)

生成對抗網絡(GAN)

變分自動編碼器(VAE)

選擇算法和架構時,請考慮問題的複雜性、數據集的大小以及所需的準確度等因素。

訓練穩定擴散模型

要訓​​練您自己的穩定擴散模型,您可以使用各種工具和平台,例如 Google Colab、Jupyter Notebooks 或 TensorFlow。這些平台提供了用於運行實驗、管理模型和生成圖像的交互式環境。

遵循本節中的步驟將使您能夠創建適合您的需求和偏好的擴散模型,從而產生富有洞察力的預測。以下是訓練穩定擴散模型的步驟:

將準備好的數據集分為訓練集和驗證集。使用訓練集來訓練模型,使用驗證集來評估其性能。

從各種可用選項中選擇合適的穩定擴散模型。

使用 PyTorch 或 TensorFlow 等軟件訓練模型。請注意,根據數據集大小和模型複雜性,訓練持續時間可以從幾個小時到幾天不等。

訓練後,使用驗證集評估模型的性能。

一旦對模型的性能感到滿意,就可以通過向模型提供隨機噪聲向量來生成圖像。

在我們詳細指南的幫助下輕鬆安裝穩定擴散。

模型評估和驗證

訓練穩定擴散模型後,必須評估其性能並驗證其準確性。這可以通過使用各種指標將模型的預測與實際結果進行比較來完成,例如:

均方誤差 (MSE)。

均方根誤差 (RMSE)。

平均絕對誤差 (MAE)。

R 平方(決定係數)。

此外,通過確保模型隨著時間的推移產生一致的結果來評估模型的穩定性也至關重要。

穩定擴散模型最佳實踐

為了確保穩定擴散模型的成功訓練,請考慮以下最佳實踐:

  • 使用準確、最新且具有代表性的數據進行培訓。
  • 使用不同的數據集測試模型以評估其性能。
  • 在評估過程中評估模型的準確性和穩定性。
  • 為模型選擇適當的算法、架構和參數。
  • 通過應用數據預處理技術來提高模型的準確性。
  • 並通過持續監控變更或更新來確保其持續性能。

擴散模型應用

擴散模型在各個行業都有廣泛的應用,包括金融、醫療保健、營銷和遊戲。穩定擴散模型的一些常見用途是:

  • 電子商務:網站可以使用穩定的擴散模型根據文字描述生成產品圖像,從而無需真實照片即可展示產品。
  • 廣告:廣告公司可以利用穩定的擴散模型為其廣告活動生成獨特且具有視覺吸引力的視覺效果。
  • 遊戲:遊戲開發者可以採用穩定的擴散模型,根據文本描述生成遊戲資產,例如角色和環境。

訓練穩定擴散需要多長時間?

訓練穩定擴散所需的時間取決於許多因素。因此包括數據集的大小、您使用的硬件以及輸出圖像的質量。

如果您使用較小的數據集或功能較弱的硬件,則訓練穩定擴散將需要更長的時間。例如,一位用戶報告說,他們花了大約 2 週的時間在單個 V100 GPU 上訓練穩定擴散。

如果您不確定訓練穩定擴散需要多長時間,您可以先嘗試使用較小的數據集或功能較弱的硬件。您還可以嘗試使用預先訓練的穩定擴散模型,這將為您節省一些時間。

以下是一些加快穩定擴散訓練的技巧:

  • 使用更大的數據集:更大的數據集將為穩定擴散提供更多可供學習的信息,這將加快訓練過程。
  • 使用更強大的GPU:更強大的GPU將能夠更快地處理數據,這也將加快訓練過程。
  • 使用預先訓練的模型:預先訓練的模型已經具有一些如何生成圖像的知識,這將加快訓練過程。

常見問題 (FAQ)

問:如何製作穩定擴散模型?

答:製作穩定擴散模型需要大量的技術知識和資源。這不是一件容易或快速就能完成的事情。以下是製作穩定擴散模型的基本步驟:

  • 收集大量圖像數據集:該數據集應盡可能多樣化,以確保模型可以生成各種圖像。
  • 預處理數據集:這涉及將圖像轉換為模型可以理解的格式。
  • 訓練模型:這是最耗時的步驟。該模型需要在數據集上進行長時間的訓練,才能學習如何生成圖像。
  • 測試模型:模型訓練完成後,需要在新的圖像數據集上進行測試。這將有助於確保模型生成高質量的圖像。

問:訓練穩定擴散模型需要多長時間?

答:訓練穩定擴散模型所需的時間取決於多種因素,包括數據集的大小、模型的複雜性和可用的計算資源。

一般來說,在大型數據集上訓練穩定擴散模型可能需要幾天甚至幾週的時間。例如,在 ImageNet 數據集上訓練穩定擴散模型在單個 GPU 上可能需要長達 10 天的時間。

如果您使用較小的數據集或不太複雜的模型,訓練時間會更短。然而,值得注意的是,即使是小模型也可能需要幾個小時來訓練。

問:如何通過穩定擴散獲得更好的結果?

答:您可以採取一些措施來獲得更好的穩定擴散效果:

  • 使用更大的數據集:模型需要學習的數據越多,結果就越好。
  • 使用更複雜的模型:更複雜的模型將能夠學習數據中更複雜的模式,從而獲得更好的結果。
  • 訓練模型的時間越長:模型訓練的時間越長,結果就越好。
  • 使用更好的優化器:優化器是一種幫助模型學習的數學算法。使用更好的優化器可以幫助模型更快收斂並獲得更好的結果。
  • 使用更複雜的損失函數:損失函數是一個數學方程,用於衡量模型的性能。使用更複雜的損失函數可以幫助模型更有效地學習。
  • 使用正則化技術:正則化是一種有助於防止模型過度擬合數據的技術。當模型學習數據中的噪聲而不是底層模式時,就會發生過度擬合。使用正則化技術有助於提高模型的泛化性能。

問:如何訓練穩定擴散權重?

用戶可以使用多種方法訓練穩定擴散權重,包括:

  • 監督學習:在監督學習中,模型在已標記有所需輸出的圖像數據集上進行訓練。例如,該模型可以使用貓和狗的圖像數據集,每個圖像標記為“貓”或“狗”。
  • 無監督學習:在無監督學習中,模型在沒有任何標籤的圖像數據集上進行訓練。該模型學習在數據中查找模式,而無需明確告知要查找什麼。
  • 半監督學習:在半監督學習中,模型在已部分標記的圖像數據集上進行訓練。當沒有足夠的標記數據可用時,這可能是提高模型性能的有用方法。

訓練穩定擴散權重的最佳方法取決於具體應用。例如,如果你想訓練一個模型來生成貓和狗的圖像,監督學習將是一個不錯的選擇。如果你想訓練一個模型來生成任何物體的圖像,無監督學習將是更好的選擇。

問:穩定擴散可以訓練嗎?

答:是的,穩定擴散是可以訓練的。它是一種擴散模型,是一類可以訓練生成圖像的生成模型。穩定擴散是一種特殊類型的擴散模型,其設計比其他擴散模型更穩定且更易於訓練。

穩定擴散模型使用稱為對抗訓練的技術進行訓練。在對抗性訓練中,兩個模型相互訓練。一種模型是生成器,它負責生成圖像。另一個模型是鑑別器,負責區分真實圖像和生成圖像。

生成器可以生成盡可能真實的圖像。鑑別器可以區分真實圖像和生成圖像。作為生成器和鑑別器,它們在各自的任務上變得更好。最終,生成器變得非常擅長生成逼真的圖像,以至於鑑別器無法再區分它們。

問:訓練穩定擴散需要多少張照片?

答:訓練穩定擴散所需的照片數量取決於要訓練的模型的大小和復雜性。較大的模型比較小的模型需要更多的照片。

一般來說,您至少需要幾千張照片來訓練穩定擴散模型。但是,如果使用稱為數據增強的技術,則可以使用更少的照片來訓練模型。數據增強是一種通過從現有圖像創建新圖像來人為地增加數據集大小的技術。

結論

訓練穩定的擴散模型似乎具有挑戰性。然而,理解這個過程並使用正確的方法可以將其變成結果預測的強大工具。

本綜合指南的步驟和最佳實踐可以幫助您掌握這些模型的訓練並充分發揮其潛力。

無論您是業餘愛好者還是專業人士,深入研究穩定擴散模型的令人興奮的世界都可以讓您創造出令人驚嘆的視覺效果並獲得寶貴的見解。