在 Keras 中理解简单的递归神经网络
原文:
machinelearningmastery.com/understanding-simple-recurrent-neural-networks-in-keras/
本教程适用于希望了解递归神经网络(RNN)工作原理及如何通过 Keras 深度学习库使用它们的任何人。虽然 Keras 库提供了解决问题和构建应用所需的所有方法,但了解一切如何工作也很重要。本文展示了 RNN 模型中的计算步骤。接下来,将开发用于时间序列预测的完整端到端系统。
完成本教程后,您将了解:
-
RNN 的结构
-
当给定输入时,RNN 如何计算输出
-
如何为 Keras 中的 SimpleRNN 准备数据
-
如何训练一个 SimpleRNN 模型
使用我的书使用注意力构建 Transformer 模型快速启动项目。它提供了自学教程和可运行代码,帮助您构建一个完全可工作的 Transformer 模型,可以
将句子从一种语言翻译成另一种语言…
让我们开始吧。
在 Keras 中理解简单的递归神经网络。照片由 Mehreen Saeed 提供,部分权利保留。
教程概述
本教程分为两部分;它们是:
-
RNN 的结构
-
不同层的不同权重和偏置与 RNN 的关联
-
在给定输入时计算输出的计算方式
-
-
用于时间序列预测的完整应用程序
先决条件
假设您在开始实施之前对 RNN 有基本的了解。递归神经网络及其动力学的简介为您快速概述了 RNN。
现在让我们直接进入实施部分。
导入部分
要开始实现 RNN,请添加导入部分。
Python
from pandas import read_csv
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
import math
import matplotlib.pyplot as plt
想要开始构建带注意力的 Transformer 模型吗?
现在立即参加我的免费 12 天电子邮件速成课程(附有示例代码)。
点击注册,并获得课程的免费 PDF 电子书版本。
Keras SimpleRNN
下面的函数返回一个包含 SimpleRNN
层和 Dense
层的模型,用于学习序列数据。input_shape
参数指定了 (time_steps x features)
。我们将简化一切,并使用单变量数据,即只有一个特征;时间步骤将在下面讨论。
Python
def create_RNN(hidden_units, dense_units, input_shape, activation):
model = Sequential()
model.add(SimpleRNN(hidden_units, input_shape=input_shape,
activation=activation[0]))
model.add(Dense(units=dense_units, activation=activation[1]))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
demo_model = create_RNN(2, 1, (3,1), activation=['linear', 'linear'])
对象 demo_model
通过 SimpleRNN
层创建了两个隐藏单元,并通过 Dense
层创建了一个密集单元。input_shape
设置为 3×1,并且在两个层中都使用了 linear
激活函数以保持简单性。需要注意的是,线性激活函数
f
(
x
)
=
x
f(x) = x
f(x)=x 对输入不做任何更改。网络结构如下:
如果我们有 m m m 个隐藏单元(在上面的案例中 m = 2 m=2 m=2),那么:
-
输入: x ∈ R x \in R x∈R
-
隐藏单元: h ∈ R m h \in R^m h∈Rm
-
输入单元的权重: w x ∈ R m w_x \in R^m wx∈Rm
-
隐藏单元的权重: w h ∈ R m x m w_h \in R^{mxm} wh∈Rmxm
-
隐藏单元的偏置: b h ∈ R m b_h \in R^m bh∈Rm
-
密集层的权重: w y ∈ R m w_y \in R^m wy∈Rm
-
密集层的偏置: b y ∈ R b_y \in R by∈R
查看上述权重。注意:由于权重是随机初始化的,所以这里展示的结果可能与您的结果不同。重要的是要了解每个使用的对象的结构及其如何与其他对象交互以产生最终输出。
Python
wx = demo_model.get_weights()[0]
wh = demo_model.get_weights()[1]
bh = demo_model.get_weights()[2]
wy = demo_model.get_weights()[3]
by = demo_model.get_weights()[4]
print('wx = ', wx, ' wh = ', wh, ' bh = ', bh, ' wy =', wy, 'by = ', by)
输出
wx = [[ 0.18662322 -1.2369459 ]] wh = [[ 0.86981213 -0.49338293]
[ 0.49338293 0.8698122 ]] bh = [0\. 0.] wy = [[-0.4635998]
[ 0.6538409]] by = [0.]
现在让我们进行一个简单的实验,看看 SimpleRNN 和 Dense 层如何生成输出。保持这个图形在视野中。
循环神经网络的层次结构
我们将输入 x
三个时间步,并让网络生成一个输出。计算时间步 1、2 和 3 的隐藏单元的值。
h
0
h_0
h0 初始化为零向量。输出
o
3
o_3
o3 是从
h
3
h_3
h3 和
w
y
w_y
wy 计算的。由于我们使用线性单元,不需要激活函数。
Python
x = np.array([1, 2, 3])
# Reshape the input to the required sample_size x time_steps x features
x_input = np.reshape(x,(1, 3, 1))
y_pred_model = demo_model.predict(x_input)
m = 2
h0 = np.zeros(m)
h1 = np.dot(x[0], wx) + h0 + bh
h2 = np.dot(x[1], wx) + np.dot(h1,wh) + bh
h3 = np.dot(x[2], wx) + np.dot(h2,wh) + bh
o3 = np.dot(h3, wy) + by
print('h1 = ', h1,'h2 = ', h2,'h3 = ', h3)
print("Prediction from network ", y_pred_model)
print("Prediction from our computation ", o3)
输出
h1 = [[ 0.18662322 -1.23694587]] h2 = [[-0.07471441 -3.64187904]] h3 = [[-1.30195881 -6.84172557]]
Prediction from network [[-3.8698118]]
Prediction from our computation [[-3.86981216]]
在 Sunspots 数据集上运行 RNN
现在我们理解了 SimpleRNN 和 Dense 层是如何组合在一起的。让我们在一个简单的时间序列数据集上运行一个完整的 RNN。我们需要按照以下步骤进行:
-
从给定的 URL 读取数据集
-
将数据分割为训练集和测试集
-
为 Keras 格式准备输入数据
-
创建一个 RNN 模型并对其进行训练。
-
对训练集和测试集进行预测,并打印两个集合上的均方根误差。
-
查看结果
步骤 1、2:读取数据并分割为训练集和测试集
下面的函数从给定的 URL 读取训练和测试数据,并将其分割成给定百分比的训练和测试数据。它使用 scikit-learn 中的 MinMaxScaler
将数据缩放到 0 到 1 之间,并返回训练和测试数据的单维数组。
Python
# Parameter split_percent defines the ratio of training examples
def get_train_test(url, split_percent=0.8):
df = read_csv(url, usecols=[1], engine='python')
data = np.array(df.values.astype('float32'))
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data).flatten()
n = len(data)
# Point for splitting data into train and test
split = int(n*split_percent)
train_data = data[range(split)]
test_data = data[split:]
return train_data, test_data, data
sunspots_url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/monthly-sunspots.csv'
train_data, test_data, data = get_train_test(sunspots_url)
步骤 3:为 Keras 调整数据形状
下一步是为 Keras 模型训练准备数据。输入数组应该被整形为:total_samples x time_steps x features
。
有许多种方法可以准备时间序列数据进行训练。我们将创建具有非重叠时间步长的输入行。下图显示了时间步长 = 2 的示例。这里,时间步长表示用于预测时间序列数据下一个值的先前时间步数。
太阳黑子示例的数据准备方法
以下函数 get_XY()
以一维数组为输入,将其转换为所需的输入 X
和目标 Y
数组。我们将使用 12 个 time_steps
作为太阳黑子数据集的时间步长,因为太阳黑子的周期通常为 12 个月。你可以尝试其他 time_steps
的值。
Python
# Prepare the input X and target Y
def get_XY(dat, time_steps):
# Indices of target array
Y_ind = np.arange(time_steps, len(dat), time_steps)
Y = dat[Y_ind]
# Prepare X
rows_x = len(Y)
X = dat[range(time_steps*rows_x)]
X = np.reshape(X, (rows_x, time_steps, 1))
return X, Y
time_steps = 12
trainX, trainY = get_XY(train_data, time_steps)
testX, testY = get_XY(test_data, time_steps)
第 4 步:创建 RNN 模型并训练
对于此步骤,你可以重用之前定义的 create_RNN()
函数。
Python
model = create_RNN(hidden_units=3, dense_units=1, input_shape=(time_steps,1),
activation=['tanh', 'tanh'])
model.fit(trainX, trainY, epochs=20, batch_size=1, verbose=2)
第 5 步:计算并打印均方根误差
函数 print_error()
计算实际值与预测值之间的均方误差。
Python
def print_error(trainY, testY, train_predict, test_predict):
# Error of predictions
train_rmse = math.sqrt(mean_squared_error(trainY, train_predict))
test_rmse = math.sqrt(mean_squared_error(testY, test_predict))
# Print RMSE
print('Train RMSE: %.3f RMSE' % (train_rmse))
print('Test RMSE: %.3f RMSE' % (test_rmse))
# make predictions
train_predict = model.predict(trainX)
test_predict = model.predict(testX)
# Mean square error
print_error(trainY, testY, train_predict, test_predict)
输出
Train RMSE: 0.058 RMSE
Test RMSE: 0.077 RMSE
第 6 步:查看结果
以下函数绘制了实际目标值和预测值。红色的线条将训练数据和测试数据点分开。
Python
# Plot the result
def plot_result(trainY, testY, train_predict, test_predict):
actual = np.append(trainY, testY)
predictions = np.append(train_predict, test_predict)
rows = len(actual)
plt.figure(figsize=(15, 6), dpi=80)
plt.plot(range(rows), actual)
plt.plot(range(rows), predictions)
plt.axvline(x=len(trainY), color='r')
plt.legend(['Actual', 'Predictions'])
plt.xlabel('Observation number after given time steps')
plt.ylabel('Sunspots scaled')
plt.title('Actual and Predicted Values. The Red Line Separates The Training And Test Examples')
plot_result(trainY, testY, train_predict, test_predict)
生成了以下图表:
综合代码
下面是本教程的全部代码。尝试在你的环境中运行这些代码,并实验不同的隐藏单元和时间步长。你可以在网络中添加第二个 SimpleRNN
观察其表现。你也可以使用 scaler
对象将数据重新缩放到正常范围。
Python
# Parameter split_percent defines the ratio of training examples
def get_train_test(url, split_percent=0.8):
df = read_csv(url, usecols=[1], engine='python')
data = np.array(df.values.astype('float32'))
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data).flatten()
n = len(data)
# Point for splitting data into train and test
split = int(n*split_percent)
train_data = data[range(split)]
test_data = data[split:]
return train_data, test_data, data
# Prepare the input X and target Y
def get_XY(dat, time_steps):
Y_ind = np.arange(time_steps, len(dat), time_steps)
Y = dat[Y_ind]
rows_x = len(Y)
X = dat[range(time_steps*rows_x)]
X = np.reshape(X, (rows_x, time_steps, 1))
return X, Y
def create_RNN(hidden_units, dense_units, input_shape, activation):
model = Sequential()
model.add(SimpleRNN(hidden_units, input_shape=input_shape, activation=activation[0]))
model.add(Dense(units=dense_units, activation=activation[1]))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
def print_error(trainY, testY, train_predict, test_predict):
# Error of predictions
train_rmse = math.sqrt(mean_squared_error(trainY, train_predict))
test_rmse = math.sqrt(mean_squared_error(testY, test_predict))
# Print RMSE
print('Train RMSE: %.3f RMSE' % (train_rmse))
print('Test RMSE: %.3f RMSE' % (test_rmse))
# Plot the result
def plot_result(trainY, testY, train_predict, test_predict):
actual = np.append(trainY, testY)
predictions = np.append(train_predict, test_predict)
rows = len(actual)
plt.figure(figsize=(15, 6), dpi=80)
plt.plot(range(rows), actual)
plt.plot(range(rows), predictions)
plt.axvline(x=len(trainY), color='r')
plt.legend(['Actual', 'Predictions'])
plt.xlabel('Observation number after given time steps')
plt.ylabel('Sunspots scaled')
plt.title('Actual and Predicted Values. The Red Line Separates The Training And Test Examples')
sunspots_url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/monthly-sunspots.csv'
time_steps = 12
train_data, test_data, data = get_train_test(sunspots_url)
trainX, trainY = get_XY(train_data, time_steps)
testX, testY = get_XY(test_data, time_steps)
# Create model and train
model = create_RNN(hidden_units=3, dense_units=1, input_shape=(time_steps,1),
activation=['tanh', 'tanh'])
model.fit(trainX, trainY, epochs=20, batch_size=1, verbose=2)
# make predictions
train_predict = model.predict(trainX)
test_predict = model.predict(testX)
# Print error
print_error(trainY, testY, train_predict, test_predict)
#Plot result
plot_result(trainY, testY, train_predict, test_predict)
进一步阅读
本节提供了更多相关资源,如果你想深入了解。
书籍
-
深度学习基础 由 Wei Di、Anurag Bhardwaj 和 Jianing Wei 编著。
-
深度学习 由 Ian Goodfellow、Joshua Bengio 和 Aaron Courville 编著。
文章
总结
在本教程中,你发现了递归神经网络及其各种架构。
具体来说,你学到了:
-
RNN 的结构
-
RNN 如何从先前的输入中计算输出
-
如何使用 RNN 实现时间序列预测的端到端系统
对于本文中讨论的 RNNs,你有任何问题吗?请在下方评论中提出你的问题,我会尽力回答。
使用 ChatGPT 作为你的编程助手
原文:
machinelearningmastery.com/using-chatgpt-as-your-programming-assistant/
大型语言模型基本上是一种可以理解和生成文本的机器。根据训练方式,有时模型会生成文本之外的内容。ChatGPT 就是这样一个大型语言模型。如果你正确地提示它,它可以生成编程代码。在这篇文章中,你将学习如何让 ChatGPT 为你生成程序。具体来说,你将学习
-
如何让 ChatGPT 启动你的编程项目
-
如何使用 ChatGPT 作为你的编程助手
开始使用并应用 ChatGPT,请参考我的书 Maximizing Productivity with ChatGPT。它提供了实际应用案例和提示示例,旨在帮助你快速使用 ChatGPT。
使用 ChatGPT 作为你的编程助手
由作者使用 Stable Diffusion 生成的图片。保留部分权利。
概述
本文分为两个部分,它们是:
-
启动编程项目
-
理解代码和生成函数片段
启动编程项目
让我们考虑一个简单的项目:你想设置一个 REST API 服务器,可以帮助你对提供的 URL 的整个网页进行“屏幕截图”。可选地,REST API 可以接受一个额外的电子邮件地址参数。在这种情况下,屏幕截图不会返回,而是通过电子邮件发送出去。
这是一个涉及多个组件的项目。你需要一些东西来充当 REST API 服务器,监听 HTTP 请求并作出响应。你还需要一些东西来获取 URL 并像普通网页浏览器一样截图。项目中还有一个逻辑,取决于是否提供了电子邮件地址;输出可以是返回的图像文件,也可以是发送附带附件的电子邮件。
如果你对如何创建 REST API 服务器不熟悉或不知道有哪些工具可用,你可以向 ChatGPT 请求帮助。只需将所有细节写入提示中并询问:
我需要创建一个 REST API 服务器,该服务器接受 URL 作为输入,将网页截图捕获为 JPEG 格式并作为输出返回。可选地,用户可以提供一个电子邮件地址作为附加输入。在这种情况下,截图应通过电子邮件发送而不是返回。你能帮我完成这个程序吗?
对此,ChatGPT 提出了以下建议:
当然!我可以帮助你。要创建一个 REST API 服务器,该服务器可以捕获网页截图并处理可选的电子邮件功能,你可以使用 Node.js 以及一些额外的包。以下是你可以遵循的步骤概述:
1. 设置一个新的 Node.js 项目并使用 npm 初始化:
2. 安装必要的包。你需要
express
作为 API 服务器,puppeteer
用于捕获屏幕截图,nodemailer
用于发送电子邮件:3. 创建一个
index.js
文件,并使用 Express 设置基本的服务器:4. 在
/screenshot
路由中,使用 Puppeteer 捕获网页截图,并相应地处理响应:5. 为了处理带有截图附件的电子邮件发送,在
if (email)
块中添加以下代码:确保将
'your-email-service-provider'
、'your-email@example.com'
和'your-email-password'
替换为你实际的电子邮件服务提供商的详细信息。6. 最后,启动服务器:
现在,当你向
http://localhost:3000/screenshot?url={URL}
发起 GET 请求时,服务器将捕获提供的 URL 的屏幕截图。如果同时提供了电子邮件地址作为email={EMAIL}
,服务器将通过电子邮件附件发送截图,而不是直接返回。记得处理错误并根据需要添加任何必要的错误检查或验证。
就这样!你现在拥有一个基本的 REST API 服务器,它可以捕获网页截图并可选地通过电子邮件发送。根据你的需求,可以进一步完善它。
这是一个非常详细的结果,告诉你如何完成这个编程任务。响应涵盖了所有要求,但你应该注意,当你在提示中没有明确指定时,ChatGPT 会为你做出一些设计决策,例如使用什么编程语言。
一开始考虑所有细节并不容易,但 ChatGPT 的特点允许你提供后续提示以修订答案,例如:
对于上述问题,我想使用 Python 和 FastAPI 作为 Web 框架,并使用 Selenium 进行 Web 浏览器自动化。你能重写这个吗?
ChatGPT 现在的响应变成了:
当然!这是使用 Python、FastAPI 作为 Web 框架和 Selenium 进行 Web 浏览器自动化的修订版解决方案。
1. 安装必要的包。你需要
fastapi
,用于运行服务器的uvicorn
,以及用于管理 Web 驱动程序的selenium
和webdriver_manager
:2. 创建一个名为
main.py
的新文件,并导入所需的模块:3. 定义一个请求模型来处理输入数据:
4. 创建一个路由以捕获网页截图:
5. 使用 Uvicorn 启动服务器:
现在,当你向
http://localhost:8000/screenshot?url={URL}
发起 GET 请求时,服务器将捕获提供的 URL 的屏幕截图。如果同时提供了电子邮件地址作为email={EMAIL}
,你可以使用请求中的记得处理错误并根据需要添加任何必要的错误检查或验证。
注意:此解决方案假设你在计算机上安装了 Chrome。如果你使用的是其他浏览器,你需要相应地调整 Web 驱动程序。
就是这样!你现在有了一个使用 Python、FastAPI 和 Selenium 的 REST API 服务器,用于捕获网页截图并处理可选的电子邮件功能。
你可以看到,你在后续提示中没有提供任何多余的细节,只是提到了“上述问题”,但 ChatGPT 可以准确地将 Node.js 实现“翻译”成 Python,并使用你指定的库。
这是一个很棒的结果,尽管你可能仍需打磨代码。一个例子是,浏览器屏幕大小肯定会影响网页的渲染,但由于你没有在提示中指定它应该是可调的,因此上述代码中尺寸是硬编码的。另一个需要打磨生成代码的潜在原因是捕捉其他编码风格问题或增加针对安全问题的防御措施。
总结来说,和其他用例一样,你在提示中提供的详细信息越清晰,对于获得有用的响应就越关键。在编程任务的情况下,明确列出细节至关重要。
-
目标是什么
-
输入和输出格式是什么
-
程序应该使用哪些工具
-
程序可能遇到的不同情况是什么,这些情况应该如何处理
理解代码和生成函数片段
有时,你想编写的不是一个大型程序,而是一个较小的函数。你可以要求 ChatGPT 使用类似于上述的提示生成一个函数,只是你需要指定输出格式,例如函数或类。
实际上,你也可以反向操作,即向 ChatGPT 提供代码并请求用英语解释它。这有时很有用,特别是为了破解其他人的代码。让我们考虑以下示例:
请解释以下代码的功能:
这个提示非常简单:只有一个关键字,“解释”。但要注意你如何向 ChatGPT 提供代码:使用反引号遵循 Markdown 的代码块语法来引用程序。这有助于识别哪些是你的指令,哪些不是。
尽管这不是一个很长的程序,但 ChatGPT 以非常详细的方式解释了代码。它还在高层次上识别了意图,即计算矩阵的行列式。以下是响应内容:
你提供的代码是一个递归实现,用于计算方阵的行列式,使用了拉普拉斯展开。
下面是代码功能的逐步分解:
- 函数
det
接受两个参数:一个指向 2D 数组 (float** a
) 的指针,表示矩阵,以及矩阵的大小 (float k
)。- 它声明了一些变量:
s
用于符号,ret
用于行列式值,**b
作为临时矩阵。- 它检查
k
是否等于 1。如果是,这意味着我们已经达到了 1×1 矩阵的基本情况,函数返回矩阵中的单个值,即行列式。- 如果
k
大于 1,则继续进行计算。- 它为临时矩阵
b
动态分配了大小为k
xk
的内存。- 它将
ret
初始化为 0。- 它进入一个循环,遍历矩阵
a
的第一行的每一列。- 在循环内部,它将索引
m
和n
重置为 0。- 它进入一个嵌套循环,遍历矩阵
a
的每一个元素。- 在嵌套循环中,它将临时矩阵
b
中位置m
,n
的元素设置为 0。- 它检查当前元素是否不在第一行(
i != 0
)和当前列(j != c
)。- 如果元素不在第一行或当前列,它将矩阵
a
中的值复制到临时矩阵b
的位置m
,n
。- 它根据
b
中下一个元素的位置更新索引m
和n
。- 在嵌套循环之后,它通过递归调用
det
函数,使用临时矩阵b
和大小k - 1
来计算子矩阵b
的行列式。- 它将子矩阵的行列式乘以符号
s
(交替符号)。- 它将符号
s
乘以-1,以便为下一次迭代切换符号。- 它将符号、第一行中的元素(
a[0][c]
)以及子矩阵的行列式的乘积加到累加和ret
中。- 循环继续到下一列。
- 循环之后,它释放了为临时矩阵
b
的每一行分配的内存。- 它释放了为临时矩阵
b
分配的内存。- 最终,它返回计算出的行列式值
ret
。总之,代码通过对第一行进行拉普拉斯展开,递归地计算方阵的行列式。它使用临时矩阵存储通过排除第一行和所选列获得的子矩阵。递归继续直到达到 1×1 矩阵的基本情况。
后续改进代码
这段代码乍看之下不容易理解。可能有办法让它更易读。的确,ChatGPT 在这种情况下能做得很好,只需一个非常简单的后续提示:
你能重写这段代码以提高清晰度并添加注释吗?
这里的关键字是“提高清晰度”和“添加注释”。ChatGPT 在回应中提供了如下内容:
当然!这里是经过修订的代码版本,包含解释每一步的注释:
我在代码中每个重要部分上方添加了注释,以解释其功能。这应该使代码更易读,更易理解。
这个版本无疑更易读。
此外,你还可以要求更多,比如捕捉代码中的错误或潜在安全问题。让我们请 ChatGPT 生成一些单元测试代码:
你能给我几个单元测试用例以确保这个函数运行良好吗?
不需要进一步解释,以下是回应:
当然!以下是一些单元测试用例,以验证
determinant
函数的正确性:测试用例 1:2×2 矩阵
测试用例 2:3×3 矩阵
测试用例 3:4×4 矩阵
这些测试用例覆盖了不同大小的矩阵(2×2、3×3 和 4×4),包括正的、负的和零行列式值。通过将计算出的行列式值与预期输出进行比较,你可以验证
determinant
函数是否正常工作。
但很明显,单元测试代码遗漏了一个边角情况:1×1 矩阵。这表明 ChatGPT 并不总是完美的。你应该仅将其作为助手而非替代品。你应该始终验证结果。
总结
在这篇文章中,你看到 ChatGPT 如何帮助你编程。它不仅可以在回应你的问题时生成代码,还能理解你提供的代码意图。具体来说,你已经了解到:
-
你可以使用 ChatGPT 为你的软件项目生成初始代码,或为函数生成测试代码
-
你可以要求 ChatGPT 解释代码给你
-
你可以利用 ChatGPT 对代码进行重构和清理
使用 ChatGPT 的自然语言理解能力
原文:
machinelearningmastery.com/using-the-natural-language-understanding-capability-of-chatgpt/
ChatGPT 作为大型语言模型,因其对人类语言的理解而著名。与其向 ChatGPT 询问你不知道的答案,不如让它在现有信息的基础上工作,同时利用自然语言理解(NLU)能力。在这篇文章中,你将学习
-
如何让 ChatGPT 从长文本中生成摘要
-
如何让 ChatGPT 从一段文字中提取关键信息
开始使用 ChatGPT,请参考我的书籍 《利用 ChatGPT 最大化生产力》。它提供了真实世界的使用案例和提示示例,旨在帮助你迅速上手使用 ChatGPT。
让我们开始吧。
使用 ChatGPT 的自然语言理解能力。
图片由作者使用 Stable Diffusion 生成。保留所有权利。
概述
本文分为三个部分;它们是:
-
你的 AI 秘书
-
提取非结构化信息
-
如何使用 ChatGPT 进行自然语言理解
你的 AI 秘书
想象一下你有一个包含不同人之间对话的会议记录。记录是检查结论如何得出的好方法,但会议纪要应该更易于阅读决策。你可以让 ChatGPT 从记录中生成会议纪要。
我们来看一下 这里的会议记录。摘录如下:
大家早上好。我是迈克尔·斯特恩,来自审计官布拉德·兰德的代表,以及纽约市过渡金融管理委员会的主席。提醒一下,请保持音频静音,除非发言。我现在开始召集金融委员会的会议。丽塔,你能请点名吗?
…
谢谢大家,祝大家周末愉快。
祝大家周末愉快。
谢谢。
这不是一个长时间的会议,但会议记录却跨越了几页。你可以使用以下提示将记录总结成 1 页的会议纪要:
作为一名经验丰富的秘书,请将以下会议记录总结为会议纪要,列出参与者、议程、关键决定和行动项。
大家早上好。我是迈克尔·斯特恩,来自审计官布拉德·兰德的代表,以及纽约市过渡金融管理委员会的主席。
布拉德·兰德和纽约市金融委员会的主席
过渡金融管理局。提醒一下,请保持您的音频静音,除非发言。
静音,除非发言。我现在开始召集金融
委员会。丽塔,你能请点名吗?
…
谢谢大家,祝大家周末愉快。
祝大家周末愉快。
谢谢。
在提示中,您提供了记录并告诉 ChatGPT 应包含哪些内容,以确保所有关键细节都已包括在内。以下是 ChatGPT 生成的内容:
会议纪要
会议:财务委员会会议
日期:[插入日期]
时间:[插入时间]
地点:[插入地点]
参与者:
– 迈克尔·斯特恩(审计员布拉德·兰德的代表及财务委员会主席)
– 大卫·沃马克(代表主任雅克·吉哈)
– 黛安娜·贝纳特(代表专员普雷斯顿·尼布莱克)
– 卢安·科齐奥尔(代表专员托马斯·福利)
– 赫克托·赫尔曼(代表发言人艾德里安·亚当斯)
议程:
1. 批准委员会上次会议的会议纪要。
2. 决议建议董事会批准第 125 系列决议,授权发行高达 16 亿美元的 2023 财年 D 系列未来税务担保债券。
关键决策:
1. 批准委员会上次会议的会议纪要。
– 会议纪要经审查后已一致批准。
2. 决议建议董事会批准第 125 系列决议,授权发行高达 16 亿美元的 2023 财年 D 系列未来税务担保债券。
– 提交了决议,并提供了子系列的预期拆分。
– 委员会成员一致投票支持该决议,并已批准。
行动事项:
1. 记录中未提及。
休会:
– 财务委员会会议已休会。
—
会议:董事会会议
日期:[插入日期]
时间:[插入时间]
地点:[插入地点]
参与者:
– 大卫·沃马克(预算主任雅克·吉哈的代表及董事会主席)
– 黛安娜·贝纳特(代表专员普雷斯顿·尼布莱克)
– 迈克尔·斯特恩(代表审计员布拉德·兰德)
– 卢安·科齐奥尔(代表专员托马斯·福利)
– 赫克托·赫尔曼(代表发言人艾德里安·亚当斯)
议程:
1. 决议允许在与 COVID-19 相关的紧急状态期间举行远程会议。
2. 批准上次董事会会议的会议纪要。
3. 批准第 125 系列决议,授权发行高达 16 亿美元的 2023 财年 D 系列未来税务担保债券。
关键决策:
1. 决议允许在与 COVID-19 相关的紧急状态期间举行远程会议。
– 提出了决议以允许在 COVID-19 紧急状态期间在城市中举行远程会议。
– 董事会成员投票支持该决议,并已批准。
2. 批准上次董事会会议的会议纪要。
– 会议纪要经审查后已一致批准。
3. 批准第 125 系列决议,授权发行高达 16 亿美元的 2023 财年 D 系列未来税务担保债券。
– 提交了决议,并提到了委员会的建议。
– 董事会成员一致投票支持该决议,并已批准。
行动事项:
1. 记录中未提及。
休会:
– 董事会会议已休会。
注意:提供的逐字稿未包含会议的具体细节,如日期、时间和地点。请根据上下文和组织的要求填写缺失的信息。
会议纪要比逐字稿要整洁得多,更易于阅读。特别的一点是,这个逐字稿包含了两个原定为一的会议,您可以从会议纪要中了解到这一点。然而,如果您希望它呈现为特定格式,您可能仍然需要对其进行润色。那些应该出现在纪要中的但逐字稿中没有的信息用占位符替换,您需要填入。这与总结逐字稿相比并不困难。
ChatGPT 可以轻松完成这项工作,因为它经过了语言理解训练,能够提取关键信息。您可以通过适当的提示将其作为一个有用的秘书,指导 ChatGPT 以特定格式再现关键信息。
尽管如此,一些会议较长。逐字稿可能非常长,会达到 ChatGPT 的上下文长度限制。在这种情况下,ChatGPT 将拒绝继续处理。您可以将逐字稿分成多个部分,并让 ChatGPT 首先总结每一部分。然后将总结结果合并生成会议纪要。
提取非结构化信息
因为 ChatGPT 可以理解文本,您可以利用它提取非结构化信息。非结构化信息是指那些嵌入在文本段落中的信息,与列表和表格相对。由于没有明显的模式,它不容易搜索。
您可以利用 ChatGPT 的语言理解能力来帮助提取非结构化信息并生成列表。考虑以下示例:
阅读以下文本,并回答以下问题:
1. 最新的乘客数量是多少?
2. 这个客流量参考的是什么日期?
3. 之前的乘客数量是多少?
4. 之前的客流量参考的是什么日期?
文本:
纽约和新泽西港务局今天宣布,自 COVID-19 大流行开始以来,首次在该机构的区域机场中,月度航空乘客水平超过了大流行前的水平。
在 11 月份,港务局的机场共接待了 1100 万名乘客,相当于 COVID-19 前 2019 年 11 月客流量的 102%。11 月份对航空旅行的强劲需求主要由感恩节期间的国内旅客驱动,当时飞往美国目的地的假期乘客比 2019 年感恩节多了 8%。
港务局还预测 2022 年剩余时间内航空旅行需求将保持高位,特别是在从 2022 年 12 月 23 日星期五开始到 2023 年 1 月 2 日星期一的 11 天期间。
双州地区航空旅行的显著回归标志着港务局在其三大主要区域机场的重建项目取得的一年成就和开幕。这与 2020 年疫情最严重时期的情况形成了鲜明对比,当时三大主要机场的航班量骤降至疫情前的四分之一。
“看到我们的机场恢复到疫情前水平,我们感到非常欣慰,尤其是在经历了两年多的全球疫情之后,那段时间让我们宅在家中,心生旅行的渴望,”港务局主席 Kevin O’Toole 说。“在今年,我们见证了机场乘客的稳步回归,以及当他们看到等待他们的新一流空中设施时脸上的惊喜。我们期待在未来几周内迎接更多的乘客,因为人们与亲人一起庆祝节日。”
“2022 年 11 月航空量超过了疫情前 2019 年 11 月的数据,这表明我们对该地区机场的历史性投资是至关重要的,”港务局执行董事 Rick Cotton 说。“我们的目标是为通过我们机场的航空乘客提供一个世界级的 21 世纪旅行体验,并为疫情后地区经济的复苏做出贡献。”
LaGuardia 机场在今年早些时候完成了其 80 亿美元公私合营改造工程,使其成为过去 25 年来美国建成的第一个新大型机场。新机场分阶段建设,以确保其在建设过程中始终保持完全运营,且从未失去容量。今年,新 B 航站楼的所有乘客设施以及达美航空的新 C 航站楼和新重建的道路网络都已开放。新机场因其 21 世纪的设计、设施和客户体验赢得了乘客的赞誉,并获得了全球尊敬行业组织的奖项和荣誉。
Newark Liberty 国际机场在 2022 年 11 月也庆祝了一个关键里程碑,新 A 航站楼的剪彩仪式标志着该航站楼的完成,其面积约为 100 万平方英尺,拥有 33 个登机口以处理更大的飞机,以及现代化的公共使用登记区域、安全检查和行李认领区域,预计能有效处理约 1360 万名乘客。港务局还宣布了一位世界级的总规划师来领导整个机场的改造。新的 A 航站楼预计将在 2023 年初投入使用。
在约翰·F·肯尼迪国际机场,港务局完成了两个新航站楼的财务结算——航站楼一号和航站楼六号——并扩建了航站楼八号,增加了约 130,000 平方英尺的额外和翻新空间。这次扩建标志着 JFK 机场转型的第一步,使英国航空能够从其在 50 年历史的航站楼七号的长期家迁至与美国航空共同使用的航站楼八号。航站楼七号将被拆除,为明年初开始建设的新航站楼六号腾出空间。15 亿美元的航站楼四号扩建工程也在进行中,已于 2021 年 12 月破土动工。
文本来自这里获得的新闻稿。
ChatGPT 的结果如下:
文本中提到的最新乘客数量是 1100 万。
该体积所提到的日期是 11 月。
文本未提供 COVID-19 大流行之前的乘客数量信息。
文本中未提及上一个体积的参考日期。
提炼出的结果更容易提取,你可以将其转移到其他用途。此外,请注意,当提供的文本中没有你寻找的信息时,它会告诉你。这是因为在你的提示中,你要求它仅基于文本回答。
如何使用 ChatGPT 进行自然语言理解
作为语言模型的 ChatGPT 应该能够比较轻松地理解文本。然而,为了充分利用其自然语言理解能力,你应小心不要让它产生幻觉。幻觉发生在你让它生成脱离上下文的文本时。当你在提示中明确说明仅使用提供的信息进行任务时,可以避免这种情况。
即便如此,请记住 ChatGPT 可能无法很好地理解所有内容。如果有些信息超出上下文,ChatGPT 也不会知道。一个具体的例子是领域特定的缩写和术语。如果有些信息不够直接,ChatGPT 也可能无法提取。你可以尝试多次重新生成上面的第二个示例。由于文本将乘客容量以另一个容量的百分比表示,ChatGPT 有时无法找到确切的乘客容量。
总结
在这篇文章中,你了解了如何将 ChatGPT 用作自然语言理解工具。你见到了以下示例:
-
将会议记录转化为会议纪要
-
从文本中提取特定信息
利用 ChatGPT 的这一能力,你可以轻松地构建一个助手,比如从收到的邮件中提取行动项并创建待办事项列表。
什么是注意力?
注意力在机器学习中越来越受欢迎,但是什么使它成为一个如此吸引人的概念?在人工神经网络中应用的注意力与其生物学对应物之间有什么关系?在机器学习中,人们可以期待什么组件形成一个基于注意力的系统?
在本教程中,你将发现注意力的概述及其在机器学习中的应用。
完成本教程后,你将了解:
-
简要概述注意力如何在大脑中表现
-
组成基于注意力的系统的组件及其如何受到生物学注意力的启发
启动你的项目,请参考我的书 构建具有注意力的变换器模型。它提供了自学教程和工作代码,帮助你构建一个完全可用的变换器模型。
将句子从一种语言翻译成另一种语言…
让我们开始吧。
什么是注意力?
图片来源:Rod Long,保留部分权利。
教程概述
本教程分为两部分;它们是:
-
-
注意力
-
机器学习中的注意力
-
注意事项
注意力是一个广泛研究的概念,通常与唤醒、警觉性和与周围环境的参与有关。
在最一般的形式下,注意力可以被描述为对周围环境的总体警觉性或参与能力。
– 心理学、神经科学和机器学习中的注意力,2020 年。
视觉 注意力是神经科学和心理学领域中最常研究的领域之一。
当一个对象面对不同的图像时,该对象的眼动可以揭示出显著的图像部分,这些部分是对象的注意力最感兴趣的。在对视觉注意力的计算模型进行回顾时,Itti 和 Koch (2001)提到这些显著的图像部分通常由视觉属性特征,包括强度对比、定向边缘、角落和交点以及运动所特征化。人脑在不同的神经阶段关注这些显著的视觉特征。
早期的神经元对简单的视觉属性如强度对比、颜色对抗、方向、运动方向和速度,或在多个空间尺度上的立体视差进行了调节。神经元的调节随着从低级到高级视觉区域的进展而变得越来越专业,以至于高级视觉区域包括仅对角点或交点、从阴影中获取形状线索或特定现实世界物体的视图做出反应的神经元。
– 计算视觉注意力建模,2001 年。
有趣的是,研究还观察到不同的对象往往被相同的显著视觉线索所吸引。
研究还发现了记忆和注意力之间的几种交互形式。由于人脑的记忆容量有限,因此选择存储哪些信息在最大程度利用有限资源上变得至关重要。人脑通过依赖注意力来实现这一点,从而动态地将受关注的信息存储在记忆中。
机器学习中的注意力
在人工神经网络中实现注意力机制并不一定追踪人脑的生物学和心理学机制。相反,使注意力在机器学习中如此有吸引力的概念是它能够动态地突出和利用手头信息中的显著部分,这与人脑的处理方式类似。
想象一个由三个组件组成的基于注意力的系统:
- 一个“读取”原始数据(如源句子中的源词)并将其转换为分布式表示的过程,每个词位置都关联一个特征向量。
- 存储读取器输出的特征向量列表。这可以理解为一个包含事实序列的“记忆”,这些事实可以在之后检索,顺序不一定相同,无需访问全部内容。
- 一个“利用”记忆内容来顺序执行任务的过程,每一步都能将注意力集中在一个记忆元素(或几个,具有不同权重)上。
– 第 491 页,深度学习,2017 年。
以编码器-解码器框架为例,因为在这样的框架中首次引入了注意力机制。
如果我们处理一个输入的词序列,这将首先被送入一个编码器,该编码器会为序列中的每个元素输出一个向量。这对应于我们前面提到的基于注意力的系统的第一个组件。
这些向量列表(上面基于注意力系统的第二个组成部分),连同解码器的先前隐藏状态,将被注意机制利用来动态突出显示将用于生成输出的输入信息。
在每个时间步中,注意机制会取解码器的先前隐藏状态和编码向量列表,利用它们生成未归一化的分数值,表明输入序列的元素与当前输出的对齐程度如何。由于生成的分数值需要相对重要性,它们通过 softmax 函数进行归一化以生成权重。在 softmax 归一化之后,所有权重值将位于 [0, 1] 区间并加起来为 1,这意味着它们可以被解释为概率。最后,编码向量通过计算得到的权重进行缩放,生成上下文向量。这个注意过程形成了上面基于注意力系统的第三个组成部分。然后将这个上下文向量送入解码器以生成翻译输出。
这种类型的人工注意力因此是一种迭代重新加权的形式。具体来说,它会动态突出显示预处理输入的不同组件,因为它们对输出生成是必要的。这使其像生物学的注意力一样灵活和上下文相关。
– 心理学、神经科学和机器学习中的注意力,2020 年。
包含注意机制的系统实施的过程与不包含的系统相比有所不同。在后者中,编码器会生成一个固定长度的向量,而不考虑输入的长度或复杂性。在没有突出显示整个输入中显著信息的机制的情况下,解码器只能访问编码在固定长度向量中的有限信息。这可能导致解码器错过重要信息。
注意机制最初是为了处理机器翻译中的单词序列提出的,这些序列具有暗含的时间因素。然而,它可以推广到处理静态信息,不一定以顺序方式相关,比如在图像处理的背景下。您将看到如何在单独的教程中实现这种泛化。
想要开始使用带注意力机制的 Transformer 模型吗?
立即参加我的免费 12 天电子邮件快速课程(附带示例代码)。
点击注册,还可获得课程的免费 PDF 电子书版本。
进一步阅读
本节提供了关于该主题的更多资源,如果您希望深入了解。
书籍
论文
-
心理学、神经科学和机器学习中的注意力,2020 年。
-
视觉注意力的计算建模,2001 年。
总结
在本教程中,你了解了注意力的概述及其在机器学习中的应用。
具体来说,你学到了:
-
注意力如何在大脑中表现的简要概述
-
组成注意力系统的各个部分及其如何受到生物学注意力的启发
你有任何问题吗?
在下方评论中提问,我会尽力回答。