AIGC实战——变分自编码器(Variational Autoencoder, VAE)

AIGC实战——变分自编码器

    • 0. 前言
    • 1. 变分自编码器
      • 1.1 基本原理
      • 1.2 编码器
    • 2. 构建VAE编码器
      • 2.1 Sampling 层
      • 2.2 编码器
      • 2.3 损失函数
      • 2.4 训练变分自编码器
    • 3. 变分自编码器分析
    • 小结
    • 系列链接

0. 前言

我们已经学习了如何实现自编码器,并了解了自编码器无法在潜空间中的空白位置处生成逼真的图像,且空间分布并不均匀,为了解决这些问题,我们需要将自编码器 (Autoencoder, AE) 改进为变分自编码器 (Variational Autoencoder, VAE)。在本节中,我们将学习变分自编码器的基本原理,并使用 Keras 实现变分自编码器模型。

1. 变分自编码器

1.1 基本原理

变分自编码器 (Variational Autoencoder, VAE) 是一种结合了自编码器和概率图模型的生成模型,通过学习输入数据的潜分布来进行无监督学习并生成新样本。
与传统的自编码器不同,变分自编码器引入了概率编码器和概率解码器。编码器将输入数据映射到潜在空间的概率分布,而解码器将从潜在空间中的样本重构为原始输入的分布。通过学习这两个概率分布,VAE 可以学习到输入数据的概率表示,并且能够通过从潜在空间中采样生成新的样本。
在训练过程中,VAE 使用最大似然估计来最小化观测数据与重构数据之间的差异,并通过最小化编码器和解码器之间的 KL 散度来约束潜在空间的分布与先验分布之间的差异。这使得 VAE 能够学习到连续且平滑的潜在表示,使得在潜在空间中的相邻点对应于语义上相似的样本。
接下来,我们从数学角度介绍我们需要哪些改动,才能将自编码器转换为变分自编码器,从而使其成为一个更复杂的生成模型。实际上,相比于自编码器,我们仅需要改变两部分:编码器和损失函数。

1.2 编码器

在自编码器中,每个图像直接映射为潜空间中的一个点。在变分自编码器中,每个图像映射为潜在空间中某一点周围的多元正态分布:

编码器

多元正态分布 (Multivariate Normal Distribution) 是一种概率分布,也称为高斯分布 (Gaussian Distribution)。其曲线图呈独特的钟形,一维的正态分布由两个变量确定:均值 ( μ μ μ) 和方差 ( σ 2 σ^2 σ2),标准差 ( σ σ σ) 是方差的平方根。在一维空间中,正态分布的概率密度函数为:
f ( x ∣ μ , σ 2 ) = 1 2 π σ 2 e − ( x − μ ) 2 2 σ 2 f(x|μ,σ^2) = \frac 1 {\sqrt{2πσ^2}}e^{-\frac{(x-μ)^2}{2σ^2}} f(xμ,σ2)=2πσ2 1e2σ2(xμ)2
下图展示了不同均值和方差的一维正态分布,红色曲线表示标准正态分布 (Standard Normal Distribution) N ( 0 , 1 ) \mathcal N(0,1) N(0,1),即均值为 0,方差为 1 的正态分布。

正态分布

