5 个 AI 实际项目助你迈入这个领域

5 个 AI 实际项目助你迈入这个领域

Barry Lv6

不要只是学习数据科学——要去实践!进行数据科学的最佳方式是构建能够激发你热情并与你产生共鸣的实际项目。

无论你在数据科学的旅程中处于何种阶段,你总是可以卷起袖子,动手尝试。这有助于你连接思路并挑战自己的理解。

如果你是 AI 和 LLM 世界的新手,并希望迈出第一步,我认为以下实际项目(按复杂性排序)是进入该领域的良好切入点。尽管提示工程在处理(生成)AI 模型时是一个重要方面,但我们将在本文中跳过它。

今天的议程如下

· 在 AI 项目中应关注什么?· 项目 1:构建一个 RAG 聊天机器人,询问任何关于书籍的问题! 📚· 项目 2:构建一个自主代理:关于书籍的所有信息 📚· 项目 3:训练你自己的 LLM(一个歌曲创作人 🎶🎸🎹)· 项目 4:微调 Bert 模型以理解法律文本 👩‍⚖️· 项目 5:模型评估

在人工智能项目中需要注意什么?

“人工智能”这一术语最早出现在19世纪,尽管其出现频率相对较低。

关于人工智能的一些想法在19世纪就已经存在。1872年,萨缪尔·巴特勒出版了Erewhon ,其中包含一个关于一个虚构土地的故事,机器根据达尔文的进化论以更快的速度进化,并获得意识,在各个方面超越人类。150年前非常虚构,但今天并不是完全不可想象。

1940年至1960年是人工智能发现的黄金时代。尽管在过去十年中,随着大量数据和计算能力的迅速变化,人工智能已经存在了相当长一段时间。

“人工智能”这一术语在1956年的Dartmouth AI Workshop 上正式提出。如今,当人们谈论人工智能时,他们通常指的是生成式人工智能,这是机器学习和深度学习的一个子集。

在探索人工智能项目时,在我看来,我们应该优先考虑那些提供以下内容的项目:

  • 理论基础和人工智能概念:掌握人工智能领域的基本理论、原则和核心概念。
  • 人工智能产品开发:通过应用框架和构建实际应用获得实践经验。这有助于验证你的理解并提高你的技术技能。
  • 评估:学习如何评估和改进你的人工智能应用的性能。

项目 1:构建一个 RAG 系统,以便询问任何关于书籍的问题! 📚

想象一下,您拥有一个关于书籍 (📚) 的完整数据库,并且您希望根据您的问题检索相关书籍并回答有关某些书籍的问题,这正是使用 RAG 创建文档检索应用的完美用例。

>>> 你将创建什么?

我们将创建一个RAG系统,该系统在接收到用户查询时,从我们的数据库中返回相关书籍,并回答有关书籍的任何问题! 📚📚📚

>>> 您将学习的技能

  • RAG 系统
  • 创建向量嵌入
  • 使用向量存储/数据库(例如,FAISS,Qdrant,Chroma)存储和查询嵌入
  • 结合向量存储和 LLM 进行信息检索

>>> 基本理论和概念

👉 什么是检索增强生成(RAG)系统?

基于RAG的架构为LLM(即Claude3.5)提供了访问外部知识源的能力,从而为用户查询提供额外的上下文。这通常涉及根据与查询的相似性进行搜索,检索最相关的文档,并将其插入到提示中作为信息检索的上下文。

RAG用于解决开放式场景中的幻觉问题,例如用户与容易编造内容的聊天机器人交谈时,当被问及其训练数据中没有的信息时。

以下是RAG的工作流程:

  • 将文档拆分为块
  • 将每个块转换为向量嵌入,并在向量数据库中对块进行索引
  • 查询:给定用户输入,向量化用户输入,在向量数据库中按向量搜索最接近的记录并检索相关上下文
  • 生成:结合查询和相关上下文,获取LLM响应

👉 嵌入和向量存储/数据库

