【Datawhale组队学习:Sora原理与技术实战】

Transformers+diffusion技术背景简介

Transformers diffusion背景

近期大火的OpenAI推出的Sora模型,其核心技术点之一,是将视觉数据转化为Patch的统一表示形式,并通过Transformers技术和扩散模型结合,展现了卓越的scale特性。

被Twitter上广泛传播的论文《Scalable diffusion models with transformers》也被认为是Sora技术背后的重要基础。而这项研究的发布遇到了一些坎坷,曾经被CVPR2023拒稿过。然DiT被拒了,我们看到来自清华大学,人民大学等机构共同研究的CVPR2023的论文U-ViT《All are Worth Words: A ViT Backbone for Diffusion Models》,2022年9月发表,这项研究设计了一个简单而通用的基于vit的架构(U-ViT),替换了U-Net中的卷积神经网络(CNN),用于diffusion模型的图像生成任务。

项目已经开源
GitHub链接: https://github.com/baofff/U-ViT

论文链接:https://arxiv.org/abs/2209.12152

模型链接:https://modelscope.cn/models/thu-ml/imagenet256_uvit_huge

但是,正如作者所说的,Sora将基于Transformers的diffusion model scale up成功,不仅需要对底层算法有专家级理解,还要对整个深度学习工程体系有很好的把握,这项工作相比在学术数据集做出一个可行架构更加困难。

什么是ViT

Vision Transformer (ViT) 模型由 Alexey Dosovitskiy等人在 An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 中提出。这是第一篇在 ImageNet 上成功训练 Transformer 编码器的论文,与熟悉的卷积架构相比,取得了非常好的结果。论文提出,虽然 Transformer 架构已成为自然语言处理任务事实上的标准,但其在计算机视觉中的应用仍然有限。 在视觉中,attention要么与卷积网络结合应用,要么用于替换卷积网络的某些组件,同时保持其整体结构不变。 ViT证明这种对 CNN 的依赖是不必要的,直接应用于图像块序列(patches)的纯 Transformer 可以在图像分类任务上表现良好。 当对大量数据进行预训练并转移到多个中型或小型图像识别基准(ImageNet、CIFAR-100、VTAB 等)时,Vision Transformer (ViT) 与SOTA的CNN相比取得了优异的结果,同时需要更少的计算资源来训练,Vision Transformer (ViT) 基本上是 Transformers,但应用于图像。

每个图像被分割成一系列不重叠的块(分辨率如 16x16 或 32x32),并线性embedding,接下来,添加position embedding,并通过编码器层发送。 在开头添加 [CLS] 标记以获得整个图像的表示。 可以在hidden states之上添加MLP head以对图像进行分类。
在这里插入图片描述
论文:
An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale

Paper: https://arxiv.org/abs/2010.11929

Official repo (in JAX): https://github.com/google-research/vision_transformer

ViT在大语言模型中的使用(Qwen-VL为例)

Qwen-VL: Qwen-VL 以 Qwen-7B 的预训练模型作为语言模型的初始化,并以openclip-ViT-bigG作为视觉编码器的初始化,中间加入单层随机初始化的 cross-attention,经过约1.5B的图文数据训练得到。最终图像输入分辨率为448*448。
在这里插入图片描述
论文链接:

https://arxiv.org/abs/2010.11929

ViViT:视频ViT

ViViT基于纯变压器的视频模型分类,借鉴了ViT图像分类中取得的成功。 ViViT从输入视频中提取时空标记,然后由一系列转换器层进行编码。

源自:Arnab, Anurag, et al. “Vivit: A video vision transformer.” ICCV2021

paper:https://arxiv.org/abs/2103.15691

Latte:用于视频生成的潜在扩散变压器

Latte提出了一种新颖的潜在扩散变压器,用于视频生成。Latte 首先从输入视频中提取时空标记,然后采用一系列 Transformer 块对潜在空间中的视频分布进行建模。为了对从视频中提取的大量标记进行建模,从分解输入视频的空间和时间维度的角度引入了四种有效的变体。为了提高生成视频的质量,我们通过严格的实验分析确定了 Latte 的最佳实践,包括视频剪辑补丁嵌入、模型变体、时间步级信息注入、时间位置嵌入和学习策略。我们的综合评估表明,Latte 在四个标准视频生成数据集(即 FaceForensics、SkyTimelapse、UCF101 和 Taichi-HD)上实现了最先进的性能。此外, Latte也 扩展到文本到视频生成 (T2V) 任务,其中 Latte 取得了与最新 T2V 模型相当的结果。我们坚信,Latte 为未来将 Transformer 纳入视频生成扩散模型的研究提供了宝贵的见解。

