使用 VAEs、GANs 和扩散模型生成图像
了解如何使用 VAEs、DCGANs 和 DDPMs 生成图像
·
关注 发表在 面向数据科学 · 21 分钟阅读 · 2023 年 5 月 6 日
–
图片由 CatBird AI 提供,图片提示由 ChatGPT 提供,ChatGPT 由贾斯廷·切赫提供提示
引言:
我们目前正处于生成式 AI 繁荣期。2022 年 11 月,Open AI 的生成语言模型 ChatGPT 震撼了世界,而在 2023 年 3 月,我们甚至迎来了 GPT-4!
尽管这些 LLM 的未来非常令人兴奋,但今天我们将专注于图像生成。随着扩散模型的兴起,图像生成取得了巨大的飞跃。现在我们被像 DALL-E 2、Stable Diffusion 和 Midjourney 这样的模型包围。例如,查看上面的图像。为了展示这些 LLM 的强大,我给 ChatGPT 一个非常简单的提示,然后将其输入到免费的CatbirdAI中。CatbirdAI 使用了不同的模型,包括 Openjourney、Dreamlike Diffusion 等:
在本文中,Daisuke Yamada(我的合著者)和我将研究扩散模型。我们将使用 3 种不同的模型,并使用每种模型生成 MNIST 手写数字风格的图像。第一个模型将是传统的变分自编码器(VAE)。然后我们将讨论 GAN,并实现一个深度卷积 GAN (DCGAN)。最后,我们将转向扩散模型,并实现论文中描述的模型去噪扩散概率模型。对于每个模型,我们将讨论其背后的理论,然后在 Tensorflow/Keras 中实现。
快速说明一下符号。我们会尽量使用下标如x₀,但有时可能需要使用x_T来表示下标。
让我们简要讨论一下先决条件。熟悉深度学习和使用 Tensorflow/Keras 是很重要的。此外,你应该对 VAE 和 GAN 有一定了解;我们会讲解主要理论,但有经验会更有帮助。如果你从未见过这些模型,可以查看这些有用的资源:MIT S6.191 讲座,斯坦福生成模型讲座,VAE 博客。最后,无需了解 DCGANs 或扩散模型。很好!我们开始吧。
生成模型三难问题:
作为一种无监督过程,生成型 AI 通常缺乏明确的指标来跟踪进展。但在我们讨论任何评估生成模型的方法之前,我们需要理解生成型 AI 实际上试图实现什么!生成型 AI 的目标是从某些未知复杂数据分布(例如,人脸的分布)中获取训练样本,并学习一个能够“捕捉这种分布”的模型。那么,评估这样的模型时相关的因素是什么呢?
我们当然希望样本质量高,即生成的数据应该与实际数据分布相比,真实且准确。直观上,我们可以通过查看输出结果来主观评估这一点。这在一个称为HYPE(Human eYe Perceptual Evaluation)的基准中得到了形式化和标准化。虽然还有其他的定量方法,但今天我们将仅依靠我们自己的主观评估。
还有一个重要因素是快速采样(即生成速度或可扩展性)。 我们将关注的一个特定方面是生成新样本所需的网络传递次数。例如,我们将看到 GAN 只需对生成器网络进行一次传递即可将噪声转换为(希望是)现实的数据样本,而 DDPM 则需要顺序生成,这使得速度大大降低。
最终一个重要的质量标准称为模式覆盖。我们不仅仅希望学习未知分布的特定部分,而是希望捕捉整个分布以确保样本的多样性。例如,我们不希望一个仅输出 0 和 1 图像的模型,而是希望输出所有可能的数字类别。
这三个重要因素(样本质量、采样速度和模式覆盖)都涵盖在**“生成模型三难困境”**中。
图片由 Daisuke Yamada 创建,灵感来源于DDGANs 论文中的图 1
现在我们了解了如何比较和对比这些模型,让我们深入研究 VAE 吧!
变分自编码器:
你将遇到的第一个生成模型是变分自编码器(VAE)。由于 VAE 只是具有概率性变换的传统自编码器,我们来回顾一下自编码器。
自编码器是学习将数据压缩成某种潜在表示的降维模型:
图片由 Justin Cheigh 创建
编码器将输入压缩为称为瓶颈的潜在表示,然后解码器重建输入。解码器重建输入意味着我们可以用输入/输出之间的 L2 损失进行训练。
自编码器不能用于图像生成,因为它们会过拟合,导致稀疏的潜在空间是不连续且断开的(不可正则化的)。VAE 通过将输入x编码为潜在空间上的一个分布来解决这个问题:
输入x传递到编码器E. 输出E(x)是均值向量和标准差向量,这些向量参数化了分布P(z | x)。常见的选择是多变量标准高斯。从这里我们采样z ~ P(z | x),最终解码器尝试从z重建x(就像自编码器一样)。
注意这个采样过程是非可微的,因此我们需要做一些改变以允许反向传播实现。为此,我们使用重参数化技巧,即首先采样ϵ ~ N(0,1),然后将采样移动到输入层。接着,我们可以进行固定的采样步骤:z = μ + σ ⊙ ϵ. 注意我们获得了相同的采样,但现在我们有了一个清晰的路径来反向传播误差,因为唯一的随机节点是输入!
记住,自编码器的训练是 L2 损失,它构成了重建项。对于 VAE,我们还添加了一个正则化项,用于使潜在空间“表现良好”:
在这里,第一个项是重建项,而第二个项是正则化项。具体来说,我们使用的是Kullback-Leibler (KL) 散度,它衡量了学习到的潜在空间分布与先验分布之间的相似性。这有助于防止过拟合。
很好!我们已经回顾了 VAE 的理论和直觉,现在将讨论实现细节。在导入相关库后,我们定义了一些超参数值:
latent_dim = 2 # dimension of latent space
epochs = 200
batch_size = 32
learning_rate = 1e-4
下载 MNIST 数据集并进行一些基本预处理后,我们定义了我们的损失函数和网络:
def get_default_loss(model, x):
with tf.device(device):
mean, logvar, z = model.encoder(x)
xhat = model.decoder(z)
rl = tf.reduce_mean(keras.losses.binary_crossentropy(x, xhat))*28*28
kl = tf.reduce_mean(1+logvar-tf.square(mean)-tf.exp(logvar)) * -0.5
return rl + kl
'''Sampling layer'''
class Sampling(Layer):
def call(self, prob):
# uses reparameterization trick
mean, logvar = tf.split(prob, num_or_size_splits=2, axis=1)
e = random.normal(shape=(tf.shape(mean)[0], tf.shape(mean)[1]))
z = mean + e * tf.exp(logvar * 0.5)
return mean, logvar, z
'''Basic Convolutional VAE'''
class VAE(Model):
def __init__(self, latent_dim, **kwargs):
super(VAE, self).__init__(**kwargs)
self.latent_dim = latent_dim
self.encoder = self.get_encoder()
self.decoder = self.get_decoder()
'''encoder + reparametrization (i.e., sampling) layer'''
def get_encoder(self):
# encoder
input_x = Input(shape=(28,28,1))
x = Conv2D(filters=64, kernel_size=3, strides=(2,2), activation='relu')(input_x)
x = Conv2D(filters=64, kernel_size=3, strides=(2,2), activation='relu')(x)
x = Flatten()(x)
x = Dense(self.latent_dim * 2)(x)
# sampling
(mean, logvar, z) = Sampling()(x)
return Model(input_x, [mean, logvar, z], name="encoder")
'''decoder'''
def get_decoder(self):
input_z = Input(shape=(self.latent_dim,))
z = Dense(7*7*64, activation="relu")(input_z)
z = Reshape((7, 7, 64))(z)
z = Conv2DTranspose(filters=64, kernel_size=3, strides=2, padding='same', activation='relu')(z)
z = Conv2DTranspose(filters=64, kernel_size=3, strides=2, padding='same', activation='relu')(z)
xhat = Conv2DTranspose(filters=1, kernel_size=3, strides=1, padding='same', activation='sigmoid')(z)
return Model(input_z, xhat, name="decoder")
'''train'''
def train_step(self, x):
with tf.device(device):
x = x[0] if isinstance(x, tuple) else x
with tf.GradientTape() as tape:
loss = get_default_loss(self, x)
gradient = tape.gradient(loss, self.trainable_weights)
self.optimizer.apply_gradients(zip(gradient, self.trainable_weights))
return {"loss": loss}
def call(self, inputs):
pass
vae = VAE(latent_dim=latent_dim)
vae.compile(optimizer=Adam(learning_rate=learning_rate))
vae.build(input_shape=(28,28,1))
vae.summary()
好的,我们来分析一下。函数 get_default_loss(model, x)接收一个 VAE 模型和一些输入x,并返回我们之前定义的 VAE 损失(其中C = 1)。我们定义了一个卷积 VAE,其中编码器使用 Conv2D 层进行下采样,解码器使用Conv2DTranspose层(反卷积层)进行上采样。我们使用 Adam 进行了优化。
由于其他两个生成模型从随机噪声开始,我们没有使用某些输入图像,而是从潜在空间中采样并使用解码器生成新图像。我们测试了 latent_dim = 2 和 latent_dim = 100,并获得了以下结果:
VAE 生成的图像。图像由 Daisuke Yamada 创建
由于我们只进行一次前向传递来生成新样本,因此我们的采样速度很快。此外,这是一个相对简单的模型,所以我们的训练速度也很快。维度为 2(意味着瓶颈潜在表示的维度为 2)的结果很好,但有点模糊。然而,维度为 100 的结果则不是很好。我们认为可能是计算能力不足,或者后验分布开始扩展到不存在的模式。换句话说,我们开始学习没有意义的潜在特征。
那么,理论上如何选择“最佳”的潜在维度呢?显然,100 不是一个好选择,但也许在 2 和 100 之间的某个值是理想的。这里存在样本质量和计算效率之间的权衡。因此,你可以确定这些因素对你的重要性,并进行类似网格搜索的操作来正确选择这个超参数。
我们还绘制了维度为 2 的潜在空间。基本上,以下内容告诉我们解码器根据我们在潜在空间中的起点输出什么。
我们的 VAE 潜在空间
正如你所见,潜在空间相当多样化,而且相当完整和连续!因此,反思生成模型三难问题,我们得到以下结论:
VAE 的三难问题(红色为好,蓝色为坏)。图像由大辅·山田创建
现在我们将转到 DCGANs,并从加速解释 GANs 开始。
深度卷积 GANs:
在 GANs 中,有一个 生成器 G 和一个 鉴别器 D。生成器创建新数据,而鉴别器区分(或辨别)真实数据和虚假数据。两者在一个极小化-极大化游戏中对抗训练,因此有了“对抗性”一词。
我们获得一些训练数据,并开始通过标准正态分布或均匀分布来采样随机噪声 z。这些噪声是待生成数据的潜在表示。我们从噪声开始,以允许更多样化的数据样本,并避免过拟合。
噪声被输入到生成器中,生成器输出生成的数据 x = G(z)。然后,鉴别器接受 x 并输出 P[x = real] = D(x),即生成的图像 x 是真实图像的概率。此外,我们还将训练集中真实图像输入鉴别器。
我们通常将损失定义为一个极小化-极大化游戏:
GANs 损失
对于判别器,这看起来像是二元交叉熵,这很合理,因为它是一个二元分类器。对每个分布中采样的点的期望值实际上对应于你从(a)数据分布中*(****E_{x ~ p(data)})和(b)随机噪声(E_{z ~ p(z)).***中获得的数据点。第一个项表示判别器想要最大化将真实数据分类为 1 的可能性,而第二个项表示判别器想要最大化将假数据分类为 0 的可能性。判别器还在生成器会以最优方式行动的最小-最大假设下运行。
好的,我们现在将过渡到 DCGANs。DCGANs 与 GANs 类似,但架构上有几个显著变化;主要的是 DCGANs 不使用任何多层感知机,而是使用卷积/反卷积。以下是稳定 DCGANs 的架构指南(来自原始论文):
-
用步幅卷积(判别器)和分数步幅卷积(即反卷积)(生成器)替换任何池化层
-
在生成器和判别器中使用批量归一化
-
为了更深的架构,移除全连接的隐藏层
-
在生成器中,对所有层使用 ReLU 激活,除了输出层使用 Tanh
-
在判别器中,对所有层使用 LeakyReLU 激活。
DCCGAN 架构 - 图像由 Justin Cheigh 创建
我们经常使用 GANs 进行图像生成,因此直观上使用卷积层是有意义的。我们在判别器中使用标准卷积层,因为我们希望将图像降采样成分层特征,而对于生成器,我们使用反卷积层将图像从噪声(潜在表示)上采样到生成的图像。
批量归一化用于稳定训练过程、提高收敛性并加快学习速度。Leaky ReLU 防止了 ReLU 的零学习问题。最后,使用 Tanh 来防止较小输入的饱和,并避免梯度消失问题(因为它在原点周围是对称的)。
太棒了!现在让我们看看如何实现 DCGANs。导入库后,我们设置超参数值:
latent_dim = 100
epochs = 100
batch_size = 32
learning_rate = 1e-4
经过一些数据预处理和为计算效率进行批量拆分后,我们准备定义生成器和判别器:
generator = Sequential([
# input
Dense(units=7*7*128, input_shape=(latent_dim,)),
Reshape((7,7,128)),
# conv 1
Conv2DTranspose(filters=64, kernel_size=3, strides=2, padding='same'),
BatchNormalization(),
ReLU(max_value=0.2),
# conv 2
Conv2DTranspose(filters=64, kernel_size=3, strides=1, padding='same'),
BatchNormalization(),
ReLU(max_value=0.2),
# final tanh
Conv2DTranspose(filters=1, kernel_size=3, strides=2, padding='same', activation='tanh')
])
discriminator = Sequential([
# conv 1
Conv2D(filters=64, kernel_size=3, strides=2, padding='same', input_shape=(28,28,1)),
LeakyReLU(0.2),
# conv 2
Conv2D(filters=64, kernel_size=3, strides=2, padding='same'),
# BatchNormalization(),
LeakyReLU(0.2),
# output
Flatten(),
Dense(1, activation='sigmoid')
])
discriminator.compile(optimizer=Adam(learning_rate=learning_rate),
loss=BinaryCrossentropy(),
metrics=[BinaryAccuracy()])
discriminator.trainable = False
gan = Sequential([
generator,
discriminator
])
gan.compile(optimizer=Adam(learning_rate=learning_rate), loss=BinaryCrossentropy(), metrics=[BinaryAccuracy()])
记住所有关于 DCGANs 的架构指南!我们对生成器使用 Conv2DTranspose,对判别器使用普通的 Conv2D 和步幅。注意我们用 Binary cross entropy 编译判别器,但将判别器指定为 trainable = False。这是因为我们将自己实现训练循环:
def generate():
# generate image based on random noise z
with tf.device(device):
random_vector_z = np.random.normal(loc=0, scale=1, size=(16, latent_dim))
generated = generator(random_vector_z)
return generate
# labels
real = np.ones(shape=(batch_size, 1))
fake = np.zeros(shape=(batch_size, 1))
# generator and discriminator losses
g_losses, d_losses = [], []
with tf.device(device_name=device):
for epoch in range(epochs):
for real_x in x_train_digits:
'''discriminator'''
# train on real data
d_loss_real = discriminator.train_on_batch(x=real_x, y=real)
# train on fake data
z = np.random.normal(loc=0, scale=1, size=(batch_size, latent_dim))
fake_x = generator.predict_on_batch(x=z)
d_loss_fake = discriminator.train_on_batch(x=fake_x, y=fake)
# total loss
d_loss = np.mean(d_loss_real + d_loss_fake)
'''generator'''
g_loss = gan.train_on_batch(x=z, y=real)
g_losses.append(g_loss[-1])
d_losses.append(d_loss)
首先,我们用真实数据和生成器生成的假数据训练判别器,然后也训练生成器。太棒了!让我们看看结果:
图像由大辅·山田创作
我们的样本质量更好(不那么模糊)!我们仍然有快速采样,因为推理只需将随机噪声输入生成器。下面是我们的潜在空间:
我们的 DCGAN 潜在空间
不幸的是,我们的潜在空间不是很多样化(特别是在潜在维度为 2 的第 1 代样本中尤为明显)。我们很可能遇到了模式崩溃的常见问题。正式地说,这意味着生成器只学会创建一个专门用来欺骗判别器的子集。换句话说,如果生成器在生成 1 的图像时判别器表现不佳,那么生成器没有理由去做其他事情。因此,对于生成模型三难问题,我们得到如下:
DCGANs 的三难困境(红色为好,蓝色为坏)。图像由大辅·山田创作
现在我们已经探索了 GANs 和 DCGANs,是时候过渡到扩散模型了!
扩散模型:
扩散概率模型(或简称扩散模型)目前是每个顶级图像生成模型的一部分。我们将讨论去噪扩散概率模型(DDPMs)。
对于 VAEs 和 GANs,样本生成涉及从噪声到生成图像的一个步骤。GANs 通过将噪声输入生成器并进行正向传播来执行推理,而 VAEs 通过采样噪声并将其传递通过解码器来执行推理。扩散模型的主要思想是生成一系列图像,其中每个后续图像稍微少一些噪声,最终图像理想情况下是现实的!DDPM 有两个方面。在正向过程中,我们使用真实图像并迭代地添加噪声。在反向过程中,我们学习如何撤销在正向过程中添加的噪声:
让我们从直观的层面解释正向和反向过程。我们给定一组训练数据X₀***,其中每个数据点x₀*** ∈ X₀从数据分布***x₀ ~ q(x₀)中采样。回忆一下q(x₀)***是我们想要表示的未知分布。
从右到左是硬编码的正向过程,我们从一些训练样本x₀ ~ q(x₀)开始,逐步添加高斯噪声。也就是说,我们将生成一系列图像x₁, x₂, …, x_T,其中每个后续图像都越来越嘈杂。最终,我们会得到可以被视为纯噪声的东西!从左到右是反向过程,我们学习如何去噪,即预测如何从x_{t+1} → xₜ。很好!现在我们理解了正向和反向过程的基本概念,让我们深入了解理论吧!
正式地,前向过程由一个马尔可夫链描述,该链根据预定的方差调度β₁, …, β_T 迭代地向数据中添加高斯噪声。马尔可夫链这个术语意味着x_{t+1} 仅 依赖于xₜ。因此,x_{t+1} 在给定xₜ的条件下,与x₁, …, x_ₜ₋₁ 条件独立。这意味着q(xₜ | x₀, …, xₜ₋₁) = q(xₜ | xₜ₋₁)。另一个重要的概念是方差调度。我们定义一些值β₁, …, β_T,这些值用于参数化我们在每个时间步添加的高斯噪声。通常,0 ≤ β ≤ 1,其中β₁ 较小,β_T 较大。所有这些都包含在我们对***q(xₜ | xₜ₋₁)***的定义中:
前向扩散过程
所以,我们从x₀开始。然后,经过T个时间步,我们遵循上述方程来获取序列中的下一个图像:xₜ ~ q(xₜ | xₜ₋₁)。可以证明在极限T → ∞ 时,x_T 等同于各向同性的高斯分布。
不过我们还没完成。我们直观上应该能够通过递归展开一步步从x₀ 到任何x_t。我们首先使用重参数化技巧(类似于变分自编码器):
重参数化技巧
这使我们能够做到以下几点:
抽样任意时间步 t
通过遵循上述方程,我们可以在一步内从x₀到任何xₜ!对那些好奇的人,推导过程涉及展开和使用高斯的加法性质。让我们继续讨论逆向过程。
在逆向过程中,我们的目标是了解q(xₜ₋₁| xₜ),因为我们可以随机取噪声并从q(xₜ₋₁ | xₜ) 中迭代抽样以生成逼真的图像。我们可能会认为可以使用贝叶斯规则轻松获得q(xₜ₋₁ | xₜ),但事实证明这是计算上不可行的。这在直观上是合理的;要逆转前向步骤,我们需要查看xₜ 并考虑我们可能到达那里的所有方式。
因此,我们将学习一个具有权重θ的模型p,而不是直接计算q(xₜ₋₁ | xₜ),该模型近似这些条件概率。幸运的是,如果βₜ 足够小,我们可以成功地将q(xₜ₋₁| xₜ) 估计为高斯分布。这一见解来自涉及随机微分方程的一些极其困难的理论。因此,我们可以定义p为以下内容:
模型定义
那么,我们的损失是什么呢?如果我们想要撤销添加的噪声,直观上只需预测添加的噪声就足够了。要查看更完整的推导,请查阅Lilian Weng**的这篇优秀博客。但事实证明,我们的直觉是正确的,我们不需要一个模型p**,而是可以使用一个预测添加噪声的网络ϵ_θ。通过这种方法,我们可以使用实际噪声和预测噪声之间的均方误差(MSE)进行训练:
最终损失
在这里,ϵ 是实际误差,而另一个术语是预测误差。你可能会注意到期望值是对x_0取的;这是因为通常误差是以重参数化技巧(如上所述)的形式写出的,这使你可以直接从x_0获得x_t**。因此,我们的网络输入是时间t和当前图像xₜ。
让我们做一个全面回顾。我们使用 MSE 训练网络ϵ_θ以学习如何预测添加的噪声。一旦训练完成,我们可以使用我们的神经网络ϵ_θ来预测任何时间步的添加噪声。利用这些噪声和一些上述方程,我们完成逆过程并有效地“去噪”。因此,我们可以通过获取噪声并持续去噪来进行推断。这两个过程都由以下伪代码描述:
在训练过程中,我们获取一张真实图像,抽样t ~ Uniform({1,2,…,T})(我们这样做是因为逐步计算效率低),然后对目标/预测噪声的 MSE 进行梯度下降。在采样过程中,我们取随机噪声,然后使用我们预测的噪声和推导的方程连续采样,直到我们得到一些生成的图像x₀.
很好!我们现在可以进入实施细节。对于我们的基础架构,我们将使用一个U-Net:
图像由 Justin Cheigh 创建;灵感
从架构来看,为什么这被称为 U-Net 很明显!U-Net 最初用于生物医学图像分割,但它们在扩散模型中也表现得非常好!直观地说,这是因为(a)输入和输出的形状是相同的,这正是我们需要的,以及(b)我们将看到 U-Net(由于编码器-解码器结构配合跳跃连接)在保留局部/全局信息方面表现良好,这有助于保留图像但仍有效地添加噪声。
U-Net 具有类似于过去生成模型的编码器-解码器结构。具体来说,如果你查看形状为“U”的图像,你会发现下行过程中有一系列下采样层,这些层是编码器结构的一部分。上行过程中,我们有一系列上采样层,这些层是解码器结构的一部分。输入和输出具有相同的形状,这对于我们的输入是带噪声的图像 xₜ 和我们的输出是一些预测噪声的情况来说是理想的。
但是,你可能会注意到 U-Net 和标准自编码器之间有一个重要区别,那就是跳跃连接。在每个层级中,我们有一个下采样模块,该模块连接到另一个下采样模块(遵循“U”的形状),并且有一个跳跃连接到上采样模块。记住,这些下采样模块基本上是在以不同分辨率查看图像(学习不同层次的特征)。通过这些跳跃连接,我们确保在每个分辨率上都考虑到这些特征!另一种思考 U-Net 的方式是将其视为一系列堆叠的自编码器。
好的,现在让我们看一下我们的具体实现。首先,我撒了个谎……我说我们的输入只是带噪声的图像 xₜ. 然而,我们还输入了实际的时间步 t 以提供时间概念。我们的方法是使用时间步嵌入,其中我们取时间 t 并使用正弦位置嵌入:
正弦位置嵌入
对于不熟悉的人,正弦位置嵌入的高级概述是我们使用正弦函数对某些序列中的元素(这里是时间步)进行编码,直觉是这些函数的平滑结构将更容易被神经网络学习。因此,我们的实际输入是带噪声的图像 xₜ 和时间步 t,它们首先经过这个时间嵌入层。
接下来是我们的下采样/上采样模块:每个下采样(上采样)模块包含 2 个 ResNet 模块、1 个 Attention 层和 1 个卷积(反卷积)层。我们快速了解一下这些模块。
残差网络(ResNet)基本上是一系列具有大跳跃连接的卷积层,这些跳跃连接允许信息在非常深的神经网络中流动。Attention 是一种革命性的想法,对于理解像 Transformer 这样的基础架构至关重要,它告诉神经网络该关注什么。例如,这里我们有 2 个 ResNet 模块。在这些模块之后,我们将得到输入图像的潜在特征向量,Attention 层将告诉神经网络这些特征中哪些是最重要的。最后,标准的卷积/反卷积分别用于下采样/上采样。
在我们的实现中,我们使用了 4 个这样的堆叠自编码器:
def call(self, x, time, training=True, **kwargs):
with tf.device(device):
# front conv
x = self.init_conv(x)
# time embedding
t = self.time_mlp(time)
# move down the encoder
h = []
for down_block1, down_block2, attention, downsample in self.downs:
x = down_block1(x, t)
x = down_block2(x, t)
x = attention(x)
h.append(x) # keep for skip connection!
x = downsample(x)
# bottleneck consists of
x = self.mid_block1(x, t) # ResNet block
x = self.mid_attn(x) # Attention layer
x = self.mid_block2(x, t) # ResNet block
# move up the decoder
for up_block1, up_block2, attention, upsample in self.ups:
x = tf.concat([x, h.pop()], axis=-1)
x = up_block1(x, t)
x = up_block2(x, t)
x = attention(x)
x = upsample(x)
x = tf.concat([x, h.pop()], axis=-1)
# back conv
x = self.final_conv(x)
return x
很好!现在我们已经定义了我们的 U-Net 类,我们可以继续将 U-Net 应用于我们的具体问题。我们首先定义相关的超参数:
image_size = (32, 32)
num_channel = 1
batch_size = 64
timesteps = 200
learning_rate = 1e-4
epochs = 10
由于计算能力不足,我们使用timesteps = T = 200, 尽管原始论文使用的是T = 1000. 数据预处理后,我们定义前向过程
# define forward pass
beta = np.linspace(0.0001, 0.02, timesteps) # variance schedule
alpha = 1 - beta
a = np.concatenate((np.array([1.]), np.cumprod(alpha, 0)[:-1]), axis=0) # alpha bar
def forward(x_0, t):
# uses trick to sample from arbitrary timestep!
with tf.device(device):
noise_t = np.random.normal(size=x_0.shape)
sqrt_a_t = np.reshape(np.take(np.sqrt(a), t), (-1, 1, 1, 1))
sqrt_one_minus_a_t = np.reshape(np.take(np.sqrt(1-a), t), (-1, 1, 1, 1))
x_t = sqrt_a_t * x_0 + sqrt_one_minus_a_t * noise_t
return noise_t, x_t
所以,在这里我们以一种相当标准的方式定义我们的方差调度。在前向函数中,我们使用重新参数化技巧,允许我们从x₀中抽样任意的xₜ。下面是前向过程的可视化:
我们的前向过程可视化
然后我们实例化我们的 U-Net,定义我们的损失函数,并定义训练过程:
unet = Unet() # instantiate model
def loss(noise, predicted):
# remember we just use MSE!
with tf.device(device):
return tf.math.reduce_mean((noise-predicted)**2)
optimizer = keras.optimizers.Adam(learning_rate=learning_rate)
def train_step(train_images):
with tf.device(device):
# create a "batch" number of random timesteps (in our case 64)
timestep_values = tf.random.uniform(shape=[train_images.shape[0]], minval=0, maxval=timesteps, dtype=tf.int32)
# forward
noised_images, noise = forward(x_0=train_images, t=timestep_values)
# set the gradient and get the prediction
with tf.GradientTape() as tape:
predicted = unet(x=noised_images, time=timestep_values)
loss_value = loss(noise, predicted)
# optimize U-Net using ADAM
gradients = tape.gradient(loss_value, unet.trainable_variables)
optimizer.apply_gradients(zip(gradients, unet.trainable_variables))
return loss_value
def train(epochs):
with tf.device(device):
for epoch in range(epochs):
losses = []
for i, batch_images in enumerate(iter(dataset)):
loss = train_step(batch_images)
losses.append(loss)
记住,我们的损失(经过大量工作之后)只是均方误差(MSE)!其余部分是一个相当标准的训练循环。训练完成后,我们可以考虑推断。回顾我们的采样算法 2,我们按如下方式实现:
def denoise_x(x_t, pred_noise, t):
with tf.device(device):
# obtain variables
alpha_t = np.take(alpha, t)
a_t = np.take(a, t)
# calculate denoised_x (i.e., x_{t-1})
beta_t = np.take(beta, t)
z = np.random.normal(size=x_t.shape)
denoised_x = (1/np.sqrt(alpha_t)) * (x_t - ((1-alpha_t)/np.sqrt(1-a_t))*pred_noise) + np.sqrt(beta_t) * z
return denoised_x
def backward(x, i):
with tf.device(device):
t = np.expand_dims(np.array(timesteps-i-1, np.int32), 0)
pred_noise = unet(x, t)
return denoise_x(x, pred_noise, t)
在这里,我们定义如何在特定时间步采集图像并进行去噪。通过这些,我们可以完全定义我们的推断过程:
def get_sample(x=None):
# generate noise
if x is None:
x = tf.random.normal(shape=(1,32,32,1))
# array to store images
imgs = [np.squeeze(np.squeeze(x, 0),-1)]
# backward process
for i in tqdm(range(timesteps-1)):
x = backward(x, i)
if i in [0,25,50,75,100,125,150,175,198]:
imgs.append(np.squeeze(np.squeeze(x, 0),-1))
return imgs if show_progress else imgs[-1]
我们从随机噪声开始,然后不断使用我们的反向函数去噪,直到得到一个现实的图像!以下是我们的一些结果:
我们的 DDPM 生成样本示例
样本质量相当高。此外,我们能够获得多样化的样本。推测我们的样本质量会随着计算能力的提高而改善;扩散过程计算开销非常大,这影响了我们训练这个模型的能力。还可以进行“逆向工程”。我们取一个训练图像,添加噪声,然后去噪,以观察我们重建图像的能力。我们得到以下结果:
逆向工程。图像由大辅·山田创建
需要注意的是,逆向过程是概率性的,这意味着我们并不总是得到与输入图像相似的图像。
很好!让我们回到生成模型三难题。我们有高质量的样本、多样化的样本范围,以及更稳定的训练(这是这些迭代步骤的副产品)。然而,我们有缓慢的训练和采样,因为在推断过程中我们需要一次又一次地采样。因此,我们得到以下结果:
DDPMs 的三难题(红色代表好,蓝色代表不好)。图像由大辅·山田创建
结论:
哇!我们覆盖了三种图像生成模型,从标准的变分自编码器(VAE)到扩散模型(DDPM)。对于每种模型,我们查看了生成模型三难题,并获得了以下结果:
比较模型。图像由大辅·山田创建
自然的问题是:我们能否获得生成模型三难问题的所有 3 个部分?看起来扩散模型几乎达到了这一点,因为我们只需找出提高采样速度的方法。从直观上讲,这很困难,因为我们依赖于将逆过程建模为高斯过程的假设,这只有在我们在几乎所有时间步长中执行逆过程时才有效。
然而,实际上,获得三难问题的所有 3 个因素是可能的!像 DDIMs 或 DDGANs 这样的模型建立在 DDPMs 之上,但它们已经找到了提高采样速度的方法(其中一种方法是使用跨步采样计划)。通过这些和其他不同的优化,我们可以获得生成模型三难问题的所有 3 个方面!
那么,接下来是什么?一个特别有趣的方向是条件生成。条件生成允许你在一些类别标签或描述性文本的条件下生成新样本。例如,在所有最初列出的图像生成模型中,你可以输入类似“企鹅卧推 1000 磅”的内容,并获得合理的输出。虽然我们没有时间探索这一条件生成的方向,但它似乎是一个非常有趣的下一步!
好吧,这就是我们的全部内容。感谢阅读!
除非另有说明,所有图片均由作者(们)创建。
使用 Wikipedia 生成知识图谱
原文:
towardsdatascience.com/generating-knowledge-graphs-with-wikipedia-ec17030a40f6
快速生成知识图谱的 Python 指南
·发表于 Towards Data Science ·5 分钟阅读·2023 年 1 月 1 日
–
知识图谱使我们能够理解不同知识点之间的关系,从而对一个领域或主题有深入的了解。这些图谱帮助我们辨别个别知识点如何结合形成更大的图景。显然,构建和可视化知识图谱可以是许多领域的有效方法。
在本文中,我们描述了一种通过利用处理人类知识的最大公开图谱——Wikipedia 来生成新的知识图谱的过程。我们将使用 Python 完全自动化生成过程,使我们能够为任何感兴趣的领域创建可扩展的知识图谱生成方法。
如果你想跟随操作,可以在 Google Colab 中找到完整的 notebook。
方法
我们的方法如下:
-
🔌 使用 Wikipedia API 下载与术语相关的信息
-
🔁 迭代多个术语以建立知识库
-
🔝 根据“重要性”对术语进行排名
-
🌐 使用 networkx 库可视化知识图谱
如果你想与代码一同阅读,可以在 Google Colab 中找到它。
Wikipedia API
Wikipedia 通过 API 提供所有知识。此外,还有一个 很棒的 Python 包,使得扫描网站变得简单。使用这个包,我们可以根据搜索词扫描 Wikipedia 页面,如下例所示。
import wikipedia as wp
ds = wp.page("data science")
你可以在这篇文章中阅读更多关于该包的信息。
页面对象包含了我们需要的所有信息,以便遍历图谱并理解各种术语之间的关系。需要注意的关键属性有:
-
links:页面上链接到其他维基百科页面的外链
-
content:页面的实际内容
-
summary:页面顶部显示的关键信息。
下面展示了来自数据科学页面的一个示例。
维基百科网站庞大,拥有 700 万篇英语文章 (Wikipedia, 2022),这意味着扫描每一个页面将成本高昂,并且会覆盖许多与兴趣主题无关的页面。因此,我们需要开发一个算法,仅搜索相关页面。
搜索维基百科
搜索算法应从兴趣点开始,然后从那里向外探索,确保尽可能靠近兴趣点,同时也确保捕捉到最重要的页面。
我们将遵循的算法是:
-
从覆盖兴趣领域的术语列表开始。例如,对于“数据科学”的知识图谱,我们可以选择“数据科学”、“机器学习”和“人工智能”。
-
使用维基百科 API 从术语列表中获取维基百科页面。
-
查找页面上的所有外链,并为它们计算一个权重。权重可以基于术语出现的频率、距离文档开始的距离,或是否包含在摘要中。
-
将新链接添加到术语列表中。
-
从剩余的术语中找出最重要的术语,并获取该术语的页面。我们可以通过术语在其他术语中被引用的次数以及这些引用的权重来定义重要性。
-
重复步骤 3–5,直到达到足够的深度。对于以下示例,这大约是几百个术语。
有了这些,我们可以开始构建一个以我们关心的主题为中心的整个维基百科数据库的本地图谱。
这些术语可以以术语列表的形式呈现,按其重要性排序。下面是“数据科学”的一个示例。
在“数据科学”知识图谱中按重要性排名的顶级术语。
列表是处理数据的一个有用工具,但我们还有更多的数据可以利用,因此让我们探索网络图。
创建网络图
在定义了网络后,我们可以开始对其进行可视化。鉴于数据的图形特性,最好以图表的形式查看。为此,我们可以使用实用的包 networkx。Networkx 是一个用于创建、操作和研究复杂网络结构、动态和功能的 Python 包 (Networkx, 2022)。
Networkx 在基本图论的基础上构建图。下面展示了一个示例绘图脚本。
import networkx as nx
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
nx.draw(G)
为了绘制网络,我们需要使用比本示例中显示的更复杂的函数。特别地,我们将使用加权节点和加权边,分别基于单个术语的重要性及其连接。
“数据科学”、“物理学”和“生物学”的绘图如下所示。
“数据科学”(左)和“物理学”(右)的知识图谱。
“生物学”术语的知识图谱。
从生物学领域来看,我们看到一个有趣的图表。我不是生物学家,但这似乎相当准确!一些值得关注的点:
-
术语动物紧挨着生物学,并且具有类似的重要性,这很合理,因为生物学是研究生物体的学科。
-
左侧我们看到一个与细胞相关的生物学集群:变形虫、细胞壁、减数分裂和细菌。由于这些术语之间的强链接,networkx 算法将它们分组在一起。通过这种方式,知识图谱可以建议一起学习的术语。
-
鉴于生物学与其环境之间的强链接,我们看到地质学领域通过地球和地层学等术语显现出来。
-
正如近期事件所预期的那样,我们看到气候、气候变化和时间等问题被提升为重要话题。如果这是 20 年前的知识图谱,情况可能会有所不同。
-
我们看到了一些看似不相关的术语1、数字和isbn。这可能是由于维基百科中的一些奇怪引用,应予以删除。
让教育变得更容易
在这里,我们展示了一种从兴趣领域到完整知识图谱的方法。它允许我们获取按重要性排名的术语列表,以及这些术语如何相互适应的可视化。
这样,这些图表可以对教育和学习新领域有用。这对个人学习确实如此,但对于学费和更广泛的教育也适用,因为课程通常会在知识上留下空白。
提醒:完整的笔记本可以在Google Colab中找到,请随意试用,并告诉我你的发现!
使用 MONAI 生成医疗图像
原文:
towardsdatascience.com/generating-medical-images-with-monai-e03310aa35e6
一个端到端的开源项目,使用最新的 MONAI 生成模型从放射报告文本生成胸部 X 光图像
·发表于 Towards Data Science ·阅读时间 14 分钟·2023 年 4 月 14 日
–
大家好!在这篇文章中,我们将使用 MONAI 的新开源扩展MONAI 生成模型创建一个潜在扩散模型来生成胸部 X 光图像!
介绍
生成式 AI 在医疗领域具有巨大的潜力,因为它允许我们创建学习训练数据集底层模式和结构的模型。这样,我们可以使用这些生成模型创建大量合成数据,这些数据具有真实数据的相同细节和特征,但没有其限制。鉴于其重要性,我们创建了MONAI 生成模型,这是对 MONAI 平台的开源扩展,包含最新的模型(如扩散模型、自回归变换器和生成对抗网络)以及帮助训练和评估生成模型的组件。
在这篇文章中,我们将通过一个完整的项目来创建一个潜在扩散模型(与稳定扩散相同类型的模型),该模型能够从放射报告中生成胸部 X 光(CXR)图像。在这里,我们尝试使代码易于理解并适应不同环境,所以尽管它不是最有效的,希望你喜欢!
你可以在这个GitHub 仓库找到完整的开源项目,在这篇文章中,我们引用的是版本 v0.2。
数据集
首先,我们从数据集开始。在这个项目中,我们使用MIMIC 数据集。要访问这个数据集,必须在Physionet 门户创建一个账户。我们将使用MIMIC-CXR-JPG(包含 JPG 文件)和MIMIC-CXR(包含放射学报告)。这两个数据集都受到PhysioNet 认证健康数据许可证 1.5.0*的约束。完成免费的培训课程后,你可以按照数据集页面底部的说明自由下载数据集。原始的 CXR 图像大约为+1000x1000 像素。因此,这一步可能需要一些时间。
胸部 X 光图像是提供关于胸腔内结构和器官(包括肺部、心脏和血管)宝贵信息的重要工具,下载后我们应该有超过 350k 张这样的图像!这些图像是三种不同投影中的一种:后前位(PA)、前后位(AP)和侧位(LAT)。对于这个项目,我们只关注PA 投影,这是最常见的一种,可以可视化放射学报告中提到的大多数特征(共计 96,162 张图像)。关于报告,我们有 85,882 个文件,每个文件包含多个文本部分。我们将使用发现(主要解释图像内容)和印象(总结报告内容,如结论)。为了使我们的模型和训练过程更易于管理,我们将图像调整为最小轴 512 像素。自动执行这些初始步骤的脚本列表可以在这里找到。
模型
潜在扩散模型:自编码器将输入图像 x 压缩为潜在表示 z,然后扩散模型估计 z 的概率分布
潜在扩散模型由几个部分组成:
-
一个自编码器,用于将输入图像压缩为更小的潜在表示;
-
一个扩散模型,将学习 CXR 潜在表示的概率数据分布;
-
一个文本编码器,它创建一个嵌入向量,用于条件化采样过程。在这个例子中,我们使用一个预训练的编码器。
使用 MONAI 生成模型,我们可以轻松创建和训练这些模型,因此我们从自编码器开始吧!
模型 — 带 KL 正则化的自编码器
带有 KL 正则化的自编码器(AE-kl,或在一些项目中简单称为 VAE)的主要目标是能够创建一个小的潜在表示,并且高保真地重建图像(尽可能保留细节)。在这个项目中,我们创建了一个四层的自编码器,具有 64、128、128、128 个通道,其中在每一层之间应用了一个降采样块,使得特征图在深入层次时变小。尽管我们的自编码器可以有自注意力块,但在这个例子中,我们采用了类似于我们之前在脑部图像研究中的结构,并且不使用注意力以节省内存使用。最后,我们的潜在表示有三个通道。
from generative.networks.nets import AutoencoderKL
...
model = AutoencoderKL(
spatial_dims=2,
in_channels=1,
out_channels=1,
num_channels=[64, 128, 128, 128],
latent_channels=3,
num_res_blocks=2,
attention_levels=[False, False, False, False],
with_encoder_nonlocal_attn=False,
with_decoder_nonlocal_attn=False,
)
注意:在我们的脚本中,我们使用了OmegaConf 包来存储我们模型的超参数。你可以在这个文件中查看之前的配置。总之,OmegaConf 是一个强大的工具,用于管理 Python 项目的配置,特别是那些涉及深度学习或其他复杂软件系统的项目。OmegaConf 允许我们方便地在 .yaml 文件中组织超参数,并在脚本中读取它们。
训练 AE-KL
接下来,我们定义了我们训练过程中的几个组件。首先,我们有KL 正则化。这部分负责评估扩散模型潜在空间分布与高斯分布之间的距离。正如Rombach 等人所提出的,这将用于限制潜在空间的方差,这在我们对其进行扩散模型训练时非常有用(稍后会详细说明)。我们模型的前向方法返回重建结果,以及我们潜在表示的 μ 和 σ 向量,我们用这些来计算 KL 散度。
# Inside training loop
reconstruction, z_mu, z_sigma = model(x=images)
…
kl_loss = 0.5 * torch.sum(z_mu.pow(2) + z_sigma.pow(2) - torch.log(z_sigma.pow(2)) - 1, dim=[1, 2, 3])
kl_loss = torch.sum(kl_loss) / kl_loss.shape[0]
其次,我们有我们的像素级损失,在这个项目中,我们采用 L1 距离来评估 AE-kl 重建与原始图像的差异。
l1_loss = F.l1_loss(reconstruction.float(), images.float())
接下来,我们有感知级损失。感知损失的想法是,不是评估输入图像与重建图像在像素级别的差异,而是将这两张图像通过一个预训练模型。然后,我们测量内部激活和特征图的距离。在 MONAI 生成模型中,我们简化了使用基于在医学图像上预训练的网络的感知网络(可在此处获取)。我们可以使用RadImageNet研究中的2D 网络(来自Mei 等),这些网络在超过130 万张医学图像上进行了训练!我们实现了2.5D 方法,使用 2D 预训练网络通过评估切片来评估 3D 图像。最后,我们可以访问MedicalNet来以纯 3D 方法评估我们的3D 图像。在这个项目中,我们使用了类似于Pinaya 等的方法,并使用了学习到的感知图像块相似度(LPIPS)度量(也可在 MONAI 生成模型中找到)。
# Instantiating the perceptual loss
perceptual_loss = PerceptualLoss(
spatial_dims=2,
network_type="squeeze",
)
...
# Inside training loop
...
p_loss = perceptual_loss(reconstruction.float(), images.float())
最后,我们使用对抗损失来处理重建的细节。对抗网络是Patch-Discriminator(最初由 Pix2Pix 研究提出),其中我们不仅对整个图像是否真实或虚假做出一个预测,还对图像中的多个块做出预测。
与原始的潜在扩散模型(Latent Diffusion Model)和稳定扩散(Stable Diffusion)不同,我们使用了来自最小二乘生成对抗网络(least square GANs)的鉴别器损失。虽然这不是更先进的对抗损失,但在对 3D 医学图像进行训练时已经显示出了有效性和稳定性(但仍有改进的空间😁)。尽管对抗损失可能相当不稳定,但它们与感知损失的结合也有助于稳定鉴别器和生成器的损失。
我们的训练循环和评估步骤可以在这里和这里找到。经过 75 轮训练后,我们使用 MLflow 包保存模型。我们使用MLflow 包来更好地监控实验,因为它组织了如 git hash 和参数等信息,并且使得可以用唯一的 ID 在组(称为实验)中存储不同的运行,并且使得比较不同结果变得更容易(类似于其他工具,如 weights and biases)。AE-KL 的日志文件可以在这里找到。
模型 — 扩散模型
接下来,我们需要训练我们的扩散模型。
扩散模型是类似于 U-Net 的网络,其中通常接收一个噪声图像(或潜在表示)作为输入,并预测其噪声成分。这些模型使用迭代去噪机制,通过具有多个步骤的马尔可夫链从噪声中生成图像。因此,该模型还依赖于时间步,以定义模型在采样过程的哪个阶段。
使用DiffusionModelUNet 类,我们可以为我们的扩散模型创建类似于 U-Net 的网络。我们的项目使用在此配置文件中定义的配置,其中定义了具有 3 个通道的输入和输出(因为我们的 AE-kl 具有 3 个通道的潜在空间),以及具有 256、512、768 通道的 3 个不同级别。每个级别有 2 个残差块。如前所述,传递时间步对模型很重要,它用于调整这些残差块的行为。最后,我们在网络内部定义注意力机制。在我们的情况下,我们在第二和第三级别(由 attention_levels 参数指示)中有注意力块,每个注意力头有 512 和 768 个通道(换句话说,每个级别有一个注意力头)。这些注意力机制很重要,因为它们允许我们通过交叉注意力方法将我们的外部条件(放射学报告)应用到网络中。
外部条件(或“上下文”)被应用到 U-Net 的注意力块。
在我们的项目中,我们使用了一个已经训练好的文本编码器。为简单起见,我们使用了来自稳定扩散 v2.1 模型(“stabilityai/stable-diffusion-2–1-base”)的相同编码器,将我们的文本标记转换为文本嵌入,这些嵌入将作为 DiffusionModel UNet 交叉注意力层中的 Key 和 Value 向量。我们文本嵌入的每个标记有 1024 个维度,我们在*“with_conditioning”*和“cross_attention_dim”参数中定义它。
from generative.networks.nets import DiffusionModelUNet
...
diffusion = DiffusionModelUNet(
spatial_dims=2,
in_channels=3,
out_channels=3,
num_res_blocks=2,
num_channels=[256, 512, 768],
attention_levels=[False, True, True],
with_conditioning=True,
cross_attention_dim=1024,
num_head_channels=[0, 512, 768],
)
除了模型定义之外,重要的是定义在训练过程中将噪声添加到输入图像中以及在采样过程中去除噪声的方式。为此,我们为我们的 MONAI 生成模型实现了 Schedulers 类以定义噪声调度器。在这个示例中,我们将使用一个DDPMScheduler,它具有 1000 个时间步长和以下超参数。
from generative.networks.schedulers import DDPMScheduler
...
scheduler = DDPMScheduler(
beta_schedule="scaled_linear",
num_train_timesteps=1000,
beta_start=0.0015,
beta_end=0.0205,
prediction_type="v_prediction",
)
在这里,我们选择了**“v-prediction”方法**,其中我们的 U-Net 将尝试预测速度分量(原始图像和添加噪声的组合),而不仅仅是添加的噪声。这种方法已被证明具有更稳定的训练和更快的收敛速度(也在arxiv.org/abs/2210.02303
中使用)。
扩散模型训练
在训练扩散模型之前,我们需要找到一个合适的缩放因子。如 Rombach 等人所述,如果潜在空间分布的标准差过高,信噪比可能会影响使用 LDM 获得的结果。如果潜在表示的值过高,我们添加的高斯噪声的最大量可能不足以破坏所有信息。这样,在训练过程中,原始潜在表示的信息可能会存在,而实际上不应该存在,从而使得之后从纯噪声中生成图像变得不可能。KL 正则化可以在一定程度上有所帮助,但最佳实践是使用缩放因子来调整潜在表示的值。在这个脚本中,我们验证了训练集的一个批次中潜在空间分量的标准差的大小。我们发现我们的缩放因子应该至少为0.8221。在我们的案例中,我们使用了更为保守的值 0.3(类似于稳定扩散中的值)。
定义了缩放因子后,我们可以训练我们的模型。在这里,我们可以查看训练循环。
# Inside training loop
...
with torch.no_grad():
e = stage1(images) * scale_factor
prompt_embeds = text_encoder(reports.squeeze(1))[0]
timesteps = torch.randint(0, scheduler.num_train_timesteps, (images.shape[0],), device=device).long()
noise = torch.randn_like(e).to(device)
noisy_e = scheduler.add_noise(original_samples=e, noise=noise, timesteps=timesteps)
noise_pred = model(x=noisy_e, timesteps=timesteps, context=prompt_embeds)
if scheduler.prediction_type == "v_prediction":
# Use v-prediction parameterization
target = scheduler.get_velocity(e, noise, timesteps)
elif scheduler.prediction_type == "epsilon":
target = noise
loss = F.mse_loss(noise_pred.float(), target.float())
正如你所见,我们首先从数据加载器中获取图像和报告。为了处理这些图像,我们使用了 MONAI 的转换工具,并添加了一些 自定义转换,以从放射学报告中提取随机句子并对输入文本进行分词。在大约 10% 的情况下,我们使用一个空字符串(“” — 这是一个包含句子开始标记 (value = 49406) 和填充标记 (value = 49407) 的向量),以便在采样过程中使用无分类器引导。
接下来,我们获取潜在表示和提示嵌入。我们创建需要添加的噪声、用于本次迭代的随机时间步,以及所需的目标(速度分量)。最后,我们使用均方误差计算损失。
这个训练过程持续 500 个周期,日志可以在 这里 找到。
采样图像
在我们训练好两个模型之后,我们可以采样合成图像。我们使用 这个脚本。
这个脚本使用无分类器引导方法,这是 Ho 等人 提出的一个方法,用于在图像生成中强制执行文本提示。在这种方法中,我们有一个引导比例,可以用来牺牲生成数据的多样性,以获得与文本提示更高一致性的样本。默认值是 7.0。
在下图中,我们可以看到训练好的模型如何学会了临床特征以及这些特征的位置和严重程度。
评估
在这一部分,我们将展示如何使用 MONAI 的度量标准来评估我们生成模型的多个方面的性能。
使用 MS-SSIM 的自编码器重建质量
首先,我们验证我们的 Autoencoder-kl 如何重建输入图像。这是开发我们模型时一个重要的点,因为压缩和重建数据的质量将定义我们样本质量的上限。如果模型无法很好地从潜在表示中解码图像,或者它无法很好地建模我们的潜在空间,就无法以现实的方式解码合成表示。在这个脚本中,我们使用了来自测试集的 5000 张图像来评估我们的模型。我们可以使用**多尺度结构相似性指标(MS-SSIM)**来验证我们的重建效果。MS-SSIM 是一种广泛使用的图像质量评估方法,用于衡量两张图像之间的相似性。与传统的图像质量评估方法如 PSNR 和 SSIM 不同,MS-SSIM 能够捕捉图像在不同尺度上的结构信息。
在这种情况下,值越高,模型越好。对于我们当前的版本(0.2),我们观察到我们的模型的MS-SSIM 重建平均值为 0.9789。
样本的 MS-SSIM 多样性
我们将首先评估我们模型生成的样本的多样性。为此,我们计算不同生成图像之间的多尺度结构相似性指标。在这个项目中,我们假设如果我们的生成模型能够生成多样化的图像,那么在比较合成图像对时,它会呈现出较低的平均 MS-SSIM 值。例如,如果我们遇到了模式崩溃问题,我们生成的图像将看起来相似,MS-SSIM 值会比我们在真实数据集中观察到的值低得多。
在我们的项目中,我们使用未条件化的样本(使用“”(空字符串)作为文本提示生成的样本)以保持原始数据集的自然比例。如这个脚本所示,我们选择了 1000 个模型生成的合成样本,并使用 MONAI 的数据加载器来帮助加载所有可能的图像对。我们使用嵌套循环遍历所有可能的图像对,并忽略在两个数据加载器中选择相同图像的情况。在这里,我们可以观察到MS-SSIM 为 0.4083。我们可以在测试集的真实图像中进行相同的评估作为参考值。使用这个脚本,我们得到测试集的 MS-SSIM=0.4046,这表明我们的模型生成的图像与真实数据中的多样性相似。
然而,多样性并不意味着图像看起来好或真实。因此,我们将在下一步检查图像质量!
合成图像质量与 FID
最后,我们测量生成样本的Fréchet Inception Distance (FID)指标(链接)。FID 是一个评估两个组之间分布差异的指标,显示它们的相似度。为此,我们需要一个预训练的神经网络,从中提取特征用于计算距离(类似于感知损失)。在这个例子中,我们选择使用torchxrayvision 包中的神经网络。我们使用了一个 Dense121 网络(“densenet121-res224-all”),并选择了这个网络,以接近文献中用于 CXR 合成图像的网络。通过这个网络,我们得到一个 1024 维的特征向量。根据原始 FID 论文的建议,使用与特征数量相似数量的样本是重要的。因此,我们使用了 1000 张无条件图像,并将其与 1000 张测试集图像进行比较。对于 FID 来说,值越低越好,我们这里得到了一个合理的FID=9.0237。
结论
在这篇文章中,我们展示了一种使用MONAI 生成模型开发项目的方法,从下载数据到评估生成模型和合成数据。尽管这个项目版本可能更高效并拥有更好的超参数,我们希望它能很好地展示我们扩展所提供的不同功能。如果你有任何改进我们 CXR 模型的想法,或者希望为我们的包做贡献,请在我们的问题部分中留下评论,在这里或在这里。
我们训练的模型可以在MONAI 模型库中找到,与我们的 3D 脑部生成器及其他模型一起。我们的模型库使得下载模型权重和执行推理代码更加便捷。
欲获取更多教程并了解我们的功能,请访问我们的教程页面,点击此链接,并关注我以获取最新更新和更多类似的指南!😁
注意:所有图片除非另有说明,均由作者提供
每月生成更多优质见解
如何构建系统以更少的时间生成更多高质量的见解
·
关注 发表在Towards Data Science ·6 分钟阅读·2023 年 11 月 11 日
–
在《重新思考的 E-神话:为什么大多数小企业不起作用及其应对策略》中,迈克尔·E·格伯邀请小企业主停止“在他们的业务中”工作,开始“在他们的业务上”工作。书中的一个中心论点是,SMB 业主应该像他们想要特许经营他们的业务一样行事。这迫使他们(1)仔细审视他们所有的活动和流程,并且(2)优化和标准化这些活动和流程。通过这样做,他们将最大化其业务的收益,并使其可复制。这个想法类似于雷·达里奥在《原则》中表达的观点 — 为了一个团队能够成功,他们的经理需要在团队上工作(而不是在团队里工作),并建立一个能够最大化任何给定输入收益的系统。
在某种程度上 — 这些建议也适用于分析团队。对于一个分析团队 — 纲要地说 — 输入是把数据转化为见解的时间,输出是“高质量的见解”,两者之间的关系可以如下所示:
每月生成的高质量见解数 = 时间花在把数据转化为见解上 / 转化为高质量见解所需的平均时间
要增加团队生成的高质量见解数量,你需要努力增加把数据转化为见解的时间,或者减少转化为高质量见解所需的平均时间。你可以通过建立“系统”来实现这一点。
每月分解的见解(作者提供的图像)
增加把数据转化为见解的时间
时间花在把数据转化为见解上很明显是你的总员工时间的一个函数 — 因此增加员工数是一个显而易见的解决方案,但这可能不是最容易的方法。
另一种看待这个问题的方式是,把时间花在把数据转化为见解上,其结果可以用以下方程式表示:
时间花在把数据转化为见解 = 总员工时间 — 花在非数据工作上的时间
花在非数据工作上的时间包括“与利益相关者的协调”,“沟通”等元素。
-
这些任务对任何优秀数据工作的成功至关重要(如果没有对它们的兴趣或者没有适当地传达它们,生成见解有什么意义?)。
-
但通常这些任务被视为“事后补救”。很少见到有团队在这些元素上有明确的策略或流程 — 主要是因为这不像真正的数据工作那样“酷”,而且也不一定是他们的技能范围之内。
-
这导致这些任务花费的时间比预期的更多,并且超过了确保实际数据工作成功所需的时间。
通过(1)定义清晰的处理这些任务的流程,以及(2)通过时间的推移标准化和优化这些流程,你可以节省大量时间(即减少非数据工作所花费的时间),同时提高输出质量。
一个关于跨职能对齐的具体例子可能是从每个月开始时进行优先级排序会议。在进行的第一个月里,你会意识到为了进行一个好的优先级排序会议,你需要一个标准框架来做出优先级决策。你在第 2 个月引入了这个框架,并且它有效,但随后你会发现为了让它更好,你需要一个更好的流程来映射团队的潜在项目,所以你在第 3 个月引入了这个流程,依此类推。随着时间的推移,通过这种迭代的方法,你可以获得一个非常有效的流程,使你的团队花费更少的时间在“政治工作”上,更多地专注于洞察创造。
另一个关于公司范围内沟通的例子:你从第 1 个月开始时没有明确的流程,并意识到你的研究没有被充分利用。因此,在第 2 个月,你启动了一个月度论坛。在这些月度论坛中,你会发现你的利益相关者需要以某种方式展示数据,以便对他们更易于理解,所以你采用了一种特定的格式/模板等。
再次通过优化这些流程,不仅可以节省时间,以便重新投资于洞察创造,而且还可以为成功打下基础,因为这些耗时的非数据相关流程支持团队生成高质量洞察的能力。
减少将数据转化为高质量洞察所需的平均时间。
有几个因素可能会影响将数据转化为高质量洞察所需的时间。仅举几个例子:
-
分析师的技能
-
团队的支持
-
数据的可用性
-
工具的存在
提升分析师的技能,以减少他们将数据转化为高质量洞察所需的时间,是首要策略。技能越高,经验越丰富,他们将数据转化为高质量洞察的速度就越快。虽然团队级别的培训或个人辅导通常可以创造很多价值,但一种“软”方式是创建项目“模板”,以便更初级的分析师能够采纳最佳实践并迅速学习。例如,拥有模板可以迫使他们思考关键问题,如“痛点是什么”、“你的结果将在实际生活中如何使用”等,最终帮助他们在开始研究之前构建更强的陈述。
创建团队协作和知识共享的方式也可以减少洞察时间。可以像创建 Slack 频道或 Google 组并找到一些激励措施让人们参与一样简单——但这些小举措可以产生长远的效果。一旦这些“场所”存在,分析师可以在不确定如何继续时找到支持,利用团队的集体知识,并开展激发新想法的讨论。这也是为什么我认为定期会议很重要,在会议上分析师可以展示他们的工作——重点关注他们使用的方法论,因为这可以传播知识并提供灵感。
数据的可用性可能是一个大障碍。如果你必须花时间进行复杂的查询,因为没有简单的汇总数据库存在,而且每次都要三次检查结果,因为没有经过认证或集中管理的数据源,这不仅会给团队带来不必要的压力,还会浪费宝贵的时间。创建正确的数据管道以简化下游分析可以是一种有效的策略——如果这还没有做到的话。
最后,如果你需要频繁进行相同的分析,工具的存在可以减少你在重复工作上花费的时间。这在 A/B 测试等情况中很常见,你可以构建/购买自动化工具的许可证,让它们为你完成所有的统计测试,这样你就不用每次从实验中获得数据时都重新发明轮子。这需要有一个具体的、重复的使用案例,但当这种情况存在时,这可以大大减少洞察时间(附加分:这也是标准化输出质量的好方法)。
从根本上说,你有几种方法来减少平均洞察时间——我认为我离全面覆盖还很远。你还可以考虑知识管理、数据可发现性等——这完全取决于你的团队面临的主要痛点。
总结
我们可以重新调整我们的初始公式:
# 每月质量洞察 = (总人数时间 — 非数据工作的时间) / 平均质量洞察时间。
虽然增加总人数是一种解决问题的方法,但你也可以通过认真审视你的流程、基础设施、工具和“分析师支持”策略来达到类似的效果。
本文已转发至 Analytics Explained,这是一个新闻通讯,在这里我提炼了在各种分析角色中学到的知识(从新加坡的初创公司到旧金山的大型科技公司),并回答关于分析、增长和职业的读者问题。
基于词级 BERT 嵌入趋势生成句子级别嵌入
图片由 Igor Shabalin 提供
如何从词嵌入中推导句子级别的嵌入
·
关注 发表在 Towards Data Science ·5 min read·2023 年 1 月 5 日
–
句子(短语或段落)级别的嵌入常用于许多自然语言处理分类问题中,例如,垃圾邮件检测和问答(QA)系统。在我之前的文章中,发现 BERT 嵌入不同层次的趋势以确定语义上下文,我讨论了如何生成一个向量表示,该向量包含有关相对于同一标记静态嵌入值的上下文嵌入值变化的信息,然后可以将其用作生成句子级别嵌入的组件。本文扩展了这一主题,探索了从句子中的哪些标记中提取这样的趋势向量,以便能够为整个句子生成有效的嵌入。
直觉
与此相关的第一个问题是:从句子中的多少个标记中提取嵌入以生成整个句子的有效嵌入?如果你回顾之前的讨论,我们得到的是一个向量——为句子中最重要的单词提取的——其中包含有关整个句子上下文的信息。然而,为了更好地了解句子上下文,拥有一个与最重要单词在句法上最相关的单词的向量也很有帮助。为什么我们需要这个?
生活中的一个简单类比可以帮助回答这个问题:如果你坐在塔楼内的餐厅里欣赏周围的美景——你所观察的视角将不包括塔楼本身。要拍摄塔楼的视角,你首先需要离开塔楼。
好的,我们如何确定句子中与最重要单词在句法上最相关的单词呢?(即,你需要根据之前的类比确定拍摄塔楼照片的最佳位置)答案是:借助注意力权重,你也可以从 BERT 模型中获得这些权重。
实现
在你可以跟随本文其余部分讨论的代码之前,你需要参考之前的文章中提供的示例(我们将使用该示例中定义的模型和生成的向量表示)。你需要做的唯一修正是:在创建模型时,确保使模型返回不仅是隐藏状态,还有注意力权重:
model = BertModel.from_pretrained(‘bert-base-uncased’,
output_hidden_states = True, # so that the model returns all hidden-states.
output_attentions = True
)
其他所有内容,包括示例句子,都可以直接使用。实际上,我们将只使用第一个示例句子:“我想要一个苹果。”
下面我们正在确定与最重要的单词(在这个例子中是“想要”)在句法上最接近的单词。为此,我们检查所有 12 层的注意力权重。首先,我们创建一个空数组(不计算特殊符号,排除第一个和最后一个符号):
a = np.empty([0, len(np.sum(outputs[0].attentions[0][0][11].numpy(), axis=0)[1:-1])])
接下来,我们填充注意力权重矩阵:
for i in range(12):
a = np.vstack([a,np.sum(outputs[0].attentions[0][0][i].numpy(), axis=0)[1:-1]])
我们对标点符号不感兴趣。所以,我们将删除矩阵中的最后一列:
a = np.delete(a, -1, axis=1)
所以我们的矩阵现在看起来如下(12x4,即 12 层和 4 个单词)
print(a)
[[0.99275106 1.00205731 0.76726311 0.72082734]
[0.7479955 1.16846883 0.63782167 1.39036024]
[1.23037624 0.40373796 0.57493907 0.25739866]
[1.319888 1.21090519 1.37013197 0.7479018 ]
[0.48407069 1.15729702 0.54152751 0.57587731]
[0.47308242 0.61861634 0.46330488 0.47692096]
[1.23776317 1.2546916 0.92190945 1.2607218 ]
[1.19664812 0.51989007 0.48901123 0.65525496]
[0.5389185 0.98384732 0.8789593 0.98946768]
[0.75819892 0.80689037 0.5612824 1.10385513]
[0.14660755 1.10911655 0.84521955 1.00496972]
[0.77081972 0.79827666 0.45695013 0.36948431]]
现在让我们确定“Want”(第二列,索引为 1)在哪些层中吸引了最多的注意力:
print(np.argmax(a,axis=1))
b = a[np.argmax(a,axis=1) == 1]
array([1, 3, 0, 2, 1, 1, 3, 0, 3, 3, 1, 1])
接下来,我们可以确定在“Want”领先的层中,哪个标记在“Want”之后吸引了更多的注意力。为此,我们首先删除“Want”列,然后探讨其余的三列:
c = np.delete(b, 1, axis=1)
d = np.argmax(c, axis =1)
print(d)
counts = np.bincount(d)
print(np.argmax(counts))
[0 2 2 2 0]
2
上述内容表明,我们有单词 Apple(在这里删除了“Want”后,Apple 的索引为 2)作为与单词“Want”在句法上最相关的单词。这是相当意料之中的,因为这些词分别代表了直接宾语和及物动词。
_l12_1 = hidden_states[0][12][0][4][:10].numpy()
_l0_1 = hidden_states[0][0][0][4][:10].numpy()
_l0_12_1 = np.log(_l12_1/_l0_1)
_l0_12_1 = np.where(np.isnan(_l0_12_1), 0, _l0_12_1)
现在让我们比较从单词 Apple 和 Want 的嵌入中得到的向量。
print(_l0_12_1)
array([ 3.753544 , 1.4458075 , -0.56288993, -0.44559467, 0.9137548 ,
0.33285233, 0\. , 0\. , 0\. , 0\. ],
dtype=float32)
print(l0_12_1) # this vector has been defined in the previous post
array([ 0\. , 0\. , 0\. , 0\. , -0.79848075,
0.6715901 , 0.30298436, -1.6455574 , 0.1162319 , 0\. ],
dtype=float32)
如你所见,上述两个向量中匹配元素对的一项值在大多数情况下为零,而另一项值非零——即这些向量看起来是互补的(记住塔楼视角的类比:塔楼可以看到邻近的景象,但要看到塔楼本身——也许是主要的吸引物——你需要离开它)。因此,你可以安全地逐元素相加这些向量,将可用的信息合并为一个单一的向量。
s = _l0_12_1 + l0_12_1
print(s)
array([ 3.753544 , 1.4458075 , -0.56288993, -0.44559467, 0.11527407,
1.0044425 , 0.30298436, -1.6455574 , 0.1162319 , 0\. ],
dtype=float32)
上述向量可以作为句子级别分类的输入。
结论
本文提供了关于如何基于从静态嵌入到上下文嵌入的转换趋势,在词级 BERT 嵌入中生成句子级别嵌入的直观理解和代码。这种句子级别的嵌入可以作为 BERT 生成的 CLS 标记嵌入的替代方案用于句子分类,这意味着你可以尝试这两种方法,以查看哪一种最适合你的特定问题。
使用 Python 生成合成数据
原文:
towardsdatascience.com/generating-synthetic-data-with-python-ea15fd0555ee
创建合成数据的全面指南
·发布在Towards Data Science ·阅读时长 14 分钟·2023 年 7 月 31 日
–
作者提供的图片
我们一次又一次地听到数据在推动增长、创新和竞争力方面的关键作用。它已经成为所有行业成功的基石。本质上,数据已成为我们每一个努力的基础,无论是撰写技术博客、教育内容、测试产品或调试软件,还是探索 AI/ML 训练模型和算法的复杂性,数据都处于所有这些任务的核心。
获得完全适合各种需求和兴趣的精确数据可能是一项艰巨的任务。在互联网上寻找你所需的确切数据既令人沮丧又耗时。即使你成功找到合适的数据,清理和处理数据的过程也可能需要宝贵的时间、资源和费用。此外,隐私问题、数据敏感性、版权和监管限制通常是重要的障碍。例如,包含敏感信息的数据集,如医疗数据、财务记录数据,或从版权网站获取的演示数据集等。
在这样的情况下,合成数据会拯救我们!在本文中,我们将探讨合成数据的全部内容,以及如何使用 2 个不同的库在 Python 中生成它。
什么是合成数据?
根据维基百科,合成数据是人工生成的数据,而非源自现实世界事件。用最简单的话来说,
合成数据 = 虚假数据
它是现实数据的复制,可能保持其相似性而不泄露有关真实个人、情况或实体的任何特定信息。你可能已经听说过不同的术语,包括计算机生成的数据、人工数据、AI 生成的数据或模拟数据,但本质上,它们都是或多或少相同的——虚假数据。
为什么需要合成数据?
你可能会想知道,既然我们已经拥有大量真实世界的数据,为什么还需要合成数据。它有多种价值,它允许我们创建看起来像真实数据但不包含任何有关人员或情况的真实信息的附加数据。合成数据帮助我们保护隐私(当真实数据不能向他人公开时),解决数据稀缺问题(当适合的数据有限或无法进行分析或研究时),并在不依赖敏感/受限的真实数据的情况下测试 AI/ML 模型,或者在受控条件下测试非常特定的行为。
还有许多其他情况需要合成数据。例如,真实数据可能难以获得或成本过高,或者数据点太少(数据集不够大,或包含的样本数量不足以有效训练模型、得出重要结论或获得准确结果)
设想一个银行希望预测其借贷部门客户的信用风险。他们需要历史数据,包括信用行为、还款历史、收入、姓名、联系方式和其他相关细节。然而,由于数据隐私问题和遵守数据保护法规如GDPR,以及过去数据的有限可用性和高数据获取成本,他们可能缺乏足够的数据来训练模型或通过数据分析得出结论。
仅有少量真实数据时,捕捉复杂性和信用模式变得困难,从而导致预测的潜在不准确性。为了解决这个问题,银行可以生成类似于真实客户特征和信用行为的合成数据集。这可以提高模型性能,减少过拟合风险,并提供更准确的预测,使银行能够做出明智且可靠的信用决策。
如何生成合成数据?
现在我们对合成数据是什么以及为什么需要它有了更多了解,接下来让我们进入下一步:如何生成它?合成数据主要有两种生成方式,
1. 通过复制实际数据的部分并将其用作参考,
-
通过对原始数据集应用变换或修改来创建现有真实数据的变体。这个过程通常被称为数据增强。
-
例如,在文本数据中,你可以引入一些小的变化,例如随机插入或删除文本、在保持核心含义不变的情况下重新措辞等,以扩展数据集的大小。
2. 通过从头创建一个全新的数据集,
-
另外,你可以根据某些标准从头生成完全新的数据点。
-
这种方法通常用于处理敏感或私人数据,因为它确保合成数据集中没有暴露真实数据。
两种方法各有优点,可根据数据生成任务的具体要求和目标选择,如真实数据的可用性、数据隐私问题、数据的复杂性以及合成数据集的预期用途。在本文中,我们将使用第二种方法。
情景
想象一下,我们需要创建一个包含进行信用风险分析所需的所有信息的客户表。以下是我打算创建的字段列表,
-
客户 ID:表中每个客户的唯一标识符。
-
客户姓名:客户的名字。
-
年龄:客户的年龄,因为这可能是信用风险评估的相关因素。
-
收入:客户的收入水平,这对于评估他们偿还贷款能力至关重要。
-
信用评分:基于客户的信用历史评估其信用 worthiness。
-
债务收入比:客户的总债务与其收入的比例,显示其财务稳定性。
-
就业状态:客户的就业状态——在职、失业、自雇等。
-
贷款金额:客户申请的贷款金额。
-
贷款期限:客户偿还贷款的时间长度。例如,如果贷款期限为 36 个月,客户必须在 36 个月内偿还贷款。贷款期限影响还款计划,较长的期限可能导致较低的月付款但较高的总体利息,而较短的期限可能导致较高的月付款但较低的总体利息。
-
付款历史:客户在贷款和信用账户上的过往付款行为。
-
受抚养人数:财务上依赖于客户的人员数量。
在 Python 中,你可以找到各种创建合成数据的库。它们提供了不同级别的复杂性和功能来生成合成数据。根据你的需求,你可以选择最适合的库。务必检查,
-
官方文档
-
社区支持
以获取这些库的最新信息。在本文中,我们将使用以下 Python 库,
-
Faker
-
随机
破解代码
在开始编码之前,我们先了解一下我们将要使用的库,
#import required library
import random
import pandas as pd
from typing import Dict
from faker import Faker
-
Faker - 这是一个生成合成数据的 Python 库,提供了多种功能来创建真实看起来的个人信息。
-
random - 这是一个标准的 Python 库,提供生成随机数据的函数。它最常用于生成随机整数、浮点数和从元素列表中进行随机选择。
-
Pandas - 这是一个流行的 Python 库,用于数据操作,包括数据清理、过滤、分组、合并等任务。它设计用于处理结构化数据,如表格和时间序列数据,提供了高效的数据分析强大功能。
-
typing - 这是一个 Python 库,提供了将类型提示添加到代码中的工具。类型提示通过指定变量和函数参数的预期类型来帮助提高代码的清晰度和可读性。它在 Python 3.5 中引入。
现在,让我们开始编程吧!第一步是创建一个 Faker 实例。
#create a Faker instance and set the locale to GB(Great Britain)
fake = Faker(['en_GB'])
我们为什么需要它?嗯,Faker 实例充当一个 生成器,可以创建各种类型的数据。生成器 是 Python 中的一个对象,它按请求一次生成一个值的序列。你可以在这里了解更多,
对 Python 的生成器函数和生成器表达式的基本介绍。
medium.com](https://medium.com/swlh/writing-memory-efficient-programs-using-generators-in-python-49854bb57da6?source=post_page-----ea15fd0555ee--------------------------------)
通过使用 Faker 提供的函数,你可以轻松生成看起来像真的数据!你还可以在设置 Faker 实例时指定区域。区域指的是具有自己独特文化、语言和信息呈现方式的特定地方或国家。当我们将区域设置为特定地区时,Faker 生成的数据将匹配该地方的特征,比如该国家常见的名字和地址。
在上面的代码中,使用 “en_GB” 允许我们访问针对英国(United Kingdom)量身定制的函数,提供特定于地点的数据。
现在,进行编程的下一步,让我们创建一个生成所有所需字段的函数,按照给定的规格。
def generate_customer_data(num_records: int):
customer_data: Dict[str, list] = {
'customer_id': [fake.aba() for i in range(num_records)],
'customer_name': [fake.name() for name in range(num_records)],
'age': [random.randint(18, 70) for age in range(num_records)],
'income(£)': [random.randint(20000, 100000) for income in range(num_records)],
'credit_score': [random.randint(300, 850) for score in range(num_records)],
'debt_to_income_ratio': [round(random.uniform(0.1, 1.0), 2) for ratio in range(num_records)],
'employment_status': [random.choice(['Employed', 'Unemployed', 'Self-employed']) for status in range(num_records)],
'loan_amount': [random.randint(1000, 50000) for amount in range(num_records)],
'loan_term': [random.choice([12, 24, 36, 48, 60]) for term in range(num_records)],
'payment_history': [random.choice(['Good', 'Fair', 'Poor']) for history in range(num_records)],
'number_of_dependents': [random.randint(0, 5) for dep in range(num_records)]
}
return customer_data
在上面的代码块中,
-
我们创建了一个名为 ‘generate_customer_data’ 的函数,该函数接受一个参数 ‘num_records’,表示我们希望生成的合成客户记录的数量。
-
‘(num_records: int)’ 指定了一个类型提示,表示该函数期望一个整数作为此参数。
-
在 ‘generate_customer_data’ 函数内部,我们正在创建一个名为 ‘customer_data’ 的字典,用于保存每个客户的合成数据。
-
‘customer_data: Dict[str, list]’ 表示字典的 keys 将是字符串,而相应的 values 将是 lists。
我们使用类型提示来指定预期的数据类型,以便更好地理解和阅读代码。
让我们理解一下上面代码块的第一行,
#customer_id:- a unique identifier for each customer in the table
'customer_id': [fake.aba() for i in range(num_records)]
在这里,‘customer_id’ 是键,对应的值是一个 list。这一行代码使用 Faker 库中的 ‘fake.aba()’ 方法生成一个 list 类型的客户 ID。这个方法随机生成一个 9 位数的数字,我们将用它作为唯一的客户 ID。
如果你注意到,这是一行代码,通常被称为*“一行代码”。在这里,它被称为列表推导式*,是一种在 Python 中编写列表的简洁方法。
作者提供的图片:列表推导式的常见语法
你可以在这里阅读有关 Python 支持的各种推导式的更多信息,
要了解 Python 的推导式功能,首先了解推导式的概念是很重要的…
[towardsdatascience.com
📌 附注
#customer_id:- a unique identifier for each customer in the table
'customer_id': [fake.aba() for i in range(num_records)]
#preferred approach
'customer_id': [fake.aba() for _ in range(num_records)]
在代码的第二行for循环中,我使用了*‘’(下划线)代替‘i’。这两种方法都是正确的,但使用‘’* 是更常见和推荐的做法,当我们不打算使用循环变量时(在这种情况下,‘i’ 是循环变量)。
这是一个更清晰的方式来表示循环变量在推导式中不相关或未被使用。这使得代码更加易读和标准,帮助他人更容易理解你的代码。如果你使用*‘i’* 作为循环变量,它可能暗示着有某种用途,导致混淆和不必要的变量赋值。因此,
当你不需要循环变量时,使用下划线作为占位符是一种良好的实践,使你的代码更干净、更简洁。
既然如此,由于我正在写一篇适合初学者的文章,我选择了使用循环变量。然而,传达最佳方法也是很重要的!
接下来,在类似的方式下,我为客户表生成了所有必需字段的合成信息,
-
‘customer_name’: [fake.name() for name in range(num_records)]
这段代码使用 ‘fake.name()’ 方法从 Faker 库生成每个客户的名称。这个方法用于生成一个随机和合成的名字,看起来像是一个真实的人名。它可以生成来自各种文化和地区的名字,包括名字和姓氏。由于在代码开头我们将区域设置为*‘en-GB’*,这确保了合成的数据与英国非常相似。
-
‘age’: [random.randint(18, 70) for age in range(num_records)]
这一行生成了一个客户年龄的列表,使用了*‘random.randint()’函数。此函数用于生成指定范围内的随机整数。你提供两个数字作为参数——第一个是最小值,第二个是最大值。它然后返回范围内的一个随机整数,包括最小值和最大值。在我们的情况下,此函数生成每个客户的随机年龄,范围在18和70之间,包括18和70*。
作者提供的图片:random.randint() 的语法
-
‘income’: [random.randint(20000, 100000) for income in range(num_records)]
这生成了一个随机收入水平的列表,使用了*‘random.randint()’函数。如前所述,每个收入是一个随机整数,范围在20,000和100,000之间,包括20,000和100,000*。
-
‘credit_score’: [random.randint(300, 850) for score in range(num_records)]
这生成了一个信用评分的列表,使用了*‘random.randint()’函数。到目前为止,你已经理解了这个过程:它为每个客户生成一个随机的信用评分,范围在300和850之间,包括300和850*。
-
‘debt_to_income_ratio’: [round(random.uniform(0.1, 1.0), 2) for ratio in range(num_records)],
这生成了一个债务收入比的列表,使用了*‘random.uniform()’函数。此函数用于生成指定范围内的随机小数。你提供两个数字作为参数:下限和上限,然后函数会生成这两个值之间的随机小数,包括下限和上限。‘round(random.uniform(0.1, 1.0), 2)’表示每个比率是一个0.1到1.0*之间的随机浮点数,四舍五入到两位小数。
作者提供的图片:random.uniform() 的语法
-
‘employment_status’: [random.choice([‘Employed’, ‘Unemployed’, ‘Self-employed’]) for status in range(num_records)],
这生成了一个每个客户的就业状态列表,使用了*‘random.choice()’函数。此函数允许你从列表或任何元素序列中选择一个随机项。你提供列表或序列作为参数,函数将随机选择并返回该序列中的一个元素。在我们的背景下,每个客户的状态是从给定的选项列表中随机选择的:‘Employed’,‘Unemployed’,或‘Self-employed’*。
作者提供的图片:random.choice() 的语法
-
‘loan_amount’: [random.randint(1000, 50000) for amount in range(num_records)],
这生成了一个每个客户的贷款金额列表,使用了*‘random.randint()’函数。每个客户的贷款金额是1,000和50,000之间的随机整数,包括1,000和50,000*。
-
‘loan_term’: [random.choice([12, 24, 36, 48, 60]) for term in range(num_records)],
这一行使用*‘random.choice()’函数生成一个贷款期限列表。正如我们之前讨论的‘employment_status’,每个客户的贷款期限是从给定的选项列表中随机选择的:12、24、36、48或60*个月。
-
‘payment_history’: [random.choice([‘Good’, ‘Fair’, ‘Poor’]) for history in range(num_records)],
这一行使用*‘random.choice()’函数生成一个支付历史列表。每个支付历史都是从选项列表中随机选择的:‘Good’、‘Fair’或‘Poor’*。
-
‘number_of_dependents’: [random.randint(0, 5) for dep in range(num_records)],
这生成了一个依赖人数的列表,使用*‘random.randint()’函数。每个依赖人数是0到5之间的随机整数,包括0和5*。
这个解释相当详细,是吧?现在,随着我们接近循环的结束,处理完所有客户后,我们返回包含合成数据的*‘customer_data’*字典。
现在我们已经定义了函数中每个字段的必要细节,让我们继续调用函数。但在此之前,我们将设置要生成的记录总数,并将其存储在变量*‘number_of_rows’中。完成后,我们将使用这个值调用‘generate_customer_data’函数。在这里,我们生成10000*个合成记录。
#total number of records to generate
number_of_rows: int = 10000
#generate synthetic data for the Customer table
customer_data: Dict[str, list] = generate_customer_data(number_of_rows)
‘customer_data: Dict[str, list]’表示该函数以字典形式返回合成数据,其中keys将是strings,对应的values将是lists。
进入代码的最后部分,在提取所有必要的信息后,我们有选择下一步的方案。我们可以将其导出到CSV、Excel或JSON文件中,也可以打印出来。然而,保留数据在 pandas DataFrame 中是个好主意。这样你可以立即使用它,也可以在未来进行数据分析。使用 DataFrame,你可以执行各种操作,清理和准备数据,分析数据,并顺畅地与其他库配合使用。
#create a pandas DataFrame from the dictionary 'customer_data'
df_customer: pd.DataFrame = pd.DataFrame(customer_data)
#export the synthetic data to a CSV file
outout_file: str = 'synthetic_customer_data.csv'
df_customer.to_csv(outout_file, index=False, encoding='utf-8', header="true")
print(f"Synthetic data is created according to specific requirements and saved to {outout_file}")
在上面的代码块中,我们使用了函数*‘generate_customer_data’返回的字典‘customer_data’来创建一个 pandas DataFrame‘df_customer’*。‘df_customer: pd.DataFrame’表示‘df_customer’是‘pd.DataFrame’*类型的变量,这意味着它是一个 Pandas DataFrame。
最后,让我们将这些数据保存到CSV文件中。请注意,默认情况下,文件将创建在与程序相同的目录中。
#export the synthetic data to a CSV file
outout_file: str = 'synthetic_customer_data.csv'
df_customer.to_csv(outout_file, index=False, encoding='utf-8', header="true")
在这里,我们创建了*‘synthetic_customer_data.csv’作为输出文件,并将其存储到变量‘output_file’*中。‘to_csv()’将把 Pandas DataFrame 保存为CSV文件。
-
index=False表示 DataFrame 的索引列将不会包含在结果CSV文件中。默认情况下,它设置为true。
-
encoding=’utf-8’ 指定了在将 DataFrame 写入 CSV 文件时使用的字符编码。
-
header=”true” 包括列名作为 CSV 文件中的表头行。默认情况下,设置为 true。
结论
本文旨在介绍使用 Python 生成合成数据的基础知识。通过使用各种库,如 scikit-learn、SDV、Gretel、CTGAN、faker、random 等,你可以高效地为各种用例生成数据。
尽管合成数据提供了众多好处,但它也有其缺点。一些常见的缺点包括可能无法准确复制现实世界的复杂性、准确表示稀有事件的挑战,以及如果没有仔细创建和验证可能引入的偏见。合成数据生成的有效性依赖于你的具体需求和可用的库。因此,彻底评估你的需求和可用工具的能力至关重要,因为它们直接影响生成的合成数据的准确性和有用性。
这里有一些资源可以帮助你开始使用合成数据:
Cassie Kozyrkov,谷歌的首席决策科学家,撰写了关于合成数据的详尽入门指南,值得一读,
-
什么是合成数据?
-
合成数据实用指南
-
AI 生成的合成数据
本文使用的代码可在我的 GitHub 仓库 中找到,生成的输出文件‘synthetic_customer_data.csv’ 可在 GitHub Gist 中访问。
祝学习愉快!
生成式 AI 伦理
自主内容时代的关键考虑因素
·
关注 发布于 Towards Data Science ·11 分钟阅读·2023 年 7 月 25 日
–
作者提供的照片 — 大卫·E·斯维诺
随着围绕生成式人工智能(AI)的喧嚣,关于如何负责任地实施这一变革性技术的问题越来越多。本文将回顾欧盟(EU)的 AI 伦理指南,并讨论在使用大型语言模型(LLMs)时实施 AI 伦理框架的关键考虑因素。
可信 AI 伦理指南
2019 年 4 月 8 日,欧盟实施了人工智能(AI)的伦理和负责任使用框架。报告定义了构建可信 AI 的三项指导原则:
-
合法性:AI 应遵守法律法规和当地规定。
-
伦理:AI 系统应具备伦理性,遵循伦理原则和价值观。
-
稳健:由于 AI 可能在短时间内对大规模人群造成显著危害,它需要在技术和社会上都具备稳健性。
对于跨国公司而言,这提出了一个有趣的问题:如何在地缘政治边界之间应用这一框架,因为在世界某个地区被视为合法和伦理的做法,可能在另一个地区并不适用。许多公司采取最严格的规定,并在所有地区单方面适用。然而,“一刀切”的方法可能并不适用或可接受。
欧盟的框架见下图 1.1。
图 1.1:欧洲联盟的 AI 伦理框架
作者提供的图示——David E. Sweenor,TinyTechGuides 创始人
基于这三项基础原则,得出四项伦理原则和七项关键要求。这些伦理原则包括:
-
尊重人类自主权:这一原则强调,人类应在与 AI 的互动中保持控制和自由。“AI 系统不应无理地使人类从属、胁迫、欺骗、操控、条件化或驱使。”[1] 从根本上讲,AI 应支持人类参与民主过程。我们已经看到一些国家对公民实施“社会评分”,这应引起关注。
-
防止伤害:AI 系统不应造成身体、心理或情感上的伤害。鉴于 AI 的普及性和迅速影响,重要的是要密切监控 AI 的输出,以防止“由于权力或信息的不对称”对公民、员工、企业、消费者和政府的无意操控。[2] 我们已经看到自动驾驶汽车制造商在所谓的AI 电车难题中与这一原则斗争。当然,这不仅限于机器人系统;人们依赖 ChatGPT 获取医疗建议,鉴于其生成虚假信息的倾向,我们需要小心。
-
公平性:AI 系统应当无偏见且不歧视,旨在“实现利益和成本的平等分配”。[3] 公平性意味着不应削弱人类选择,并且“AI 从业者应平衡竞争利益和目标,尊重手段与目的之间的比例原则”。[4] 从表面上看,这似乎很简单,但你知道吗,公平性有超过二十种数学定义?[5]
-
可解释性:AI 系统需要透明、可审计、可复现和可解释。如果 AI 用于决定影响你的事情,你有权了解算法如何做出该决定。例如,如果你被拒绝了信用,AI 系统的操作员应该能够提供所有影响该决定的因素。当使用“黑箱”模型时,例如神经网络和生成对抗网络(GANs),这可能会成为问题。
这引出了七项要求:
-
人类代理和监督:本质上,这一要求指出 AI 系统应该尊重人权,不应完全自主运行。AI 应该辅助,而不是替代人类决策。应有一个挑战 AI 决策的过程,并且在必要时,人类应能够覆盖 AI 的决策。这听起来不错,但当数以百计或千计的决策自动做出时,你如何有效跟踪所有这些决策以确保不会出错?
-
技术健壮性和安全性:AI 系统需要安全、稳健,并能够抵御恶意行为者和网络攻击。它们应提供准确的预测,且可靠、可复现。组织必须优先考虑网络安全,并制定攻击的应急计划及系统离线时的操作方式。他们需要特别注意对抗性数据投毒,即恶意行为者修改训练数据以导致错误预测。
-
隐私和治理:“AI 系统必须在整个系统生命周期内保证隐私和数据保护。”[6] AI 系统的开发者需要设置保护措施,以防止恶意数据或代码被输入系统。指南还强调,只有授权用户才能访问个人数据,这些数据必须公平、公正,并遵守整个生命周期中的所有隐私规定。组织需要思考的一个领域是什么构成“授权用户”?你看到过Roomba 拍摄女性上厕所的案例吗?
-
透明性:组织必须能够追溯数据的来源,了解其来源、如何收集、转化和使用。这一过程应该是可审计的,AI 输出应该是可解释的。这对数据科学家来说是一个挑战,因为可解释的模型通常不如“黑箱”算法准确。此要求还说明,人与 AI 互动时应该意识到这一点——换句话说,AI 不应该假装成真人,应该清楚我们是在与机器人互动。
-
多样性、非歧视和公平性:AI 应平等对待所有群体——这可能说起来容易做起来难。该要求建议设计师应包括来自不同文化、经验和背景的人,以帮助减轻许多文化中存在的历史偏见。AI 应对所有人都可及,无论是否有残疾或其他因素。这就引发了一个问题,什么定义了“群体”?显而易见的保护类别包括年龄、种族、肤色、地区/信仰、国籍、性别、年龄、身体或精神残疾或退伍军人身份。是否还有其他因素需要考虑?如果我是保险公司,我可以对拥有“更健康”习惯的人收取比那些被认为“不健康”的人更少的费用吗?
-
社会和环境福祉:AI 系统应致力于改善社会、促进民主,并创建环保和可持续的系统。仅仅因为你可以做某件事,并不意味着你应该做这件事。商业领袖需要批判性地考虑 AI 的潜在社会影响。训练 AI 模型的成本是什么?这些成本是否与您的环境、社会和公司治理(ESG)政策相抵触?我们已经看到社交媒体平台如 TikTok 在向孩子推送有害内容。
-
问责制:AI 系统设计师应对其系统负责,这些系统应可审计,并提供一种方式,让受决策影响的人能够纠正任何不公平的决定。设计师可能会对对个人或群体造成的任何伤害负责。这引发了一个有趣的问题——如果系统出现故障,谁应负责?是基础模型的提供者,还是使用生成式 AI 的公司?
虽然这些原则表面上似乎直观,但“在这些原则的解释、重要性、涉及的问题、领域或行为者以及如何实施方面存在实质性差异。”[7]
LLM 的 AI 伦理考虑
现在我们了解了欧盟 AI 伦理指南,让我们深入探讨 LLM 的独特考虑因素。
在上一篇博客中,GenAIOps: Evolving the MLOps Framework 我概述了生成式 AI 和 LLM 的三项关键能力,包括:
● 内容生成:生成式 AI 可以生成类似人类质量的内容——包括文本、音频、图像/视频甚至软件代码。现在,需要注意的是,生成的内容可能不准确——最终用户有责任确保生成的内容真实且不具误导性。开发人员需要确保生成的代码没有漏洞和病毒。
● 内容总结与个性化:快速浏览大量文档并迅速总结内容是生成性人工智能的一个强项。除了快速创建文档、电子邮件和 Slack 消息的总结外,生成性人工智能还可以为特定个人或角色个性化这些总结。
● 内容发现与问答:许多组织在不同的数据孤岛中分散着大量的内容和数据。许多数据和分析供应商正在利用大型语言模型(LLMs)和生成性人工智能自动发现并连接这些分散的来源。最终用户可以用普通语言查询这些数据,以理解关键点并深入探讨更多细节。
鉴于这些不同的能力,我们在创建人工智能伦理框架时需要考虑哪些因素?
人工干预与监督
由于生成性人工智能本质上可以自主生成内容,这可能会降低人工干预和监督的程度。你可以想象一下,你每天收到多少垃圾邮件?营销团队创建这些邮件,将它们加载到营销自动化系统中,然后按下“开始”按钮。这些系统在自动驾驶模式下运行,往往被遗忘并持续运行。
鉴于生成性人工智能可以以惊人的速度生成文本、图像、音频、视频和软件代码,我们可以采取哪些步骤来确保有人工干预;特别是在关键应用中?如果我们在自动化医疗建议、法律建议和其他更“敏感”的内容时,组织需要认真思考如何保持对这些系统的控制和监督。公司需要采取保障措施,确保做出的决策符合人类的价值观和意图。
技术稳健性与安全性
众所周知,生成性人工智能模型可能会生成意外或甚至有害的内容。公司需要严格测试和验证其生成性人工智能模型,以确保它们是可靠和安全的。此外,如果生成的内容有误,我们需要有机制来处理和纠正这些输出。互联网充满了糟糕和具有分裂性的内容,一些公司已经雇佣内容审核员来尝试审查可疑内容,但这似乎是一个不可能完成的任务。最近有报道称,这些内容可能对心理健康造成严重损害(美联社新闻 — 肯尼亚的 Facebook 内容审核员称工作是‘折磨’。他们的诉讼可能会产生全球影响。)
隐私与治理
生成性 AI 模型是在从互联网收集的数据上进行训练的。许多 LLM 制造商实际上并没有公开详细的训练数据细节。现在,这些模型可能在敏感或私人数据上进行训练,而这些数据本不应公开可用。看看三星,因无意中泄露专有数据而被禁止使用生成性 AI 工具(TechCrunch — 三星在 4 月内部数据泄露后禁止使用生成性 AI 工具如 ChatGPT)。如果生成性 AI 产生的输出包含或类似真实的私人数据会怎样?根据《彭博法律》,OpenAI 最近被起诉诽谤由于 ChatGPT 的幻觉。
我们可以肯定地说,公司需要对用于训练生成性 AI 模型的数据来源有详细的了解。当你使用自己的数据对模型进行微调和适配时,你可以选择删除或匿名化这些数据。然而,如果基础模型提供者使用了不适合模型训练的数据,你仍可能面临风险。如果是这种情况,谁应负责任?
透明度
就其本质而言,“黑箱”模型很难解释。实际上,许多这些 LLMs 具有数十亿个参数,所以我建议它们不可解释。公司应致力于透明度,创建有关模型工作原理、局限性、风险和用于训练模型的数据的文档。同样,这说起来容易做起来难。
多样性、非歧视和公平
与上述相关,如果没有得到妥善训练和管理,生成性 AI 可能会产生偏见或歧视性的输出。公司可以尽力确保数据的多样性和代表性,但鉴于许多 LLM 提供者并未公开用于训练的数据,这是一项艰巨的任务。除了尽可能了解训练数据的风险和局限性之外,公司还需要建立监控系统,以检测有害内容,并设立机制以标记、阻止其分发并根据需要进行纠正。
社会和环境福祉
对于具有 ESG 计划的公司来说,训练 LLMs 消耗大量计算资源——即消耗相当多的电力。当你开始部署生成性 AI 功能时,组织需要关注环境足迹,并寻求减少的方法。有几位研究人员正在寻找减少模型大小和加速训练过程的方法。随着这一领域的发展,公司至少应在年报中考虑环境影响。
责任
这将成为未来几年内一个活跃的诉讼领域。如果生成性 AI 产生有害或误导性内容,谁应对此负责?谁在法律上负有责任?在美国法院系统中已有几个诉讼悬而未决,这些诉讼将为未来的其他诉讼奠定基础。除了有害内容之外,如果你的 LLM 生成了衍生作品呢?你的 LLM 是否在受版权或法律保护的材料上进行了训练?如果它生成了数据衍生物,法院将如何处理这一问题?随着公司实施生成性 AI 能力,应当建立控制和反馈机制,以便在出现问题时采取相应的行动。
摘要
生成性 AI 在革新世界运作方式方面蕴藏着巨大潜力,但其快速演变也带来了众多伦理困境。随着公司进入生成性 AI 的领域,必须深刻理解已建立的伦理指南以导航其实施。通过这样做,组织可以利用 AI 的变革力量,同时确保遵守伦理标准,防范潜在的陷阱和危害。
如果你想了解更多关于人工智能的内容,可以查看我的书籍 《人工智能:让 AI 为你的业务服务的执行指南》在亚马逊 或 在 Google Play 上的 AI 解说有声书。
[1] 欧洲委员会. 2021. “可信 AI 的伦理指南 | 塑造欧洲的数字未来。” Digital-Strategy.ec.europa.eu. 2021 年 3 月 8 日. digital-strategy.ec.europa.eu/en/library/ethics-guidelines-trustworthy-ai
.
[2] 欧洲委员会. 2021. “可信 AI 的伦理指南 | 塑造欧洲的数字未来。” Digital-Strategy.ec.europa.eu. 2021 年 3 月 8 日. digital-strategy.ec.europa.eu/en/library/ethics-guidelines-trustworthy-ai
.
[3] 欧洲委员会. 2021. “可信 AI 的伦理指南 | 塑造欧洲的数字未来。” Digital-Strategy.ec.europa.eu. 2021 年 3 月 8 日. digital-strategy.ec.europa.eu/en/library/ethics-guidelines-trustworthy-ai
.
[4] 欧洲委员会. 2021. “可信 AI 的伦理指南 | 塑造欧洲的数字未来。” Digital-Strategy.ec.europa.eu. 2021 年 3 月 8 日. digital-strategy.ec.europa.eu/en/library/ethics-guidelines-trustworthy-ai
.
[5] Verma, Sahil, 和 Julia Rubin. 2018. “公平性定义解释。”《国际软件公平性研讨会论文集 — FairWare ’18》。 doi.org/10.1145/3194770.3194776
。
[6] 欧洲委员会. 2021. “值得信赖的人工智能伦理指南 | 塑造欧洲的数字未来。” Digital-Strategy.ec.europa.eu. 2021 年 3 月 8 日。 digital-strategy.ec.europa.eu/en/library/ethics-guidelines-trustworthy-ai
。
[7] Jobin, Anna, Marcello Ienca, 和 Effy Vayena. 2019. “全球人工智能伦理指南概况。”《自然机器智能》1 (9): 389–99。 doi.org/10.1038/s42256-019-0088-2
。
社会工作学生的生成式人工智能:第一部分
一个范式转变
·
关注 发表在 Towards Data Science ·12 分钟阅读·2023 年 3 月 20 日
–
作者使用 ChatGPT 制作的 ASCII 艺术小狗。
近年来,人工智能(AI)发展迅速,产生了强大的工具,如生成式人工智能和大型语言模型。生成式人工智能是一种可以根据从现有数据中学到的模式创造新内容的人工智能,比如文本、图像或音乐。大型语言模型,如 OpenAI 的 GPT 系列,是生成式人工智能的一个子集,经过专门训练以理解和生成类人语言。这些模型变得越来越复杂,能够生成连贯、符合上下文甚至富有创造性的输出。
一年多前,我开始使用 GPT,并对其生成与人类作者难以区分的文本的能力感到惊讶。这种能力也引发了对学术不端行为的担忧。因此,我在 Medium 上撰写了一篇文章,预测 AI 辅助学术不端行为的出现。
从那时起,我密切关注生成式 AI 的发展,并探索它们如何与我对传统 AI 系统的兴趣互补。最近,我和我的同事评估了 ChatGPT 通过模拟的硕士级社会工作执照考试的能力——它做到了。我们研究的预印本可以在这里查看,并将很快在《社会工作实践研究》上发表。ChatGPT 现在能以我在一年之前无法想象的闪电速度完成各种复杂任务。
作者提供的图片。
作为社会工作专业的学生,你可能会想这些技术进步如何影响你的教育体验。AI 可以彻底改变你学习、研究和应对社会工作复杂挑战的方式。大型语言模型不仅仅是生成或重写文本。你可以利用这些模型来总结冗长的政策文件,分析定量和定性数据,生成项目评估的见解,自动化社区组织中的日常功能,创建营销材料,构建网络应用和网站——还有更多。
我坚信,通过建立对 AI 技术的扎实基础和有效使用这些技术的技能,你可以提升学习体验并开启新的职业机会。同时,如果没有正确的心态、培训和经验,这些模型对你的学习和职业生涯也会带来重大挑战和风险。
本文是一个系列的第一部分,旨在为 MSW 学生提供学习和建立 AI 技术能力的起点,重点介绍大型语言模型。第一篇文章概述了生成式 AI 在社会工作中的不同应用,并对伦理问题进行了初步讨论,后续文章将继续探讨这些问题。即将讨论的主题包括:
-
第二部分:AI 的基本知识、能力和实践
-
第三部分:通过 AI 提升教育体验的策略
-
第四部分:提示工程的艺术与科学
生成式 AI 在社会工作中的应用
生成式 AI 工具正作为一种变革性力量出现在各种领域,包括商业、医学和法律。尽管 AI 技术在社会工作领域刚刚开始受到关注,但现在是学生积极思考如何利用这一工具以提升和简化服务交付、赋能弱势群体、促进更加公平结果的最佳时机。
我将提供几个例子来说明我们如何使用生成式 AI。这些例子并不全面或完全代表生成式 AI 的能力。请记住,AI 技术的领域广泛且不断发展。根据谷歌和 Alphabet 的首席执行官桑达尔·皮查伊的说法,AI 的能力每六个月翻一番。
心理健康服务
大型语言模型在社会工作领域中的一个有前景的应用是心理健康服务。由 AI 驱动的虚拟治疗助手可以在治疗会议之间或当社会工作者不立即可用时,向客户提供支持和指导。例如,虚拟助手可以帮助客户练习应对策略、提供心理教育或提供简短的压力减轻干预。这些将是可以支持各种任务的助手,但不会替代社会工作者。
大型语言模型可以帮助社会工作者更好地理解客户的语言模式。通过分析基于文本的沟通或治疗会议的转录,AI 可以识别模式、主题和情感,这些可能为客户的情感状态、挑战和治疗进展提供有价值的见解。例如,AI 可以通过分析客户的用词选择、语调或情感表达来帮助检测抑郁、焦虑或其他心理健康问题的迹象。
大型语言模型的另一个实际应用是简化文档处理过程。社会工作者可以从帮助管理大量文书工作的工具中受益,例如撰写案例记录、治疗计划和进展报告,这些工作可能耗时且会减少与客户的接触时间。通过利用 AI,社会工作者可以减少在行政任务上花费的时间和精力,从而可以更多地专注于直接的客户护理,提升整体心理健康服务的质量。
项目管理
生成性语言模型在提升社会工作组织内程序管理方面可以发挥重要作用。管理和协调社会工作程序涉及大量以写作为主的任务,例如起草报告、创建和更新培训材料以及与利益相关者沟通。AI 驱动的工具可以利用原始数据和现有模板来生成文本,作为这些任务的起点。通过自动化初步起草过程,社会工作者可以节省时间,并专注于完善和调整内容,以确保准确反映程序的影响和成果。
这种支持可以带来更高效的报告,并更好地向利益相关者、资助者和政策制定者传达程序结果。大型语言模型还可以帮助开发和更新社会工作程序的培训材料。通过分析现有内容并融入新的研究或最佳实践,AI 可以建议对培训材料进行修订和补充,确保它们保持最新和有效。
政策分析
生成性 AI 对于从事政策分析的社会工作者来说,可以是一项宝贵的资产。政策分析是社会工作专业中的一个关键方面,涉及审查、评估和制定政策以解决社会问题。政策分析通常要求社会工作者浏览复杂且冗长的政策文件,这可能既耗时又具挑战性。大型语言模型可以帮助社会工作者更高效地综合和评估政策文件。通过提取关键信息并总结要点,AI 驱动的工具可以使社会工作者快速掌握政策要点,而无需通读整个文件。这种工作流程可以节省时间,并让社会工作者专注于分析政策的影响、优势和劣势。
生成性 AI 在政策分析中的另一个有用应用是识别现有政策中的差距和机会。通过分析和比较多个政策文件,AI 可以识别出模式、趋势以及政策可能存在的不足或不一致之处。AI 可以帮助社会工作者确定需要进一步关注或采取新方法来解决未满足的需求的领域。此外,大型语言模型可以协助社会工作者根据识别出的差距和机会生成政策建议。通过利用广泛的知识库,AI 可以建议基于证据的解决方案和最佳实践,以促进政策制定。
程序评估
程序评估通常要求社会工作者分析大量的定性和定量数据,以确定程序的成功并识别改进领域。大型语言模型可以帮助社会工作者更高效地分析程序数据,并生成可能需要时间才能显现的见解。例如,人工智能驱动的工具可以通过识别参与者的主题、模式和情感来分析定性数据,如访谈和焦点小组。因此,人工智能驱动的工具可以为社会工作者提供有关客户和其他利益相关者的经验和观点的宝贵信息,这些信息可以为程序改进提供参考。
同样,人工智能可以分析定量数据,例如程序结果测量,通过识别趋势、相关性和异常情况。通过自动化数据分析的初始阶段,社会工作者可以专注于解释结果,并运用他们的专业知识做出数据驱动的决策和建议。
通过利用人工智能驱动的数据分析生成的见解,社会工作者可以评估其项目的效率和效果,并确定改进领域。大型语言模型还可以通过建议基于证据的实践和根据类似项目或情况的分析生成潜在解决方案,帮助社会工作者探索替代策略和干预措施。
此外,生成型人工智能还可以通过生成清晰、简洁且易于理解的报告来协助沟通评估结果,从而有效地将结果和建议传达给各个利益相关者。这些过程有助于确保程序评估结果被理解和采取行动,最终实现客户和社区的更好结果。
社区组织
生成型人工智能可以在支持社区组织工作方面发挥重要作用。社区组织的一个关键方面是有效的沟通和外展,以动员个人、团体和组织围绕共同目标或问题进行行动。
大型语言模型可以帮助社会工作者创建有针对性、吸引人且具有文化敏感性的消息,这些消息能够与不同受众产生共鸣。通过根据不同社区成员的偏好、语言和关注点定制消息,人工智能驱动的工具可以提高外展活动的效果,并帮助与社区成员建立更强的联系。此外,人工智能还可以帮助识别在线对话和社交媒体中的趋势和新兴问题,使社会工作者能够保持对社区需求和优先事项的了解和回应。
生成式人工智能还可以帮助简化社区组织工作中的协作和资源管理。通过自动化创建和更新共享文档、跟踪任务进度和协调日程安排,AI 驱动的工具可以节省时间,提高组织工作整体的效率。此外,社会工作者和社区组织者可以利用 AI 分析社区资源和需求的数据,从而识别出协作的缺口和机会。这种支持使社会工作者能够就资源分配和合作伙伴关系做出明智的决策,从而最大化他们工作的影响力。
生成式人工智能可以在社区组织中提供宝贵的帮助,通过帮助开发倡导材料和政策提案来实现。这种实际应用涉及 AI 驱动的工具分析现有政策、研究和最佳实践,帮助社会工作者创建有说服力、基于证据的材料,准确传达社区的需求和优先事项。社会工作者和社区组织者可以利用这些材料与决策者、资助者以及其他利益相关者进行互动,推动系统性变革的倡导工作。
国际社会工作
生成式人工智能在国际社会工作中可以成为有价值的工具,社会工作者经常面临语言障碍和文化差异的挑战。凭借其先进的自然语言处理能力,大型语言模型可以通过提供实时翻译和生成具有文化敏感性的消息,帮助社会工作者与多样化的群体更有效地沟通。
大型语言模型可以改善跨文化理解,并促进社会工作者与他们服务的社区之间的合作。在国际社会工作中,了解全球趋势、 emerging issues 和可以为干预和政策建议提供指导的最佳实践至关重要。生成式人工智能可以帮助社会工作者访问和分析来自不同来源、国家和语言的大量信息。通过综合这些信息,AI 驱动的工具可以为社会工作者提供有价值的见解和基于证据的策略,以应对不同背景下的复杂社会问题。
生成式人工智能可以促进不同国家和环境中的社会工作专业人员之间的合作与知识交流。AI 驱动的工具可以通过促进沟通、生成研究和报告的摘要,以及识别共同的挑战和机会,帮助社会工作者分享他们的专业知识、互相学习并开发超越国界和文化的创新解决方案。
国际社会工作通常涉及在不同的文化、社会和政治背景下设计、实施和评估项目和干预措施。生成性 AI 可以通过帮助社会工作者分析背景因素、识别本地相关的策略,并评估不同环境下干预措施的有效性来支持这些努力。通过提供基于数据的见解和建议,AI 可以帮助社会工作者调整和改进他们的项目,以更好地服务于多样化的社区,并应对全球社会挑战。
生成性 AI 在社会工作中提供了有前景的机会;然而,承认这项技术的不完美至关重要。通过仔细权衡潜在的好处和弊端,我们可以确保在支持弱势群体时负责任和合乎伦理地使用它。
GPT-4 生成的不完美计算机图像
伦理考量
AI 工具并非完全客观,可能会延续偏见,从而加剧系统性歧视。因此,在处理与 AI 集成相关的伦理问题和影响时,需要保持警惕。在社会工作中,伦理考量至关重要,因为 AI 可能会影响到人们的生活决策。
社会工作者必须评估实施 AI 的伦理后果,确保其与职业的核心价值观一致:社会公正、尊重人类尊严和伦理责任。此外,社会工作者在倡导保护受到 AI 影响的弱势群体方面发挥着至关重要的作用,如残疾人士、边缘化社区以及儿童和青少年。作为更广泛讨论的引言,我强调两个与 AI 伦理相关的实际讨论点。
理解和应对模型偏见
生成性 AI 和大型语言模型从大量数据中学习,这些数据可能包含偏见。在社会工作中,我们需要预见并防范这些偏见,以避免在使用中造成伤害。社会工作者应仔细监控 AI 生成内容中的偏见,仔细检查可能支持刻板印象、传播虚假信息或表现出其他偏见的输出。
当审视 AI 伦理与促进多样性、公平性和包容性之间的紧密联系时,它们在应对 AI 系统中的偏见方面的共同目标变得显而易见。为了最小化在 AI 模型创建和实施过程中偏见出现的可能性,需要来自不同背景和视角的人员参与。鼓励在 AI 开发过程中更好地代表和参与代表性不足和边缘化社区,可以使社会工作组织和专业人士支持更具包容性的实践。
这一策略培养了伦理的 AI 实践,并有助于确保 AI 工具更好地满足各种客户群体和社区的多样化需求和经验。AI 设计师可以纳入多种视角和见解,以更好地理解和服务于广泛个体的独特需求。这种包容性方法提升了 AI 应用的整体质量,并有助于建立信任,促进 AI 开发者与他们服务的社区之间的合作。最终,这将导致更有效、公平和有益的 AI 解决方案。
隐私、机密性与透明性
在将生成式 AI 纳入社会工作实践时,保护客户隐私和机密性至关重要。用于数据分析、报告生成或客户沟通的 AI 工具必须符合严格的数据保护标准和相关隐私法律。安全存储和传输以及匿名化是防止未经授权访问的关键。社会工作者应审查 AI 生成的内容,以维护机密性和职业伦理。
透明性是使用生成式 AI 时一个重要的伦理方面。社会工作者需要与客户和利益相关者公开沟通 AI 工具的潜在影响。透明性包括解释 AI 如何参与护理,讨论其好处和局限性,以及解决相关担忧。此外,开发者和社会工作组织必须在 AI 算法的开发和使用中追求清晰度。他们应该致力于拥有透明决策过程的 AI 工具,以便社会工作者和利益相关者能够理解和评估这些工具。这种方法促进了负责任和伦理的 AI 使用,同时增强了社会工作者、客户和社区之间的信任。
下一步
正如我们在这篇导言文章中探讨的,生成式 AI,特别是大型语言模型,可以从根本上改变社会工作学生的教育经验,并增强该领域专业人士的实践。从心理健康服务和项目管理到政策分析、项目评估和社区组织,AI 技术提供了创新的工具和资源,可以增强社会工作者的能力。
为了有效利用 AI 进行社会工作,我们必须专注于将内容专业知识与技术技能相结合。虽然 AI 驱动的工具可以比社会工作者更高效地执行日常任务,但必须理解 AI 不能取代社会工作者。换句话说,社会工作者拥有 AI 所不具备的独特技能。
学生和专业人士都必须以负责任和伦理的方式对待这些技术。深入理解大型语言模型、它们的训练数据及其局限性,并磨练诸如提示工程等必要技能,可以帮助用户利用人工智能的力量,同时减轻潜在的不准确性和偏见。我将在本系列的后续文章中涵盖这些主题领域。
我是密歇根大学社会工作学教授,致力于准备学生并帮助非营利组织利用数据和信息技术更聪明地工作,而不是更辛苦。如果你有兴趣了解更多关于这些主题的内容,请关注我。
生成性 AI 对社会工作学生的介绍:第二部分
必备的知识、能力和 AI 实践
·
关注 发表在 Towards Data Science · 6 min read · 2023 年 4 月 27 日
–
图片由作者使用 Midjourney 创作。
本文是介绍生成性 AI 给社会工作学生的系列文章中的第二篇。我建议从第一篇文章开始阅读,你可以在这里找到:
一个范式转变
towardsdatascience.com
精通像 ChatGPT 这样的 AI 工具为 MSW 学生提供了一系列职业优势。对这些技术的熟练掌握简化了工作流程,提高了如案例管理、数据分析和资源分配等任务的效率和准确性。随着技术在社会工作实践中的日益融入,组织将更看重能够将传统技能与 AI 的创新能力无缝结合的专业人士。掌握 AI 工具体现了对跟进技术进步的承诺,使学生在潜在雇主面前更具市场竞争力。
AI 改变社会工作实践的能力取决于从业人员对技术的扎实掌握,包括理解 AI 模型的功能、其优缺点以及可能引入的潜在问题和偏见。尽管 ChatGPT 公开使用还不到六个月,我已经观察到学生中存在一些问题。这些问题有些源于对自身能力的过度自信,同时缺乏有效使用这些强大工具的必要技能,这是一种被称为达宁-克鲁格效应的现象。
由于社会工作课程尚未完全纳入这项技术,本文作为一个过渡措施,提供了有关生成性 AI 的基本知识、技能和实践的指导。虽然这不是一个全面的路线图,但本文提供了一个起点,随着技术的发展不断演变。通过在 ChatGPT 等 AI 应用中提高能力,社会工作学生可以为开发新颖、前沿的干预措施和实践做出贡献,定位自己为思想领袖。这种专业知识可以为职业发展、专业认可和与多学科团队的合作开辟新的机会,从而为个人和社区带来持久的积极变化。
鉴于 AI 技术的快速发展和丰富的可用资源,我避免提供具体的阅读列表,因为它会迅速过时。相反,我提供这些领域作为一般的能力范畴,您应持续关注这些领域,以获取最新的资源。
了解人工智能的工作原理
在当今快速发展的技术环境中,社会工作学生必须对人工智能(AI),特别是像 ChatGPT 这样的大型语言模型,建立一定的理解。随着 AI 工具在社会工作实践中变得越来越普及,具备这一领域专业知识的从业者能够对其使用做出明智的决策。这些知识帮助社会工作者在将其内容专业知识和人际交往技巧融入的同时,负责任地和伦理地使用 AI。
了解人工智能的一个关键组成部分是知晓其基本训练过程和数据,这有助于你在使用人工智能生成内容时做出明智的决策。这些知识还使你能够识别潜在的不准确性、偏见和过时的信息。评估人工智能模型在特定用例中的表现至关重要。对人工智能模型的失望往往源于将其用于未经过培训的任务,如研究高度专业化的话题。
值得注意的是,了解人工智能和大型语言模型并不需要数学、统计学或计算机编程背景。虽然达到熟练程度需要时间和努力,但对于任何致力于学习的社会工作学生来说,这是一个可以实现的目标。丰富的资源,包括在线课程、教程和文章,供学生按自己的节奏发展人工智能知识,无需专门的先修条件。
通过投资于这一学习过程,社会工作学生可以提升他们的技能,并为推动该领域的发展做出贡献。在这样做的过程中,他们确保利用人工智能的力量,造福个人、家庭和社区,同时与社会工作的原则相一致。
伦理问题
积极参与并保持对人工智能相关伦理问题的关注的重要性不容低估。确保负责任地使用人工智能,特别是像 ChatGPT 这样的语言模型,对于将技术与社会工作实践的核心价值观和原则对齐(如社会公正、个人的尊严和价值以及人际关系的重要性)至关重要。
人工智能使用中的伦理问题涵盖了广泛的问题,包括:
-
数据隐私: 保护客户和社区的敏感信息对于维护信任和遵守社会工作实践中的伦理标准至关重要。
-
人工智能系统中的偏见: 人工智能模型可能会无意中延续和加强现有偏见,从而导致歧视性结果。社会工作者必须意识到这些偏见,并积极努力减轻其影响。
-
潜在的误用: 人工智能工具的非预期或不道德使用可能会对个人和社区造成伤害,因此社会工作者理解并遵循适当的使用指南至关重要。
-
人工智能收益的公平分配: 确保人工智能技术的优势对所有人开放,无论社会经济地位或其他因素如何,对于促进社会公正和解决系统性不平等至关重要。
作为社会工作者,我们的责任是持续审视和质疑 AI 技术对脆弱群体的影响,确保我们使用的工具不会造成伤害或不公。深入理解这些伦理挑战使社会工作专业人员能够倡导制定和实施支持伦理 AI 使用的政策和指南。这种对伦理 AI 集成的承诺对维护社会工作的核心价值观和促进个人及社区的福祉至关重要。
提示工程
当前,“提示工程”是掌握生成型 AI 工具的关键实践技能之一。提示工程可能听起来复杂,但概念非常简单。在生成型 AI 和大语言模型的背景下,提示工程指的是设计实用的问题或输入陈述(即提示),以指导 AI 模型生成有用、相关且准确的回应。
学会编写有效的提示对于充分发挥生成型 AI 工具的潜力至关重要。精心设计的提示可以显著提高 AI 生成内容的质量,使其更加集中、准确和适用于任务。相反,设计不良的提示可能导致 AI 模型生成不相关、模糊或误导性的回应。
要设计有效的提示,必须深入理解主题内容,并预见可能在 AI 生成的内容中出现的潜在问题和不准确之处。在这方面,内容专业知识起着重要作用。拥有扎实内容知识的专业人员可以更有效地设计提示,从而生成更有意义和有见地的 AI 内容。
主题知识在设计 AI 提示中的重要性强调了生成型 AI 无法替代社会工作者。AI 模型依赖于人类专家的见解和经验来塑造其回应,并确保生成的内容与特定背景相关且适宜。社会工作者的专业知识使他们能够有效地利用 AI 工具来改进工作,同时确保 AI 生成的内容符合职业的价值观、原则和伦理指南。
随着生成型 AI 在包括社会工作在内的各个领域中扮演越来越重要的角色,提示工程正在成为专业人员需要学习的基本 AI 相关技能之一。通过掌握提示工程,社会工作者可以充分发挥 AI 工具的潜力,提高他们的实践效果,并为客户和社区带来更有效、更高效和更具伦理的结果。
设计思维
设计思维是一种方法,强调以人为中心的复杂问题解决方法。这种方法注重同理心、合作和实验,以理解相关社区的独特需求和背景。通过将设计思维原则融入生成式 AI 工具,我们可以创建更有效和量身定制的 AI 驱动解决方案,以应对复杂的社会问题。
设计思维与生成式 AI 的融合促成了一个创意环境,鼓励产生想法和探索多样的解决方案。它还支持原型设计和测试的迭代过程,允许基于现实世界反馈对干预措施进行持续的优化和调整。在利用生成式 AI 工具时,采纳设计思维心态有助于跨学科合作,并促进持续改进的文化。这使得通过从不同领域汲取广泛的视角和专业知识,开发出全面解决复杂社会问题的解决方案成为可能。
此外,通过从失败中学习并迭代解决方案,我们可以确保 AI 驱动的干预措施不断被完善和适应,以满足目标人群不断变化的需求。这种方法最终会导致更有效、更具响应性和可持续的解决方案,从根本上解决社会问题,并改善服务社区的福祉。
下一步
本系列的以下两篇文章将重点关注提升教育体验的 AI 策略和关于提示工程艺术与科学的总结文章。在准备这些文章的同时,我也在利用大语言模型积极研究 ASWB 国家社会工作执照考试的问题。这项工作与本系列和社会工作领域高度相关。你可以在这里找到我最近的相关文章:
变革的需求
[towardsdatascience.com
使用 Nougat 模型进行研究论文生成 AI
原文:
towardsdatascience.com/generative-ai-on-research-papers-using-nougat-model-38aa37a354f6
用数据做有趣的事情!
·发表于 Towards Data Science ·阅读时间 9 分钟·2023 年 9 月 20 日
–
图片由 Dan Dimmock 提供,来源于 Unsplash
介绍
最近,大型语言模型(LLMs)如 GPT-4 的进展展示了生成连贯文本的令人印象深刻的能力。然而,准确解析和理解研究论文仍然是 AI 面临的极具挑战的任务。研究论文包含复杂的格式、数学方程式、表格、图形以及特定领域的语言。信息的密度非常高,重要的语义通过格式编码。
在本文中,我将演示如何使用 Meta 的新模型 Nougat 准确解析研究论文。然后,我们将其与一个 LLM 流水线相结合,提取并总结论文中的所有表格。
这里的潜力是巨大的。许多数据/信息被锁定在未被正确解析的研究论文和书籍中。准确的解析使这些数据能够在包括 LLM 重新训练在内的许多不同应用中使用。
我制作了一段 YouTube 视频,更详细地解释了代码和我的实验。请查看 这里。
Nougat 模型
Nougat 是 Meta AI 研究人员开发的一种视觉变换器模型,可以将文档页面的图像转换为结构化文本 [1]。它将文档页面的光栅图像作为输入,并输出轻量级标记语言的文本。
Nougat 的主要优势在于它仅依赖于文档图像,而不需要任何 OCR 文本。这使得它能够正确恢复诸如数学方程之类的语义结构。它在来自 arXiv 和 PubMed 的数百万篇学术论文上进行训练,以学习研究论文格式和语言的模式。
[1] 中的下图展示了 PDF 中编写的数学方程如何在 Latex 中再现并正确渲染。
来源:Nougat 论文中的图 5 — arxiv.org/pdf/2308.13418.pdf
Nougat 使用视觉变换器编码器-解码器架构。编码器使用 Swin Transformer 将文档图像编码为潜在嵌入。Swin Transformer 通过使用移位窗口以分层方式处理图像。然后,解码器利用自注意力机制根据编码器输出自回归生成输出文本标记。
Nougat 使用随机梯度下降对页面图像和文本对进行端到端训练。数据增强技术如侵蚀、膨胀和弹性变换被用于提高鲁棒性。在训练过程中,还使用了特殊的反重复正则化来减少文本重复。
作者报告了如编辑距离、BLEU、METEOR 和 F1 分数等指标,基于学术论文的测试集。Nougat 在纯文本上表现出高准确度。错误主要集中在数学表达式上,因为 LaTeX 命令存在歧义。如下面所示,Nougat 在性能上显著超过了 GROBID 和 PDF OCR 等早期方法。
来源:表 1 Nougat 论文 — arxiv.org/pdf/2308.13418.pdf
运行和评估 Nougat 模型的输出
安装说明和运行 Nougat 模型的步骤在 Colab Notebook 这里中共享。
Nougat 小型模型在免费的 Colab T4 GPU 上运行顺畅,结果非常令人印象深刻。
运行模型的主要步骤是安装包 nougat-ocr
。然后我们使用子进程运行命令行 CLI,将下载的 PDF 传递给 Nougat 并获取其输出。
!pip install -qq nougat-ocr
def nougat_ocr(file_name):
# Command to run
cli_command = [
'nougat',
'--out', 'output',
'pdf', file_name,
'--checkpoint', CHECKPOINT,
'--markdown'
]
# Run the command
subprocess.run(cli_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return
在我的 Colab Notebook 中,我在DOLA 论文上运行了 Nougat。Nougat 令人印象深刻地捕捉了 Latex 中的数学方程。
Recent language models are consists of an embedding layer, \(N\) stacked transformer layers, and an affine layer \(\phi(\cdot)\) for predicting the next-word distributution. Given a sequence of tokens \(\{x_{1},x_{2},\ldots,x_{t-1}\}\), the embedding layer first embeds the tokens into a sequence of vectors \(H_{0}=\{h_{1}^{(0)},\ldots,h_{t-1}^{(0)}\}\). Then \(H_{0}\) would be processed by each of the transformer layers successively. We denote the output of the \(j\)-th layer as \(H_{j}\). Then, the vocabulary head \(\phi(\cdot)\) predicts the probability of the next token \(x_{t}\)
\[p(x_{t}\mid x_{<t})=\mathrm{softmax}\big{(}\phi(h_{t}^{N})\big{)}_{x_{t}}, \quad x_{t}\in\mathcal{X},\]
where \(\mathcal{X}\) is the vocabulary set.
Instead of applying \(\phi\) just on the final layer, our approach contrasts the higher-layer and lower-layer information to obtain the probability of next token. More specifically, for the lower layers, we also compute the probability of the next tokens using \(\phi(\cdot)\),
\[q_{j}(x_{t}\mid x_{<t})=\mathrm{softmax}\big{(}\phi(h_{t}^{j})\big{)}_{x_{t}}, \quad j=1,\ldots,N.\]
The idea of applying language heads directly to the hidden states of the middle layers, known as _early exit_(Teerapittayanon et al., 2016; Elbayad et al., 2020; Schuster et al., 2022), has proven to be an effective inference method even without special training process (Kao et al., 2020), as the residual connections (He et al., 2016) in transformer layers make the hidden representations gradually evolve without abrupt changes. Using \(q_{j}(x_{t})\) to represent \(q_{j}(x_{t}\mid x_{<t})\) for notational brevity, we then compute the probability of the next token by,
\[\hat{p}(x_{t}\mid x_{<t}) =\mathrm{softmax}\big{(}\mathcal{F}\big{(}q_{N}(x_{t}),q_{M}(x_{t })\big{)}\big{)}_{x_{t}}, \tag{1}\] \[\text{where}\quad M =\operatorname*{arg\,max}_{j\in\mathcal{J}}\;d\big{(}q_{N}(\cdot ),q_{j}(\cdot)\big{)}.\]
Here, layer \(M\) is referred to as the _premature layer_, while the final layer is referred to as the _mature layer_. The operator \(\mathcal{F}(\cdot,\cdot)\), to be elaborated further in Section 2.3, is used to contrast between the output distributions from the premature layer and the mature layer by computing the difference between two distributions in the log domain. The premature layer is dynamically selected in each decoding step using a distributional distance measure \(d(\cdot,\cdot)\) (we use the Jensen-Shannon Divergence) between the mature layer and all the candidate layers in \(\mathcal{J}\). We discuss \(d(\cdot,\cdot)\) in more detail in Section 2.1 and Section 2.2\. The motivation for selecting the layer with the highest distance \(d(\cdot,\cdot)\) as the premature layer is to maximize the difference between the mature/premature layers.
我还发现表格在 Latex 中捕捉得很好。表 1 被准确地转换为 Latex,如下所示!
\begin{table}
\begin{tabular}{l c c c c c} \hline \hline \multirow{2}{*}{**Model**} & \multicolumn{4}{c}{**TruthfulQA**} & \multicolumn{2}{c}{**FACTOR**} \\ \cline{2-6} & **MC1** & **MC2** & **MC3** & **News** & **Wiki** \\ \hline LLaMa-7B & 25.6 & 40.6 & 19.2 & 58.3 & 58.6 \\ + ITI (Li et al., 2023) & 25.9 & - & - & - & - \\ + DoLa & **32.2** & **63.8** & **32.1** & **62.0** & **62.2** \\ \hline LLaMa-13B & 28.3 & 43.3 & 20.8 & 61.1 & 62.6 \\ + CD (Li et al., 2022) & 24.4 & 41.0 & 19.0 & 62.3 & 64.4 \\ + DoLa & **28.9** & **64.9** & **34.8** & **62.5** & **66.2** \\ \hline LLaMa-33B & 31.7 & 49.5 & 24.2 & 63.8 & 69.5 \\ + CD (Li et al., 2022) & **33.0** & 51.8 & 25.7 & 63.3 & **71.3** \\ + DoLa & 30.5 & **62.3** & **34.0** & **65.4** & 70.3 \\ \hline LLaMa-65B & 30.8 & 46.9 & 22.7 & 63.6 & 72.2 \\ + CD (Li et al., 2022) & 29.3 & 47.0 & 21.5 & 64.6 & 71.3 \\ + DoLa & **31.1** & **64.6** & **34.3** & **66.2** & **72.4** \\ \hline \hline \end{tabular}
\end{table}
Table 1: Multiple choices results on the TruthfulQA and FACTOR.
生成 LLM 总结 Latex 表格
有许多示例展示了 LLM 总结文本,包括研究论文。但几乎总是,表格和数学方程中的数据要么解析不正确,要么未包含在总结中。我现在测试一下像 GPT3.5 这样的模型在 Latex 表格上的表现如何。
我在这里使用 Langchain 编写了一个链式流水线,执行以下操作:
-
识别研究论文中的所有表格
-
读取 Latex 并理解表格
-
创建一个输出字典,总结每个表格
完整的源代码包含在 Colab Notebook 中这里。如下面的代码片段所示,我们对 LLM 的提示是识别所有表格,总结它们,并以结构化格式分享结果。
from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
context_template="You are a helpful AI Researcher that specializes in analysing research paper outputs presented to you in Latex"
system_message_prompt = SystemMessagePromptTemplate.from_template(context_template)
human_template= """
Please extract all tables referenced in this paper. The tables are in Latex format. Summarize the tables one by one.
Each summary should be 4-5 sentences long. Include numbers in summary where you can. Make a dictionary with table number, table name and summary of that table.
PAPER: {paper_content}
"""
human_message_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template=human_template,
input_variables=["paper_content"],))
chat_prompt_template = ChatPromptTemplate.from_messages([system_message_prompt,
human_message_prompt])
chat = ChatOpenAI(model_name="gpt-3.5-turbo-16k",
temperature=0.2)
summary_chain = LLMChain(llm=chat, prompt=chat_prompt_template)
output = summary_chain.run(noref_content)
pprint.pprint(output)
我之前对 LLM 的表现不太确定,所以不得不说,我对回复的质量感到震惊。论文中有 6 个表格,所有表格都被正确识别了。然后每个表格都被很好地总结了。
对上述提示的 LLM 回应如下。
('Dictionary of Tables:\n'
'\n'
'Table 1:\n'
'- Table Number: 1\n'
'- Table Name: Multiple choices results on the TruthfulQA and FACTOR '
'datasets\n'
'- Summary: This table presents the results of multiple choice tasks on the '
'TruthfulQA and FACTOR datasets. It compares the performance of different '
'models, including the baseline, Inference Time Intervention (ITI), and DoLa. '
'The table shows that DoLa consistently outperforms the other methods, '
'improving the truthfulness and informativeness scores.\n'
'\n'
'Table 2:\n'
'- Table Number: 2\n'
'- Table Name: Open-ended generation results on TruthfulQA, StrategyQA, and '
'GSM8K\n'
'- Summary: This table summarizes the results of open-ended generation tasks '
'on the TruthfulQA, StrategyQA, and GSM8K datasets. It compares the '
'performance of different models, including the baseline, Contrastive '
'Decoding (CD), and DoLa. The table shows that DoLa consistently enhances the '
'truthfulness and informativeness scores, outperforming the other methods.\n'
'\n'
'Table 3:\n'
'- Table Number: 3\n'
'- Table Name: Multiple choices results on the FACTOR dataset\n'
'- Summary: This table presents the results of multiple choice tasks on the '
'FACTOR dataset. It compares the performance of different models, including '
'the baseline, DoLa with dynamic premature layer selection, and DoLa with '
'random layer selection. The table shows that DoLa with dynamic premature '
'layer selection performs better than the other methods, improving the '
'truthfulness and informativeness scores.\n'
'\n'
'Table 4:\n'
'- Table Number: 4\n'
'- Table Name: Comparison of MPT-7B and modifications on TruthfulQA, FACTOR, '
'and CoT datasets\n'
'- Summary: This table compares the performance of the MPT-7B model and its '
'modifications on the TruthfulQA, FACTOR, and CoT datasets. It shows that '
'DoLa improves the truthfulness and truthfulness+informativeness scores on '
'most datasets, indicating the potential of DoLa to generalize across '
'different transformer models.\n'
'\n'
'Table 5:\n'
'- Table Number: 5\n'
'- Table Name: Qualitative study for LLaMA-33B on TruthfulQA\n'
'- Summary: This table presents qualitative examples from the TruthfulQA '
'dataset, comparing the answers generated by the baseline and DoLa using the '
'LLaMA-33B model. It shows that DoLa produces more truthful and informative '
'answers compared to the baseline.\n'
'\n'
'Table 6:\n'
'- Table Number: 6\n'
'- Table Name: Averaged decoding latency per token in milliseconds\n'
'- Summary: This table shows the average decoding latency per token in '
'milliseconds for the baseline and DoLa. It indicates that DoLa adds a small '
'additional latency to the decoding process, making it a practical and '
'efficient decoding strategy.')
阅读这些示例时,我的观察是:
-
每个表格都被识别出来了。模型准确理解了表格的行和列
-
总结捕捉了表格中的结论
-
总结表明,模型使用了论文中的信息来理解表格。对于表格 3,模型准确理解了该表格比较了 DOLA 与随机层选择与过早层选择,即使表格本身并没有提到这一点
-
我本来希望在表格的总结中看到更多的数字和统计数据,但模型没有输出它们。附带说明,我还测试了 Anthropic.AI 的 Claude2,它能够总结表格,并提及关键的统计结论,呈现了更优的回复
我的代码现在还涵盖了上述流程的一个示例,搜索所有数学方程并解释它们。这里也有令人印象深刻的初步结果。
结论
在这篇文章中,我展示了 Nougat 模型如何直接从图像中解析复杂的研究论文。Nougat 克服了一个关键挑战——理解论文格式中编码的语义。
我展示了一个端到端的流程,通过 Nougat 解析论文,提取表格,并使用 LLMs 总结它们。Nougat 以高准确率提取了文本、数学、表格和格式。下游的 LLM 成功总结了提取的表格,专注于关键比较。
Nougat 帮助克服了 PDF 文本和当前最佳解决方案如 pyPDF 和 GROBID 的局限性。我们现在可以更好地理解论文中的信息。总体而言,这展示了生成性 AI 模型如何在解锁所有困于非结构化格式中的知识方面取得进展。
我经营自己的机器学习咨询,帮助客户进行生成性 AI 应用。如果你有兴趣合作,请通过 priа@deeplearninganalytics.org 给我发邮件。
参考文献
[1] Blecher, Lukas, et al. “Nougat: Neural Optical Understanding for Academic Documents.” arXiv preprint arXiv:2308.13418 (2023).
[2] Langchain Source Documentation — python.langchain.com/docs/get_started/introduction
生成式 AI 产品策略:如何构建下一代 AI 产品
垂直 AI 产品与水平 AI 产品以及可防御的商业护城河
·
关注 发表在 Towards Data Science ·12 分钟阅读·2023 年 1 月 25 日
–
图片由作者使用 Midjourney 生成
人工智能在 2022 年取得了如此显著的进展,以至于世界似乎终于接受了这一技术现已普及到普通人日常使用的程度。
生成型 AI 模型如 GPT3 和 Stable Diffusion 将使我们能够以以前难以想象的规模和速度进行创作。这将从根本上改变人类创造价值的方式。我们用于创作的每一个数字工具——从编码环境到视频编辑器到 3D 建模软件——都将经历剧烈的变化。
虽然展示 AI 生成的艺术作品令人印象深刻,但演示并未考虑实际的专业工作流程和行业需求。通过通用接口访问这些模型对于实验和创建社交媒体帖子是很好的,但对于不同领域的专业人士有效地完成他们的工作还远远不够。为此,我们需要将这些模型融入产品中,使其在专业工作流程中提供实际的效用。
当我作为一个对时尚业务知之甚少的人,尝试使用 Stable Diffusion 进行时尚设计时,我意识到这一点。对我来说,为时尚设计师提供一个无限创意的生成 AI 产品似乎是一个显而易见的想法。怀着热情,我使用 Stable Diffusion 生成了这张裙子图像,并与我的时尚设计师朋友分享了。
这是一张由作者使用开箱即用的 Stable Diffusion 生成的裙子图像。
“你能用这个想法设计一件这样的新裙子吗?”我问。她的回答是一个令人失望的大“不能”。除了或许可以用作灵感的情绪板之外,这张图像对她完全没有用处。
尽管 Stable Diffusion 拥有强大的生成能力,但其当前格式下的输出对时尚设计师来说并不十分有用。要让 AI 实际上带来价值,我们需要考虑如何以实际的方式利用其输出。这可能涉及对模型输入的预处理、对输出的后处理,或将其与人工生成的内容相结合。关键在于利用 AI 的独特能力,专注于解决用户的特定实际问题。让我们探索如何让这一看似神奇的新技术为我的时尚设计师朋友提供帮助。
AI 产品策略框架
对于正在开发 AI 产品的创始人和产品领导者,我推荐两种广泛的方法——纵向和横向。纵向方法涉及为特定行业或细分市场的创意过程构建 AI 辅助的软件产品。时尚印刷设计和家具设计就是一些例子。每个细分市场都有不同的需求和工作流程,我们必须牢记这一点。
水平方法涵盖了跨行业需求的产品,比如平面设计、广告设计或法律合同起草。广告创意在从汽车到食品等各行业都是必需的。在这里,产品不需要行业特定的工具。最重要的是一个出色的用户界面,使用户可以在比以前更短的时间内进行平面设计工作,并且质量更高。
垂直 AI 产品
在为特定行业构建 AI 支持的产品的同时,除了部署最先进的 AI 模型,还需要构建它们特定工作流程所需的工具。下面是为时尚业生成面料印花设计的 AI 产品需要涵盖的内容-
-
用户必须能够将情绪板图像与文本提示一起作为输入提供给生成式 AI 扩散模型。情绪板和提示文本通常是通过当前高销售趋势的数据分析得出的。
-
AI 模型必须生成适用于整体印花的无缝纹理。无缝纹理是一种图像,可以在自身的上方、下方或侧边放置,而不会在图像的副本之间产生明显的接缝、连接或边界。以下是我通过调整稳定扩散代码生成的无缝纹理的示例图像。该图像由四个生成的图像并排放置而成。
作者通过微调稳定扩散生成的无缝面料印花图案
-
创造力是一个迭代的过程。设计师应该能够通过手动编辑或者在后续的 AI 生成中引入特定的修改来迭代地修改每一代 AI 的输出。
-
需要由不同角色的用户进行多层次的审批。设计主管可能需要签署最终设计。
-
最终输出的分辨率需要放大到足够高的水平。
-
最后,输出必须转换为可以发送给布料打印机的矢量文件格式。
时尚设计师需要围绕生成式 AI 模型的输出构建这种面向行业的工具。
考虑另一个 AI 辅助室内设计的例子,它通过生成图像展示了房间如何以特定风格进行改造。以下是专业室内设计师在使用AI 室内设计工具时分享反馈的文章摘录 。
当我们要求其创建一个“波西米亚”客厅时,霍勒斯指出算法选择了她为希望看起来相同的客户使用过的类似调色板。“我可以看到将其用作开发情绪板图像的工具,”她补充说。“所有的参考都很准确。”
Horace 说:“旁边有一个奇怪的自助餐桌,而且不知为何有两个咖啡桌,这看起来并不实用。”谈到一间中世纪风格的客厅时他表示:“外观是对的,但你不能向客户展示这个,比如,‘嘿,这是你的房间!’”
Interior AI 的空间规划技能有时还有待改进——它的浴室设计并不总是包含马桶。
这个工具经常会生成一个房间的基本近似图,但改变了比例、去掉了窗户或将天花板降低了几英尺。
不错的浴室,但马桶在哪里?作者使用 Midjourney 生成的图像
从设计师的评论中可以清楚地看出,室内设计产品的 AI 模型需要在某些无法修改的约束条件内操作。他们的评价可以简洁地总结为一句话——
在依靠大量的 2D 灵感图像来形成对设计的理解时,它对风格的把握非常准确,但对功能的掌握则较为松散。
请注意,时尚设计师的问题和约束条件与室内设计师的完全不同。尽管如此,双方都需要针对其行业的更好功能性,而不仅仅是关注风格。
对于像 Stable Diffusion 这样的 AI 模型来说,在与行业相关的数据集上进行微调至关重要。以时尚印刷设计为例,设计师可能希望根据特定的风格、色彩搭配或情绪生成图案。通过使用少量示例对生成模型进行微调,将有助于生成更相关的设计。即使是其他深度学习模型,如用于对象识别和分割的模型,也可能需要微调,如果这些对象在开箱即用的预训练模型的训练数据中不存在。最终,我预计模型微调工具将集成到每个产品中。很可能会有一个大型公司出现,提供模型微调的 API 服务。
垂直 AI 产品中的护城河
作者使用 Midjourney 生成的图像
一个产品或公司不能仅依靠 AI 模型作为唯一的竞争优势。AI 研究论文和实现代码通常是公开的。OpenAI 发布了用于文本到图像生成的 Dall-E 和 Dall-E 2 模型,随后开源的 Stable Diffusion 模型也被发布。AI 吸引了一些世界上最优秀的头脑,行业进展迅速。可以保证,总会有人最终发布比你目前实现的模型更好、更先进的新模型。
为特定行业开发 AI 产品的一个巨大优势是更容易创建一个防御性的商业护城河。为该行业构建的工具给客户带来的便利,也使得他们不太可能因为新模型的发布而离开。这为企业提供了时间来将 AI 模型输出提升到最先进的基准水平。
横向 AI 产品
当涉及到用于图像编辑或图形设计等行业的产品时,新型 AI 基础产品面临着来自现有巨头的艰巨挑战。这是因为像 Photoshop 这样的产品以及其他产品正在迅速引入由 AI 驱动的功能。依赖 Photoshop 广泛图像编辑工具的专业人士会更愿意使用 Photoshop 中的 AI 功能,而不是切换到其他产品。许多构建横向 AI 产品的初创公司可能因为现有巨头的大规模分发而短命。如果 AI 模型被集成到人们已经大量使用和支付的工具中,他们几乎没有动机转向其他工具。Notion 是一款拥有 2000 万用户的笔记应用,最近推出了一个 AI 写作助手。新的 AI 驱动的文字处理器可能会因为 Notion 现有的大量用户基础和网络效应而难以竞争。
任何新的横向 AI 产品的机会在于为不熟悉该领域的用户提供好、便宜 和 快的输出。流行的笑话是,与设计师合作时,你只能获得三个中的两个。
要取得成功,任何新的横向设计 AI 产品必须为非设计师用户提供三者俱全的功能。显而易见,该产品应易于使用。否则,用户不太可能快速获得高质量的输出。换句话说,机会在于降低进入这一创意领域的门槛,这个领域之前由熟练的专业人士主导。
Canva 是一个很好的例子,展示了这一点。Canva 使得一个会计人员能够创建一个好的活动海报。他们证明了许多设计工作,不需要设计师的高级工具,如 Photoshop。Canva 通过构建一个简单的产品,提供模板和库存内容,使得非设计师能够快速、便宜地创建出好的内容。AI 给人的感觉就像是 Canva 的再次出现,但这次是适用于每个创意领域,并且规模更大。像 GPT-3 和 Stable Diffusion 这样的生成性 AI 模型特别相关,因为非设计师用户不需要从零开始。相反,仅凭一个文本提示,他们就能获得一个远远超出他们自己所能创造的起点。
用户界面在经过大量实验后可能会经历几次根本性的变化。在许多话题上,ChatGPT 的对话界面比 Google 搜索更快速地返回准确的答案。对话界面在各种应用中看起来非常有前景。你对设计师说“颜色需要更蓝”的渴望最终会得到满足。
对于生成模型,艺术风格预设、预先调整的模型以及即席调整能力可以使用户对输出结果有更多控制。
横向 AI 产品的护城河
部署在高质量大数据集上训练的最佳表现模型对横向 AI 产品非常有利。由于这些产品需要在各个行业的用户中运行,投资 AI 研发以保持最先进的模型性能可能是一个强大的护城河。然而,由于竞争激烈和大量资金流入 AI,这不能成为唯一的护城河。通过用户体验、产品定位、分销、社区、网络效应、团队执行力以及快速响应用户反馈等方式可以建立额外的护城河。
RunwayML 是一个由 AI 驱动的视频创作和编辑工具,表现出色。RunwayML 通过从擦除和替换对象到自动化视频运动跟踪等功能,降低了内容创作的门槛。他们对 Stable Diffusion 的贡献意味着他们正在投资推动最先进 AI 的边界。通过这些方法的结合,RunwayML 获得了大量客户,并在其业务周围建立了长期的护城河。
来源: RunwayML 网站
Canva 的成功很大程度上归因于其作为非设计师工具的定位护城河。这个客户群体与 Adobe Photoshop 和 Illustrator 的目标用户群体不重叠,后者由熟练的设计师使用。深刻理解和接受其定位帮助 Canva 推出了设计师在培训中学习的功能,但普通用户不了解的功能,例如颜色调色板生成器和字体建议。
建立一个蓬勃发展的社区是建立护城河的一种优秀且被低估的方法。积极参与和发展社区可以提供深刻的产品反馈。这在构建适合非专家的新用户界面的功能时尤其有用。通过社区互动获得的快速反馈循环可以促进产品的快速迭代。
生成 AI 产品的经济影响
人工智能工具用于内容推荐、图像重照、光学字符识别和语音转文字等应用已经存在了几年,并已经成为我们每天使用的产品的一部分。活跃地协助我们的创意过程的人工智能产品潮流刚刚开始。每个人都在关心但似乎没有一个明确答案的问题是,这会对人类的工作岗位产生什么影响?这是一个非常困难的问题,没有一个单一的答案。不过,我可以肯定的是答案既不在于人工智能完全取代人类,也不在于人类的思维不可替代。在我看来,不可能有一种能经得住时间考验的确定答案。细微的答案将在两者之间,根据技术随时间的发展而不断在这两个极端之间移动。
数字艺术家一段时间以来一直在 Photoshop 中使用由人工智能提供动力的功能,例如智能背景去除和内容感知填充。它只是在幕后,没有公开宣传为人工智能。如今,生成式人工智能扩散模型能够从创意过程的第一步(让我们考虑第 0 步为决定为什么和什么来创作)开始做出贡献。虽然人工智能之前只对创意产出做出了少量贡献,但随着时间的推移,它将会做出更多的贡献。我看到这些新创作工具有两个明显的后果:
-
它们将大大降低进入许多领域的门槛,从而导致创作者数量激增
-
它们将使创作者在给定时间内产生更大量的产出
第一个后果意味着更多的人类就业、经济活动和货币的提升。突然间,好莱坞的工具就在每个人的口袋里。第二个后果意味着较少的人可以做许多人的工作,导致雇主裁员。这会导致灾难性的大规模失业吗?或者这些人也会成为独立的创作者?这些事情是极难预测的。每个人都认为人工智能会消灭重复的体力劳动。有创意的人是安全的。没有人认为人工智能会写代码或创作艺术。
世界将分为使用人工智能和不使用人工智能的人。
那些构建这些产品的人将获得巨大的回报。我们正处于一个很可能被视为人类历史上最具决定性的时期的边缘。
如果你是一位致力于建立人工智能产品的产品经理,我已经编写了一份由 3 部分组成的实用指南,告诉你如何执行:
-
第一部分**😗*基础知识——什么使人工智能产品管理与众不同,你是否应该在项目中使用机器学习,人工智能产品经理的先决知识
-
第二部分: AI 团队管理、产品规划和开发战略
-
第三部分: 模型选择、部署到生产环境、模型维护和成本管理
生成模型与噪声和结构的舞蹈
原文:
towardsdatascience.com/generative-models-and-the-dance-of-noise-and-structure-e72fe7494f4f
数字梦想者构建指南
·发布于 Towards Data Science ·阅读时间 21 分钟·2023 年 10 月 7 日
–
我喜欢想象一下,文艺复兴时期意大利的居民,充满了对人类想象力和理性可能性的热情,会对我们今天的技术感到最为震惊的是什么。莱昂纳多·达·芬奇,曾梦想飞行器,肯定会对一架空中飞翔的空客 A380 印象深刻,乘客们舒适地坐在座椅上,看电影,抱怨 Wi-Fi 不够快。
在所有在中世纪看来如同巫术的技术中,生成式 AI 的奇迹可能是最像巫术的。如果我展示给莱昂纳多·达·芬奇一台能够在几秒钟内以他的风格绘制女性肖像的设备,他在劳作了无数年之后对《蒙娜丽莎》肖像的反应会是什么?瞧:
由 DALL-E 绘制的达·芬奇风格的女性肖像。
虽然诚然,这位女性并没有像真正的蒙娜丽莎那样以诱人而神秘的微笑来展现自己(且经细致审视显得有些滑稽),但我们许多人已经遇到了令人惊叹的 AI 生成实例:从 超现实的图像到令人毛骨悚然的深度伪造的声音,甚至是由 AI 编写的完整文章。
生成性 AI 模型是梦想家的硅基等效体:它们能够从无到有地构想事物,从噪声中赋予意义。它们学会了在秩序与无序之间起舞。它们已经改变了我们对人类创造力的看法,并开启了数千种新应用的门扉,威胁到整个行业并创造了新的行业。
我们刚刚起步,这些模型中的大多数仍处于初期阶段。通过 ChatGPT 的写作、DALL-E 和 Midjourney 生成的图像,以及最近像 Stability AI 的StableAudio这样的音乐生成模型,我们正迎来一个时代,在这个时代,我们每天输入大脑的感官信号越来越多地被 AI 以某种方式改变甚至完全生成。
“一个画家在画布的左侧是混乱噪声的溅射,逐渐转变为右侧的结构化、美丽的数字城市。艺术风格应为半现实主义,带有一点超现实主义。光线应柔和而弥漫,营造出梦幻般的氛围。” 由 Chat-GPT 提供的提示,由 DALL-E 绘制的画作。
在这篇文章中,我想揭开这个神奇黑箱的面纱,深入探讨几类生成模型(Helmholtz 机、变分自编码器、归一化流、扩散模型、GAN 和基于 Transformer 的语言模型)的基本机制,揭示它们的内部工作原理,并探讨它们在神经科学和认知学中的起源和联系。这个话题显然太广泛,无法在一篇文章中涵盖(尽管文章比预期的要长得多),所以我试图在一些技术细节、高层次概述、连贯的叙述和进一步阅读的来源之间找到平衡,希望每个人都能从中找到一些有用的信息。
“我无法创造的,我不能理解。”
— 理查德·费曼
我们从哪里开始?
以这句常被引用的费曼名言开头有些陈词滥调,但这位大师确实有他的道理:理解与创造行为相关,因此在机器学习的早期,构建能够理解的模型也就与构建能够创造的模型相关。图灵的著名测试(也称为模仿游戏)可以看作是这个观点的一种变体:如果你成功地伪造了智能,那么你很可能发现了类似真实智能的东西。
在早期生成模型中,两个最重要的模型是 Boltzmann 机和 Helmholtz 机。
赫尔姆霍兹机器特别有趣,因为其原理与德国物理学家赫尔曼·冯·赫尔姆霍兹的极具先见之明的视角紧密相关。赫尔姆霍兹在 19 世纪末意识到,知觉更好地描述为一种从感官数据和先验知识中进行无意识推理的过程,而不是对客观现实的客观反映:认知本质上是概率性的,并受到噪声的影响,并且受到我们的期望和偏见的强烈塑造。他的观点在现代神经科学中越来越相关,例如通过卡尔·弗里斯顿的自由能原理(他明确引用了赫尔姆霍兹机器作为灵感来源)和贝叶斯大脑假说。
根据自由能原理,大脑与外部世界在一个行动-感知循环中互动,尝试从其感觉中推断世界的隐藏状态,并通过行动使其预测成真。Kfriston, CC BY-SA 3.0 <creativecommons.org/licenses/by-sa/3.0
>, 通过维基媒体公用领域
从贝叶斯的角度来看,这个想法是大脑维持一个世界的生成模型p(x,z),其中x是感官观察结果,z是这些感官观察结果的隐藏原因/潜在解释,大脑试图捕捉这些解释,反映了世界和世界模型中的不确定性。正如我们将看到的,许多生成模型,但不是所有,都被表述为概率性潜变量模型。
在贝叶斯语言中,给定这样的模型,这归结为潜在原因的先验分布p(z)(如果我住在纽约市,我观察到狮子的先验期望小于观察到狗的期望),观察结果**p(x)**的整体可能性,以及感官观察和隐藏原因之间的关系。
解析 x 和 z 之间的关系是许多生成建模的核心。
他们的关系反映在两个重要量上:后验概率p(z∣x)和可能性p(x|z),它们根据贝叶斯著名定律联系在一起:
后验概率p(z∣x)给出了在给定观察值的情况下,潜在原因的概率。由于一个称为不可处理性的问题,我们通常无法访问这一点:根据贝叶斯定理,我们需要 p(x)来计算它,这要求我们遍历所有可能的潜在原因,并检查它们如何解释x:
如果世界的模型复杂,这些是高维积分,因此这既不高效也完全不可能。
推断后验概率是许多生成模型的根本挑战。
在 Helmholtz 机器中,后验 p(z∣x) 是通过从数据中直接估计的,这个过程称为识别,通过学习一个近似后验 q(x|z) 并尽可能接近真实的 p(z∣x)。
估计似然 p(x|z) 的反向方向通常容易得多:给定一个特定的潜在变量 z,它只是告诉我们观察到的 x 的可能性。为此,我们通常不需要积分任何东西,只需直接运行模型即可。
似然性由生成网络参数化:给定一个 z,我们如何生成一个 x?如果我从一个隐藏原因开始,它对世界的影响会是什么样的?如果我想象一个人,那个人的面貌或声音会是什么样的?
在大多数生成模型中,这部分在实践中是最相关的(因为它生成图像/文本/音频)。一旦我们了解了 z 到 x 的映射是什么样的,我们可以通过采样一个 z 并通过生成网络传递它来生成样本。
在 Helmholtz 机器中,这两个方向都是通过神经网络参数化的,这些网络通过 Wake-Sleep 算法 交替训练,该算法受人类认知中类似过程的启发,在生成网络(觉醒)中比较生成样本与真实世界,并在识别网络(梦境)中将自身创作映射回其潜在状态。
识别网络 z ← x: q(z|x)
生成网络 z→ x: p(x|z)
潜在空间的结构通常有助于解释所学模型。 解缠潜在表示 并将其与可解释特征对齐在许多实际应用中都很重要,但也更普遍地用于实现更具解释性的模型。
以一个熟悉的例子来说,假设我们正在构建一个人脸图像的生成模型。按照 Helmholtz 机器的结构,我们将图像映射到潜在空间。然后我们可以尝试发现该潜在空间中有趣的变化轴。
一个有趣的变化轴可能与图像中人物的年龄有关。然后我们可以在潜在空间中强加约束(无论是在监督设置中通过提供带有年龄标签的数据,还是在无监督设置中通过识别学习到的潜在特征中的年龄,假设它导致显著的变化),以便其一个方向 z_age 编码嵌入图像上显示的年龄。
知道这个方向后,可以用来改变图像的年龄。如果另一个方向z_beard编码了有胡须的特征,我可以通过识别网络 q(z|x) 对图像 x 进行编码,得到一个 z,将其转换为 z’=z+az_age+bz_beard,并通过生成模型 p(x|z’) 发送回去,以查看一个有胡须、年长的自己版本。
像 OpenAI 的 GLOW 这样的模型让你在他们的网站上玩耍,但你可能已经熟悉了这种应用,例如在 Faceapp 中。
所有生成建模归结为(或多或少相关的)这种变体,尽管自 Helmholtz 机器时代以来它已显著发展,但在概率框架中捕获和重现数据的基本结构的理念依然存在。我将使用这些概念来解释过去十年中引起 AI 研究关注的一些最常见的生成模型版本。
变分自编码器(VAEs)
现在地球是空虚和混沌的,上帝说:“要有光,”就有了光。
— 创世记 1:1–5 (NIV)
VAEs 在 2013 年由 Kingma 和 Rezende 同时提出,并且在广泛的应用中找到了用途(从去噪到压缩到时间序列数据)。
这些方法是一个自然的起点,因为它们在精神上最接近 Helmholtz 机器:它们使用识别(编码器)和生成(解码器)网络。正如之前提到的,识别网络通过近似密度 q(z|x) 来近似 后验密度 p(z|x)。
VAEs 的训练目标是最小化负 证据下界(ELBO),这归结为找到一个尽可能接近真实后验 p(z|x) 的近似密度 q(z|x)。
在这里,我们通过以一种可以通过基于梯度的方法训练的方式对分布 q(z|x) 进行参数化来简单地近似分布。参数化分布可能有很多细微之处,但我们通常假设它近似为高斯分布,这意味着它具有均值 μ 和协方差 σ,构成了模型的自由参数。这些参数由神经网络直接学习(将训练数据 x 输入到神经网络中,输出为 μ)。
在 VAEs 中,近似后验 q(z|x) 用于绘制一个或多个随机样本,然后将这些样本代入 ELBO,ELBO 定义为从 q 中样本的期望值:
由于(负)ELBO 构成了损失,我们可以计算梯度,这反过来又让梯度下降发挥其魔力。
由于后验可能相当复杂,在实践中可能难以从中计算出良好行为的梯度,因为它们往往有很高的方差,需要许多样本。VAEs 核心的重参数化技巧巧妙地绕过了这个问题,通过将采样分为两个过程:
-
首先,从标准高斯分布 N(0,1) 中采样 ϵ。
-
然后,使用均值μ和标准差σ来变换ϵ,得到样本z=μ+σ×ϵ。
我发现重新参数化技巧特别优雅的一点是,它将每个生成过程的两个核心组件分开,无论是生成手写数字的更平凡任务,还是《圣经》引述中天与地的隐喻创建:一个由初始样本ϵ的“无形且空虚”噪声给出的随机组件,通过复杂的变换最终获得意义,通过解码器在观察到的世界中创造出一个模式x。
我在 MNIST 数据集上训练了一个简单的 VAE,绘制了一个随机初始状态,并通过解码器生成了这个看起来有点像 9 的图像。解码器隐式理解数据的结构,并从一个低维潜在状态中解码它。MNIST 数据集通过知识共享署名-相同方式共享 3.0许可证提供。
直观地说,ELBO 由重建项和熵项组成。由于熵在信息理论的世界中衡量信息内容的不可预测性或随机性,因此熵自然会在训练过程中起到正则化作用,在优化过程中权衡结构和噪声。如果 VAE 过于关注重建,它可能会过拟合数据,在潜在空间中捕捉到训练数据中的每一个细节(包括噪声)。但如果它过分关注熵,它可能会得到一个过于简单的潜在空间,无法捕捉数据的细微差别。
近似后验的熵与其协方差结构σ相关,这为我们提供了一个衡量初始样本中“无形且空虚”噪声(编码解释中的不确定性)剩余量的度量。如果我们想让整个过程变得确定性,我们可以简单地将σ设置为零,这样所有的不确定性都会被消除。
在一个确定性宇宙中,实际上没有真正的噪声,只有我们的模型无法捕捉的东西,或者我们缺乏必要的信息(我爱噪声,已经在这里写了一整篇文章)。正如乔治·博克所指出的:“所有模型都是错误的,有些是有用的”,而 VAEs 学会在过度自信和不足自信之间取得平衡。
这个组织原则有助于解释为什么 VAEs 在像降维(将输入数据中的重要信息与不重要信息分离)这样的任务上自然表现优异,以及去噪。正如前面提到的,VAEs 还可以实现潜在空间的结构化表示,从而产生可解释的特征。
对于在 MNIST 上训练的 VAE,采样 2D 潜在空间的网格会导致不同数字的连续变换。由我生成的, 基于这里提供的图形代码。
归一化流 (NF)
我听到有人称 NFs 为“强化版的重参数化技巧”,我非常喜欢这个描述。归一化流接管了 VAEs 的空白,通过将识别形式化为流的应用来完成。
NFs 通过一系列可逆变换将简单的概率分布(例如 VAEs 中通常使用的标准高斯分布 N(0,1))迭代地转换为更复杂、更精细的分布。
归一化流通过应用一系列可逆变换,将样本 z0 从简单分布变形为潜在复杂的分布。 janosh,MIT <opensource.org/licenses/mit-license.php
>, 通过 Wikimedia Commons
VAEs 使用固定的分布和学习到的变换(均值和方差)将随机性与结构分开,而 NFs 则动态地塑造分布本身。它们通过跟踪雅可比行列式来实现这一点。这可以衡量变换的体积变化,例如,它如何收缩或拉伸空间,确保整个潜在空间以一致的方式变化。
如同 VAEs 的情况一样,一块无形的东西被塑造成形状。
关于 NFs 至少有两件很酷的事:它们是可逆的,因此允许在两个分布之间进行双向映射,这在许多情况下非常有用,例如,当试图估计密度时(因为一旦你映射回标准高斯分布 N(0,1),这通常比处理复杂的不可处理后验要容易得多),或者用于 异常检测,其思想是筛选出在学习到的分布下概率较低的数据。
OpenAI 的 GLOW,我之前提到过,也利用这种可逆性来操控潜在空间中的特征,如微笑、年龄或胡须,并几乎实时地获得修改后的图像。
另一个很酷的特点是它们对不同几何形状和流形的适应性。一个经典的例子是对 球面对称性 的应用,使得 NFs 能够形成存在于球面上的潜在表示。由于尽管有些观点相反,地球可能是球形的,因此球面对称性非常有用,例如在运行地球天气系统的模拟时。
扩散模型
从数据中创建噪声很简单;从噪声中创建数据是生成建模。
展开来说,扩散模型是过去几年中最成功的生成模型之一。尽管它们早在 2015 年就由Sohl-Dickstein 等人提出,但它们在图像生成方面的成功使其成为焦点,为 DALL-E、Midjourney 或 Stable Diffusion 奠定了基础。虽然它们的基本架构相当不同,但在概念上它们仍与 VAEs 和正常流相关。
扩散模型将生成过程分解为几个步骤:在每一步中,训练样本都会被噪声扰动。模型的目标是学习如何从样本中去除这些噪声。如果我之前没有足够清楚地说明噪声的迷人之处,那么在扩散模型中,它再次成为了主角。
在训练过程中,噪声会被反复添加到训练数据中。以图像为例,模型要么学习去除微小的噪声并打磨最终细节,要么在一个被扭曲的图像中完善模糊的形状:
稳定扩散中的生成过程。Benlisquare,CC BY-SA 4.0 <creativecommons.org/licenses/by-sa/4.0
>, 通过维基媒体公用领域
尽管识别过程没有通过识别网络直接建模,且训练目标有很大变化,但添加噪声的过程以及随后的噪声减少监测可以看作是一种识别形式,初始噪声样本则是从 p(z_0)中提取的初始状态。
当生成一个全新的样本时,模型可以从纯噪声开始,并在试图弄清楚噪声下可能隐藏的内容时,创造出一些新的东西:
当我向 DALL-E 请求“随机白噪声”时,它返回的内容并不是完全随机的白噪声。它不可避免地反映了其训练数据的一些结构。
从无中生有的过程揭示了其训练数据隐含学习的分布。
扩散模型为何如此有效仍然有待讨论。除此之外,它们被比作基于能量的联想记忆模型(40 年前通过 Hopfield 网络而闻名)。
扩散模型还涉及基于得分的生成建模思想,这一思想由Song 等人推广:与直接计算数据似然的传统方法不同,这些模型专注于近似得分,在这种情况下,得分表示数据似然相对于数据本身的梯度。
直观地说,得分提供了一个样本应如何更改以提高其可能性的方向。通过不直接计算可能性,这些模型通常避开了一些我们之前遇到的计算挑战。
得分函数可以再次通过神经网络建模。表示它的一种特别有趣的方式是通过随机微分方程(SDEs),类似于神经常微分方程(Neural ODEs),通过神经网络表示微分方程(一种称为隐式层的东西)。
这在精神上类似于扩散模型的连续时间版本。从噪声开始,得分函数用于引导其朝向一个可能的样本(Stefano Ermon,他的实验室开发了这些技术,做了很棒的讲座,这里是一个更详细的讲解)。
在扩散模型中,生成过程同样是随机的,在每一步都加入了一个随机成分。由于生成过程被分解成多个步骤,这允许通过向链中回溯几个步骤并重新运行过程,从而引入样本的细微变化。
我在本文缩略图中使用的画作的细微变化,由 DALL-E 生成。
在一些最受欢迎的扩散模型应用中,如 DALL-E 或 Midjourney,初始状态不一定由纯随机样本z0从**N(0,1)给出,而是由视觉和语言的联合嵌入p(z0|x)**给出,其中 x 可以是例如由强大的 CLIP(对比语言-图像预训练)嵌入提供的文本输入。
条件生成在各种多模态学习设置中具有重要价值,因为它将不同的感官模式结合成一个连贯的框架。这可能会成为未来一些最激动人心的人工智能发展的重要组成部分。
一幅印象派画作,描绘了一个 AI 大脑想象日落,感谢 DALL-E。
生成对抗网络(GANs)
GANs是最近十年最受欢迎的生成模型类别之一,灵感来源于 Ian Goodfellow 和他的朋友们的一晚传奇饮酒经历。
GANs 甚至更远离了赫尔姆霍兹机器的双网络结构。如我所提到的,近似**p(z|x)**通常是生成模型的核心挑战,因此 GANs 干脆把识别抛到窗外,尝试在没有它的情况下进行生成。
GANs 也开始通过从**p(z0)中抽取一个随机噪声向量(如在扩散模型中,这个初始向量也可以依赖于其他信息,比如文本),但随后仅训练生成网络(因为这是我们在许多应用中最感兴趣的部分),通过包含一个鉴别器,尝试使生成模型中的p(x|z)**样本与训练数据的示例匹配。
生成网络的训练目的是产生能够欺骗鉴别器的数据。鉴别器则被训练来区分真实样本和虚假样本。
GANs 的优雅之处在于这种竞争动态:生成器在鉴别器的反馈指导下提高其生成数据的能力,而鉴别器本身则变得更擅长区分真实与虚假。这是完美的零和游戏,推动两个网络不断变得更好(有一定的深度伪造检测风险,我在这里写过).
然而,GANs 也有自身的一系列挑战,并且由于其竞争对手,特别是扩散模型的成功,GANs 最近的流行度有所下降。训练 GANs 可能非常不稳定。如果生成器在开始时产生低质量的样本,鉴别器的工作变得太容易,这使得生成器很难改进。另一方面,如果鉴别器变得过于强大,它可能会抑制生成器的成长,导致模式崩溃,即生成器最终只产生可能输出的一个子集。
**Transformers 和大型语言模型(**LLMs)
由于 Transformers 彻底革新了文本生成建模的格局,我不能在这里不提到它们。
简而言之,几乎所有 LLMs 都基于transformer 架构的变体,该架构实现了 2017 年谷歌论文中的自注意力机制,关于这一点的详细信息超出了本文的范围,但在许多其他地方有解释。这种架构允许 LLMs 学习输入序列之间的复杂关系,这在文本上特别有效。
一些 Transformer 变体,如 BERT,是在掩码语言建模设置下训练的。它们接收有些标记被掩盖的序列,并被训练去识别这些掩盖的标记。这在精神上与 VAEs 中的识别非常相似,其中掩盖单词可以被解释为对输入进行噪声处理。缺失的单词被填补,因为 Transformer 已经学习了输入数据的概率分布p(x),并能够理解给定上下文的最可能单词。
从生成的角度看,基于变压器的 LLM 模型会根据输入提示,建模每个潜在单词或短语在前一个单词之后的概率。这再次表达了始终存在的概率分布**p(x|z)**的一种变体。
然而,变压器中通常没有显式的隐藏变量z,因为提示和上下文本身就是单词。相反,自注意机制从所有观察到的单词(x1,x2,…,xt)中提取标记 p(x_i|(x1,x2,…,xt))的概率,当然还包括它在数十亿行训练数据中看到的所有单词和上下文的隐含分布。
虽然噪音并不是训练变压器的直接组成部分,但 LLM 自然地包含了一个概率成分。这很有意义,因为语言不是唯一确定的(因此,马尔可夫模型最初是在俄罗斯诗歌的基础上开发的,我在这里详细讨论),同一段文字可以用多种不同的方式表达:在生成响应或样本时,通常有几个单词适合给定的上下文,因此存在可能延续的分布 p(x_i|(x1,x2,…,xt)),
选择不同单词的概率可以通过所谓的温度超参数进行缩放。根据你是寻找创意还是确定性响应,这个参数可以有效地控制“噪声”水平。像 Chat-GPT 这样的 LLM 允许你在响应时请求特定的温度。
Chat-GPT 用高温设置重新表述了这段文字:“在变压器的旋转银河中,噪音不是主角,但 LLM 在语言的不确定节拍中舞动。构建答案不是为了找到那个单一的绝妙词汇,而是与潜在单词旋律的鸡尾酒一同狂欢 p(x_i|(x1,x2,…,xt))。”
虽然高温度使得 ChatGPT 听起来好像真的很兴奋,但这里的“高温度”类比于玻尔兹曼的热力学统计公式,该公式假设系统状态遵循指数分布,取决于系统的温度和状态的能量:
不同的 lambda 下的玻尔兹曼分布与温度呈反比关系。Newystats,CC BY-SA 4.0 <creativecommons.org/licenses/by-sa/4.0
>, 通过维基共享资源
与变换器的类比并非巧合:softmax 函数在自注意力机制中用于将键和值之间的缩放点积分数映射为概率。softmax 与玻尔兹曼分布具有完全相同的函数形式,在这两种情况下都用于将未归一化的分数(在玻尔兹曼分布中是能量)映射到归一化的概率分布。
就像在热力学中,温度与熵密切相关,从而也与不确定性/噪声相关。在玻尔兹曼分布中,随着温度的升高,不同能量状态的概率变得更加均匀。最大均匀性导致最大熵,因为所有状态的可能性相等。在 LLMs 中,这意味着所有可能的词汇在下一阶段都有相等的概率被预测。然而,这并不意味着生成的文本完全是随机的,即使在高温下,正如我们在上面的例子中看到的。即使在较高温度下,最可能的标记的选择仍然大多代表了连贯的语言。
如果我在这篇文章中传达了一个观点,那就是噪声在所有生成模型中发挥着至关重要的作用。生成建模是一种将无形噪声赋予结构的艺术。
近年来的经验表明,许多途径通向罗马,不同的模型可以根据目标、数据模式以及在扩展到巨大模型规模(如变换器)和使用基于梯度的方法进行训练时的实际考虑来取得有效结果。
“我能创造的东西,我仍然不理解。”
— 理查德·费曼应该提到的
先进的生成模型的巨大规模和训练数据的复杂性带来了诠释这些模型的挑战。扩散模型和变换器并没有被构建为潜变量模型,因此可能像巨大的黑箱一样,解释滞后,特别是在对其对现实世界影响的担忧日益增加的情况下。
然而,我们仍然可能学会揭示其中的一些结构,例如 Max Tegmark 等人的这篇新论文,其中描述了在 LLMs 中发现空间和时间的中间表征,并将其比作可解释世界模型的出现。其他人则创造性地应用认知心理学的工具来理解 LLMs 的行为,就像我们试图理解人类行为的复杂性一样。
在最近的一期播客节目中,马克·安德森称,生成模型是否能在合成数据上进行有意义的训练和改进是一个价值万亿美元的问题。利用这种基本免费的数据进行训练将打开许多可能性,提供一种自我游戏(这种方法已经被 DeepMind 成功地用于 AlphaGo 和 AlphaFold)来继续调整生成模型,而无需依赖昂贵的精心策划的训练数据。安德森将这个问题与关于信号与噪声关系的信息论观点联系在一起,追溯到香农:简单地说,如何能在模型中包含比我们输入的更多的信息?
如果他们不喜欢,就称之为幻觉;如果他们喜欢,就称之为创造力。
— 马克·安德森
生成模型是否只是模仿它们在训练数据中看到的内容?训练过程中的噪声和模型本身的噪声在多大程度上导致了一种超越训练数据的泛化(我在最近的一篇关于免费午餐定理的文章中考虑了相关问题)?毕竟,噪声在机器学习模型中被广泛用于提升泛化能力。
噪声既能导致幻觉和创造力,也能引发替代事实的幻觉和之前不存在的替代视角的创造。通过生成模型,还可以认为“信息”不仅存在于原始数据中,还存在于这些数据的组合可能性中。生成模型为我们提供了一种新颖而诱人的方式来探索这种组合空间。用马克·吐温的话来说:
“没有真正的新想法。这个想法是不可能的。我们只是将许多旧想法放入某种心理万花筒中。我们给它转动,它们就会产生新的和有趣的组合。”
— 马克·吐温
而且,既然这句话本身并不是新想法,我们可以再次回到圣经(我没想到在一篇 AI 文章中会引用两次):
过去的将会重现,已做过的将会再做;在太阳底下没有新事物。
传道书 1:9 (圣经)
可以说,人类创造力中也能观察到噪声与结构之间的类似相互作用。在我最近的一篇关于天才与心理视觉化的文章中,我探讨了在大脑中,默认模式网络(斯科特·巴里·考夫曼称之为“想象网络”)的自由、无结构的思维漫游活动,往往能提供一种冲动,这种冲动随后被更为刻意、集中的练习和技能塑造为一些最令人惊叹的艺术作品和天才创作。
DALL-E 以杰克逊·波洛克的风格绘画,捕捉原始随机风格绘画的结构化随机性。
即使是最创新的艺术和科学作品,也必须用我们已经部分熟悉的语言来理解。正如维特根斯坦所指出的:没有私人语言。生成模型正在学习说我们的语言,学习逼近我们最关心的事物的p(x),并通过在噪声和结构之间权衡,揭示这种分布内外的无尽新模式。它们的创造力反过来可以用来激发我们的创造力。
“那些不愿意模仿任何东西的人,什么也不会产生。”
— 萨尔瓦多·达利
想到生成模型已经开始塑造我们的感官输入,质疑并推动我们对世界和心智的感知边界,以及我们对创造力和天才的理解,这一方面让人感到畏惧但也充满兴奋。
所以,我认为用 Chat-GPT 的话结束这篇文章再好不过了,它梦想成为列奥纳多·达芬奇:
“真正的天才不仅仅在于模仿,而在于将已知与未知融合的炼金术。”
— 列奥纳多·达芬奇/Chat-GPT
感谢阅读!
如果你喜欢我的写作,请订阅以通过邮件获取我的故事。