尽管嵌入模型在生成AI出现之前就已经存在,但生成AI模型再次推动了文本的向量表示,或称为词嵌入,这是一种将文本或图像表示为数字列表的高级说法。例如,您可以将其视为位置的坐标。

您可以计算巴黎 — 法国 + 荷兰,结果是接近阿姆斯特丹的向量嵌入,这似乎表明首都的概念在嵌入中被编码。

这是另一个著名的例子:如果您计算国王 — 男人 + 女人(对这些词的嵌入向量进行加减),那么结果将非常接近于“女王”这个词的嵌入。这似乎表明嵌入编码了性别的概念!

当您向ChatGPT提出问题时,您的问题会在后台转换为ChatGPT可以理解的嵌入/向量。该嵌入被索引并存储在向量数据库中。向量数据库将文本记录及其向量表示作为键存储。这项技术通过在提示中引用ChatGPT未经过训练的相关上下文,帮助减少幻觉,从而使其可以在计算响应时使用这些上下文。

>>> 实施步骤

技术栈:

  • LLM框架:Langchain。它为您提供了许多与LLM合作的组件
  • 基础模型:GPT4o
  • 向量存储:Qdrant(您可以使用Chroma或FAISS)
  • 前端:Holoviz Panel(替代可以是Streamlit)
  • 嵌入模型:OpenAI text-embedding-large-03

👉 第一步:设置环境

首先,确保您已安装必要的库:

1
uv pip install --upgrade langchain openai qdrant-client pandas nltk tomotopy pyvis

👉 第二步:抓取书籍数据

为了简洁起见,函数细节省略,请参见此仓库

1
2
3
4
5
6
def scrape_book():
""""""
# (函数实现细节省略)
# 此函数将包括使用Google API从Google Books抓取数据
# 和使用Selinium从亚马逊抓取评论
return df_books

👉 第三步:设置向量数据库

首先,我们需要创建嵌入对象并设置一个向量数据库来存储我们的书籍数据的嵌入。我将使用OpenAI text-embedding-3-large来生成嵌入。

1
2
3
4
5
6
7
8
9
10
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
def create_db(documents):
return Qdrant.from_documents(
documents=documents,
embedding=embeddings,
collection_name="my_documents",
location=":memory:",
force_recreate=False,
)
db = create_db(documents)

在设置向量数据库时,我们传递location=”:memory:”以指定数据库应在内存中创建,并且我们计划在同一会话中与其交互。

👉 第四步:使用相关上下文进行信息检索

接下来,我们获取用户查询,搜索数据库并返回相关文档的列表。在这里,您可以调整一些参数,例如搜索空间(返回的文档数量k)或相似性类型(similarity_score_threshold,最大边际相关性mmr):

1
2
3
4
5
6
7
8
9
10
11
12
retriever = db.as_retriever(
search_type="mmr", search_kwargs={"k": 2, "lambda_mult": 0.25}
)
# 创建一个链来回答问题
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
query = "能告诉我书籍《Life 3.0》的关键主题是什么,20个字吗?"
result = qa({"query": query})

就这样!一个根据查询的相似性进行搜索的系统,检索最相关的文档并将其用作回答用户问题的上下文:

>>> 有用资源

项目 2:构建自主代理:关于书籍的一切 📚

生成式 AI 模型催生了 基于代理的架构。如果你想了解代理是如何工作的并从头开始构建一个,我有一篇文章 可以参考。

>>> 你将创建什么?

基础 模型出现之前,只有具备足够资源的组织才能开发AI模型并创建AI应用。随着基础模型的出现,任何人都可以构建AI应用。

在这个项目中,我们将创建一个增强版的RAG系统,能够自主决策并采取行动,无需任何人类干预。令人兴奋!

>>> 您将学习的技能

  • 代理架构
  • 使用 OpenAI 函数调用和 Langchain LCEL 构建自定义代理
  • 使用 Holoviz Panel 创建交互式用户界面

>>> 基本理论和概念

👉 什么是代理? 🤖

代理是一个自主实体,能够根据高级指令进行规划、使用行动/工具,并执行多个迭代步骤以实现期望目标。