代码实战

Patch最佳实践

图像预处理:

具体步骤如下:

读取图像: 使用 tf.keras.utils.load_img 函数从给定路径 /mnt/workspace/image_1.png 读取图像。设置参数 grayscale=False 表示读取彩色图像,color_mode=‘rgb’ 指定了图像为 RGB 格式。由于 target_size=None,图像将保持原始尺寸不变。interpolation=‘nearest’ 表示在缩放时采用最近邻插值方法。

转换为数组格式: 使用 tf.keras.preprocessing.image.img_to_array 将读取到的 PIL 图像对象转换为 Numpy 数组(在 TensorFlow 中表示为 tensor)。

图像缩放: 判断条件 if (scale),如果为真,则使用 tf.image.resize 对图像进行缩放到指定大小(即 image_dim)。这里采用了双线性插值方法 (ResizeMethod.BILINEAR) 进行缩放,并且不保留原始宽高比 (preserve_aspect_ratio=False)。

裁剪图像: 使用 tf.image.crop_to_bounding_box 对图像进行裁剪,裁剪区域是从原图的左上角 (0, 0) 开始,裁剪出一个 image_dim x image_dim 大小的正方形图像。

返回处理后的图像: 最终返回经过上述预处理步骤后得到的图像数组(tensor)。

这段代码,能够以统一大小加载并预处理图片,这对于后续将图片输入到深度学习模型中是非常常见的做法。

import tensorflow as tf

# Image preprocessing

def read_image(image_file="/mnt/workspace/image_1.png", scale=True, image_dim=336):

    image = tf.keras.utils.load_img(
        image_file, grayscale=False, color_mode='rgb', target_size=None,
        interpolation='nearest'
    )
    image_arr_orig = tf.keras.preprocessing.image.img_to_array(image)
    if(scale):
        image_arr_orig = tf.image.resize(
            image_arr_orig, [image_dim, image_dim],
            method=tf.image.ResizeMethod.BILINEAR, preserve_aspect_ratio=False
        )
    image_arr = tf.image.crop_to_bounding_box(
        image_arr_orig, 0, 0, image_dim, image_dim
    )

    return image_arr
创建Patch

这段代码是使用TensorFlow库来从输入图像中提取32x32大小的图像块(即patch)并将其转化为一维向量。以下是详细的步骤解释:

def create_patches(image): 定义了一个名为create_patches的函数,参数为image图像张量。

im = tf.expand_dims(image, axis=0):使用TensorFlow的expand_dims函数在图像数据的第0维(batch维度)增加一个维度,以便能够处理一批图片,即使现在我们只有一张图片。

patches = tf.image.extract_patches(…):调用TensorFlow的extract_patches函数从图像中提取 patches。这里的设置表明:

images=im 表示要提取 patches 的图像。
sizes=[1, 32, 32, 1] 表示每个 patch 的大小为 32x32 像素,并且深度(通道数)与原图相同。
strides=[1, 32, 32, 1] 表示在宽度和高度方向上以32像素为步长移动来提取相邻的 patch。
rates=[1, 1, 1, 1] 表示采样率,在此处等于 strides,意味着没有进行亚像素采样。
padding=“VALID” 表示不进行额外的填充,只对完全包含在原始图像内的 patch 进行提取。
patch_dims = patches.shape[-1]:获取提取出的 patches 在最后一个维度(在这里指的是每个 patch 的元素数量,即3232C,C为通道数)的大小。

patches = tf.reshape(patches, [1, -1, patch_dims]):将提取到的一系列 patches 进行reshape,将其展平为一个一维数组,其中第一个维度表示 batch 大小(这里为1),第二个维度是所有 patches 的总数量(-1表示自动计算这一维度的大小),第三个维度是每个 patch 的元素数量。

函数最后返回经过处理得到的 patches 张量。

image_arr = read_image():假设这是一个读取图像并转换为张量的函数,用于获取待处理的图像。

patches = create_patches(image_arr):调用create_patches函数,传入读取到的图像数据,得到该图像分割后的 patches。

# Patching
def create_patches(image):
    im = tf.expand_dims(image, axis=0)
    patches = tf.image.extract_patches(
        images=im,
        sizes=[1, 32, 32, 1],
        strides=[1, 32, 32, 1],
        rates=[1, 1, 1, 1],
        padding="VALID"
    )
    patch_dims = patches.shape[-1]
    patches = tf.reshape(patches, [1, -1, patch_dims])

    return patches

image_arr = read_image()
patches = create_patches(image_arr)
绘制patches

