机器学习课程学习周报十

news2024/9/29 15:20:22

机器学习课程学习周报十

文章目录

  • 机器学习课程学习周报十
    • 摘要
    • Abstract
    • 一、机器学习部分
      • 1.1 生成对抗网络
      • 1.2 生成器与辨别器的训练过程
      • 1.3 信息论
        • 1.3.1 信息量
        • 1.3.2 熵
        • 1.3.3 交叉熵
        • 1.3.4 相对熵/KL散度
        • 1.3.5 交叉熵损失函数
        • 1.3.6 JS散度
      • 1.4 GAN的理论介绍
    • 总结

摘要

本周学习了生成对抗网络(GAN)的基本原理和训练过程。重点介绍了生成器和判别器的协同训练机制,以及信息论在GAN中的应用。通过GAN的实践,理解了如何通过最小化生成数据与真实数据分布之间的差异来提高生成器的效果。

Abstract

This week I focused on the foundational principles and training process of Generative Adversarial Networks(GAN). The study highlighted the collaborative training mechanism of the generator and discriminator, along with the application of information theory in GAN. Practical insights were gained into improving generator performance by minimizing the divergence between generated and real data distributions.

一、机器学习部分

1.1 生成对抗网络

生成模型generative model)中的网络通常被作为一个生成器generator)来使用。在模型输入时会将一个随机变量 z z z与原始输入 x x x一并输入到模型中,随机变量 z z z是从随机分布中采样得到的,这个随机分布应能知道其函数表达式,例如高斯分布Gaussian distribution)、均匀分布uniform distribution)。虽然我们每次输入同样的 x x x,但随着采样得到的 z z z不同,我们得到的输出 y y y也会不一样。同理,对于网络来说,其输出也不再固定,而变成了一个复杂的分布,我们也将这种可以输出一 个复杂分布的网络称为生成器,如下图所示。

在这里插入图片描述

提出生成模型的原因,是我们的任务需要创造性的输出。对于生成模型来说,其输出的结果能够输出一个分布,能够说出多种答案,以处理开放式的问题。生成模型又分为无限制生成unconditional generation),也就是不需要原始输入 x x x,以及条件型生成conditional generation),这种则需要原始输入 x x x。以无限制的图片生成为例,一张图片就是一个高维的向量,所以生成器实际上做的事情就是输出一个高维的向量。我们首先从正态分布中采样得到一个向量 z z z,并输入到生成器中,生成器输出一个高维向量,如 64 × 64 × 3 64 \times 64 \times 3 64×64×3大小的彩色图片。我们也可以选择其他的分布,但是根据经验,不同分布之间的差异并没有非常大。正态分布比较简单且常见,后面的学习都以正态分布为前提。

生成模型中,现在非常火的是扩散模型Diffusion Model),这种模型将在下一章进行学习。本节将学习最为经典的生成式对抗网络Generative Adversarial Network, GAN)。

在GAN中,除了生成器,还需要多训练一个判别器discriminator),其通常是一个神经网络。判别器会输入一张图片,输出一个标量,其数值越大就代表现在输入的图片越像是真实的图像。举例来说,假设1是最大的值,生成得很好的图像输出就是1,不知道在画什么就输出0.5,再差一些就输出0.1 等等。判别器从本质来说与生成器一样也是神经网络,是由我们自己设计的。

在这里插入图片描述

举一个使用GAN生成动漫人物图像的例子:首先, 第一代生成器的参数几乎是完全随机的,所以它根本就不知道要怎么画动漫人物,所以其画出来的东西就是一些莫名其妙的噪音。那判别器学习的目标是要成功分辨生成器输出的动漫图片。 当然在上图里面可能非常容易,对判别器来说它只要看图片中是否有两个黑黑的眼睛即可。接下来生成器就要通过训练调整里面的参数来骗过判别器。假设判别器判断一张图片是不是真实图片的依据是看图片有没有眼睛,那新的生成器就需要输出有眼睛的图片。所以生成器产生眼睛出来,它是可以骗过第一代的判别器的。同时判别器也是会进化的,其会试图分辨新的生成器与真实图片之间的差异。例如,通过有没有嘴巴来识别真假。所以第三代的生成器就会想办法去骗过第二代的判别器,比如把嘴巴加上去。当然同时判别器也会逐渐的进步,会越来越严苛,来“逼迫”生成器产生出来的图片越来越像动漫的人物。所以生成器和判别器彼此之间是一直的互动、促进关系,和我们所说的“内卷”一样。最终,生成器会学会画出动漫人物的脸,而判别器也会学会分辨真假图片,这就是 GAN 的训练过程。