可以使用以下公式从均值为 μ μ μ,标准差为 σ σ σ 的正态分布中采样一个点 z z z
z = μ + σ ϵ z = μ + σϵ z=μ+σϵ
其中 ϵ ϵ ϵ 是从标准正态分布中采样得到的。
正态分布的概念可以扩展到多维空间,具有均值向量 μ μ μ 和对称协方差矩阵 Σ Σ Σ k k k 维多元正态分布(或多元高斯分布) N ( μ , Σ ) \mathcal N(\mu,Σ) N(μΣ)的概率密度函数如下:
f ( x 1 , . . . , x k ) = e x p ( − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ) ( 2 π ) k ∣ Σ ∣ f(x_1,...,x_k) = \frac {exp(-\frac 12 (x-μ)^T Σ^{-1} (x-μ)) } {\sqrt{(2π)^k |Σ|}} f(x1,...,xk)=(2π)k∣Σ∣ exp(21(xμ)TΣ1(xμ))
我们通常使用各向同性的多元正态分布,其中协方差矩阵是对角矩阵。这意味着在每个维度上分布都是独立的,即我们可以采样一个向量,其中每个元素都服从独立的均值和方差的正态分布。
多元标准正态分布 (multivariate standard normal distribution) N ( 0 , I ) \mathcal N(0,I) N(0,I) 是一个多元分布,具有零值均值向量和单位协方差矩阵。
在多数情况下,正态分布与高斯分布通常可以互换使用,并且通常隐含着各向同性和多元性。
变分自编码器假设潜空间中的维度之间没有相关性,因此协方差矩阵是对角矩阵。编码器只需将每个输入映射到一个均值向量和一个方差向量,而不需要考虑维度之间的协方差。
此外,我们选择映射为方差的对数,因为对数可以是 ( − ∞ , ∞ ) (-∞, ∞) (,) 范围内的任意实数,与神经网络单元的自然输出范围—致,而方差值始终为正。这样,我们可以使用神经网络作为编码器,将输入图像映射到均值和对数方差向量。
总之,编码器将每个输入图像编码为两个向量 z_meanlog_var,两者共同定义了潜空间中的多元正态分布:

  • z_mean:分布的均值
  • z_log_var:各个维度上方差的对数

我们可以使用以下公式从由上述值定义的分布中采样一个点 z z z
z = z _ m e a n + z _ s i g m a ∗ e p s i l o n z = z\_mean + z\_sigma * epsilon z=z_mean+z_sigmaepsilon
其中:
z _ s i g m a = e x p ( z l o g v a r ∗ 0.5 ) e p s i l o n ∼ N ( 0 , I ) z\_sigma = exp(z_log_var * 0.5)\\ epsilon \sim \mathcal N(0,I) z_sigma=exp(zlogvar0.5)epsilonN(0,I)
z _ s i g m a ( σ ) z\_sigma(σ) z_sigma(σ) z _ l o g _ v a r ( l o g ( σ 2 ) ) z\_log\_var(log(σ^2)) z_log_var(log(σ2)) 之间的关系推导如下:
σ = e x p ( l o g ( σ ) ) = e x p ( 2 l o g ( σ ) / 2 ) = e x p ( l o g ( σ 2 ) / 2 ) σ = exp(log(σ)) = exp(2log(σ)/2) = exp(log(σ^2)/2) σ=exp(log(σ))=exp(2log(σ)/2)=exp(log(σ2)/2)
变分自编码器的解码器与普通自编码器的解码器相同,整体结构如下所示:

变分自编码器架构

为什么对编码器进行这样小的改变会有所帮助呢?在自编码器中,潜空间并不要求是连续的,即使点 (-2,2) 可以解码为完好的凉鞋图像,也不能保证点 (-2.1,2.1) 有类似的特征。而在变分自编码器中,由于我们从z_mean周围的区域中采样一个随机点,解码器必须确保当对同一邻域中的所有点进行解码时都能产生非常相似的图像,以便确保重构损失相对较小。这一属性确保了即使我们在隐空间中选择了一个解码器从未见过的点,编码器也可以将其解码为完好的图像。

2. 构建VAE编码器

接下来,我们利用 Keras 构建变分自编码器。

2.1 Sampling 层

首先,我们需要创建一种新层,称为 Sampling 层,用于从由 z_meanz_log_var 定义的分布中采样:

# 通过继承 Keras 基础 Layer 类来创建一个新层
class Sampling(layers.Layer):def call(self, inputs):z_mean, z_log_var = inputsbatch = tf.shape(z_mean)[0]dim = tf.shape(z_mean)[1]epsilon = K.random_normal(shape=(batch, dim))# 使用重参数化技巧构建一个从由 z_mean 和 z_log_var 参数化的正态分布中采样的样本return z_mean + tf.exp(0.5 * z_log_var) * epsilon

子类化 Layer 类
我们可以通过子类化 Layer 类并定义 call 方法在 Keras 中创建新的层,call 方法描述了如何通过该层转换张量。
例如,在变分自编码器中,可以创建一个 Sampling 层,处理从由 z_meanz_log_var 定义的参数化正态分布中对 z 进行采样。子类化 Layer 类可以对一个张量应用不包含在 Keras 内置层类型中的变换。