这段代码是使用matplotlib库在Python中绘制图像及其分块patches的函数定义,并在最后调用了这两个函数来显示结果。它假定您正在处理一个TensorFlow环境,其中image_arr是一个图像数组(可能已经被转换为浮点数),而patches是一个形状如(batch_size, num_patches, patch_height, patch_width, channels)的张量,其中包含了从image_arr图像中提取出的多个小图像块(patches)。

函数解释:

  1. render_image_and_patches(image, patches)

    • 这个函数首先创建一个新的图形窗口,并设置其大小为16x16英寸。
    • 使用suptitle添加标题"Cropped Image",并设置字体大小为48。
    • 使用plt.imshow显示原始image_arr图像,将其转换回uint8类型以便正确显示,并关闭坐标轴显示。
    • 计算patches矩阵的行数和列数(假设patch的数量是平方数)。
    • 创建第二个图形窗口同样大小为16x16英寸,添加标题"Image Patches"。
    • 遍历patches的第一个样本的所有patch,对每个patch进行以下操作:
      • 在网格布局中创建一个新的子图(subplot)。
      • 将该patch reshape为(32, 32, 3),即尺寸为32x32像素且有3个颜色通道的小图像。
      • 使用imshow展示这个patch,并关闭坐标轴显示。
  2. render_flat(patches)

    • 这个函数创建一个图形窗口,其宽度为32英寸,高度为2英寸。
    • 添加标题"Flattened Image Patches",并设置字体大小为24。
    • 同样遍历patches的第一个样本的所有patch,但这次是在一个水平方向上连续排列的子图中显示它们。
      • 只显示前100个patch(通过if条件判断i == 100时跳出循环)。
      • 对每个patch重复与上述相同的reshaping和显示过程。

当调用这两个函数时,将会显示两个图表:

  • 第一个图表包含原始整幅图像以及从该图像分割出来的patches。
  • 第二个图表则展示了patches在一行内水平排列的扁平化视图,最多显示前100个patch。

原图:
在这里插入图片描述

# Drawing
import numpy as np
import matplotlib.pyplot as plt

def render_image_and_patches(image, patches):
    plt.figure(figsize=(16, 16))
    plt.suptitle(f"Cropped Image", size=48)
    plt.imshow(tf.cast(image, tf.uint8))
    plt.axis("off")
    n = int(np.sqrt(patches.shape[1]))
    plt.figure(figsize=(16, 16))
    plt.suptitle(f"Image Patches", size=24)
    for i, patch in enumerate(patches[0]):
        ax = plt.subplot(n, n, i+1)
        patch_img = tf.reshape(patch, (32, 32, 3))
        ax.imshow(patch_img.numpy().astype("uint8"))
        ax.axis("off")

def render_flat(patches):
    plt.figure(figsize=(32, 2))
    plt.suptitle(f"Flattened Image Patches", size=24)
    n = int(np.sqrt(patches.shape[1]))
    for i, patch in enumerate(patches[0]):
        ax = plt.subplot(1, 101, i+1)
        patch_img = tf.reshape(patch, (32, 32, 3))
        ax.imshow(patch_img.numpy().astype("uint8"))
        ax.axis("off")
        if(i == 100):
            break


render_image_and_patches(image_arr, patches)
render_flat(patches)

运行结果
在这里插入图片描述
在这里插入图片描述

ViT最佳实践

在这里插入图片描述

from transformers import ViTForImageClassification
import torch
from modelscope import snapshot_download
from PIL import Image
import requests
from transformers import ViTImageProcessor

model_dir = snapshot_download('AI-ModelScope/vit-base-patch16-224')

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

model = ViTForImageClassification.from_pretrained(model_dir)
model.to(device)

url = './000000039769.jpg'
image = Image.open(url)

processor = ViTImageProcessor.from_pretrained(model_dir)
inputs = processor(images=image, return_tensors="pt").to(device)
pixel_values = inputs.pixel_values

print(pixel_values.shape)

with torch.no_grad():
  outputs = model(pixel_values)
logits = outputs.logits
print(logits.shape)

prediction = logits.argmax(-1)
print("Predicted class:", model.config.id2label[prediction.item()])

运行结果

torch.Size([1, 3, 224, 224])
torch.Size([1, 1000])
Predicted class: Egyptian cat

UViT最佳实践

下载代码仓

git clone https://github.com/baofff/U-ViT
pip install einops

创建代码并且放到U-ViT目录下

import os
import torch
from dpm_solver_pp import NoiseScheduleVP, DPM_Solver
import libs.autoencoder
from libs.uvit import UViT
import einops
from torchvision.utils import save_image
from PIL import Image
import os

from modelscope.hub.file_download import model_file_download