1.2 生成器与辨别器的训练过程

在这里插入图片描述

第一步,生成器和判别器是两个网络,在训练前我们要先分别进行参数初始化。然后固定生成器,只训练判别器。因为生成器的初始参数是随机初始化的,所以它什么都没有学习到,输入一系列采样得到的向量给它,它的输出肯定都是些随机、混乱的图片。这时,我们开始训练判别器,判别器的训练目标是要分辨真正的动漫人物与生成器产生出来的动漫人物间的差异。我们从图库中采样一些动漫人物头像图片,再将其与生成的结果作对比,将真正图片的标签标1,生成器产生的图片标签标0。此时,将训练判别器看作为分类或回归问题。如果是分类问题,判别器应能将真实图片当作类别1,将生成图片当作类别2;如果是回归问题,判别器得到真实图片的输入就要输出1,得到生成图片的输入就要输出0,并在0-1之间打分。

在这里插入图片描述

第二步,固定判别器,只训练生成器。训练生成器的目的就是让生成器想办法去骗过判别器,因为在第一步中判别器已经学会分辨真图和假图间的差异,如果生成器如果可以骗过判别器,那生成器产生出来的图片可能就可以以假乱真。现在,生成器先产生一个图片,然后将这个图片输入到判别器中,判别器会给这个图片一个打分。这里判别器是固定的,它只需要给更“真”的图片更高的分数即可,生成器训练的目标就是 让图片更加真实,也就是提高分数。生成器和判别器都是有很多层的神经网络络,我们通常将两者一起当作一 个比较大的网络来看待,但是不会调整判别器部分的模型参数,判别器在这一步是固定的。

GAN 算法的两个步骤:步骤一,固定生成器训练判别器;步骤二,固定判别器训练生成器。接下来就是重复以上的训练,训练完判别器固定判别器训练生成器。训练完生成器以后再用生成器去产生更多的新图片再给判别器做训练。训练完判别器后再训练生成器, 如此反覆地去执行。当其中一个进行训练的时候,另外一个就固定住,期待它们都可以在自己的目标处达到最优,这就是生成式对抗网络的思想。

1.3 信息论

在介绍GAN的理论之前,我认为有必要先在这里学习一下信息论相关的知识。

1.3.1 信息量

信息量Amount of Information)表示事情包含的信息量大小(事件发生的难度有多大)。小概率事件,它发生的难度比较大,所以有较大的信息量。大概率事件,它发生的难度比较小,所以有较小的信息量。例如:小明考试及格的概率是20%,则不及格的概率就是80%。小明考试及格这件事,就是小概率事件,发生的难度大,信息量大;小明考试不及格这件事,就是大概率事件,发生的难度小,信息量小。

信息量的性质:对于独立事件A、B,有 p ( A B ) = p ( A ) p ( B ) p(AB) = p(A)p(B) p(AB)=p(A)p(B)。两个事件同时发生的信息量等于两个事件的信息量相加,有 I ( A B ) = I ( A ) + I ( B ) I(AB) = I(A) + I(B) I(AB)=I(A)+I(B)

信息量公式 I ( x ) = log ⁡ 2 ( 1 p ( x ) ) = − log ⁡ 2 ( p ( x ) ) I(x) = {\log _2}(\frac{1}{{p(x)}}) = - \log {}_2(p(x)) I(x)=log2(p(x)1)=log2(p(x))

这样设计信息量公式的原因是,要满足上面信息量的定义和性质:

  • 概率 p ( x ) p(x) p(x)和信息量 I ( x ) I(x) I(x)是负相关的,所以设计为 1 p ( x ) \frac{1}{{p(x)}} p(x)1

  • 两个事件同时发生的信息量等于两个事件的信息量相加,所以设计为log的形式