重参数化技巧
变分自编码并不直接从由 z_meanz_log_var 参数化的正态分布中进行采样,而是从标准正态分布中采样 epsilon,然后调整采样以得到正确的均值和方差,这称为重参数化技巧 (Reparameterization Trick),使用此技术后,梯度可以自由地通过该层进行反向传播。通过将层的所有随机性都包含在变量 epsilon 中,可以证明该层输出相对于其输入的偏导数是确定性的(即与随机的 epsilon 无关),这对于反向传播通过该层是至关重要的。

2.2 编码器

编码器的完整代码如下:

# 编码器
encoder_input = layers.Input(shape=(IMAGE_SIZE, IMAGE_SIZE, 1), name="encoder_input"
)
x = layers.Conv2D(32, (3, 3), strides=2, activation="relu", padding="same")(encoder_input
)
x = layers.Conv2D(64, (3, 3), strides=2, activation="relu", padding="same")(x)
x = layers.Conv2D(128, (3, 3), strides=2, activation="relu", padding="same")(x)
shape_before_flattening = K.int_shape(x)[1:]  x = layers.Flatten()(x)
# 将 Flatten 层连接到 z_mean 和 z_log_var 层,而不是直接连接到 2D 潜空间中
z_mean = layers.Dense(EMBEDDING_DIM, name="z_mean")(x)
z_log_var = layers.Dense(EMBEDDING_DIM, name="z_log_var")(x)
# Sampling 层从由 z_mean 和 z_log_var 参数定义的正态分布中对潜空间中的点 z 进行采样
z = Sampling()([z_mean, z_log_var])
# 定义编码器,接受一张输入图像,并输出 z_mean、z_log_var 以及从由这些参数定义的正态分布中采样得到的点 z
encoder = models.Model(encoder_input, [z_mean, z_log_var, z], name="encoder")
print(encoder.summary())

编码器架构摘要信息输出如下:

编码器架构

2.3 损失函数

在自编码器中,损失函数只包括经过编码器和解码器传递后的图像与其原始图像之间的重建损失。在变分自编码器中,除了重建损失外,还增加了一个额外的组成部分:KL 散度 (Kullback-Leibler divergence)。
KL 散度是衡量两个概率分布之间差异程度的方法。在 VAE 中,我们希望衡量由参数 z_meanz_log_var 构成的正态分布与标准正态分布之间的差异程度。在这种情况下,可以证明 KL 散度有以下解析解:
k l _ l o s s = − 0.5 ∗ s u m ( 1 + z _ l o g _ v a r − z _ m e a n 2 − e x p ( z _ l o g _ v a r ) ) kl\_loss = -0.5 * sum(1 + z\_log\_var - z\_mean ^ 2 - exp(z\_log\_var)) kl_loss=0.5sum(1+z_log_varz_mean2exp(z_log_var))
用数学符号表示如下:
D K L [ N ( μ , σ ) ∣ ∣ N ( 0 , 1 ) ] = − 1 2 ∑ ( 1 + l o g ( σ 2 ) − μ 2 − σ 2 ) D_{KL}[\mathcal N(\mu, \sigma)||\mathcal N(0,1)]=-\frac 12\sum(1+log(\sigma^2)-\mu^2-\sigma^2) DKL[N(μ,σ)∣∣N(0,1)]=21(1+log(σ2)μ2σ2)
求和是在潜空间的所有维度上进行的。当 z_mean = 0z_log_var = 0 时,kl_loss 会得到最小值 0。当这两个项开始与 0 的差距增大时,kl_loss 也会随之增加。
总之,KL 散度在编码观测样本时,如果 z_meanz_log_var 变量与标准正态分布参数(即 z_mean = 0z_log_var = 0 )出现显著不同,对网络施加的惩罚。
在损失函数中添加 KL 散度后,就有一个明确定义的分布(即标准正态分布),可以用于选择潜空间中的点,从该分布中采样更有可能得到 VAE 已经见过的范围内的点。其次,由于 KL 散度试图将所有编码分布强制趋近于标准正态分布,因此点簇之间形成较大间隙的可能性较小。相反,编码器将尝试以对称的方式高效利用原点周围的空白区域。
VAE 论文中,VAE 的损失函数只是重建损失和 KL 散度损失项之和。我们通过 r_loss_factor 为重建权重添加权重因子,用于平衡 KL 散度损失和重建损失。如果重建损失权重过大,KL 损失将无法产生预期的调节效果,就会遇到与普通自编码器相同的问题。如果 KL 散度项的权重过大,KL 散度损失将占主导地位,重建图像的质量将较差。权重因子是训练 VAE 时需要调整的超参数之一。