代理可以采取各种行动,例如执行一个 Python 函数;然后,代理将观察执行该行动后发生的结果,并决定下一步采取哪种行动。这个过程会重复,直到代理获得主要任务的最终答案。

您还可以在以下伪代码中看到这个过程的书写方式:

1
2
3
4
5
next_action = agent.get_action(...)
while next_action != AgentFinish:
observation = run(next_action)
next_action = agent.get_action(..., next_action, observation)
return next_action

代理具有以下组件,例如输入、期望目标和可用行动。考虑一辆自动驾驶汽车,它接收传感器数据(摄像头或超声波)等输入。目标是确保安全、高效的导航。奖励函数可以是行驶的里程数而无需干预(特斯拉)。可用的行动包括加速、减速、转弯、变道、停车等……

有许多代理框架旨在改善 LLM 的响应。最初的框架是 ReAct,允许 LLM 在通过工具采取 行动 后创建观察。这些观察随后被转化为关于下一步使用哪个 正确工具思考,直到达到 最终答案

OpenAI 发布了更精细调整的 LLM ,专门针对函数调用。它为工具使用提供了一个替代标准 ReAct 模式的选项。

>>> 实施步骤

对于这个项目,我们将使用 OpenAI 的函数调用和 Langchain LCEL 来构建代理。

代理使用可用的工具/操作,因此第一步是定义工具。

👉 步骤 1:定义工具

工具只是一个预定义的函数,允许代理采取特定的行动。

由于 LLM(如 GPT-4)通常只生成文本/图像,我们可以提供可以执行其他操作的工具,例如与数据库交互或执行 Python 代码。

我们将开始定义代理将使用的四个主要工具。为简洁起见,这里省略了函数实现细节:

  1. scrape_books : 从谷歌和亚马逊抓取书籍和书评
  2. find_relevant_books: 根据用户查询检索相关书籍。
  3. create_topic_network: 创建书籍主题的可视化。
  4. qa: 根据检索到的文档回答用户的问题

这些工具被定义为函数,并使用 LangChain 的 @tool 装饰器进行装饰,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@tool
def find_relevant_books(user_query):
"""
Return all relevant books based on user query.
Important: This function should be called only for queries that require finding specific books.
For general queries that do not require finding specific books, use other available functions.
"""
retriever = db.as_retriever(
search_type="mmr", search_kwargs={"k": 4, "lambda_mult": 0.25}
)
relevant_docs = retriever.get_relevant_documents(user_query)
session_state["relevant_docs"] = relevant_docs
session_state["retriever"] = retriever
return relevant_docs

llm = ChatOpenAI(
model="gpt-4o",
temperature=0,
openai_api_key=os.getenv("OPEN_AI_KEY")
)
@tool
def qa(user_query):
"""
Answer user questions based on the retrieved documents
"""
retriever = session_state["retriever"]
relevant_docs = session_state.get("relevant_docs")
if relevant_docs is None:
# If no documents are stored, retrieve them
relevant_docs = retriever.get_relevant_documents(user_query)
session_state["relevant_docs"] = relevant_docs

# Create a chain to answer questions using stored documents
qa = ConversationalRetrievalChain.from_llm(llm, retriever)
chat_history = []
result = qa(
{"question": user_query, "chat_history": chat_history, "context": relevant_docs}
)
return result

在使用 @tool 装饰这些操作时,主代理将能够访问函数列表、它们的参数和文档字符串。这使得代理能够智能地选择最相关的工具来完成任务。

为方便起见,我们将在全局定义的字典 session_state 中存储相关文档和检索器。这使得代理更容易访问这些信息。

👉 步骤 2. 创建提示

现在我们设置带有系统消息、用户消息和 MessagesPlaceholder 的提示,允许代理存储其中间步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder

# Define the prompt template
prompt_template = """
You are a helpful AI assistant specializing in answering questions
related to books from users. Use retrieved relevant books to
answer questions.
====================
{relevant_docs}
"""
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"""You are helpful AI assistant. Use the following
template for your actions and observations."""
),
("user", prompt_template),
MessagesPlaceholder(variable_name="chat_history"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)

