当前位置:AIGC资讯 > AIGC > 正文

AIGC时代智能绘画开启视觉新时代

  大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理解,而且能够帮助新手快速入门。

  本文主要是AIGC时代智能绘画开启视觉新时代,希望能对学习AI绘画的同学们有所帮助。

文章目录

1. Stable Diffusion 2. 书籍推荐 2.1 《AI创意绘画与视频制作: 基于Stable Diffusion和ControlNet》 2.2 内容介绍 2.3 适合人群 2.4 粉丝福利 2.5 自主购买

1. Stable Diffusion

  Stable Diffusion是一种基于深度学习的图像生成技术,旨在解决生成式模型中的许多稳定性和收敛性问题。Stable Diffusion的主要特点之一是它采用了一种新颖的训练方法,称为“Diffusion Process(扩散过程)”,这一过程有助于生成模型在训练过程中更加稳定和可控。通过Diffusion Process,模型可以逐渐地将噪声信号转化为高质量的生成物,而不会出现训练不稳定或崩溃的问题。这种技术在艺术创作、游戏开发、电影制作等领域有着广泛的应用潜力,能够创造出逼真的视觉效果,同时也为人工智能在图像生成领域的研究提供了新的方向。

  Stable Diffusion作为一种先进的人工智能图像生成技术,不仅能够创造出令人叹为观止的星空景象(如下图所示),还能描绘出宛如天使般纯洁美丽的小姐姐形象。这项技术通过深度学习算法,能够理解并模拟现实世界中的各种视觉元素,将用户的想象转化为生动的图像。

  随着技术的不断进步,Stable Diffusion的应用领域也在不断拓宽。它不仅能够生成静态图像,还能够创造出动态场景,甚至是完整的故事片段。想象一下,你只需提供一段简短的描述,比如“一个穿着古典服饰的天使小姐姐在月光下漫步于古老的城堡花园”,Stable Diffusion的进阶版本Stable Video Diffusion便能迅速生成一幅充满诗意的画面,让你仿佛置身于那个梦幻般的场景之中。

  此外,Stable Diffusion还在艺术创作、游戏设计、电影制作等领域展现出巨大的潜力。艺术家们利用它来探索新的创作灵感,游戏开发者用它来设计独特的游戏角色和环境,电影制作人则用它来预览和完善视觉效果。这项技术的出现,无疑为创意产业带来了革命性的变化。

  Stable Diffusion WebUI 中的核心组件,人脸图像面部画面修复模型 CodeFormer的核心代码如下所示:

import math
import torch
from torch import nn, Tensor
import torch.nn.functional as F
from typing import Optional

from modules.codeformer.vqgan_arch import VQAutoEncoder, ResBlock
from basicsr.utils.registry import ARCH_REGISTRY


