AI生图之入门AI生图(Datawhale X 魔搭 AI夏令营)

探索AI生图技术:能力与局限的深度解读

        在现代人工智能技术的飞速发展中,AI生成图片(AI生图)技术逐渐成为一个备受关注的领域。然而,对于许多人来说,AI能够生成什么样的图片,以及它可能带来的风险和挑战,仍然是一个不太了解的领域。在深入研究和应用这一技术之前,我们需要先了解其背景知识,从而更好地掌握和利用AI生图技术。

1. 为什么要关注AI生图的前沿发展?

        AI生成内容(AIGC)是一种通过人工智能技术自动生成内容的创新生产方式,早期就有专家指出,AIGC将成为未来人工智能的重点发展方向,并且会大幅度改造相关行业和领域的内容生产方式。AI生图作为AIGC的重要组成部分,已经逐渐被大众所熟知,并在诸多领域中广泛应用。

        AI生图技术的发展对各个行业都产生了深远的影响。摄影、美术等艺术领域尤其感受到了这种变化,传统的“有图有真相”的观念正在被颠覆。同时,随着技术的普及,我们还需要意识到AI生图可能带来的风险,尤其是在Deepfake等技术的滥用可能带来的社会和法律挑战。

2. AI生图技术的历史与演进

        AI生图技术的发展历史可以追溯到20世纪70年代。最早的尝试由艺术家哈罗德·科恩(Harold Cohen)发起,他开发了AARON系统,这个系统可以通过机械臂输出绘画。此后,随着计算机技术和人工智能的进步,AI生图技术逐渐从简单的规则匹配发展到现代的深度学习模型。

近年来,诸如DALL-E、CLIP和Stable Diffusion等模型的出现,使得AI生图技术能够根据输入的文本生成高度复杂和逼真的图像。这些技术的演进不仅提升了图像生成的质量,也扩大了其应用范围,使其在设计、广告、艺术创作等领域发挥了重要作用。

3. AI生图的挑战与难点解析

        尽管AI生图技术取得了显著进展,但它仍然面临许多技术挑战。例如,生成的图像有时会表现出“AI味”,即图像与真实生活场景或传统艺术作品相比,存在明显的违和感。此外,AI生图在处理特定细节(如人物的手部)时,往往表现出不足,这导致生成的图像在某些场景下不够真实或细腻。

        这些技术难题促使科研界和工业界不断探索新的解决方案,以提升图像的真实性和精细度。不同的模型在处理这些问题时会有不同的表现,因此选择合适的模型和方法对于实现高质量的AI生图至关重要。

4. 如何开启AI生图的前沿探索?

        要深入探索AI生图的前沿技术,首先需要持续关注这一领域的最新动态,并积极参与相关的学习和实践活动。通过参与像魔搭社区这样的平台提供的AIGC工具和挑战赛,用户可以深入了解AI生图的最新技术进展,并逐步掌握这些技术的应用场景和实现方法。

        学习和实践是探索前沿技术的关键。通过不断地尝试和总结经验,我们可以更好地理解AI生图的原理,并将这些技术应用到实际项目中,从而提升自己的技术能力和创新能力。

5. 利用魔搭社区深入探索AI生图技术

        魔搭社区是一个提供丰富AI生图工具和资源的平台,无论是初学者还是有经验的开发者,都可以在这里找到适合自己的学习资源和实践项目。通过魔搭社区,用户可以了解最新的AI生图技术,获取实践经验,并与其他开发者交流合作。

        魔搭社区还提供了多种开源模型和工具,用户可以根据自己的需求进行选择和应用。无论是探索AI生图的基础技术,还是研究更为复杂的应用场景,魔搭社区都为用户提供了一个极好的平台,帮助他们在AI生图领域不断成长。

Part 1:初识通义千问——你的AI学习助教

        在开始深入学习AI生图技术之前,我们不妨先武装好我们的“工具箱”。今天要介绍的“工具”——通义千问,是一个功能强大的大语言模型,能够帮助我们更高效地理解和分析代码。正所谓“磨刀不误砍柴工”,我们先来了解这一工具的强大功能,确保后续的学习更为顺利。

1. 为什么选择通义千问?

        通义千问不仅是一个多功能的AI助手,还是编程与技术支持方面的专家。它集信息查询、语言理解、文本创作等多种能力于一身,特别是在代码分析和问题解决上表现尤为出色。对于初学者和资深开发者来说,通义千问都是一个不可多得的好帮手。