草稿本是代理将存储所有中间结果的地方。例如,如果用户要求创建第一本哈利·波特书籍的所有主题的可视化,代理将首先找到相关书籍(魔法石),将输出存储在草稿本中,然后推理出应该调用 create_topic_network

👉 步骤 3. 初始化代理

为了让代理知道所有可用的工具,您需要首先将工具直接绑定到 LLM 以进行函数调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain.agents.format_scratchpad import format_to_openai_functions
from langchain.tools import Tool

# These are custom functions for finding books, answering questions, and creating topic networks.
tools = [find_relevant_books, qa, create_topic_network]
# OpenAI Function Formatting. This converts the tools into a format compatible with OpenAI's function calling feature.
functions = [format_tool_to_openai_function(f) for f in tools]
#This sets up the GPT-4o model with the defined functions.
model = ChatOpenAI(
openai_api_key=openai.api_key,
temperature=0,
model_name="gpt-4o",
).bind(functions=functions)

现在我们已经定义了工具和提示,可以创建代理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from langchain.agents import AgentExecutor
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
from langchain.schema.runnable import RunnablePassthrough
from langchain.memory import ConversationBufferMemory

# Set up the agent chain.
# including assigning relevant documents and agent scratchpad, applying the prompt, running the model, and parsing the output.
agent_chain = (
RunnablePassthrough.assign(
agent_scratchpad=lambda x: format_to_openai_functions(x["intermediate_steps"]),
relevant_docs=lambda x: "\n".join(
str(doc) for doc in session_state.get("relevant_docs", [])
),
)
| prompt
| model
| OpenAIFunctionsAgentOutputParser()
)
# Set up a memory component to store conversation history.
memory = ConversationBufferMemory(
return_messages=True,
memory_key="chat_history",
input_key="input",
output_key="output",
)
# Initialize an agent with the agent and defined tools
# This combines all components into an executable agent that can process queries and maintain conversation context.
# With AgentExecutor, the agent is equipped with the tools and verbose output is enabled, allowing for detailed logging.
agent = AgentExecutor(agent=agent_chain, tools=tools, verbose=True, memory=memory)

就这样!一个功能齐全的代理,拥有访问少量工具的能力,准备开始工作。

👉 步骤 4. 使用 Panel 创建用户界面

现在我们已经设置了代理,让我们使用 Panel 创建一个用户友好的界面以与该代理交互:

>>> 有用资源

项目 3:训练你自己的 LLM (一个歌曲创作工具 🎶🎸🎹)

如果你关心 AI 的 理论基础 并希望高层次地理解这些基础模型是如何训练的,从头开始构建一个 LLM 将挑战你的理解。

如果你对基于 Transformer 的语言模型不熟悉,你很幸运,因为使用 nanoGPT 非常简单。在视频 让我们从零开始构建 GPT 中,Andrej Kapathy 讲解了从头构建一个小型 GPT 模型(或 nanoGPT)的过程,并解释了其底层的工作原理以及 chatGPT 的核心内容。基于莎士比亚文本构建 babyGPT 模型的代码可以在这个 仓库 中找到。

>>> 你将创造什么?

你喜欢音乐吗?为什么不创建一个可以生成你想要风格歌曲的 LLM 呢?

因为我喜欢 Ed Sheeran,在这个项目中,我们将创建一个小型基于词的变换器模型,能够以 Ed Sheeran 的风格写歌! 🎶🎸🎹

>>> 您将学习的技能

  • 从头开始使用 Pytorch “训练” 语言模型的含义
  • 神经网络基础:前向传播、反向传播、传播、激活函数、梯度下降算法、权重更新的方式
  • 一些重要的 NLP 概念,例如分词
  • 重要的超参数:n_layer, n_head, n_embd, learning_rate, max_iters , lr_decay_iters

>>> 基础理论和概念

与文章的其他部分相比,本节内容数学较多。如果您觉得困惑,可以选择跳过数学部分。