image_size = "256" #@param [256, 512]
image_size = int(image_size)

if image_size == 256:
    model_file_download(model_id='thu-ml/imagenet256_uvit_huge',file_path='imagenet256_uvit_huge.pth', cache_dir='/root/temp/workspace')
    os.system("mv /root/temp/workspace/thu-ml/imagenet256_uvit_huge/imagenet256_uvit_huge.pth /root/temp/workspace/U-ViT/imagenet256_uvit_huge.pth")
else:
    model_file_download(model_id='thu-ml/imagenet512_uvit_huge',file_path='imagenet512_uvit_huge.pth', cache_dir='/root/temp/workspace')
    os.system("mv /root/temp/workspace/thu-ml/imagenet512_uvit_huge/imagenet512_uvit_huge.pth /root/temp/workspace/U-ViT/imagenet512_uvit_huge.pth")
 
z_size = image_size // 8
patch_size = 2 if image_size == 256 else 4
device = 'cuda' if torch.cuda.is_available() else 'cpu'

nnet = UViT(img_size=z_size,
       patch_size=patch_size,
       in_chans=4,
       embed_dim=1152,
       depth=28,
       num_heads=16,
       num_classes=1001,
       conv=False)

nnet.to(device)
nnet.load_state_dict(torch.load(f'/root/temp/workspace/U-ViT/imagenet{image_size}_uvit_huge.pth', map_location='cpu'))
nnet.eval()

model_file_download(model_id='AI-ModelScope/autoencoder_kl_ema',file_path='autoencoder_kl_ema.pth', cache_dir='/root/temp/workspace')
os.system("mv /root/temp/workspace/AI-ModelScope/autoencoder_kl_ema/autoencoder_kl_ema.pth /root/temp/workspace/U-ViT/autoencoder_kl_ema.pth")
autoencoder = libs.autoencoder.get_model('/root/temp/workspace/U-ViT/autoencoder_kl_ema.pth')
autoencoder.to(device)

seed = 4321 #@param {type:"number"}
steps = 25 #@param {type:"slider", min:0, max:1000, step:1}
cfg_scale = 3 #@param {type:"slider", min:0, max:10, step:0.1}
class_labels = 207, 360, 387, 974, 88, 979, 417, 279 #@param {type:"raw"}
samples_per_row = 4 #@param {type:"number"}
torch.manual_seed(seed)

def stable_diffusion_beta_schedule(linear_start=0.00085, linear_end=0.0120, n_timestep=1000):
    _betas = (
        torch.linspace(linear_start ** 0.5, linear_end ** 0.5, n_timestep, dtype=torch.float64) ** 2
    )
    return _betas.numpy()


_betas = stable_diffusion_beta_schedule()  # set the noise schedule
noise_schedule = NoiseScheduleVP(schedule='discrete', betas=torch.tensor(_betas, device=device).float())


y = torch.tensor(class_labels, device=device)
y = einops.repeat(y, 'B -> (B N)', N=samples_per_row)

def model_fn(x, t_continuous):
    t = t_continuous * len(_betas)
    _cond = nnet(x, t, y=y)
    _uncond = nnet(x, t, y=torch.tensor([1000] * x.size(0), device=device))
    return _cond + cfg_scale * (_cond - _uncond)  # classifier free guidance


z_init = torch.randn(len(y), 4, z_size, z_size, device=device)
dpm_solver = DPM_Solver(model_fn, noise_schedule, predict_x0=True, thresholding=False)

with torch.no_grad():
  with torch.cuda.amp.autocast():  # inference with mixed precision
    z = dpm_solver.sample(z_init, steps=steps, eps=1. / len(_betas), T=1.)
    samples = autoencoder.decode(z)
samples = 0.5 * (samples + 1.)
samples.clamp_(0., 1.)
save_image(samples, "sample.png", nrow=samples_per_row * 2, padding=0)

运行结果
在这里插入图片描述

ViViT最佳实践

安装依赖

pip install ipywidgets medmnist

下载数据集到/root/temp/workspace

wget https://modelscope.oss-cn-beijing.aliyuncs.com/resource/organmnist3d.npz -O /root/temp/workspace/organmnist3d.npz

代码

import os
import io
import imageio
import medmnist
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# setting seed for reproducibility
SEED = 42
os.environ["TF_CUDNN_DETERMINISTIC"] = "1"
keras.utils.set_random_seed(SEED)

# DATA
DATASET_NAME = "organmnist3d"
BATCH_SIZE = 32
AUTO = tf.data.AUTOTUNE
INPUT_SHAPE = (28, 28, 28, 1)
NUM_CLASSES = 11

