Bootstrap

AIGC | Midjourney——图片一致性操作及深度学习原理剖析

目录

# 一、前言

# 二、生成高度相似图片详解 

 # 三、人物一致性操作详解

  #后缀参数调整

#优化提示词

#借助变体功能

# 四、相似或一致性图片原理解析

垫图原理

风格迁移原理

人物一致性原理

# 五、声明

# 六、写在最后


# 一、前言

MJ作为AI圈很抗打的AI生图工具,在其强大的功能里,人物一致性的保持堪称一大亮点。我们在制作插画或角色故事时,人物一致性至关重要。此操作不仅仅靠单一的后缀参数调整来实现,要想更大程度上挖掘MJ进阶用法,需要打出一套组合拳并理解背后严谨的数学原理和机器学习。

# 二、生成高度相似图片详解 

我们在第一篇博客中讲过,垫图、风格迁移......都可以高度还原理想图片。

不了解MJ基本操作的朋友们可以先阅读这篇博客:《AIGC | Midjourney使用指南,直接拿捏~》

但是要想充分利用MJ这一工具需要调用多个功能:

第一步:  使用/describe,对目标图片进行描述

第二步:将描述结果进行翻译,选择更为全面的描述,同时也可以综合四条结果自己整合出更全面的提示词。 

第三步:复制目标图片链接在提示词前进行垫图,垫图后输入空格后再写入提示词 ,写入提示词后,空格 加入后缀参数,每个后缀参数间要插入空格。

注:--iw(范围为0-2)数值越大,对垫图链接的参考越大。--sref空格+链接+空格+--sw空格(0-1000)数值越大,对链接图片的风格参考性更大。--cref空格+链接+空格+--cw空格(0-100)数值为0时,只是对图片脸部进行参考,数值为100时,是对全图细节元素进行参考。

--sref --sw & --cref --cw 使用贴士

--sref与--sw不一定要同时使用,但--sw 不能单独使用,故只能出现:--sref空格+链接或--sref空格+链接+空格+--sw空格(0-1000)这两种形式。

--cref与--cw必须同时使用,故只能出现:-cref空格+链接+空格+--cw空格(0-100)否则会报错。

此外,我们在一张图中也可以融合多张图的元素,比如人脸参考图A,风格参考图B,大致垫图为图C,也就是说,这三张图不一定要是一张图。

 # 三、人物一致性操作详解

  #后缀参数调整

垫图+--iw +--cref --cw 0+--seed,对提示词进行修改,从而呈现不同画面。

提示词:https://s.mj.run/RiqmbDqC2HA , A little girl plays the guitar in the garden --seed 2023957784 --cref https://s.mj.run/RiqmbDqC2HA --cw 0 --iw 2 --niji 6

在垫图中我们可以多次垫不同的图,确保有更大的发挥性,垫图的先后次序有关权重,我们也可以在链接后输入::+数值来调整权重。

#优化提示词

我们在提示词中加入特定指令也可实现,人物一致性操作。

如:不同动作:Different actions

连续动作:Continuous action

多视角动作:Multi-view action

不同表情:Different expressions

正在做什么:What is being done

连续拍摄:Continuous shooting

序列拍摄:Sequence shooting

#借助变体功能

  • 利用初始生成的图像变体:在 Midjourney 生成一组初始图像后,选择最符合人物一致性要求的图片,然后使用 U1-U4 或 V1-V4 等变体功能,让 Midjourney 在该图片基础上进行变化,生成与原人物形象保持一致的其他图片。
  • 使用局部重画变体:若对生成图像中的某些局部不满意,影响了人物一致性,可使用局部重画功能,在不改变人物整体形象的前提下,对局部进行调整和修改,使人物形象更加统一。

详情请看: 《AIGC | Midjourney使用指南,直接拿捏~》

# 四、相似或一致性图片原理解析

垫图原理

通过提供视觉参考,垫图帮助 AI 抓取并应用关键元素,如风格、纹理等,与文本提示相结合来指导创作。主要有 “克隆” 和 “牵引” 两种用途,“克隆” 是尽可能复刻风格,“牵引” 是引导创作方向而非完全复制。

风格迁移原理

核心是利用深度学习中的卷积神经网络(CNN)等技术,将内容图像的内容与风格图像的风格进行融合。

  • 特征提取:利用预训练的神经网络,如 VGG16 等,分别对内容图像和风格图像进行特征提取。
  • 损失计算
    • 内容损失:计算内容图像与生成图像在内容特征上的差异,一般使用均方误差损失函数,确保生成图像保留内容图像的主要内容。
    • 风格损失:通过计算风格图像与生成图像的 Gram 矩阵之间的均方误差来衡量风格差异。Gram 矩阵用于描述特征图中不同特征之间的相关性,以此捕捉图像的风格信息。
  • 优化生成:以内容损失和风格损失的加权和作为总损失,通过优化算法,如随机梯度下降等,不断调整生成图像的像素值,使得总损失最小,从而生成具有目标风格的图像。

代码实现: 以 Python 和 TensorFlow 为例,使用 VGG19 模型实现风格迁移。

import tensorflow as tf
from tensorflow import keras
from keras.applications.vgg19 import VGG19
from keras.preprocessing.image import load_img, img_to_array
import numpy as np

# 定义内容层和风格层
content_layers = ['block3_conv1']
style_layers = ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1', 'block5_conv1']

# 加载预训练的VGG19模型
base_model = VGG19(weights='imagenet', include_top=False)

# 构建内容模型
content_model = keras.Model(inputs=base_model.input, outputs=[base_model.get_layer(layer).output for layer in content_layers])

