一文看明白Transformer微调过程中嵌入向量的变化

在这里插入图片描述

TL;DR

微调在图像分类中显著影响嵌入向量。微调前的嵌入向量提供通用性表征,而微调后的嵌入向量捕获任务特定的特征。这种区别可能导致在异常检测和其他任务中的不同结果。微调前和微调后的嵌入向量各有其独特优势,应结合使用以实现图像分类和分析任务中的全面分析。
请查看本文的 CIFAR-10 数据集【3】在线演示之一。
点击跳转

1 引言

在图像分类中,先使用如 ImageNet 这样的大型数据集上预训练模型,随后对特定目标数据集进行微调,已成为默认方法。然而,在处理现实世界的目标数据集时,考虑其固有噪声非常重要,包括异常值、标签错误和其他异常。数据集的交互式探索在全面理解数据中发挥着关键作用,通过数据丰富化,能够识别和解决关键数据段。
在分析非结构化图像数据时,嵌入向量扮演着关键角色。它们提供高层次的语义信息,支持数据分析、洞察生成和异常检测等各种任务。通过在低维空间中表示图像,嵌入向量使得探索数据内的相似性和差异性变得更加容易,并允许使用 t-SNE 或 UMAP 等技术创建相似性映射。我们将使用 Spotlight 来交互式探索我们创建的丰富数据集:

免责声明:本文作者也是 Spotlight 的开发者之一。本文中的部分代码片段也可在 Spotlight 仓库中找到。

在本文中,我们将深入探讨微调前后嵌入向量的差异,并特别关注异常检测。虽然重要的是要注意,使用经过微调的模型的嵌入向量并不总是为异常检测带来最佳结果(我们也可以使用概率),但这仍然是一种引人入胜的方法。嵌入向量的可视化为分析过程增添了一种视觉上的吸引力。

为了评估嵌入向量在异常检测任务中的性能和有效性,我们将检查在图像分类中广泛使用的典型数据集。此外,我们将使用两种常见的基础模型。通过这种探索,我们旨在深入了解模型微调对嵌入向量的影响,更好地理解它们的能力和局限。

2.环境准备

安装所需要的python包

!pip install renumics-spotlight datasets torch pandas cleanlab annoy

2.1 提取嵌入向量