# OPTIMIZER
LEARNING_RATE = 1e-4
WEIGHT_DECAY = 1e-5

# TRAINING
EPOCHS = 60

# TUBELET EMBEDDING
PATCH_SIZE = (8, 8, 8)
NUM_PATCHES = (INPUT_SHAPE[0] // PATCH_SIZE[0]) ** 2

# ViViT ARCHITECTURE
LAYER_NORM_EPS = 1e-6
PROJECTION_DIM = 128
NUM_HEADS = 8
NUM_LAYERS = 8

def download_and_prepare_dataset(data_info: dict):
    """
    Utility function to download the dataset and return train/valid/test
    videos and labels.
    Arguments:
        data_info (dict): Dataset metadata
    """
    data_path = "/root/temp/workspace/organmnist3d.npz"

    with np.load(data_path) as data:
        # Get videos
        train_videos = data["train_images"]
        valid_videos = data["val_images"]
        test_videos = data["test_images"]

        # Get labels
        train_labels = data["train_labels"].flatten()
        valid_labels = data["val_labels"].flatten()
        test_labels = data["test_labels"].flatten()

    return (
        (train_videos, train_labels),
        (valid_videos, valid_labels),
        (test_videos, test_labels),
    )


# Get the metadata of the dataset
info = medmnist.INFO[DATASET_NAME]

# Get the dataset
prepared_dataset = download_and_prepare_dataset(info)
(train_videos, train_labels) = prepared_dataset[0]
(valid_videos, valid_labels) = prepared_dataset[1]
(test_videos, test_labels) = prepared_dataset[2]

@tf.function
def preprocess(frames: tf.Tensor, label: tf.Tensor):
    """Preprocess the frames tensors and parse the labels"""
    # Preprocess images
    frames = tf.image.convert_image_dtype(
        frames[
            ..., tf.newaxis
        ],  # The new axis is to help for further processing with Conv3D layers
        tf.float32,
    )

    # Parse label
    label = tf.cast(label, tf.float32)
    return frames, label


def prepare_dataloader(
    videos: np.ndarray,
    labels: np.ndarray,
    loader_type: str = "train",
    batch_size: int = BATCH_SIZE,
):
    """Utility function to prepare dataloader"""
    dataset = tf.data.Dataset.from_tensor_slices((videos, labels))

    if loader_type == "train":
        dataset = dataset.shuffle(BATCH_SIZE * 2)

    dataloader = (
        dataset.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE)
        .batch(batch_size)
        .prefetch(tf.data.AUTOTUNE)
    )

    return dataloader


trainloader = prepare_dataloader(train_videos, train_labels, "train")
validloader = prepare_dataloader(valid_videos, valid_labels, "valid")
testloader = prepare_dataloader(test_videos, test_labels, "test")

class TubeletEmbedding(layers.Layer):
    def __init__(self, embed_dim, patch_size, **kwargs):
        super().__init__(**kwargs)
        self.projection = layers.Conv3D(
            filters=embed_dim,
            kernel_size=patch_size,
            strides=patch_size,
            padding="VALID",
        )
        self.flatten = layers.Reshape(target_shape=(-1, embed_dim))

    def call(self, videos):
        projected_patches = self.projection(videos)
        flattened_patches = self.flatten(projected_patches)
        return flattened_patches

class PositionalEncoder(layers.Layer):
    def __init__(self, embed_dim, **kwargs):
        super().__init__(**kwargs)
        self.embed_dim = embed_dim

    def build(self, input_shape):
        _, num_tokens, _ = input_shape
        self.position_embedding = layers.Embedding(
            input_dim=num_tokens, output_dim=self.embed_dim
        )
        self.positions = tf.range(start=0, limit=num_tokens, delta=1)

    def call(self, encoded_tokens):
        # Encode the positions and add it to the encoded tokens
        encoded_positions = self.position_embedding(self.positions)
        encoded_tokens = encoded_tokens + encoded_positions
        return encoded_tokens