2.4 训练变分自编码器

将整个 VAE 模型构建为 Keras Model 类的子类,以便在自定义的 train_step 方法中计算损失函数的 KL 散度项。

class VAE(models.Model):def __init__(self, encoder, decoder, **kwargs):super(VAE, self).__init__(**kwargs)self.encoder = encoderself.decoder = decoderself.total_loss_tracker = metrics.Mean(name="total_loss")self.reconstruction_loss_tracker = metrics.Mean(name="reconstruction_loss")self.kl_loss_tracker = metrics.Mean(name="kl_loss")@propertydef metrics(self):return [self.total_loss_tracker,self.reconstruction_loss_tracker,self.kl_loss_tracker,]# 变分自编码器前向计算def call(self, inputs):"""Call the model on a particular input."""z_mean, z_log_var, z = encoder(inputs)reconstruction = decoder(z)return z_mean, z_log_var, reconstruction# VAE训练过程,包括损失函数的计算def train_step(self, data):"""Step run during training."""with tf.GradientTape() as tape:z_mean, z_log_var, reconstruction = self(data)reconstruction_loss = tf.reduce_mean(BETA* losses.binary_crossentropy(data, reconstruction))kl_loss = tf.reduce_mean(tf.reduce_sum(-0.5* (1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var)),axis=1,))total_loss = reconstruction_loss + kl_lossgrads = tape.gradient(total_loss, self.trainable_weights)self.optimizer.apply_gradients(zip(grads, self.trainable_weights))self.total_loss_tracker.update_state(total_loss)self.reconstruction_loss_tracker.update_state(reconstruction_loss)self.kl_loss_tracker.update_state(kl_loss)return {m.name: m.result() for m in self.metrics}def test_step(self, data):"""Step run during validation."""if isinstance(data, tuple):data = data[0]z_mean, z_log_var, reconstruction = self(data)# 重建损失权重因子 beta 为 500reconstruction_loss = tf.reduce_mean(BETA* losses.binary_crossentropy(data, reconstruction))kl_loss = tf.reduce_mean(tf.reduce_sum(-0.5 * (1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var)),axis=1,))# 总损失是重建损失和KL散度损失之和total_loss = reconstruction_loss + kl_lossreturn {"loss": total_loss,"reconstruction_loss": reconstruction_loss,"kl_loss": kl_loss,}# 创建变分自编码器
vae = VAE(encoder, decoder)
# 编译变分自编码器
optimizer = optimizers.Adam(learning_rate=0.0005)
vae.compile(optimizer=optimizer)
# 模型训练
vae.fit(x_train,epochs=EPOCHS,batch_size=BATCH_SIZE,shuffle=True,validation_data=(x_test, x_test),
)

梯度记录器 (Gradient Tape)
TensorFlowGradient Tape 用于在模型的前向传播过程中计算操作的梯度。为了使用梯度记录器,需要将需要求导的操作的代码包装在 tf.GradientTape() 上下文中。一旦记录了这些操作,就可以通过调用 tape.gradient() 计算损失函数相对于某些变量的梯度,然后使用优化器利用这些梯度更新网络权重。
这一机制对于计算自定义损失函数的梯度非常有用,也适用于创建自定义的训练流程。

3. 变分自编码器分析

训练好 VAE 后,我们使用编码器对测试集中的图像进行编码,并在潜在空间中绘制 z_mean 值。我们还可以从标准正态分布中采样,生成潜空间中的点,并使用解码器将这些点解码回像素空间,以测试 VAE 的性能。
下图展示了新的潜空间的结构,以及采样点及其解码后的图像。我们可以看到潜空间的组织方式发生了 一些变化。

变分自编码器潜空间

首先,KL 散度损失项确保编码图像的 z_meanz_log_var 值不会偏离标准正态分布太远。其次,由于现在编码器是随机的而不是确定性的,因此,潜空间更加连续,所以不会生成过多不合理的图像,潜在空间现在更加连续。
最后,如下图所示,通过按图像类型对潜在空间中的点进行着色,可以看到没有任何一种类型有倾向性。右图显示了将潜空间转换为 p 值的情况,可以看到每种颜色占据的区域大致相等。需要强调的是,在训练过程中并没有使用标签,VAE 通过学习掌握了各种 Fashion-MNIST 图像的形式,以最小化重建损失。