📢 注意事项:

  • 如果你已经对大语言模型非常熟悉,可以跳过这部分内容,直接进入代码学习部分。
  • 学习过程中,你可以根据个人需求选择其他大语言模型工具,我们的重点在于掌握技术而非工具本身。
  • 此外,通义系列产品还包含了文生图工具——通义万相,感兴趣的朋友可以自行探索。

2. 通义千问的核心功能

2.1 AI助手的自我介绍

        通义千问是一款致力于提升用户生产力的AI助手,它不仅支持信息查询和文本创作,还特别擅长编程与技术支持。无论你是需要调试代码、查找错误,还是希望理解复杂的编程概念,通义千问都可以为你提供强有力的支持。

2.2 如何利用通义千问提升编程效率?

        接下来,我们将重点介绍通义千问在编程领域的应用。通过与通义千问的互动,你可以更快地找到代码中的问题,优化你的编程流程,甚至自动生成部分代码。这对于那些想要提升编程效率的开发者来说,无疑是一个极大的帮助。

3. 开启你的AI助学之旅

        作为一名学习者,你需要一个随时随地都能帮助你的“助教”。通义千问正是这样一个AI助手——24小时在线,随时待命,帮助你解决学习和编程中的各种问题。

        当你在学习中遇到难题时,不妨试试向通义千问求助。通过简单的几步操作,你就能获得它的帮助,让你的学习之路更加轻松愉快。点击这里,立即接收通义千问的邀请函,开启你的AI助学之旅吧!

Part 2:精读Baseline——从零开始掌握AI生图

        在这部分内容中,我们将借助AI助手,从代码分析和逐行解析两个角度,帮助大家更好地理解和掌握AI生图技术。通过这次学习,你将了解如何分解复杂的代码结构,并深入理解每一行代码的功能。

1. 分析代码的整体架构

        首先,我们将从整体上感知这个文生图代码的框架结构。通过这种方式,你可以更清晰地了解代码的逻辑和工作流程。

!pip install simple-aesthetics-predictor

!pip install -v -e data-juicer

!pip uninstall pytorch-lightning -y
!pip install peft lightning pandas torchvision

!pip install -e DiffSynth-Studio

from modelscope.msdatasets import MsDataset

ds = MsDataset.load(
    'AI-ModelScope/lowres_anime',
    subset_name='default',
    split='train',
    cache_dir="/mnt/workspace/kolors/data"
)

import json, os
from data_juicer.utils.mm_utils import SpecialTokens
from tqdm import tqdm