def create_vivit_classifier(
    tubelet_embedder,
    positional_encoder,
    input_shape=INPUT_SHAPE,
    transformer_layers=NUM_LAYERS,
    num_heads=NUM_HEADS,
    embed_dim=PROJECTION_DIM,
    layer_norm_eps=LAYER_NORM_EPS,
    num_classes=NUM_CLASSES,
):

    # Get the input layer
    inputs = layers.Input(shape=input_shape)
    # Create patches.
    patches = tubelet_embedder(inputs)
    # Encode patches.
    encoded_patches = positional_encoder(patches)

    # Create multiple layers of the Transformer block.
    for _ in range(transformer_layers):
        # Layer normalization and MHSA
        x1 = layers.LayerNormalization(epsilon=1e-6)(encoded_patches)
        attention_output = layers.MultiHeadAttention(
            num_heads=num_heads, key_dim=embed_dim // num_heads, dropout=0.1
        )(x1, x1)

        # Skip connection
        x2 = layers.Add()([attention_output, encoded_patches])

        # Layer Normalization and MLP
        x3 = layers.LayerNormalization(epsilon=1e-6)(x2)
        x3 = keras.Sequential(
            [
                layers.Dense(units=embed_dim * 4, activation=tf.nn.gelu),
                layers.Dense(units=embed_dim, activation=tf.nn.gelu),
            ]
        )(x3)

        # Skip connection
        encoded_patches = layers.Add()([x3, x2])

    # Layer normalization and Global average pooling.
    representation = layers.LayerNormalization(epsilon=layer_norm_eps)(encoded_patches)
    representation = layers.GlobalAvgPool1D()(representation)

    # Classify outputs.
    outputs = layers.Dense(units=num_classes, activation="softmax")(representation)

    # Create the Keras model.
    model = keras.Model(inputs=inputs, outputs=outputs)
    return model

def run_experiment():
    # Initialize model
    model = create_vivit_classifier(
        tubelet_embedder=TubeletEmbedding(
            embed_dim=PROJECTION_DIM, patch_size=PATCH_SIZE
        ),
        positional_encoder=PositionalEncoder(embed_dim=PROJECTION_DIM),
    )

    # Compile the model with the optimizer, loss function
    # and the metrics.
    optimizer = keras.optimizers.Adam(learning_rate=LEARNING_RATE)
    model.compile(
        optimizer=optimizer,
        loss="sparse_categorical_crossentropy",
        metrics=[
            keras.metrics.SparseCategoricalAccuracy(name="accuracy"),
            keras.metrics.SparseTopKCategoricalAccuracy(5, name="top-5-accuracy"),
        ],
    )

    # Train the model.
    _ = model.fit(trainloader, epochs=EPOCHS, validation_data=validloader)

    _, accuracy, top_5_accuracy = model.evaluate(testloader)
    print(f"Test accuracy: {round(accuracy * 100, 2)}%")
    print(f"Test top 5 accuracy: {round(top_5_accuracy * 100, 2)}%")

    return model

model = run_experiment()

import ipywidgets
NUM_SAMPLES_VIZ = 25
testsamples, labels = next(iter(testloader))
testsamples, labels = testsamples[:NUM_SAMPLES_VIZ], labels[:NUM_SAMPLES_VIZ]

ground_truths = []
preds = []
videos = []


for i, (testsample, label) in enumerate(zip(testsamples, labels)):
    # Generate gif
    with io.BytesIO() as gif:
        imageio.mimsave(gif, (testsample.numpy() * 255).astype("uint8")[..., 0], "GIF", fps=5)
        videos.append(gif.getvalue())

    # Get model prediction
    output = model.predict(tf.expand_dims(testsample, axis=0))[0]
    pred = np.argmax(output, axis=0)

    ground_truths.append(label.numpy().astype("int"))
    preds.append(pred)


def make_box_for_grid(image_widget, fit):
    """
    Make a VBox to hold caption/image for demonstrating
    option_fit values.
    Source: https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Styling.html
    """
    # Make the caption
    if fit is not None:
        fit_str = "'{}'".format(fit)
    else:
        fit_str = str(fit)

    h = ipywidgets.HTML(value="" + str(fit_str) + "")

    # Make the green box with the image widget inside it
    boxb = ipywidgets.widgets.Box()
    boxb.children = [image_widget]

    # Compose into a vertical box
    vb = ipywidgets.widgets.VBox()
    vb.layout.align_items = "center"
    vb.children = [h, boxb]
    return vb


boxes = []
for i in range(NUM_SAMPLES_VIZ):
    ib = ipywidgets.widgets.Image(value=videos[i], width=100, height=100)
    true_class = info["label"][str(ground_truths[i])]
    pred_class = info["label"][str(preds[i])]
    caption = f"T: {true_class} | P: {pred_class}"

    boxes.append(make_box_for_grid(ib, caption))

ipywidgets.widgets.GridBox(
    boxes, layout=ipywidgets.widgets.Layout(grid_template_columns="repeat(5, 200px)")
)

Latte最佳实践

下载代码仓

git clone https://github.com/maxin-cn/latte.git

安装依赖

pip install timm
pip install einops
pip install omegaconf
pip install modelscope
pip install diffusers==0.24.0
pip install sentencepiece beautifulsoup4 ftfy
pip install imageio[ffmpeg] imageio[pyav]
pip install transformers
pip install accelerate
pip install tensorboard