潜空间

小结

变分自编码器通过在模型中引入随机性,并限制潜空间中的点的分布来解决自编码器存在的问题。只需进行一些微小的调整,就可以将自编码器转换为变分自编码器,从而使其成为真正的生成模型。在本节中,我们介绍了变分自编码器的基本原理,并使用 Keras 实现了一个变分自编码器用于生成 Fashion-MNIST 图像。

系列链接

AIGC实战——生成模型简介
AIGC实战——深度学习 (Deep Learning, DL)
AIGC实战——卷积神经网络(Convolutional Neural Network, CNN)
AIGC实战——自编码器(Autoencoder)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

<C++> 反向迭代器

我们知道正向迭代器的设计:begin迭代器指向第一个数据,end迭代器指向最后一个数据的下一个位置 。移向下一个数据,解引用得到数据的值,并根据容器储存方式的不同,容器有不同类型的迭代器。 注意:rbegin迭代…

SecureCRT 9.4.2最新终端SSH工具

SecureCRT是一款终端SSH工具,它提供了类似于Telnet和SSH等协议的远程访问功能。SecureCRT软件特色包括: 支持SSH(SSH1和SSH2)的终端仿真程序,能在Windows下登录UNIX或Linux服务器主机。SecureCRT支持SSH,同…

媒体行业的3D建模:在影视中创造特效纹理

在线工具推荐: 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 在本文中,我们将探讨 3D 建模在媒体行业中的作用,特别是它在影视特效创作…

基于STM32的无线通信系统设计与实现

【引言】 随着物联网的迅速发展,无线通信技术逐渐成为现代通信领域的关键技术之一。STM32作为一款广受欢迎的微控制器,具有丰富的外设资源和强大的计算能力,在无线通信系统设计中具有广泛的应用。本文将介绍如何基于STM32实现一个简单的无线通…

站群服务器 CentOS 搭建socks5多IP代理服务器详细教程,12个步骤教会你!

准备工作 首先要保证服务上能正常使用wget tar make vim,如果正常就直接进入【第一步】 #安装wget的命令 yum install wget#安装tar解压工具 yum install -y tar#安装make的命令 yum groupinstall "Development Tools"#安装vim的命令 yum install…

《洛谷深入浅出进阶篇》P3397 地毯————二维差分

上链接:P3397 地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P3397 上题干: 题目描述 在 nn 的格子上有 m 个地毯。 给出这些地毯的信息,问每个点被多少个地毯覆盖。 输入格式 第一行,两个…

浅尝:iOS的CoreGraphics和Flutter的Canvas

iOS的CoreGraphic 基本就是创建一个自定义的UIView&#xff0c;然后重写drawRect方法&#xff0c;在此方法里使用UIGraphicsGetCurrentContext()来绘制目标图形和样式 #import <UIKit/UIKit.h>interface MyGraphicView : UIView endimplementation MyGraphicView// Onl…

桌面云架构讲解(VDI、IDV、VOI/TCI、RDS)

目录 云桌面架构 VDI 虚拟桌面基础架构 IDV 智能桌面虚拟化 VOI/TCI VOI 虚拟系统架构 TCI 透明计算机架构 RDS 远程桌面服务 不同厂商云桌面架构 桌面传输协议 什么是云桌面 桌面云是虚拟化技术成熟后发展起来的一种应用&#xff0c;桌面云通常也称为云桌面、VDI等 …

Flink(五)【DataStream 转换算子(上)】

前言 这节注定是一个大的章节&#xff0c;我预估一下得两三天&#xff0c;涉及到的一些东西不懂就重新学&#xff0c;比如 Lambda 表达式&#xff0c;我只知道 Scala 中很方便&#xff0c;但在 Java 中有点发怵了&#xff1b;一个接口能不能 new 来构造对象? 答案是可以的&…

代码随想录 Day47 动态规划15 LeetCode T583 两个字符串的删除操作 T72 编辑距离

LeetCode T583 两个字符串的删除操作 题目链接:583. 两个字符串的删除操作 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 本题有两个思路 1.使用两个字符串的长度之和-2*最长公共子串(换汤不换药) 代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交…

跨国企业如何选择安全靠谱的跨国传输文件软件?