I ( A B ) = log ⁡ 2 ( 1 p ( A B ) ) = log ⁡ 2 ( 1 p ( A ) p ( B ) ) = log ⁡ 2 ( 1 p ( A ) ) + log ⁡ 2 ( 1 p ( B ) ) = I ( A ) + I ( B ) I(AB) = {\log _2}(\frac{1}{{p(AB)}}) = {\log _2}(\frac{1}{{p(A)p(B)}}) = {\log _2}(\frac{1}{{p(A)}}) + {\log _2}(\frac{1}{{p(B)}}) = I(A) + I(B) I(AB)=log2(p(AB)1)=log2(p(A)p(B)1)=log2(p(A)1)+log2(p(B)1)=I(A)+I(B)

log以2为底,是转换到二进制下表示复杂度。其实以e为底,以10为底都可以,只不过以2为底更优。

1.3.2 熵

Entropy)表示概率分布的信息量期望: H ( p ) = E ( I ( x ) ) H(p) = E(I(x)) H(p)=E(I(x)),亦可以理解为系统整体的信息量。其中,系统整体由所有可能发生的事件构成。比如抛硬币,抛正面和抛反面就构成一个系统整体。

在这里插入图片描述

熵的公式 H ( p ) = ∑ p i I i p = − ∑ p i log ⁡ 2 ( p i ) H(p) = \sum {{p_i}} I_i^p = - \sum {{p_i}} {\log _2}({p_i}) H(p)=piIip=pilog2(pi)

熵的作用:用来评估概率模型的不确定性程度。不确定性越大,熵越大;不确定性越小,熵越小。

在这里插入图片描述

如上图,左边的图片类似于一个均匀分布,右边的图片类似于一个正态分布。均匀分布中概率都相等,完全不确定哪一个会发生,因此均匀分布的不确定性程度较高;正态分布中,概率的差异明显,因此正态分布的不确定性程度较低。

例子在这里插入图片描述

结论

  • 若概率密度均匀,产生的随机变量的不确定性就更高,则熵的值就更大
  • 若概率密度聚拢,产生的随机变量的不确定性就更低,则熵的纸较小
1.3.3 交叉熵

假设真实概率分布为 p p p,预测概率分布(估计概率分布)为 q q q

交叉熵Cross Entropy)表示预测概率分布 q q q对真实概率分布 p p p的平均信息量的估计。

交叉熵公式 H ( p , q ) = ∑ p i I i q = − ∑ p i log ⁡ 2 ( q i ) H(p,q) = \sum {{p_i}} I_i^q = - \sum {{p_i}} {\log _2}({q_i}) H(p,q)=piIiq=pilog2(qi)

例子

在这里插入图片描述

结论

  • 预估概率分布与真实概率分布越接近,交叉熵越小。

  • 交叉熵的值总是大于熵的值,根据吉布斯不等式。

在这里插入图片描述

1.3.4 相对熵/KL散度

相对熵Relative Entropy)/ KL散度KL Divergence),用于衡量2个概率分布之间的差异。

KL散度公式:(交叉熵减去熵)

D K L ( p ∥ q ) = ∑ p i [ I q − I p ] {D_{KL}}(p\parallel q) = \sum {{p_i}\left[ {{I_q} - {I_p}} \right]} DKL(pq)=pi[IqIp]

= ∑ p i [ log ⁡ 2 ( 1 q i ) − log ⁡ 2 ( 1 p i ) ] = \sum {{p_i}} \left[ {{{\log }_2}(\frac{1}{{{q_i}}}) - {{\log }_2}(\frac{1}{{{p_i}}})} \right] =pi[log2(qi1)log2(pi1)]

= ∑ p i log ⁡ 2 ( 1 q i ) − ∑ p i log ⁡ 2 ( 1 p i ) = \sum {{p_i}} {\log _2}(\frac{1}{{{q_i}}}) - \sum {{p_i}} {\log _2}(\frac{1}{{{p_i}}}) =pilog2(qi1)pilog2(pi1)

= H ( p , q ) − H ( p ) = H(p,q) - H(p) =H(p,q)H(p)

= ∑ p i log ⁡ 2 ( p i q i ) = \sum {{p_i}} {\log _2}(\frac{{{p_i}}}{{{q_i}}}) =pilog2(qipi)