👉 神经网络基础

人工神经网络的架构具有输入信号和输出信号,当输入被激活时,它将简单地激活输出。

神经网络中的每个输入都与一个权重相关联。首先,神经网络计算所有输入值的加权和。

前向传播在隐藏层中,激活函数会考虑每个输入的输入和权重,在每个神经元中应用,并产生一个输出,该输出作为下一层的输入。

激活函数是一个帮助神经网络学习数据中模式的函数,并将前一层的输出传递到下一隐藏层的输入中 该过程持续进行,直到我们获得神经网络最终层的输出,即预测值。

反向传播过程

现在,我们有了一个输出,网络将开始反向传播过程。这一切都与所谓的损失函数有关。实质上,损失函数是一个比较网络的预测输出和实际输出的函数,并返回错误信息(y 和 ŷ 之间的差异)。

对于每个训练实例,反向传播测量网络中每个权重对整体错误的贡献。这使得模型能够使用优化算法更新权重,该算法调整网络中所有的权重,直到损失函数最小化。

在优化算法中,基于梯度下降的算法是最广泛使用的算法 要了解权重是如何通过梯度下降进行调整的,可以在这里找到详细的解释。您还可以在这篇文章中获得一些梯度下降替代方案的见解

在过去,循环神经网络(RNNs)卷积神经网络(CNNs)是深度学习中用于图像(CNNs)和文本(RNNs)的流行神经网络架构。然而,在2017年,具有里程碑意义的论文“Attention is all you need” 引入了变压器架构,彻底改变了AI的世界,因为它是如今大型语言模型(LLMs),包括ChatGPT背后的架构。

👉 分词

Token是语言模型的基本构件。分词是将一段文本分离成称为tokens的小块的方式。因此,您可以将tokens视为单词的片段。将原始文本拆分为tokens的过程称为分词。对于OpenAI的GPT模型,平均一个token大约是一个单词长度的¾,因此1000个tokens大约是750个单词。根据您使用的分词器,tokens可以是单词、字符或子词。

tiktoken库是一个常用的文本分词库,特别是在处理像OpenAI的GPT-3或GPT-4这样的模型时。下面是如何使用tiktoken将一个单词转换为tokens的示例:

>>> 实施步骤

好了,够多的闲聊,让我们开始动手吧。我们正在训练一个小型基于词的变换器模型,预测下一个出现的词。

👉 步骤 1. 准备训练数据

加载数据集

在这篇文章中,我们将使用 Ed-sheeran 数据集 ,该数据集包含了 Ed Sheeran 所有歌曲的歌词。您可以使用 datasets 库加载此数据集:

1
2
from datasets import load_dataset
dataset = load_dataset("huggingartists/ed-sheeran")

太棒了!我们现在准备进行一些数据处理,以获取数据集中每首歌的歌词。以下代码块将处理数据并保存到一个 csv 文件中:

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
df = pd.DataFrame(data=dataset)
df['text'] = df.train.apply(lambda row: row.get("text"))

def get_title_lyrics(text):
lyrics_start = "Lyrics"
lyrics_index = text.index(lyrics_start)
title = text[:lyrics_index].strip()
lyrics = text[lyrics_index + len(lyrics_start):].strip()
return {'Title': title, 'Lyrics': lyrics}
df[['Title', 'Lyrics']] = df['text'].apply(get_title_lyrics).apply(pd.Series)

编码文本并创建训练/测试/验证集

由于语言模型使用的是标记,我们将原始歌词转换为整数序列或标记 ID。因为我们将训练一个基于词的变换器模型,我们将使用 GPT2 标记器对每个标记进行编码,每个标记由一个唯一的标记 ID(整数)表示。

让我们选择 90% 的文本作为训练数据,10% 作为验证数据。

编码后的文本被分成训练集(train_ids)和验证集(val_ids)。这些训练和验证集包含与原始文本中的标记对应的整数序列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import os
import tiktoken
import numpy as np
import pandas as pd