我们将使用基于 google/vit-base-patch16-224-in21k [1] 和 [microsoft/swin-base-patch4-window7-224(https://huggingface.co/microsoft/swin-base-patch4-window7-224) [2] 的模型,这些模型可在 Hugging Faces 上获得,用以提取微调前的嵌入向量以及每个数据集最受欢迎的微调模型:araki/vit-base-patch16-224-in21k-finetuned-cifar10、MazenAmria/swin-tiny-finetuned-cifar100、nateraw/vit-base-beans、farleyknight/mnist-digit-classification-2022-09-04。

case = {
    "cifar10": {
        "base_model_name": "google/vit-base-patch16-224-in21k",
        "ft_model_name": "aaraki/vit-base-patch16-224-in21k-finetuned-cifar10",
    },
    "beans": {
        "base_model_name": "google/vit-base-patch16-224-in21k",
        "ft_model_name": "nateraw/vit-base-beans",
    },
    "mnist": {
        "base_model_name": "google/vit-base-patch16-224-in21k",
        "ft_model_name": "farleyknight/mnist-digit-classification-2022-09-04",
    },
    "cifar100": {
        "base_model_name": "microsoft/swin-base-patch4-window7-224",
        "ft_model_name": "MazenAmria/swin-tiny-finetuned-cifar100",
    },
}

为了加载数据集,我们使用 datasets 模块中的 load_dataset 函数,并为图像分类任务做好准备。你可以从本文测试并报告的数据集中选择 CIFAR-10 [3]、CIFAR-100 [3]、MNIST [4] 和 Beans [5],或尝试使用与之对应的模型,从 Hugging Face 获取不同的图像分类数据集。

import datasets
# 可选 cifar10, cifar100, mnist 或 beans。
# 对应模型将自动选择
DATASET = "cifar10"
ds = datasets.load_dataset(DATASET, split="train").prepare_for_task(
    "image-classification"
)
df = ds.to_pandas()
# df = df.iloc[:1000] # 取消注释以限制数据集大小进行测试

我们定义了 huggingface_embedding 函数,用于从微调模型和基础/基本模型中提取嵌入向量。这些嵌入向量被存储在原始数据框(df)的不同列中(“embedding_ft” 和 “embedding_foundation”)。

import datasets
from transformers import AutoFeatureExtractor, AutoModel
import torch
import pandas as pd

ft_model_name = case[DATASET]["ft_model_name"]
base_model_name = case[DATASET]["base_model_name"]
def extract_embeddings(model, feature_extractor, image_name="image"):
    """
    计算嵌入向量的工具函数。
    参数:
        model: huggingface 模型
        feature_extractor: huggingface 特征提取器
        image_name: 数据集中图像列的名称
    返回:
        计算嵌入向量的函数
    """
    device = model.device
    def pp(batch):
        images = batch[image_name]
        inputs = feature_extractor(
            images=[x.convert("RGB") for x in images], return_tensors="pt"
        ).to(device)
        embeddings = model(**inputs).last_hidden_state[:, 0].cpu()
        return {"embedding": embeddings}
    return pp

def huggingface_embedding(
    df,
    image_name="image",
    modelname="google/vit-base-patch16-224",
    batched=True,
    batch_size=24,
):
    """
    使用 huggingface 模型计算嵌入向量。
    参数:
        df: 含有图像的数据框
        image_name: 数据集中图像列的名称
        modelname: huggingface 模型名称
        batched: 是否批量计算嵌入向量
        batch_size: 批量大小
    返回:
        包含嵌入向量的新数据框
    """
    # 初始化 huggingface 模型
    feature_extractor = AutoFeatureExtractor.from_pretrained(modelname)
    model = AutoModel.from_pretrained(modelname, output_hidden_states=True)
    # 从 df 创建 huggingface 数据集
    dataset = datasets.Dataset.from_pandas(df).cast_column(image_name, datasets.Image())
    # 计算嵌入向量
    device = "cuda" if torch.cuda.is_available() else "cpu"
    extract_fn = extract_embeddings(model.to(device), feature_extractor, image_name)
    updated_dataset = dataset.map(extract_fn, batched=batched, batch_size=batch_size)
    df_temp = updated_dataset.to_pandas()
    df_emb = pd.DataFrame()
    df_emb["embedding"] = df_temp["embedding"]
    return df_emb

embeddings_df = huggingface_embedding(
    df,
    modelname=ft_model_name,
    batched=True,
    batch_size=24,
)
embeddings_df_found = huggingface_embedding(
    df, modelname=base_model_name, batched=True, batch_size=24
)
df["embedding_ft"] = embeddings_df["embedding"]
df["embedding_foundation"] = embeddings_df_found["embedding"]

2.2 计算异常值得分

接下来,我们使用 Cleanlab 来计算基于嵌入向量的微调模型和基础/基本模型的异常值得分。我们利用 OutOfDistribution 类来计算异常值得分。生成的异常值得分将存储在原始数据框(df)中:

from cleanlab.outlier import OutOfDistribution
import numpy as np
import pandas as pd
def outlier_score_by_embeddings_cleanlab(df, embedding_name="embedding"):
    """
    使用 cleanlab 通过嵌入向量计算异常值得分
        参数:
            df: 含有嵌入向量的数据框
            embedding_name: 嵌入向量所在列的名称
        返回:
            新的 df_out: 含有异常值得分的数据框
    """
    embs = np.stack(df[embedding_name].to_numpy())
    ood = OutOfDistribution()
    ood_train_feature_scores = ood.fit_score(features=np.stack(embs))
    df_out = pd.DataFrame()
    df_out["outlier_score_embedding"] = ood_train_feature_scores
    return df_out

df["outlier_score_ft"] = outlier_score_by_embeddings_cleanlab(
    df, embedding_name="embedding_ft"
)["outlier_score_embedding"]
df["outlier_score_found"] = outlier_score_by_embeddings_cleanlab(
    df, embedding_name="embedding_foundation"
)["outlier_score_embedding"]

2.3 寻找最近邻居图像

为了评估异常值,我们使用仅经过微调模型的 Annoy 库计算最近邻居图像。生成的图像将存储在原始数据框(df)中:

from annoy import AnnoyIndex
import pandas as pd
def nearest_neighbor_annoy(
    df, embedding_name="embedding", threshold=0.3, tree_size=100
):
    """
    使用 annoy 查找最近邻居。
    参数:
        df: 含有嵌入向量的数据框
        embedding_name: 嵌入向量列的名称
        threshold: 异常检测的阈值
        tree_size: annoy 的树大小
    返回:
        新的数据框,包含最近邻居信息
    """
    embs = df[embedding_name]
    t = AnnoyIndex(len(embs[0]), "angular")
    for idx, x in enumerate(embs):
        t.add_item(idx, x)
    t.build(tree_size)
    images = df["image"]
    df_nn = pd.DataFrame()
    nn_id = [t.get_nns_by_item(i, 2)[1] for i in range(len(embs))]
    df_nn["nn_id"] = nn_id
    df_nn["nn_image"] = [images[i] for i in nn_id]
    df_nn["nn_distance"] = [t.get_distance(i, nn_id[i]) for i in range(len(embs))]
    df_nn["nn_flag"] = df_nn.nn_distance < threshold
    return df_nn

df_nn = nearest_neighbor_annoy(
    df, embedding_name="embedding_ft", threshold=0.3, tree_size=100
)
df["nn_image"] = df_nn["nn_image"]

2.4 可视化

为了使用 Spotlight 进行可视化,通过使用 lambda 函数将整数标签映射到它们的字符串表示形式,我们在数据框中创建了一个新的“label_str”列。使用 dtypes 字典来指定每列的数据类型,以获得正确的可视化效果,同时布局确定了可视化中的排列和显示的列:

from renumics import spotlight
df["label_str"] = df["labels"].apply(lambda x: ds.features["labels"].int2str(x))
dtypes = {
    "nn_image": spotlight.Image,
    "image": spotlight.Image,
    "embedding_ft": spotlight.Embedding,
    "embedding_foundation": spotlight.Embedding,
}
spotlight.show(
    df,
    dtype=dtypes,
    layout="https://spotlight.renumics.com/resources//layout_pre_post_ft.json",
)

之后会打开一个浏览器的新窗口
在这里插入图片描述
在可视化部分,左上角显示了一个全面的表格,展示了数据集中存在的所有字段。选择了基础模型的嵌入向量识别为异常值的图像。在右上角,你可以观察到两个 UMAP 表示:第一个表示来自基础模型的嵌入向量,而第二个表示来自微调模型的嵌入向量。在底部,选定的图像与数据集中它们的最近邻居一起展示。

3 结果

现在让我们检查所有数据集的结果。你可以通过使用不同的输入数据集重复第2节的所有步骤来复制结果,或者可以使用下面的代码片段加载预处理的数据集。或者你可以查看链接的在线演示。

3. 1 CIFAR-10

加载 CIFAR-10数据集

from renumics import spotlight
import datasets
ds = datasets.load_dataset("renumics/cifar10-outlier", split="train")
df = ds.rename_columns({"img": "image", "label": "labels"}).to_pandas()
df["label_str"] = df["labels"].apply(lambda x: ds.features["label"].int2str(x))
dtypes = {
    "nn_image": spotlight.Image,
    "image": spotlight.Image,
    "embedding_ft": spotlight.Embedding,
    "embedding_foundation": spotlight.Embedding,
}
spotlight.show(
    df,
    dtype=dtypes,
    layout="https://spotlight.renumics.com/resources/layout_pre_post_ft.json",
)

或查看在线演示 https://huggingface.co/spaces/renumics/cifar10-outlier 来检查异常值:
在这里插入图片描述
在这里插入图片描述

微调后嵌入向量的 UMAP 可视化显示了独特的模式,其中某些类别完全与其他所有类别分离,而有些可能只与一两个其他类别相连。
在 CIFAR-10 中,使用微调前嵌入向量检测到的异常值似乎并不特别少见,因为它们与相邻图像相对相似。相比之下,使用微调后嵌入向量识别出的异常值则非常独特且在数据集中极为少见。

3.2 CIFAR-100

加载CIFAR-100数据集

from renumics import spotlight
import datasets
ds = datasets.load_dataset("renumics/cifar100-outlier", split="train")
df = ds.rename_columns({"img": "image", "fine_label": "labels"}).to_pandas()
df["label_str"] = df["labels"].apply(lambda x: ds.features["fine_label"].int2str(x))
dtypes = {
    "nn_image": spotlight.Image,
    "image": spotlight.Image,
    "embedding_ft": spotlight.Embedding,
    "embedding_foundation": spotlight.Embedding,
}
spotlight.show(
    df,
    dtype=dtypes,
    layout="https://spotlight.renumics.com/resources/layout_pre_post_ft.json",
)

或查看在线演示 https://huggingface.co/spaces/renumics/cifar100-outlier 来检查异常值:
在这里插入图片描述
在这里插入图片描述

当检查包含 100 个类别的 CIFAR-100 的嵌入向量时,我们观察到即使在微调之后,与微调前的嵌入向量相比,仍有更多的类别相连。然而,嵌入空间内的结构变得更加明显和有序。
微调前的嵌入向量并未显示出明显突出于其邻近图像的异常值,表明在异常检测方面的效果有限。然而,当使用微调后的嵌入向量时,性能得到提升。在识别出的六个异常值中,前三个被有效地检测为数据集内不常见的异常。

3.3 MNIST

加载MINIST数据集

from renumics import spotlight
import datasets
ds = datasets.load_dataset("renumics/mnist-outlier", split="train")
df = ds.rename_columns({"label": "labels"}).to_pandas()
df["label_str"] = df["labels"].apply(lambda x: ds.features["label"].int2str(x))
dtypes = {
    "nn_image": spotlight.Image,
    "image": spotlight.Image,
    "embedding_ft": spotlight.Embedding,
    "embedding_foundation": spotlight.Embedding,
}
spotlight.show(
    df,
    dtype=dtypes,
    layout="https://spotlight.renumics.com/resources/layout_pre_post_ft.json",
)

或查看在线演示 huggingface.co/spaces/renumics/mnist-outlier 来检查异常值:
在这里插入图片描述
在这里插入图片描述

在 MNIST 的微调过程中,嵌入向量经历了显著变化。微调前,不同数字类别之间可能存在重叠区域,仅凭嵌入向量的邻近性难以区分它们。然而,微调后,嵌入向量展现出数字类别之间更清晰的分离。
微调前的嵌入向量只揭示出一个与邻近图像明显不同的异常值,表明其在异常检测方面的性能中等。然而,当使用微调后的嵌入向量时,异常值的检测性能提高。大约能够识别出 3 到 4 个在数据集中非常罕见的异常值。

3.4 Beans

加载Beans数据集

from renumics import spotlight
import datasets
ds = datasets.load_dataset("renumics/beans-outlier", split="train")
df = ds.to_pandas()
df["label_str"] = df["labels"].apply(lambda x: ds.features["labels"].int2str(x))
dtypes = {
    "nn_image": spotlight.Image,
    "image": spotlight.Image,
    "embedding_ft": spotlight.Embedding,
    "embedding_foundation": spotlight.Embedding,
}
spotlight.show(
    df,
    dtype=dtypes,
    layout="https://spotlight.renumics.com/resources/layout_pre_post_ft.json",
)

或查看在线演示 huggingface.co/spaces/renumics/beans-outlier 来检查异常值:
在这里插入图片描述
在这里插入图片描述
在 Beans 数据集中,经过微调后,大多数嵌入向量展现出三个类别之间的完全分离。然而,仍有一些案例显示出轻微的重叠,可能是由于某些类型的豆类之间的相似性或误分类所致。
使用微调前和微调后的嵌入向量进行的异常检测并未产生显著偏离常态的异常值。识别出的异常值在数据集中并不突出或罕见。

4 结论

总之,微调对图像分类中的嵌入向量有显著影响。微调前,嵌入向量提供通用性表征,而微调后,它们捕获了特定于当前任务的特征。
这种区别在 UMAP 可视化中清晰反映出来,其中微调后的嵌入向量展示出更加结构化的模式,某些类别完全与其他类别分离。
对于异常检测而言,使用微调后的嵌入向量可能更有效。然而,值得注意的是,基于微调所获得的概率计算异常值可能比仅依赖嵌入向量带来更好的结果。
微调前和微调后的嵌入向量各有其独特优势,应结合使用以在图像分类和分析任务中实现全面分析。

参考文献

[1] Alexey Dosovitskiy, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, Matthias Minderer, Georg Heigold, Sylvain Gelly, Jakob Uszkoreit, Neil Houlsby An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale (2020), arXiv

[2] Ze Liu, Yutong Lin, Yue Cao, Han Hu, Yixuan Wei, Zheng Zhang, Stephen Lin, Baining Guo Swin Transformer: Hierarchical Vision Transformer using Shifted Windows (2021), arXiv

[3] Alex Krizhevsky, Learning Multiple Layers of Features from Tiny Images (2009), University Toronto

[4] Yann LeCun, Corinna Cortes, Christopher J.C. Burges, MNIST handwritten digit database (2010), ATT Labs [Online]

[5] Makerere AI Lab, Bean disease dataset (2020), AIR Lab Makerere University

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

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

相关文章

OceanBase原理之内存管理

第1章 前言 1.1 多租户管理简介 OceanBase数据库中&#xff0c;应用了单集群多租户的设计&#xff0c;使得一个集群内能够创建多个彼此独立的租户。在OceanBase数据库&#xff0c;租户成为了资源分配的单位&#xff0c;同时还是数据库对象管理和资源管理的基础。 在某种程度…

k8s的pod和svc相互访问时网络链路解析

k8s的pod和svc相互访问时网络链路解析 1. k8s环境中pod相互访问1.1. k8s中pod相互访问的整体流程1.2. k8s的相同机器的不同pod相互访问1.3. k8s的不同机器的不同pod相互访问 3. k8s访问svc3.1 nat操作3.2 流量进入到后端pod 4. 疑问和思考4.1 访问pod相互访问为什么不用做nat?…

03.JavaScript中的数组

数组 知道什么是数组及其应用的场景&#xff0c;掌握数组声明及访问的语法。 数组是什么&#xff1f; 数组&#xff1a;(Array)是一种可以按顺序保存数据的数据类型 **使用场景&#xff1a;**如果有多个数据可以用数组保存起来&#xff0c;然后放到一个变量中&#xff0c;管理…

前端基础篇-深入了解用 HTML 与 CSS 实现正文排版、正文布局

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 HTML 与 CSS 概述 2.0 HTML - 正文排版 2.1 视频标签 2.2 音频标签 2.3 段落标签 2.4 文本加粗标签 2.5 换行标签 2.6 CSS 样式 2.7 实现正文排版 3.0 HTML - …

2024年A特种设备相关管理(锅炉压力容器压力管道)证考试题库及A特种设备相关管理(锅炉压力容器压力管道)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;证考试题库及A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#…

Android中ANR机制

Android中的ANR分为两种&#xff0c;前台ANR和后台ANR。 前台ANR&#xff0c;是指ANR时对用户可感知&#xff0c;比如拥有当前前台可见的activity的进程&#xff0c;或者拥有前台通知的fg-service的进程&#xff0c;这些是用户可感知的场景。前台ANR&#xff0c;会出现一个系统…

linux命令深入研究——vim

vim可以对指定文件内容进行编辑&#xff0c;同时其操作还有一些快捷方式&#xff0c;常用的有如下部分

TypeScript编译选项

编译单个文件&#xff1a;终端 tsc 文件名 自动编译单个文件&#xff1a;终端 tsc 文件名 -w 编译整个项目&#xff1a;tsc 前提是得有ts的配置文件tsconfig.json 自动编译整个项目&#xff1a;tsc --w tsconfig.json默认文件内容&#xff1a; tsconfig.json是ts编译器的配…

<商务世界>《第10课 招投标的多种形式》

1 公开招标 1.1 什么是公开招标 《招投标法》第十条第二款规定:“公开招标是指招标人以招标公告的方式邀请不特定的法人或者其他组织投标。”也就是说,所有公开招标的项目都必须在公共平台发布招标信息,符合条件的供应商均可以参与投标。 公开招标的采购方式,因为投标人较…

面向对象【static关键字】

文章目录 Java中的static关键字1. 静态变量2. 静态方法的特点3. 静态块4. 静态导入5. 单例模式中的应用 Java中的static关键字 在Java中&#xff0c;static是一个关键字&#xff0c;用于定义类级别的成员&#xff0c;这些成员与类的实例无关。static成员属于类而不是类的实例&…

刷题日记——01字符串、非素数个数(厦门大学机试)

题目1——01字符串 分析 经过拆解找规律&#xff0c;发现是两个斐波那契 那么代码就好写了呀 #include <stdio.h>unsigned long long f(int n){if(n0||n1){return n;}return (f(n-1)f(n-2))%2333333; }int main(){int n;scanf("%d",&n);printf("%…

sqllab第六关通关笔记

知识点&#xff1a; 报错注入回顾原始语句测试截取函数 mid(字符串&#xff0c;起始位置&#xff0c;长度)substr(字符串&#xff0c;起始位置&#xff0c;长度)left(字符串&#xff0c;长度)right(字符串&#xff0c;长度)加入截取控制的错误注入payload payload:id1"%2…

深度学习(十一):YOLOv9之最新的目标检测器解读

YOLOv9 1.YOLOv9:物体检测技术的飞跃发展1.1 YOLOv9 简介1.2YOLOv9 的核心创新1.2.1信息瓶颈:神经网络在抽取相关性时的理论边界1.2.2可逆函数:保留完整的信息流1.2.3对轻型模型的影响&#xff1a;解决信息丢失1.2.4可编程梯度信息 (PGI)&#xff1a;解决信息瓶颈1.2.5通用高效…

掘根宝典之C++迭代器简介

在C中&#xff0c;容器是一种用于存储和管理数据的数据结构。C标准库提供了多种容器&#xff0c;每种容器都有其独特的特点和适用场景。 我们知道啊&#xff0c;我们可以通过下标运算符来对容器内的元素进行访问&#xff0c;但是只有少数几种容器才同时支持下标运算符&#xf…

Leetcode 3.12

leetcode hot 100 链表1.两两交换链表中的节点2.随机链表的复制3.排序链表 链表 1.两两交换链表中的节点 两两交换链表中的节点 1.必须要设置一个dummy (temp) 结点2.保存第二个节点3.先让第一个节点指向第三个节点4.再让第二个节点指向第一个节点5.最后让dummy指向第二个节点…

2024 年 2 月 NFT 行业动态:加密货币飙升,NFT 市场调整

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;NFT 研究页面 - Footprint Analytics 2024 年 2 月&#xff0c;加密货币与 NFT 市场显现出了复杂性。该月&#xff0c;NFT 领域的交易量达到 12 亿美元&#xff0c;环比下降了 3.7%。值得关注的是&#xff0c;包…

AI智能分析网关V4将HTTP消息推送至安防监控视频汇聚EasyCVR平台的操作步骤

TSINGSEE青犀视频智能分析网关V4内置了近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、物、行为等实时检测分析&#xff0c;上报识别结果&#xff0c;并能进行语音告警播放。硬件管理平台支持RTSP、GB28181协议、以及厂家私有协议接入&#xff0c;可兼容市面上常…

从根到叶:深入了解Map和Set

窗间映出一片高远的天空&#xff0c; 向晚的天际宁静而又清明。 我孤独的心灵在幸福地哭泣&#xff0c; 它在为天空如此美好而高兴。 恬静的晚霞一片火红&#xff0c; 晚霞灼烧着我的热情。 此刻的世界没有别人&#xff0c; 只有上帝&#xff0c;我和天空。 ——&#x…

利用“定时执行专家”软件的25种任务与12种触发器,提升IT系统管理自动化水平

在IT系统管理中&#xff0c;自动化是提高工作效率、减少人为错误的关键。而《定时执行专家》这款软件&#xff0c;以其强大的功能、易用性和毫秒级的执行精度&#xff0c;成为了IT系统管理员的得力助手。今天&#xff0c;我们就来探讨一下如何利用这款软件的25种任务类型和12种…

【AI绘画】AI绘画免费网站推荐

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是指一种模拟人类智能的技术。它是通过计算机系统来模拟人的认知、学习和推理能力&#xff0c;以实现类似于人类智能的行为和决策。人工智能技术包含多个方面&#xff0c;包括机器学习、深度学习、自…