随着全球化的不断发展&#xff0c;跨国企业之间的合作变得越来越频繁。而在这种合作中&#xff0c;如何安全、可靠地将文件传输给合作伙伴或客户&#xff0c;成为了跨国企业必须面对的问题。 然而&#xff0c;跨国文件传输并不是一件容易的事情&#xff0c;由于网络物理条件的…

OpenCV入门4——实现图形的绘制

文章目录 OpenCV绘制直线OpenCV绘制矩形和圆画矩形画圆 OpenCV椭圆的绘制OpenCV绘制多边形OpenCV绘制文本实现鼠标绘制基本图形 OpenCV绘制直线 # -*- coding: utf-8 -*- import cv2 import numpy as npimg np.zeros((480, 640, 3), np.uint8) # 坐标点为(x, y) cv2.line(img,…

《视觉SLAM十四讲》-- 后端 1(下)

8.2 BA 与图优化 Bundle Adjustment 是指从视觉图像中提炼出最优的 3D 模型和相机参数&#xff08;内参和外参&#xff09;。 8.2.1 相机模型和 BA 代价函数 我们从一个世界坐标系中的点 p \boldsymbol{p} p 出发&#xff0c;把相机的内外参数和畸变都考虑进来&#xff0c;…

C语言从入门到精通之【char类型】

char类型用于储存字符&#xff08;如&#xff0c;字母或标点符号&#xff09;&#xff0c;但是从技术层面看&#xff0c;char是整数类型。因为char类型实际上储存的是整数而不是字符。计算机使用数字编码来处理字符&#xff0c;即用特定的整数表示特定的字符。 char类型占1个字…

wx.canvasToTempFilePath生成图片保存到相册

微信小程序保存当前画布指定区域的内容导出生成指定大小的图片&#xff0c;记录一下 api&#xff1a;wx.canvasToTempFilePath 效果&#xff1a; 代码&#xff1a;wxml <canvas style"width: {{screenWidth}}px; height: {{canvasHeight}}px;" canvas-id"my…

NewStarCTF2023 Week3 Reverse方向 题目STL WP

分析 代码不多&#xff0c;逻辑挺清楚的。 先用Z3解出V7&#xff1a; from z3 import *s Solver() v1, v2, v3, v4, v5, v6 BitVecs(v1 v2 v3 v4 v5 v6, 32) v7, v8, v9, v10, v11 BitVecs(v7 v8 v9 v10 v11, 32)s.add((v1 << 15) ^ v1 0x2882D802120E) s.add((v2 …

借助拧紧曲线高效管理螺栓装配防错——SunTorque智能扭矩系统

拧紧曲线作为拧紧质量的“晴雨表”&#xff0c;在拧紧过程中&#xff0c;能够实时探知到拧紧状态是否存在异常&#xff0c;并根据曲线特质推测出拧紧过程中遇到了什么样的问题&#xff0c;今天SunTorque智能扭矩系统带您了解拧紧曲线在螺栓装配防错管理中如何发挥作用。 合格的…

搭建知识付费系统的最佳实践是什么

在数字化时代&#xff0c;搭建一个高效且用户友好的知识付费系统是许多创业者和内容创作者追求的目标。本文将介绍一些搭建知识付费系统的最佳实践&#xff0c;同时提供一些基本的技术代码示例&#xff0c;以帮助你快速入门。 1. 选择合适的技术栈&#xff1a; 搭建知识付费…

论文阅读:YOLOV: Making Still Image Object Detectors Great at Video Object Detection

发表时间&#xff1a;2023年3月5日 论文地址&#xff1a;https://arxiv.org/abs/2208.09686 项目地址&#xff1a;https://github.com/YuHengsss/YOLOV 视频物体检测&#xff08;VID&#xff09;具有挑战性&#xff0c;因为物体外观的高度变化以及一些帧的不同恶化。有利的信息…

GitHub Universe 2023:AI 技术引领软件开发创新浪潮

GitHub 是全球领先的软件开发和协作平台&#xff0c;数百万开发者和企业在此分享、学习和创建卓越的软件。同时 GitHub 处在 AI 技术前沿&#xff0c;通过其先进的 AI 技术增强开发者体验并赋能未来软件开发的使命。在今天的文章中&#xff0c;我们将一起看看在 GitHub 年度大会…