KL散度性质

  • D K L ( p ∥ q ) {D_{KL}}(p\parallel q) DKL(pq) D K L ( q ∥ p ) {D_{KL}}(q\parallel p) DKL(qp)是不一样的, D K L ( p ∥ q ) ≠ D K L ( q ∥ p ) {D_{KL}}(p\parallel q) \ne {D_{KL}}(q\parallel p) DKL(pq)=DKL(qp) D K L ( p ∥ q ) {D_{KL}}(p\parallel q) DKL(pq)表示以 p p p为基准(为真实概率分布),估计概率分布 q q q与真实概率分布 p p p之间的差异; D K L ( q ∥ p ) {D_{KL}}(q\parallel p) DKL(qp)表示以 q q q为基准(为真实概率分布),估计概率分布 p p p与真实概率分布 q q q之间的差异。
  • 由上面介绍的吉布斯不等式可知: D K L ( p ∥ q ) ≥ 0 {D_{KL}}(p\parallel q) \ge 0 DKL(pq)0;当分布 p p p和分布 q q q完全一样时, D K L ( p ∥ q ) = 0 {D_{KL}}(p\parallel q) = 0 DKL(pq)=0
1.3.5 交叉熵损失函数

由上可知,KL散度能够衡量2个概率分布之间的差距,所以我们直接将损失函数定义为KL散度: L o s s = D K L ( p ∥ q ) L{\rm{oss}} = {D_{KL}}(p\parallel q) Loss=DKL(pq),并且我们希望模型的预测分布 p p p与真是分布 q q q完全相同,即: L o s s = D K L ( p ∥ q ) = 0 L{\rm{oss}} = {D_{KL}}(p\parallel q) = 0 Loss=DKL(pq)=0

L o s s = D K L ( p ∥ q ) = H ( p , q ) − H ( p ) = ∑ p i log ⁡ 2 ( 1 q i ) − ∑ p i log ⁡ 2 ( 1 p i ) L{\rm{oss}} = {D_{KL}}(p\parallel q) = H(p,q) - H(p) = \sum {{p_i}} {\log _2}(\frac{1}{{{q_i}}}) - \sum {{p_i}} {\log _2}(\frac{1}{{{p_i}}}) Loss=DKL(pq)=H(p,q)H(p)=pilog2(qi1)pilog2(pi1)

对于分类问题,真实分布是一个单点分布,真实类别的概率为1,其他类别的概率为0,类似如下:

类别class1class2class3class4
概率0010

1.3.6 JS散度

由于KL散度是非对称的, D K L ( p ∥ q ) ≠ D K L ( q ∥ p ) {D_{KL}}(p\parallel q) \ne {D_{KL}}(q\parallel p) DKL(pq)=DKL(qp)JS散度在其基础上,稍作修改,有 D J S ( p ∥ q ) = D J S ( q ∥ p ) {D_{JS}}(p\parallel q) = {D_{JS}}(q\parallel p) DJS(pq)=DJS(qp),成为对称的。

[外链图片转存中...(img-h3C1OYnv-1724950774844)]

1.4 GAN的理论介绍

生成器的输入是一系列的从分布中采样出的向量,生成器就会产生一个比较复杂的分布,我们称之为 P G {P_G} PG。另外我们还有一组原始数据,这些数据会形成另一个分布,我们称之为 P d a t a {P_{data}} Pdata。GAN的训练效果是希望 P G {P_G} PG P d a t a {P_{data}} Pdata尽可能得相似。

在这里插入图片描述

差异Divergence),是衡量两个分布的相似度的一个指标,我在上面学习KL Divergence时,提到“当分布 p p p和分布 q q q完全一样时, D K L ( p ∥ q ) = 0 {D_{KL}}(p\parallel q) = 0 DKL(pq)=0。”。即我们现在要求 P G {P_G} PG P d a t a {P_{data}} Pdata之间的差异越小越好,越小越表明 P G {P_G} PG P d a t a {P_{data}} Pdata相似。上图中,使得 P G {P_G} PG P d a t a {P_{data}} Pdata分布最相似的最优的生成器称为 G ∗ {G^ * } G

然而,训练生成器的过程训练例如卷积神经网络等简单网络非常地像,相比于之前的找一组参数最小化损失函数,我们现在其实也定义了生成器的损失函数,即 P G {P_G} PG P d a t a {P_{data}} Pdata之间的差异。 对于一般的神经网络,其损失函数是可以计算的,但是对于生成器的差异,其中连续的差异例如KL散度和JS散度是很复杂的,在实际离散的数据中,我们或许无法计算其对应的积分。