class CodeFormer(VQAutoEncoder):
    def __init__(self, dim_embd=512, n_head=8, n_layers=9,
                codebook_size=1024, latent_size=256,
                connect_list=('32', '64', '128', '256'),
                fix_modules=('quantize', 'generator')):
        super(CodeFormer, self).__init__(512, 64, [1, 2, 2, 4, 4, 8], 'nearest',2, [16], codebook_size)

        if fix_modules is not None:
            for module in fix_modules:
                for param in getattr(self, module).parameters():
                    param.requires_grad = False

        self.connect_list = connect_list
        self.n_layers = n_layers
        self.dim_embd = dim_embd
        self.dim_mlp = dim_embd*2

        self.position_emb = nn.Parameter(torch.zeros(latent_size, self.dim_embd))
        self.feat_emb = nn.Linear(256, self.dim_embd)

        # transformer
        self.ft_layers = nn.Sequential(*[TransformerSALayer(embed_dim=dim_embd, nhead=n_head, dim_mlp=self.dim_mlp, dropout=0.0)
                                    for _ in range(self.n_layers)])

        # logits_predict head
        self.idx_pred_layer = nn.Sequential(
            nn.LayerNorm(dim_embd),
            nn.Linear(dim_embd, codebook_size, bias=False))

        self.channels = {
            '16': 512,
            '32': 256,
            '64': 256,
            '128': 128,
            '256': 128,
            '512': 64,
        }

        # after second residual block for > 16, before attn layer for ==16
        self.fuse_encoder_block = {'512':2, '256':5, '128':8, '64':11, '32':14, '16':18}
        # after first residual block for > 16, before attn layer for ==16
        self.fuse_generator_block = {'16':6, '32': 9, '64':12, '128':15, '256':18, '512':21}

        # fuse_convs_dict
        self.fuse_convs_dict = nn.ModuleDict()
        for f_size in self.connect_list:
            in_ch = self.channels[f_size]
            self.fuse_convs_dict[f_size] = Fuse_sft_block(in_ch, in_ch)

    def _init_weights(self, module):
        if isinstance(module, (nn.Linear, nn.Embedding)):
            module.weight.data.normal_(mean=0.0, std=0.02)
            if isinstance(module, nn.Linear) and module.bias is not None:
                module.bias.data.zero_()
        elif isinstance(module, nn.LayerNorm):
            module.bias.data.zero_()
            module.weight.data.fill_(1.0)

    def forward(self, x, w=0, detach_16=True, code_only=False, adain=False):
        # ################### Encoder #####################
        enc_feat_dict = {}
        out_list = [self.fuse_encoder_block[f_size] for f_size in self.connect_list]
        for i, block in enumerate(self.encoder.blocks):
            x = block(x)
            if i in out_list:
                enc_feat_dict[str(x.shape[-1])] = x.clone()

        lq_feat = x
        # ################# Transformer ###################
        # quant_feat, codebook_loss, quant_stats = self.quantize(lq_feat)
        pos_emb = self.position_emb.unsqueeze(1).repeat(1,x.shape[0],1)
        # BCHW -> BC(HW) -> (HW)BC
        feat_emb = self.feat_emb(lq_feat.flatten(2).permute(2,0,1))
        query_emb = feat_emb
        # Transformer encoder
        for layer in self.ft_layers:
            query_emb = layer(query_emb, query_pos=pos_emb)

        # output logits
        logits = self.idx_pred_layer(query_emb) # (hw)bn
        logits = logits.permute(1,0,2) # (hw)bn -> b(hw)n

        if code_only: # for training stage II
          # logits doesn't need softmax before cross_entropy loss
            return logits, lq_feat

        # ################# Quantization ###################
        # if self.training:
        #     quant_feat = torch.einsum('btn,nc->btc', [soft_one_hot, self.quantize.embedding.weight])
        #     # b(hw)c -> bc(hw) -> bchw
        #     quant_feat = quant_feat.permute(0,2,1).view(lq_feat.shape)
        # ------------
        soft_one_hot = F.softmax(logits, dim=2)
        _, top_idx = torch.topk(soft_one_hot, 1, dim=2)
        quant_feat = self.quantize.get_codebook_feat(top_idx, shape=[x.shape[0],16,16,256])
        # preserve gradients
        # quant_feat = lq_feat + (quant_feat - lq_feat).detach()

        if detach_16:
            quant_feat = quant_feat.detach() # for training stage III
        if adain:
            quant_feat = adaptive_instance_normalization(quant_feat, lq_feat)

        # ################## Generator ####################
        x = quant_feat
        fuse_list = [self.fuse_generator_block[f_size] for f_size in self.connect_list]

        for i, block in enumerate(self.generator.blocks):
            x = block(x)
            if i in fuse_list: # fuse after i-th block
                f_size = str(x.shape[-1])
                if w>0:
                    x = self.fuse_convs_dict[f_size](enc_feat_dict[f_size].detach(), x, w)
        out = x
        # logits doesn't need softmax before cross_entropy loss
        return out, logits, lq_feat

2. 书籍推荐

2.1 《AI创意绘画与视频制作: 基于Stable Diffusion和ControlNet》

  随着ChatGPT、Stable Diffusion等AI技术的蓬勃发展,人工智能技术已经逐渐进入到深水区。虽然现阶段AI不会淘汰所有人,但已经淘汰部分不会使用AI的人。所以我们必须要抓紧时间学习最新的AI技术,才能在职场和生活中立于不败之地。

  这里,向大家强烈推荐清华出版社的新书——《AI创意绘画与视频制作: 基于Stable Diffusion和ControlNet》。

2.2 内容介绍

  《AI创意绘画与视频制作:基于Stable Diffusion和ControlNet》将带领读者探索AI绘画和短视频创作的奇妙世界。本书详细介绍Stable Diffusion的基本概念、原理及其主要功能的使用,阐述如何使用提示词生成创意无限的图像,如何使用ControlNet插件对图像进行精细调整,如何使用Stable Diffusion结合各类插件和第三方应用进行视频制作。书中精选了大量案例,介绍了AI工具文生图、图生图的创作技巧,以及当前主流短视频平台中使用Stable Diffusion制作短视频所需的热门技术工具,如Deforum、LoopBack Wave、DepthMap、TemporalKit和EbSynth等。

  本书针对Stable Diffusion的使用给出了详细的说明,并通过多种艺术风格的案例介绍了软件的使用技巧,并对提示词的使用,给出了大量案例。

  书中对于制作高品质、高精度图像也给出了很多可供参考的方案 ,详细介绍了ControlNET插件的原理及其在精细化图像如手部绘制等方面的运用。

  介绍了使用Deforum、LoopBack和FILM制作动画与短视频的技巧,以及使用Depthap、EbSynth、TemporalKit生成丝滑动画的多种技巧。

  AI创意绘画一书结合了作者长期研究虚拟人和AI绘画技术的成果 ,从原理、技术与创意三个方面介绍了AI绘画与短视频制作的 技术要点,对于希望运用AI创作的读者是一本极好的入门教材。

2.3 适合人群

  《AI创意绘画与视频制作:基于Stable Diffusion和ControlNet》内容丰富,理论与实践并重,既适合初学者作为自学参考书,也适合设计师、数字媒体从业者作为参考手册,同时还可以作为高等院校数字媒体等相关的教学用书。

2.4 粉丝福利

本次送书两本 活动时间:截止到2024-1-26 14:00 参与方式:关注博主、并在此文章下面点赞、收藏并任意评论。

2.5 自主购买

  小伙伴也可以访问链接进行自主购买哦~

  直达京东购买链接🔗:《AI创意绘画与视频制作:基于Stable Diffusion和ControlNet》

更新时间 2024-01-26