os.makedirs("./data/lora_dataset/train", exist_ok=True)
os.makedirs("./data/data-juicer/input", exist_ok=True)
with open("./data/data-juicer/input/metadata.jsonl", "w") as f:
    for data_id, data in enumerate(tqdm(ds)):
        image = data["image"].convert("RGB")
        image.save(f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg")
        metadata = {"text": "二次元", "image": [f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg"]}
        f.write(json.dumps(metadata))
        f.write("\n")

data_juicer_config = """
# global parameters
project_name: 'data-process'
dataset_path: './data/data-juicer/input/metadata.jsonl'  # path to your dataset directory or file
np: 4  # number of subprocess to process your dataset

text_keys: 'text'
image_key: 'image'
image_special_token: '<__dj__image>'

export_path: './data/data-juicer/output/result.jsonl'

# process schedule
# a list of several process operators with their arguments
process:
    - image_shape_filter:
        min_width: 1024
        min_height: 1024
        any_or_all: any
    - image_aspect_ratio_filter:
        min_ratio: 0.5
        max_ratio: 2.0
        any_or_all: any
"""
with open("data/data-juicer/data_juicer_config.yaml", "w") as file:
    file.write(data_juicer_config.strip())

!dj-process --config data/data-juicer/data_juicer_config.yaml

import pandas as pd
import os, json
from PIL import Image
from tqdm import tqdm


texts, file_names = [], []
os.makedirs("./data/data-juicer/output/images", exist_ok=True)
with open("./data/data-juicer/output/result.jsonl", "r") as f:
    for line in tqdm(f):
        metadata = json.loads(line)
        texts.append(metadata["text"])
        file_names.append(metadata["image"][0])

df = pd.DataFrame({"text": texts, "file_name": file_names})
df.to_csv("./data/data-juicer/output/result.csv", index=False)

df

from transformers import CLIPProcessor, CLIPModel
import torch

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

images = [Image.open(img_path) for img_path in df["file_name"]]
inputs = processor(text=df["text"].tolist(), images=images, return_tensors="pt", padding=True)

outputs = model(**inputs)
logits_per_image = outputs.logits_per_image  # this is the image-text similarity score
probs = logits_per_image.softmax(dim=1)  # we can take the softmax to get the probabilities

probs

from torch.utils.data import Dataset, DataLoader

class CustomDataset(Dataset):
    def __init__(self, df, processor):
        self.texts = df["text"].tolist()
        self.images = [Image.open(img_path) for img_path in df["file_name"]]
        self.processor = processor

    def __len__(self):
        return len(self.texts)

    def __getitem__(self, idx):
        inputs = self.processor(text=self.texts[idx], images=self.images[idx], return_tensors="pt", padding=True)
        return inputs

dataset = CustomDataset(df, processor)
dataloader = DataLoader(dataset, batch_size=8)

for batch in dataloader:
    outputs = model(**batch)
    logits_per_image = outputs.logits_per_image
    probs = logits_per_image.softmax(dim=1)
    print(probs)

import torch
from diffusers import StableDiffusionPipeline

torch.manual_seed(1)
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v-1-4", torch_dtype=torch.float16)
pipe = pipe.to("cuda")

prompt = "二次元,一个紫色长发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌,手持话筒"
negative_prompt = "丑陋、变形、嘈杂、模糊、低对比度"
guidance_scale = 4
num_inference_steps = 50

image = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    guidance_scale=guidance_scale,
    num_inference_steps=num_inference_steps,
    height=1024,
    width=1024,
).images[0]

image.save("example_image.png")
image

from PIL import Image

torch.manual_seed(1)
image = pipe(
    prompt="二次元,日系动漫,演唱会的观众席,人山人海,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,舞台上衣着华丽的歌星们在唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("1.jpg")

torch.manual_seed(1)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,露出憧憬的神情",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,色情擦边",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("2.jpg")

torch.manual_seed(2)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,露出憧憬的神情",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,色情擦边",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("3.jpg")

torch.manual_seed(5)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙,对着流星许愿,闭着眼睛,十指交叉,侧面",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,扭曲的手指,多余的手指",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("4.jpg")

torch.manual_seed(0)
image = pipe(
    prompt="二次元,一个紫色中等长度头发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("5.jpg")

torch.manual_seed(1)
image = pipe(
    prompt="二次元,一个紫色长发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌,手持话筒",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("6.jpg")

torch.manual_seed(7)
image = pipe(
    prompt="二次元,紫色长发少女,穿着黑色连衣裙,试衣间,心情忐忑",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("7.jpg")

torch.manual_seed(0)
image = pipe(
    prompt="二次元,紫色长发少女,穿着黑色礼服,连衣裙,在台上唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("8.jpg")

import numpy as np
from PIL import Image


images = [np.array(Image.open(f"{i}.jpg")) for i in range(1, 9)]
image = np.concatenate([
    np.concatenate(images[0:2], axis=1),
    np.concatenate(images[2:4], axis=1),
    np.concatenate(images[4:6], axis=1),
    np.concatenate(images[6:8], axis=1),
], axis=0)
image = Image.fromarray(image).resize((1024, 2048))
image
1.1 安装与卸载依赖包

        代码的第一部分涉及依赖包的安装和卸载。这些操作通过 !pip 命令进行,安装了诸如 simple-aesthetics-predictordata-juicerpeftlightningpandastorchvisionDiffSynth-Studio 等必要的Python包,同时也卸载了可能冲突的 pytorch-lightning 包。

1.2 加载数据集

        第二部分代码利用 ModelScopeMsDataset 类,加载了一个名为 AI-ModelScope/lowres_anime 的数据集,并指定了子集名称和分割类型。这部分操作的目的是准备好训练所需的数据。

1.3 数据预处理

        接下来,我们会将数据集中的图像转换为RGB格式,并保存到指定目录。此外,还会创建包含图像路径和文本描述的元数据文件 metadata.jsonl,用于后续的数据处理。

1.4 数据处理与过滤

        在数据准备好之后,代码利用 data-juicer 工具对数据进行过滤处理。这一步会生成一个 result.jsonl 文件,其中包含了过滤后的有效数据。

1.5 数据整理与训练

        过滤后的数据被转换为 Pandas DataFrame,并保存为CSV文件,准备供后续训练使用。然后,下载模型并在基础模型上执行LoRA微调训练,最后加载微调后的模型。

1.6 图像生成与合成

        通过设定提示词和图像生成参数,代码最终生成目标图像,并保存为 .jpg 文件。为了展示最终的结果,代码将生成的多个图像合成到一张大图中,以便更直观地展示生成效果。

2. 逐行解析代码

        接下来,我们将逐行解析这段代码,以更深入地理解每个模块和函数的具体作用。

2.1 安装与卸载依赖
!pip install simple-aesthetics-predictor
!pip install -v -e data-juicer
!pip uninstall pytorch-lightning -y
!pip install peft lightning pandas torchvision
!pip install -e DiffSynth-Studio

        这些命令用于安装和配置代码运行所需的各种依赖包,确保环境准备就绪。

2.2 数据集加载
from modelscope.msdatasets import MsDataset
ds = MsDataset.load(
    'AI-ModelScope/lowres_anime',
    subset_name='default',
    split='train',
    cache_dir="/mnt/workspace/kolors/data"
)

        这段代码用于加载数据集 lowres_anime,并将其存储在指定缓存目录中,供后续操作使用。

2.3 数据预处理
import json, os
from data_juicer.utils.mm_utils import SpecialTokens
from tqdm import tqdm

os.makedirs("./data/lora_dataset/train", exist_ok=True)
os.makedirs("./data/data-juicer/input", exist_ok=True)
with open("./data/data-juicer/input/metadata.jsonl", "w") as f:
    for data_id, data in enumerate(tqdm(ds)):
        image = data["image"].convert("RGB")
        image.save(f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg")
        metadata = {"text": "二次元", "image": [f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg"]}
        f.write(json.dumps(metadata))
        f.write("\n")

        该部分将数据集图像处理为RGB格式,并保存元数据文件 metadata.jsonl,为后续的数据过滤做好准备。

2.4 数据处理与过滤
data_juicer_config = """
# global parameters
project_name: 'data-process'
dataset_path: './data/data-juicer/input/metadata.jsonl'  # path to your dataset directory or file
np: 4  # number of subprocess to process your dataset

text_keys: 'text'
image_key: 'image'
image_special_token: '<__dj__image>'

export_path: './data/data-juicer/output/result.jsonl'

# process schedule
# a list of several process operators with their arguments
process:
    - image_shape_filter:
        min_width: 1024
        min_height: 1024
        any_or_all: any
    - image_aspect_ratio_filter:
        min_ratio: 0.5
        max_ratio: 2.0
        any_or_all: any
"""
with open("data/data-juicer/data_juicer_config.yaml", "w") as file:
    file.write(data_juicer_config.strip())
!dj-process --config data/data-juicer/data_juicer_config.yaml

        这里通过设置过滤规则,对数据集进行清洗和过滤,以确保后续训练的数据质量。

2.5 数据整理与训练
import pandas as pd
import os, json
from PIL import Image
from tqdm import tqdm

texts, file_names = [], []
os.makedirs("./data/data-juicer/output/images", exist_ok=True)
with open("./data/data-juicer/output/result.jsonl", "r") as f:
    for line in tqdm(f):
        metadata = json.loads(line)
        texts.append(metadata["text"])
        file_names.append(metadata["image"][0])

df = pd.DataFrame({"text": texts, "file_name": file_names})
df.to_csv("./data/data-juicer/output/result.csv", index=False)

        这段代码将处理后的数据存储为CSV格式,以供后续模型训练使用。

2.6 图像生成与合成
torch.manual_seed(0)
image = pipe(
    prompt="二次元,一个紫色短发小女孩,在家中沙发上坐着,双手托着腮,很无聊,全身,粉色连衣裙",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("1.jpg")

# 合并多张生成的图像
images = [np.array(Image.open(f"{i}.jpg")) for i in range(1, 9)]
image = np.concatenate([
    np.concatenate(images[0:2], axis=1),
    np.concatenate(images[2:4], axis=1),
    np.concatenate(images[4:6], axis=1),
    np.concatenate(images[6:8], axis=1),
], axis=0)
image = Image.fromarray(image).resize((1024, 2048))

        这里设置了图像生成的提示词,并将多张生成图像合成为一张大图,以便直观展示效果。如果你在以上解析中仍然有不理解的部分,不妨尝试利用通义千问或其他AI助手进行更深层次的分析。例如,你可以提出针对性的细节问题,让AI为你进一步解释代码的作用和实现逻辑。通过这次深入的代码解析,希望大家不仅了解了AI生图技术的实现过程,更能掌握如何利用AI助手帮助自己提升代码阅读和理解能力。记住,学会借助AI工具将会让你的学习和工作更加高效。

Part 3:实战演练——基于AI生图的连环画制作

1. 数据准备

        在这部分实战中,我们将通过AI生成一部连环画。整个话剧由8张场景图片组成,每张图片都需要生成相应的提示词。我们将利用通义千问来帮助生成这些提示词,并在此基础上进行调整和优化,确保最终生成的图片符合预期。

1.1 编写提示词

        作为一名文生图专家,你将负责编排一个基于AI生图技术的话剧。这个话剧包含以下8个场景,每个场景都需要生成一张图片。为了保证生成结果的风格一致,我们需要为每张图片编写合适的提示词。

场景列表:

  1. 女主正在上课
  2. 开始睡着了
  3. 进入梦乡,梦到自己站在路旁
  4. 王子骑马而来
  5. 两人相谈甚欢
  6. 一起坐在马背上
  7. 下课了,梦醒了
  8. 又回到了学习生活中

提示词要求:

  • 风格:古风
  • 描述:根据场景决定是否为全身或上半身描述
  • 人物:包括人物外貌和服装细节
  • 场景:描述背景和氛围
  • 动作:描述人物在做什么

提示词示例: 古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙

1.2 询问通义千问

        我们将使用通义千问生成初步的提示词,并在此基础上不断调整,直至我们对生成的提示词和最终的图像效果感到满意。通过多次试验,你可以打磨出一组最佳提示词,用于生成高质量的连环画。

1.3 整理最终话剧场景

        根据AI生成的图片和提示词结果,我们将对生成的内容进行调整,最终整理出完整的话剧场景表格。

场景表格:

图片编号场景描述正向提示词反向提示词
图片1女主正在上课古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙丑陋,变形,嘈杂,模糊,低对比度
图片2开始睡着了古风,水墨画,一个黑色长发少女,坐在教室里,趴在桌子上睡着了,上半身,红色长裙丑陋,变形,嘈杂,模糊,低对比度
图片3进入梦乡,梦到自己站在路旁古风,水墨画,一个黑色长发少女,站在路边,上半身,红色长裙丑陋,变形,嘈杂,模糊,低对比度
图片4王子骑马而来古风,水墨画,一个英俊少年,骑着白马,上半身,白色衬衫丑陋,变形,嘈杂,模糊,低对比度
图片5两人相谈甚欢古风,水墨画,一个英俊少年,白色衬衫,一个黑色长发少女,红色长裙,两个人一起聊天,开心,上半身丑陋,变形,嘈杂,模糊,低对比度
图片6一起坐在马背上古风,水墨画,一个英俊少年,白色衬衫,一个黑色长发少女,红色长裙,两个人一起骑着马,全身丑陋,变形,嘈杂,模糊,低对比度
图片7下课了,梦醒了古风,水墨画,一个黑色长发少女,坐在教室里,下课铃声响了,同学们开始走动,从睡梦中醒来,深思,上半身,红色长裙丑陋,变形,嘈杂,模糊,低对比度
图片8又回到了学习生活中古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,认真上课,上半身,红色长裙丑陋,变形,嘈杂,模糊,低对比度

2. 执行Task 1的30分钟速通Baseline

        在掌握了提示词编写后,我们将再次运行Baseline,验证编写的提示词效果。通过这次实战练习,你将从零开始,深入理解AI生图的原理和实际操作。

3. 提示词的进一步修改

  1. 打开Baseline文件
  2. 找到生成图像的代码块
  3. 依次替换8张图片的正向提示词和反向提示词

        调整后的提示词将直接影响生成图像的质量,因此,这一步至关重要。你可以根据生成结果,反复优化提示词,以达到最佳效果。

4. 结果展示

        在运行完所有步骤后,你将生成并展示8张连环画图片。通过对比和分析这些图片,你可以进一步优化提示词和生成参数。

5. 测试美学打分

        最后,为了评估生成图像的质量,可以利用美学评分工具对图像进行打分。通过评分,你可以客观地判断提示词和生成设置的优劣,并做出相应调整,以提升整体效果。

结语

        通过这次深入的学习和实践,我们从多个角度探索了AI生图技术的潜力与应用。从初识通义千问,到精读代码架构,再到实际操作AI生成连环画,每一个步骤都在帮助我们更好地理解和掌握这一前沿技术。在未来的创作和工作中,善用AI工具不仅可以提升效率,还能激发更多创意与可能性。希望通过本次学习,你能够将所学的知识应用到实际项目中,并不断探索AI技术带来的更多创新机会。让我们继续保持好奇心和进取心,在AI的世界里开辟新的篇章。

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的Anthony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值