对于GAN,只要我们知道怎样从 P G {P_G} PG P d a t a {P_{data}} Pdata中采样,就可以计算得到差异,而不需要知道实际的公式,这其中要依靠判别器的力量。我们在训练判别器时,其训练目标是看到真实数据就给它比较高的分数,看到生成的数据就给它比较低的分数。这时,我们希望训练判别器时是最大化其目标函数,该目标函数就写为了下图所示的 V ( G , D ) V(G,D) V(G,D)

在这里插入图片描述

我们希望目标函数 V ( G , D ) V(G,D) V(G,D)越大越好,其中 y y y如果是从 P d a t a {P_{data}} Pdata中采样得到的真实数据,分数就要越大越好,因为 D ( y ) D(y) D(y)大, log ⁡ D ( y ) \log D(y) logD(y)就大;如果是从 P G {P_G} PG采样得到的生成数据,它就要越小越好,因为 D ( y ) D(y) D(y)越小, log ⁡ ( 1 − D ( y ) ) \log (1 - D(y)) log(1D(y))就越大。这个过程在 GAN 提出之初,人们将其写为这样其实还有一个缘由,就是为了让判别器和二分类产生联系,因为这个目标函数本身就是一个交叉熵乘上一个负号。训练一个分类器时的操作就是要最小化交叉熵, 所以当我们最大化目标函数的时候,其实等同于最小化交叉熵,也就是等同于是在训练一个分类器,训练后就等同于是解了这个优化问题。

在这里插入图片描述

上图红框中的 max ⁡ V ( G , D ) \max V(G,D) maxV(G,D)与JS散度有关。如上图,当示蓝色的星星和红色的星星混在一起时,两种分布的差异不大,交叉熵的值大,交叉熵的负值小,也就是 V ( G , D ) V(G,D) V(G,D)小,在最大化 V ( G , D ) V(G,D) V(G,D)时,很难让目标函数 V ( G , D ) V(G,D) V(G,D)达到最大值。但是当两组数据差距很大时,也就是蓝色的星星和红色的星星并没有混在一起,那么分类器就可以轻易地把它们分开,交叉熵的值小,交叉熵的负值大,也就是 V ( G , D ) V(G,D) V(G,D)大,在最大化 V ( G , D ) V(G,D) V(G,D)时,目标函数 V ( G , D ) V(G,D) V(G,D)就可以很大。

将:

在这里插入图片描述

中的Divergence替换为:
在这里插入图片描述

总结

后面会继续重点学习GAN的数学原理,这一节的数学知识较多,需要好好消化一下。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

知识竞赛活动中的一些新颖特殊的赛制

以下知识竞赛海活动一些特殊新颖的竞赛规则,可以作为特殊情况下的参考。 (一)争分夺秒 答题选手:各队1号选手。1和2号队、3和4号队、5和6号队、7和8号队各为一组。 答题步骤:1号队和2号队1号选手同时离开座位&#x…

企业如何防止内部人员泄密?(5种方法详细说明)

企业内部信息泄密问题已经成为许多企业的严重威胁。随着数字化办公的普及,企业信息泄密的风险越来越高。内部人员泄密问题更是防不胜防,因此企业必须采取有效的措施来防止内部人员泄密。以下是五种可以帮助企业防止内部人员泄密的方法: 1. 使…

【412】【统计近似相等数对 I】

我的思路: 两层循环找数组两个数 然后进行1次过滤,如果数字相同直接下一组 不相同的话就要进行2次过滤 方便处理,转移到str格式 change函数用于比较两个输入的字符串是否相同 change中使用两层循环暴力调用两位数位进行交换比较&#xf…

SpringBoot 新手入门(实操)

Spring Boot 是一个开源框架,旨在简化基于 Spring 的 Java 应用程序的开发。它通过提供一系列默认配置和约定大于配置的理念,让开发者可以更快速地创建和部署应用。以下是一个 Spring Boot 新手入门的实操指南,帮助你从零开始创建一个简单的 …

Gitee上传项目(从0开始)

1.默认你Git已经下载好的情况下。 下载好的两种显示: 1.右击桌面显示这个 2.如果没有情况1出现,需要自己去创建快捷方式 2.去网站创建仓库 网站参考:yanyongzhitest/java_web - 码云 - 开源中国 (gitee.com) 新建仓库: 仓库名…

科研绘图系列:R语言基因PPI互作网络图(PPI network plot )