# 构建风格模型
style_model = keras.Model(inputs=base_model.input, outputs=[base_model.get_layer(layer).output for layer in style_layers])

# 加载并预处理图像
def preprocess_img(img_path, target_size=(224, 224)):
    img = load_img(img_path, target_size=target_size)
    img = img_to_array(img)
    img = np.expand_dims(img, axis=0)
    img = keras.applications.vgg19.preprocess_input(img)
    return img

# 计算Gram矩阵
def gram_matrix(feature_map):
    shape = tf.shape(feature_map)
    height, width, channels = shape[1], shape[2], shape[3]
    feature_map = tf.reshape(feature_map, [height * width, channels])
    gram = tf.matmul(tf.transpose(feature_map), feature_map)
    return gram

# 计算内容损失
def content_loss(generated_content, content_target):
    return tf.reduce_mean(tf.square(generated_content - content_target))

# 计算风格损失
def style_loss(generated_style, style_target):
    style_loss = 0.0
    for gen, target in zip(generated_style, style_target):
        gen_gram = gram_matrix(gen)
        target_gram = gram_matrix(target)
        style_loss += tf.reduce_mean(tf.square(gen_gram - target_gram))
    return style_loss

# 图像风格迁移
def style_transfer(content_img_path, style_img_path, num_iterations=1000, content_weight=1.0, style_weight=100.0):
    content_img = preprocess_img(content_img_path)
    style_img = preprocess_img(style_img_path)

    # 初始化生成图像为内容图像
    generated_img = tf.Variable(content_img, dtype=tf.float32)

    optimizer = tf.optimizers.Adam(learning_rate=5, beta_1=0.99, epsilon=1e-1)

    for i in range(num_iterations):
        with tf.GradientTape() as tape:
            generated_content = content_model(generated_img)
            generated_style = style_model(generated_img)

            content_loss_value = content_weight * content_loss(generated_content, content_model(content_img))
            style_loss_value = style_weight * style_loss(generated_style, style_model(style_img))

            total_loss = content_loss_value + style_loss_value

        gradients = tape.gradient(total_loss, generated_img)
        optimizer.apply_gradients([(gradients, generated_img)])

    return generated_img

content_img_path = 'content.jpg'
style_img_path = 'style.jpg'
generated_img = style_transfer(content_img_path, style_img_path)
# 保存生成的图像
keras.preprocessing.image.save_img('output.jpg', generated_img.numpy()[0])

 

人物一致性原理

  • 生成基础图像:使用生成对抗网络(GAN)生成一组基础图像,作为生成一致性人物图像的基础。
  • 调整图像参数:通过调整基础图像的姿态、表情和场景等参数,生成一系列具有一致性的人物图像。
  • 引入特征提取器网络:提取人物的特征信息,并将其应用于生成的新图像上,确保生成的人物图像与原始图像具有相同的人物特征。
  • 使用相关参数和工具:如使用 “--cref” 参数直接匹配人物面部,通过 “--cw” 参数调整对原图的参考程度

代码实现: 

import tensorflow as tf

# 定义生成器和判别器网络结构
def generator(inputs):
    # 生成器网络架构
    return generated_image

def discriminator(image):
    # 判别器网络架构
    return discrimination_result

# 定义损失函数
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

# 定义生成器损失
def generator_loss(fake_output):
    return cross_entropy(tf.ones_like(fake_output), fake_output)

# 定义判别器损失
def discriminator_loss(real_output, fake_output):
    real_loss = cross_entropy(tf.ones_like(real_output), real_output)
    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
    return real_loss + fake_loss

# 定义优化器
generator_optimizer = tf.keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5)
discriminator_optimizer = tf.keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5)

# 训练循环
for epoch in range(num_epochs):
    for batch in data_loader:
        real_images = batch

        # 生成随机噪声作为生成器输入
        noise = tf.random.normal([batch_size, noise_dim])

        with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
            # 生成假图像
            fake_images = generator(noise)

            # 判别器对真实图像和假图像的判别结果
            real_output = discriminator(real_images)
            fake_output = discriminator(fake_images)

            # 计算生成器和判别器损失
            gen_loss = generator_loss(fake_output)
            disc_loss = discriminator_loss(real_output, fake_output)

        # 计算生成器和判别器的梯度
        gen_gradients = gen_tape.gradient(gen_loss, generator.trainable_variables)
        disc_gradients = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

        # 更新生成器和判别器的参数
        generator_optimizer.apply_gradients(zip(gen_gradients, generator.trainable_variables))
        discriminator_optimizer.apply_gradients(zip(disc_gradients, discriminator.trainable_variables))

# 五、声明

本文代码实现来自:豆包

数学原理参考文献:

  • “Backpropagation Applied to Handwritten Zip Code Recognition” by Yann LeCun et al., 1989.
  • “ImageNet Classification with Deep Convolutional Neural Networks” by Alex Krizhevsky et al., 2012.
  • “A Neural Algorithm of Artistic Style” by Leon A. Gatys, Alexander S. Ecker, Matthias Bethge, 2015.
  • “Generative Adversarial Nets” by Ian J. Goodfellow, Jean Pouget-Abadie, Mehdi Mirza et al., 2014.
  • “Auto-Encoding Variational Bayes” by Diederik P. Kingma, Max Welling, 2014.
  • “CharacterFactory: A Framework Launched by Dalian University of Technology to Create Characters with Consistent Identity Features”.
  • “Variational Autoencoders for Face Generation and Editing”

# 六、写在最后

不作溢美之词,不作浮夸文章,此文与功名进取毫不相干也!

与大家共勉~感谢您的阅读!您的三联是我更新最大的动力!

;