df = pd.read_csv("data/ed-sheeran/ed_sheeran.csv")
data = df["Lyrics"].str.cat(sep="\n")
n = len(data)
train_data = data[: int(n * 0.9)]
val_data = data[int(n * 0.9) :]
# encode with tiktoken gpt2 bpe
enc = tiktoken.get_encoding("gpt2")
train_ids = enc.encode_ordinary(train_data)
val_ids = enc.encode_ordinary(val_data)
# export to bin files
train_ids = np.array(train_ids, dtype=np.uint16)
val_ids = np.array(val_ids, dtype=np.uint16)
train_ids.tofile(os.path.join(os.path.dirname(__file__), "train.bin"))
val_ids.tofile(os.path.join(os.path.dirname(__file__), "val.bin"))
# train has 433,585 tokens
# val has 48,662 tokens

现在,我将把上述代码保存到一个名为 prepare-edsheeran.py 的文件中,并运行以下命令:

1
python data/prepare-edsheeran.py

这样做会将 train_idsval_ids 序列保存为二进制文件 - train.binval.bin,其中保存了 GPT2 标记 ID 的一个序列。就这样!数据准备好了。我们可以开始训练了。

👉 步骤 2. 定义模型

代码实现细节省略。以下过程概述了创建模型和训练的基本步骤(代码可以在这个 仓库 中看到)。

创建 model.py,定义 GPT 类:

  • 初始化变换器组件(嵌入、块等)
  • 定义前向传播:通过嵌入和变换器块处理输入
  • 配置优化器:为权重衰减分离参数
  • 对于每个纪元和批次,执行前向传播,计算损失并反向传播和更新参数

然后,我们将创建 train.py 来初始化模型,运行训练循环并生成文本。

👉 步骤 3. 训练 babyGPT 模型

在这一部分,我们将实际训练一个 baby GPT 模型。让我们创建一个名为 config/train_edsheeran.py 的新文件来定义超参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
out_dir = "out-lyrics"
eval_interval = 250 # 保持频繁,因为我们会过拟合
eval_iters = 20
log_interval = 10 # 不要太频繁打印
# 我们期望在这个小数据集上过拟合,所以只有在验证改善时才保存
always_save_checkpoint = False
dataset = "ed-sheeran"
batch_size = 12 # 每次迭代 12 个样本
block_size = 64 # 上下文大小
# 一个 baby GPT 模型 :)
n_layer = 6
n_head = 6
n_embd = 384 # 每个标记的嵌入向量将具有 384 维
dropout = 0.2
learning_rate = 1e-3 # 对于小网络,可以稍微高一些
max_iters = 2000
lr_decay_iters = 2000 # 通常与 max_iters 相等
min_lr = 1e-4 # 通常为学习率 / 10
beta2 = 0.99 # 因为每次迭代的标记数量较少,所以稍微大一些
warmup_iters = 100 # 可能不是特别必要

要训练模型,请在终端中运行以下代码:

1
python train.py config/train_edsheeran.py

训练开始了…!

***等待中****

好了!训练完成。我们将创建一个图表,显示验证集上的损失与迭代次数的关系。观察以下图表,我们注意到在 500 次迭代后验证损失增加,提示存在过拟合。

为了解决这个问题,我们将限制选择这 500 次迭代,并继续对模型进行重新训练。一旦重新训练完成,训练好的模型 ckpt.pt 将直接保存到输出目录 out-lyrics

步骤 4. 生成 Ed Sheeran 风格的歌曲

现在是有趣的部分!让我们看看我们的模型能多好地学习创作听起来像 Ed Sheeran 的歌曲!我们可以通过将采样脚本指向此目录来从最佳模型中采样:

1
python sample.py --out_dir=out-lyrics

运行上述代码生成一些样本。以下是结果:

我认为这确实听起来像 Ed Sheeran,有着甜蜜的爱情歌曲和浪漫主题,不是吗? 🎶🎸🎹

>>> 资源

Project 4: 微调Bert模型以理解法律文本 👩‍⚖️

如果你可以使用最先进的模型,而不必从头开始为自己的特定任务训练一个,那将是多么棒的事情呢?微调是一种非常强大的训练技术!