下载模型到Latte/models目录下

import torch
from modelscope import snapshot_download, AutoModel, AutoTokenizer
import os
model_dir = snapshot_download('AI-ModelScope/Latte', cache_dir='/root/temp/Latte/models/', revision='master')

修改配置文件configs/t2v/t2v_sample.yaml

path:
ckpt: ./models/Latte/t2v.pt
save_img_path: "./sample_videos/t2v"
pretrained_model_path: "./models/Latte/t2v_required_models"

执行命令

export CUDA_VISIBLE_DEVICES=0
export PYTHONPATH=../
python sample/sample_t2v.py --config configs/t2v/t2v_sample.yaml

扩展学习:LaVie

安装依赖

pip install accelerate==0.19.0
pip install av==10.0.0
pip install decord==0.6.0
pip install diffusers[torch]==0.16.0
pip install einops==0.6.1
pip install ffmpeg==1.4
pip install imageio==2.31.1
pip install imageio-ffmpeg==0.4.9
pip install pandas==2.0.1
pip install timm==0.6.13
pip install tqdm==4.65.0
pip install transformers==4.28.1
pip install xformers==0.0.20
pip install omegaconf==2.3.0
pip install natsort==8.4.0
pip install rotary_embedding_torch

下载代码仓

git clone https://github.com/Vchitect/LaVie

设置hf-mirror

export HF_ENDPOINT="https://hf-mirror.com"

下载模型到代码仓models目录下

huggingface-cli download --resume-download --local-dir-use-symlinks False YaohuiW/LaVie --local-dir /root/temp/LaVie/pretrained_models

huggingface-cli download --resume-download --local-dir-use-symlinks False CompVis/stable-diffusion-v1-4 --local-dir /root/temp/LaVie/pretrained_models/stable-diffusion-v1-4

huggingface-cli download --resume-download --local-dir-use-symlinks False stabilityai/stable-diffusion-x4-upscaler --local-dir /root/temp/LaVie/pretrained_models/stable-diffusion-x4-upscaler

参考资料

学习视频:https://www.bilibili.com/video/BV1px421y7qU

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/437807.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

成功实施自动化测试的优点

随着技术的发展,保证应用程序的质量变得越来越具有挑战性。由于敏捷开发和成本因素,导致了发现问题窗口时间有限,因此测试经常会忽略某些应该关注的地方。 测试工程师应该在发布产品之前发现其中存在的问题,但是任何软件都不可能…

SpringBoot项目如何添加全局接口上下文

1. 定义Spring Boot应用的路由 首先,确保您的Spring Boot应用有一个统一的路由前缀。例如,可以在application.properties或application.yml配置文件中使用server.servlet.context-path属性来定义所有请求的基础路径。 # application.properties server…

Ansible 基础入门

2)Ansible 介绍 Ansible 基本概念 Ansible 是一种自动化运维工具,基于 Paramiko 开发的,并且基于模块化工作,Ansible 是一种集成 IT 系统的配置管理、应用部署、执行特定任务的开源平台,它是基于 Python 语言&#xf…

sudo command not found

文章目录 一句话Intro其他操作 一句话 sudo 某命令 改成 sudo -i 某命令 试试。 -i 会把当前用户的环境变量带过去,这样在sudo的时候,有更高的权限,有本用户的环境变量(下的程序命令)。 -i, --login run login shell as the target user; a …

I’m stuck!(CCF201312-5)解析(java实现)