介绍 基因的PPT互作网络图。 加载R包 导入所需要的R包,在导入前需要用户自己安装。 library("tidyverse") library("magrittr") library("here") library("janitor") library("ggpubr") library("ComplexHeatmap&…

js函数方法apply,bind,call,手写new操作符

函数方法 函数方法可以用来改变函数的this指向,对于内置的标准函数来说,改变this就相当于改变了函数的作用目标;比如说,对于一个对象的方法toString(),可以将它的使用目标修改成指定的参数, 这里原本是对o…

大语言模型数据增强与模型蒸馏解决方案

背景 在人工智能和自然语言处理领域,大语言模型通过训练数百亿甚至上千亿参数,实现了出色的文本生成、翻译、总结等任务。然而,这些模型的训练和推理过程需要大量的计算资源,使得它们的实际开发应用成本非常高;其次&a…

Android经典实战之OkDownload:一个经典强大的文件下载开源库,支持断点续传

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 OkDownload 是一个为 Android 平台设计的开源下载框架,它支持多线程下载、多任务处理、断点续传等功能,并且具有可靠性、…

8款好用的电脑监控软件推荐?(一口气了解8款!)赶紧Get吧!

电脑监控软件成为了企业和个人管理电脑、提高工作效率、保护信息安全的重要工具。 这些软件不仅能够实时监控电脑的使用情况,还能帮助管理者制定合理的工作计划,预防潜在的安全风险。 本文将为您详细介绍八款功能强大、易于使用的电脑监控软件&#xff…

stm32之软件I2C读写MPU6050陀螺仪、加速度传感器应用案例

系列文章目录 1. stm32之I2C通信协议 文章目录 系列文章目录前言一、电路接线图二、应用案例代码三、应用案例分析3.1 I2C通信模块3.2 MPU6050模块 前言 提示:本文主要用作在学习江科大自化协STM32入门教程后做的归纳总结笔记,旨在学习记录&#xff0c…

空间计量 | 空间杜宾误差模型SDEM

空间计量研究中,空间杜宾误差模型,其考虑两项,分别是自变量X的空间滞后作用,以及误差扰动项的空间滞后作用,其数学模型公式如下: y βk * x θk * Wx u, u λ * Wu (其中βk表示X的回归系…

AI学习记录 - 线性代数(3Blue1Brown)

一天更新一点点,只更新重点内容,一句话定义,简单的定义,避免脑子及记太多 向量的加法就是一种趋势运动 向量的延长缩短,就是分量的延长缩短 基向量就是在平面或者任意维度空间随便定义的一个向量 多个基向量的组合可…

每天分享一个FPGA开源代码(1)- spi

1、SPI总线进行通信的结构 SPI总线主要包括四根关键信号线: (1)SCK (Serial Clock) 串行时钟线,由主设备产生,控制数据传输的速率和时机。 (2)MOSI (Master Out Slave In) 主设备数据输出线…

指针的一些细节补充———C语言

野指针: 1.未初始化的指针: eg: int *p; // 未初始化的指针 *p 5; // 未定义行为,p 是野指针 ————————————————————————————————————————————————————————…

记Codes 开源研发项目管理平台——管理系统颠覆性创新实现之事件驱动+信息流

引言 市面上所有管理系统,数据都不是以推流的方式展现到前端,有新数据产生需主动刷新页面才能看到,也就是“人找事”;而不是主动推送的“事找人”,Codes 敢为人先,采用事件驱动信息流实现“事找人”。 1、…

一起学习LeetCode热题100道(64/100)

64.搜索二维矩阵(学习) 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则&am…

Java Excel转PDF(免费)

目前市面上 Excel 转 PDF 的组件较多: 收费:aspose、GcExcel、spire开源:jacob、itextpdf 其中收费的组件封装得比较好,代码简洁,转换的效果也很好,但收费也高得离谱: 为了成本考虑&#xff…

共享单车|基于SprinBoot+vue的共享单车数据储存系统(源码+数据库+文档)

共享单车数据储存系统 基于SprinBootvue的共享单车数据储存系统 一、前言 二、系统设计 三、系统功能设计 系统登录注册实现 管理员模块实现 用户模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介…

STM32和TMSF28335定时器的系统时钟问题

用户可通过多个预分频器配置AHB、高速APB(APB2)和低速APB(APB1)域的频率。AHB和APB2域的最大频率是72MHz。APB1域的最大允许频率是36MHz。 定时器时钟频率分配由硬件按以下2种情况自动设置: 如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线…