>>> 你将创建什么?

我们将创建一个专门的基于Bert的模型,用于法律文本的语义角色标注任务!🤗 Transformers 提供了数千个预训练模型,以支持各种任务。

>>> 您将学习的技能

  • 使用 Transformers Trainer 框架微调预训练模型
  • 使用 Transformers 的 Dataset 对象

>>> 基础理论

👉 什么是微调?

微调模型意味着使用特定于您的任务的数据集继续训练一个先前训练过的模型。因此,模型权重是从之前的训练过程中获得的。例如,如果您将童年日记输入到 ChatGPT 中并继续训练,这就是微调。

>>> 实施步骤

(Code adapted from Hugging face )

👉 第一步. 加载数据集对象并拆分为训练/测试/验证集:

显然,这需要有一个带标签的数据集。

加载用于微调的数据集

1
2
3
4
5
6
7
8
9
10
11
12
data = "data/all_annotations_cleaned.csv" 
df_to_train = pd.read_csv(data, sep = ";", converters={'tokens': eval, 'srl_tags': eval})
dataset = Dataset.from_pandas(df_to_train)
# SPLITTING main dataset into train, validation, test as DatasetDict
train_testvalid = dataset.train_test_split(test_size=0.1)
# Split the 10% test + valid in half test, half valid
test_valid = train_testvalid['test'].train_test_split(test_size=0.5)
# Collect the two into a single DatasetDict
datasets = DatasetDict({
'train': train_testvalid['train'],
'test': test_valid['test'],
'validation': test_valid['train']})

👉 第二步. 标记化

为了在一步中对我们的数据集进行标记化,我们将使用 robbert-v2-dutch-base Tokenizer(因为我正在使用荷兰法律文本来微调基于荷兰Bert的模型)。datasets.map 方法将对整个数据集应用标记化:

1
2
3
4
tokenizer = AutoTokenizer.from_pretrained("pdelobelle/robbert-v2-dutch-base", add_prefix_space=True)
def tokenize_and_align_labels(examples, label_all_tokens = True):
tokenized_inputs = tokenizer(examples["tokens"], truncation=True, is_split_into_words=True)
tokenized_datasets = datasets.map(tokenize_and_align_labels, batched=True)

标记化数据集后,我们现在还获得了 ‘input_ids’ 和 ‘attention_mask’:

👉 第三步. 使用Huggingface Trainer进行微调

加载Trainer

Transformers提供了一个Trainer 类,优化了Huggingface Transformers模型的训练。我们将首先加载所选模型。我将使用荷兰Bert模型:

1
model = AutoModelForTokenClassification.from_pretrained("GroNLP/bert-base-dutch-cased", num_labels=len(label_list))

创建训练超参数

接下来,创建一个TrainingArguments 类,其中包含您可以调整的超参数:

1
2
3
4
5
6
7
8
9
batch_size = 1
args = TrainingArguments(
output_dir=".",
evaluation_strategy = "epoch",
learning_rate=5e-5,
num_train_epochs=5,
weight_decay=0.01,
seed=1
)

定义评估指标

数据集包还提供了生成准确率指标的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from datasets import load_metric
metric = load_metric("seqeval")
def compute_metrics(p):
predictions, labels = p
predictions = np.argmax(predictions, axis=2)
true_predictions = [
[label_list[p] for (p, l) in zip(prediction, label) if l != -100]
for prediction, label in zip(predictions, labels)
]
true_labels = [
[label_list[l] for (p, l) in zip(prediction, label) if l != -100]
for prediction, label in zip(predictions, labels)
]
results = metric.compute(predictions=true_predictions, references=true_labels)
return {
"precision": results["overall_precision"],
"recall": results["overall_recall"],
"f1": results["overall_f1"],
"accuracy": results["overall_accuracy"],
}

微调模型

创建一个Trainer 对象,包含所选模型、训练参数、训练和测试数据集,以及评估指标 :