代码 package test_201312;import java.util.Scanner;/** 201312-5 试题名称: I’m stuck! 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述给定一个R行C列的地图,地图的每一个方格可能是#, , -, |, ., S, T七…

JS使用方式

JS是解释性语言,所以不需要搭建类似C#/Java之类的开发运行环境,因为他们是编译型语言。JS一般运行在浏览器中或者node环境中,这里都是JS引擎的功劳。 node环境使用 推荐使用nvm管理node版本,nrm管理代理地址。 安装node&#xf…

腾讯云服务器和阿里云服务器哪家更优惠?2024价格对比

2024年阿里云服务器和腾讯云服务器价格战已经打响,阿里云服务器优惠61元一年起,腾讯云服务器61元一年,2核2G3M、2核4G、4核8G、4核16G、8核16G、16核32G、16核64G等配置价格对比,阿腾云atengyun.com整理阿里云和腾讯云服务器详细配…

【蓝桥杯基础算法】dfs(上)组合数,全排列

刚接触算法&#xff0c;有没有被递归又循环的dfs吓到&#xff1f;没关系&#xff0c;几个例题就可以彻底掌握&#xff01; 1.全排列 1-n的全排列,如输入3&#xff0c;按顺序对1-3进行排列 //枚举 #include<iostream> #include<algorithm> #include<cstring>…

【Linux基础(二)】进程管理

学习分享 1、程序和进程1.1、程序1.2、进程和进程ID 2、Linux下的进程结构3、init进程4、获取进程标识5、fork系统调用5.1、fork函数实例分析 6、进程的特性7、在Linux下进程指令7.1、终止进程指令7.2、查看进程指令&#xff1a;7.3、以树状图列出进程 8、多进程运行异常情况8.…

【Spring云原生系列】Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合!

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &a…

2024年抖店新商家自学全套教程,完整版店铺操作流程,如下!

我是王路飞。 想做一个项目的话&#xff0c;就要先了解其完整的流程是怎样的。 做抖店也不例外&#xff0c;没开店的就先了解下抖店的基本信息和大概运营流程&#xff1b;开过店的就先让自己入门并把流程跑通&#xff0c;如此才有承接后续渠道和资源的能力。 今天这篇文章专…

计算机网络:应用层知识点汇总

文章目录 一、网络应用模型二、域名系统&#xff08;DNS&#xff09;三、文本传输协议&#xff08;FTP&#xff09;四、电子邮件五、万维网和HTTP协议 一、网络应用模型 p2p也就是对等模型 二、域名系统&#xff08;DNS&#xff09; 我们知道&#xff0c;随着人们建立一个网站…

【机器学习】【决策树】分类树|回归树学习笔记总结

决策树算法概述 基本概念 决策树&#xff1a;从根节点开始一步步走到叶子节点&#xff0c;每一步都是决策过程 对于判断的先后顺序把控特别严格 一旦将判断顺序进行变化则最终的结果将可能发生改变 往往将分类效果较佳的判断条件放在前面&#xff0c;即先初略分在进行细节分…

python中的文件操作2

文件遍历 在Python中&#xff0c;遍历文件通常指的是逐行读取文件中的内容。这种方式对于处理大型文件特别有用&#xff0c;因为它不需要一次性将整个文件加载到内存中。下面是几种常见的遍历文件内容的方法&#xff1a; 1. 使用with语句和for循环 这是最推荐的方式&#xf…

[Java安全入门]三.URLDNS链

一.前言 在初步学习java的序列化和反序列化之后&#xff0c;这里学习java反序列化漏洞的一个利用链&#xff0c;也是比较基础的一条链。 由于URLDNS不需要依赖第三方的包&#xff0c;同时不限制jdk的版本&#xff0c;所以通常用于检测反序列化的点。 二.代码展开分析 构造链 …

appium解锁android真机系统的屏幕

在使用appium进行app自动化操作的过程中&#xff0c;经常遇到的第一个难题就是如何解锁系统屏幕&#xff0c;也就是亮屏解锁。 实际上解决办法如下&#xff1a;在desired_capabilities中增加两个参数unlockType和unlockKey&#xff0c;类似的示例代码如下&#xff1a; desire…

2024年腾讯云优惠政策_腾讯云服务器特价购买活动入口

腾讯云优惠活动2024新春采购节活动上线&#xff0c;云服务器价格已经出来了&#xff0c;云服务器61元一年起&#xff0c;配置和价格基本上和上个月没什么变化&#xff0c;但是新增了8888元代金券和会员续费优惠&#xff0c;腾讯云百科txybk.com整理腾讯云最新优惠活动云服务器配…

Express学习(二)

Express路由 路由的概念 现实生活中的 路由&#xff1a;例如我们在拨打10086的时候&#xff0c;会让我们按指定的按键选择对应的服务&#xff0c;这里的路由就是按键和服务之间的映射关系。 Express中的路由 在Express中&#xff0c;路由指的是客户端的请求与服务器处理函数…

基于STC系列单片机实现PNP型三极管S8550驱动共阳数码管或NPN型三极管S8050驱动共阴数码管功能

Digitron.c #include "Digitron.h" //#include "Key.h" #define uchar unsigned char//自定义无符号字符型为uchar #define uint unsigned int//自定义无符号整数型为uint //uchar code DigitronBitCodeArray[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x…

AOP理解

AOP就是面向特定的方法进行编程&#xff0c;在不改动原始方法的基础上&#xff0c;可以增强原始方法的功能&#xff0c;或者改变某些功能&#xff0c;我们可以通过AOP记录数据库的操作日志 AOP的底层实现就是动态代理技术&#xff0c;在执行原始方法前&#xff0c;生成一个代理…