1
2
3
4
5
6
7
8
9
trainer = Trainer(
model=model,
args=args,
train_dataset=reloaded_encoded_dataset["train"],
eval_dataset=reloaded_encoded_dataset["validation"],
data_collator=data_collator,
tokenizer=tokenizer,
compute_metrics=compute_metrics
)

然后,我们可以通过调用train() 方法来简单地微调模型:

1
trainer.trains()

模型训练完成,可以用于语义角色标注任务。让我们检查一下性能是否优于预训练的Robbert模型:

嗯,似乎改进并不是那么显著 😃 但至少,我们学会了如何微调Bert模型!

>>> 资源

🤗 微调预训练模型

项目 5:模型评估

评估 GenAI 模型的输出既重要又具有挑战性。

在 GenAI 时代之前,您只需将数据分为训练集/测试集/验证集——在训练集上训练模型,并在验证集和测试集上评估性能。在监督学习中,我们使用 R-squared、Precision、Recall 或 F-score 来评估性能。那么,大型语言模型是如何评估的呢?在生成新文本时,什么是基准真相?

>>> 你将创造什么?

应用不同的方法来评估开放式回答,包括功能正确性、相似度评分和AI作为评判者。

>>> 你将学习的技能

  • 与参考数据的相似性测量
  • 检查模型输出的一致性
  • 使用 LLM 作为评判者
  • 理解 NLP 模型的评估指标(例如,BLEU,ROUGE)

>>> 基本理论

👉 与参考数据的相似性测量

一种常见的方法是评估AI的输出与参考数据的相似性。生成的响应越与参考响应相似,效果越好。

有三种方法可以测量两个开放文本之间的相似性:

(1) 请求评估者判断两个文本是否相同

用于比较两个响应的评估者可以是人类或AI。然而,如果您已经使用人类进行此比较,您可能不需要参考数据——人类可以直接评估生成的响应。

(2) 词汇相似性

词汇相似性测量两个文本在外观上是否相似,而不是它们是否具有相同的意义。换句话说,这测量两个文本的重叠程度。此类度量的一个例子是ROUGE分数,如下例所示:

(3) 语义相似性

语义相似性测量生成的响应在意义(语义)上与参考响应的接近程度。这需要将文本转换为数值表示或嵌入,这在项目1和2中提到过。

👉 检查模型输出的一致性

LLM的一个大问题是可重复性。聊天完成默认是非确定性的,即使在温度=0的情况下,这意味着模型输出可能因请求而异。

为了评估模型响应的一致性,我们可以使用相同的问题和提示重复调用模型,每次使用不同的种子。通过分析这些运行中答案的分布,我们可以确定模型的一致性。如果响应的分布较窄,则表明模型生成了一致的输出。

👉 使用LLM作为评判者

随着AI成功地用于自动化许多具有挑战性的任务,AI能否自动化评估?使用AI评估AI的方法称为AI作为评判者或LLM作为评判者。用于评估其他AI模型的AI模型称为AI评判者。

>>> 实施步骤

所有代码可以在我之前的 帖子 中找到。

>>> 资源

📹 OpenAI Cookbook — 评估示例

📚 AI 工程(chip Huyen)

结论

所以,这就是五个激动人心的项目,帮助你开启生成式人工智能的旅程。我希望你能找到一些下一个人工智能项目的灵感。

我们仍然处于生成式人工智能的早期阶段,我们不知道未来会如何发展。你的下一个创意可能就是改变游戏规则的那个。因此,请继续实验,继续学习,最重要的是,继续享受这个过程。

我想以我最喜欢的亚瑟·克拉克的名言结束:

任何反馈或建议都非常感激。祝学习愉快 📚😊!

感谢阅读!

如果您想阅读更多我的作品但无法选择哪一篇,没关系,我为您挑选了一篇:

  • 标题: 5 个 AI 实际项目助你迈入这个领域
  • 作者: Barry
  • 创建于 : 2024-08-01 03:27:06
  • 更新于 : 2024-08-31 06:59:45
  • 链接: https://wx.role.fun/2024/08/01/5234d411f788412fba3630178be04570/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。