草庐IT

神经网络学习笔记6——生成式AI绘画背后的的GAN与Diffusion初解

RanceGru 2023-05-20 原文

系列文章目录


文章目录


AI绘画

AI绘画,目前AI领域里最有话题性的技术,上一个这么火的话题是swin transformer网络,而2022年8月Jason Allen凭借AI绘画作品《太空歌剧院》拿下科罗拉多州博览会美术竞赛一等奖,瞬间引爆社会争论。后来10月19日,Jasper.ai 宣布完成了 1.25 亿美元的A 轮融资,估值达到了 15 亿美金,而 Jasper AI 从产品上线到现在也就 18 个月时间。

但是这里就不谈论它的社会层面与资本层面,而是从技术层面出发,了解一下他背后的技术变化与简单原理。

对于AI和画,我最开始接触的是图片漫转,像什么风景动漫化,人物动漫化、生成人物年幼年老照片。其实自2014年诞生以来,GAN的发展非常迅速,最初的GAN难以生成高质量的图像,而现在的GAN已经可以这些模型从生成模糊的人脸到具有不同约束的高清逼真图片。

2018 年,大型半导体公司 NVIDIA 的研究团队发布了“StyleGAN”,作为 GAN 的应用,它在图像生成领域产生了巨大影响。StyleGAN 生成的人像精度高到与真人无异,引起了广泛关注。StyleGAN 此后发布了性能改进版本,例如 StyleGAN2、StyleGAN2-ADA 和 StyleGAN3。

但是随着Diffusion Model的出现似乎一切都变了,在2021年它甚至可以说混在小众没有破圈,在2022年它却大红大紫引领风潮。
其中的代表人物Stable Diffusion 的文本到图像更是横空出世, 将无过滤图像生成的门槛下放到历史最低——文本生成图像、图像+文本生成图像以及补全图像中的某个部分(例如把猫换成一只狗),就能得到相应的图像结果。它一边被 AI 艺术界所称道,另一边则被传统艺术家激烈批评;

关键词:Withered vines, old trees, crows(枯藤老树昏鸦,只能理解英文)
尝试网址1:https://replicate.com/stability-ai/stable-diffusion
尝试网址2:https://huggingface.co/spaces/stabilityai/stable-diffusion

现实风格

水墨画风格

去Hugging Face等网站体验了一番,能够感觉得到它能明白并融入部分关键词元素,不得不说确实是很强很新奇,不论是真实程度亦或是想象、理解能力,都是比较符合人类的想象。

2021年Diffusion Models Beat GANs on Image Synthesis在NeurIPS 2021上发表,认为Diffusion模型可以实现优于当前最先进的生成模型的图像样本质量。

对于GAN和Diffusion Model,选择哪一个进行图像合成或者说图像合成谁才是最出色的模型,这就成为了一个争论,甚至业界大佬都有所评论

它们都在图像、视频和语音生成领域得到了广泛应用,引发了关于哪种方法能产生更好结果的争论——扩散模型还是 GAN。

也有人对diffusion model 和 GAN 的有别的思考:GAN 能更灵活处理不同任务,应用层面部署比较容易,需要的资源小,不过学术上竞争激烈,有时生成的样本质量比较一般。且GAN在对抗训练过程中会出现模式崩塌和训练不稳定的问题,VAE则严重依赖于目标损失函数,流模型则必须使用专门的框架来构建可逆变换等问题。

Diffusion model 相对不太灵活,缺少良好的 latent space 性质,资源消耗极大,但生成效率略高于auto-regressive model, 主要优点质量好,学术上容易出论文。在DALLE2开源时候,普通人确实用不起的,但Stable Diffusion经过优化后一张卡就能放得下了,做到了真真正正的亲民,且它具有的公式理念比GAN的超参更容易理解。

当然diffusion model 和 GAN 不一定是天然对手,在既有交手也会有合作融合的时候,说不定会像VIT和CNN相互借鉴。


GAN前言

GAN的全称是Generative adversarial network,中文翻译过来就是生成对抗网络。生成对抗网络其实是两个网络的组合:
生成网络(Generator)负责生成模拟数据。生成网络要不断优化自己生成的数据让判别网络判断不出来。
判别网络(Discriminator)负责判断输入的数据是真实的还是生成的。判别网络也要优化自己让自己判断得更准确。
二者关系形成对抗,因此叫对抗网络,它们之间的关系可以用竞争或敌对关系来描述。
我们可以拿捕食者与被捕食者之间的例子来类似说明两者之间的关系。在生物进化的过程中,被捕食者会慢慢演化自己的特征,使自己越来越不容易被捕食者识别捕捉到,从而达到欺骗捕食者的目的;与此同时,捕食者也会随着被捕食者的演化来演化自己对被捕食者的识别,使自己越来越容易识别捕捉到捕食者。这样就可以达到两者共同进化的目的。生成器代表的是被捕食者,鉴别器代表的是捕食者,而GAN希望被捕猎者赢得最后的胜利。

论文


一、生成网络与判别网络的协同进化

1、生成器与判别器的学习趋向


图中的黑色虚线表示真实的样本的分布情况
蓝色虚线表示判别器判别概率的分布情况
绿色实线表示映射的生成样本的分布。
Z-X 表示均匀分布采样得到噪声z到表示通过拟合生成器x之后的分布的映射情况。

目标是使用生成样本分布(绿色实线)去拟合真实的样本分布(黑色虚线),来达到生成以假乱真样本的目的。

(a)状态处于最初始的状态的时候,生成器生成的分布和真实分布区别较大,并且判别器判别出样本的概率曲折不稳定,因此去训练判别器来更好地分辨样本。

(b)样本状态是通过多次训练判别器来达到,此时判别样本区分得非常显著和良好,能够明显做出分类判别。然后再对生成器进行训练。

(c)样本状态经过训练,使得生成器与判别器进行对比,能够拟合学习到新数据,此时生成器分布相比之前峰值逐渐逼近了真实样本分布。

(d)状态经过多次反复训练迭代之后,使得生成样本分布拟合于真实样本分布,并且判别器分辨不出样本是生成的还是真实的(判别概率均为0.5)。也就是说我们这个时候就可以生成出非常真实的样本,达成目的。

2、部分算法理念


其中,G代表生成器, D代表判别器, x代表真实数据, Pdata代表真实数据概率密度分布,z代表了随机输入数据作为随机高斯噪声。
以MLP作为生成G与辨别D的简单模型,通过minimax训练G的同时也会训练D,而生成的数据是使得判别器尽量察觉的犯错达到最小化。在这个过程中D是努力去区分数据,G是努力生成区分不了的数据,最终目的是为了达到一个D与G都无法继续学习进步为止,并称之为博弈论中的纳什均衡。
从上式可以看出,判别器D希望能尽可能区分真实样本x和生成样本G(z),因此D(x)必须尽可能大来表示区分力度,D(G(z))尽可能小来缩小与真实数据的区别, 综合来说就是V(D,G)整体尽可能大。从生成器G的角度来看,生成器G希望自己生成的虚假数据G(z)可以尽可能骗过判别器D,也就是希望D(G(z))尽可能大,也就是V(D,G)整体尽可能小。GAN的两个模块在训练V上的相互对抗,最后达到全局最优与平衡。

制作两个for循环,这两个for循环是嵌套在一起的,外部for循环执行迭代,内部for循环执行k次以下内容:

  1. 采样m个噪音样本
  2. 采样m个真实示例
  3. 将采样的2m数据传入第一条公式(真实放在x,噪音放在z)来计算辨别器的参数与梯度,用来更新辨别
  4. end for
  5. 再采样m个噪音样本
  6. 将新采样的噪音传入第二条公式(噪音放在z)来计算生成器的梯度,用来更新生成器
  7. 先更新辨别器再更新生成器,迭代k轮(k是超参数)

k值是一个需要控制浮动的值,以保证生成辨别两者之间的逐步拟合。太好导致辨别器处于完美要求过高,太坏导致跟不上生成器的更新而摆烂,这种一边倒的情况就无法使得生成器与辨别器之间产生有益对抗,类似于曲折前进的对抗学习。


Pdata(x)是指我把x放入真实数据分布中的百分比数值是多少
Pg(x)是指我把x放入G学习到的分布中的百分比数值是多少

当G固定住的时候,辨别器D的最优解是1/2,可以观察图(d),当生成样本分布拟合于真实样本分布时,判别器分辨不出样本是生成的还是真实的,这时它不在0也不在1,而是1/2。

Pdata和Pg分布数值都是0-1之间,因此DG(x)的数值也在0-1之间,当Pdata(x)==Pg(x),那么DG(x)=1/2。意味着辨别器D最优解的时候输出的值永远都是1/2,表示这两个分布是完全重合,D无法区分真实与生成数据。
D*G是通过从两个分布(真实的数据和生成的数据)分别采样,用V(D,G)这个目标函数训练一个二分类的分类器,如果这个分类器的值都是1/2,就证明这两个分布完全重合了。


Diffusion 前言

Diffusion最早是15年的一篇文章提出的,但当时并不完善,直到20年时的DDPM才真正落地。之后的事情大家也就知道了,从21年底到22年间,先后有OpenAI的GLIDE、DALLE2和Google的Imagen都用上了这个工作。

Diffusion的核心思想,就是把生成的过程拆成一个个简单的小步骤,而不是像其他模型一样「一步到位」,这样拟合起来相对容易,所以做出来效果很好,同时训练起来也更加稳定。

Diffusion Model (扩散模型) 是一类生成模型, 和 VAE (Variational Autoencoder, 变分自动编码器), GAN (Generative Adversarial Network, 生成对抗网络) 等生成网络不同的是, 扩散模型在前向阶段对图像逐步施加噪声, 直至图像被破坏变成完全的高斯噪声, 然后在逆向阶段学习从高斯噪声还原为原始图像的过程。它从物理现象中汲取灵感;它被称为扩散模型。扩散模型背后的中心思想来自气体分子的热力学,分子从高密度区域扩散到低密度区域。这种运动在物理学文献中通常被称为熵增或热寂。在信息论中,这相当于由于噪声的逐渐介入而导致的信息丢失。

扩散建模的关键概念是,如果我们可以建立一个学习模型来学习由于噪声引起的信息系统衰减,那么应该可以逆转这个过程,从而从噪声中恢复信息。这个概念类似于 VAE,因为它试图通过首先将数据投影到潜在空间然后将其恢复到初始状态来优化目标函数。然而,该系统不是学习数据分布,而是旨在对一系列噪声分布进行建模马尔可夫链并通过以分层方式对数据进行撤消/去噪来“解码”数据。


一、Diffusion前向过程

扩散的原理:
有一桶10升的矿泉水,我第一次往里面添加了一滴墨水并搅拌让它随机均匀分布,这时观察这桶矿泉水发现是几乎没什么变化,那我滴入第二滴墨水,第三滴直到第N滴,这个过程中会发现水质逐渐浑浊变黑,只就是色素在水分子中的扩散。
那么放在图像领域里,噪音就是墨水,图片就是矿泉水,把噪音一点点分批次的随机均匀的满足高斯分布的规律来注入猫猫图片中,从0到100到200到N次图片从清晰到微暇到模糊到麻花,猫猫的规律逐渐消失。

就比如这张S 曲线合成数据集的前向扩散过程结果图,他的规律就是由像素点去组成S的规律,从X0到X∞,从规律到混乱。

通过加噪音去加强他的不规律的地方,破坏图片中规律性弱的地方,而规律性强的地方一时半会是破坏不了的,随着噪音的添加,规律性会从弱到强逐渐淘汰。

公式(1)中β是一个衰减权重,负责控制噪音z的幅度变化,随着次数增加,β要越来越大比如论文中是0.0001到0.002,使得注入的噪音会比上一次多。而 x t x_t xt是t时刻的一个分布,它是由上一时刻 x t − 1 x_{t-1} xt1和噪音z组成。

公式(2)中的 α t {\sqrt α_t } α t 1 − α t \sqrt {1- α_t} 1αt 又是从公式(1)中脱胎而出的,是β这个权重的变体,所以这两者可以理解为是权重的一种。越到最后β会越大,那么根据公式(1)可知 α t {α_t } αt随之变小,那么 α t \sqrtα_t α t 也会变小,而 1 − α t \sqrt{1-α_t} 1αt 逆反过来其实就是β,说明越往后对噪声 z z z影响越大。总的来说越到后面其实 x t x_t xt受上一时刻 x t − 1 x_{t-1} xt1影响减少,受噪音 z z z影响增多,而且服从标准正态分布,简单理解就是越往后噪音注入的比例会更多。

α t = 1 − β t ( 1 ) α_t = 1-β_t (1) αt=1βt1

x t = α t x t − 1 + 1 − α t z 1 ( 2 ) x_t = \sqrt α_t x_{t-1} + \sqrt {1- α_t} z_1 (2) xt=α txt1+1αt z12

虽然我们可以从输入的图像 x 0 x_0 x0开始一直递归计算到 x n x_n xn但是会产生一个问题,如果是递归会不会太慢了,可不可以直接从 x 0 x_0 x0直接得到 x t x_t xt呢?

结合公式(2)再逆推出 x t − 1 x_{t-1} xt1的公式(3),把公式(3)代入公式(2)的 x t − 1 x_{t-1} xt1里得到公式(4)。再把公式(4)化简得到公式(5),其中因为 z 1 z_1 z1 z 2 z_2 z2都符合高斯分布也就是正态分布 X ∼ N ( μ , σ 2 ) X∼N(μ,σ^2) XN(μ,σ2),标准正态分布则是μ = 0,σ = 1,所以 1 − α t z 1 \sqrt {1- α_t} z_1 1αt z1 1 − α t − 1 z 2 \sqrt {1- α_{t-1}} z_2 1αt1 z2分别为 N ( μ t , 1 − α t ) N(μ_t,1-\alpha_t) N(μt,1αt) N ( μ t − 1 , α t ( 1 − α t − 1 ) ) N(μ_{t-1},\alpha_t(1-\alpha_{t-1})) N(μt1,αt(1αt1)),而两个不同的高斯分布相加后仍然符合高斯分布并用 z ˉ 2 \bar{z}_2 zˉ2表示,结合公式(6)将 N ( μ t , 1 − α t ) N(μ_t,1-\alpha_t) N(μt,1αt) N ( μ t − 1 , α t ( 1 − α t − 1 ) ) N(μ_{t-1},\alpha_t(1-\alpha_{t-1})) N(μt1,αt(1αt1))相加开方得到高斯分布 1 − α t α t − 1 z ˉ 2 \sqrt {1- α_tα_{t-1}} \bar{z}_2 1αtαt1 zˉ2

x t − 1 = α t − 1 x t − 2 + 1 − α t − 1 z 2 ( 3 ) x_{t-1} = \sqrt {α_{t-1}} x_{t-2} + \sqrt {1- α_{t-1}} z_2 (3) xt1=αt1 xt2+1αt1 z23

x t = α t ( α t − 1 x t − 2 + 1 − α t − 1 z 2 ) + 1 − α t z 1 ( 4 ) x_t = \sqrt α_t(\sqrt {α_{t-1}} x_{t-2} + \sqrt {1- α_{t-1}} z_2)+ \sqrt {1- α_t} z_1 (4) xt=α t(αt1 xt2+1αt1 z2)+1αt z14

x t = α t α t − 1 x t − 2 + 1 − α t α t − 1 z ˉ 2 ( 5 ) x_t = \sqrt {α_t α_{t-1}} x_{t-2} + \sqrt {1- α_tα_{t-1}} \bar{z}_2 (5) xt=αtαt1 xt2+1αtαt1 zˉ25

N ( μ 1 , σ 1 2 I ) + N ( μ 2 , σ 2 2 I ) ∼ N ( μ 1 + μ 2 , ( σ 1 2 + σ 2 2 ) I ) ) ( 6 ) N(μ_1,\sigma^2_1 \Iota )+N(μ_2,\sigma^2_2\Iota )∼N(μ_1+μ_2,(\sigma^2_1+\sigma^2_2)\Iota)) (6) N(μ1,σ12I)+N(μ2,σ22I)N(μ1+μ2,(σ12+σ22)I))6

经过这些转换计算可以总结出一些规律,观察公式(2)和公式(5),可以发现每往前一时刻就在多乘上 α t − 前 一 时 刻 α_{t-前一时刻} αt,如果一直追溯到第0次那么就只需要一直累乘 α t , α t − 1 , α t − 2 , α t − 3 … α 0 α_t,α_{t-1},α_{t-2},α_{t-3}…α_0 αt,αt1,αt2,αt3α0,这样就解决了从 x 0 x_0 x0直接得到 x t x_t xt的逐步递归问题,那么就可以通过公式(7)来简单解决任意次数的计算扩散分布,其中 α ˉ t \bar{α}_t αˉt表示累乘的意思。

X T = α ˉ t x 0 + 1 − α ˉ t z t ( 7 ) X_T = \sqrt { \bar{α}_t} x_0 + \sqrt {1- { \bar{α}_t} } z _t(7) XT=αˉt x0+1αˉt zt7

二、Diffusion反向过程

从一堆噪音点里向同性高斯噪声数据重建结果
求出S图,虽然说在前向过程中可以通过公式去推出 x 0 x_0 x0 x t x_t xt的分布,但是在反向过程中却无法直接从 x t x_t xt逆推出 x 0 x_0 x0的。

前向过程可以理解为由各种已知因素推理出结果或者说事件发展的趋向,是由因到果。

但是实际上我们做的往往是是给出到某种现象某种结论,然后让机器去反推输出。那么机器就需要去猜测计算形成这种结果的各种因素,是由果推因。

对于这个问题,使用了贝叶斯公式(8)去解决,结合公式(8)得到公式(9)。那么 x t x_t xt是已知的果, P ( x t ∣ x t − 1 ) P(x_t∣x_{t-1}) P(xtxt1)就是公式(2)中的 x t − 1 x_{t-1} xt1 x t x_t xt。而 P ( x t − 1 ) P(x_{t-1}) P(xt1) P ( x t ) {P(x_t)} P(xt)可以通过公式(7)和 x 0 x_0 x0去求出来,这样去看三个都是可计算的已知值。

P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) ( 8 ) P(A∣B) = \frac{P(B∣A)P(A)}{P(B)} (8) P(AB)=P(B)P(BA)P(A)8

P ( x t − 1 ∣ x t ) = P ( x t ∣ x t − 1 ) P ( x t − 1 ) P ( x t ) ( 9 ) P(x_{t-1}∣x_t) = \frac{P(x_t∣x_{t-1})P(x_{t-1})}{P(x_t)} (9) P(xt1xt)=P(xt)P(xtxt1)P(xt1)9

f ( x ) = 1 2 π σ e x p − ( x − μ ) 2 2 σ 2 ( 10 ) f(x) = \frac{1}{\sqrt{2πσ}} exp^{-\frac{(x-μ)^2}{2σ^2}} (10) f(x)=2πσ 1exp2σ2(xμ)210

再结合公式(6)的正态分布分别列出这三个对应分布值。

结合正态分布公式(10)计算exp幂数

进一步化简合并同类项exp

z作为反向过程是属于一个未知值,但是我们之前的噪音z是在前向过程中计算的,所以既然是未知,那就通过预测得到,所谓预测也就是模型推导,模型数据从前向过程的z训练得来。最终通过前向来预测反向过程的z值,这个模型一般是以UNet为基础。

训练是前后向过程运用,预测使用是只用反向过程,最终输出的质量取决于超参数的调整和训练时期的数量。

DDPM论文中的训练和采样方法(就是那两个阶段)

因算力要求较高,目前手头上没有足够的资源,导致一些方面无法足够的去论证。。。
未完待续。。。

有关神经网络学习笔记6——生成式AI绘画背后的的GAN与Diffusion初解的更多相关文章

  1. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  2. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  3. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  4. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  5. ruby - 我如何学习 ruby​​ 的正则表达式? - 2

    如何学习ruby​​的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby​​的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/

  6. 深度学习12. CNN经典网络 VGG16 - 2

    深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG

  7. 机器学习——时间序列ARIMA模型(四):自相关函数ACF和偏自相关函数PACF用于判断ARIMA模型中p、q参数取值 - 2

    文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk​=Var(yt​)Cov(yt​,yt−k​)​其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞

  8. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

  9. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  10. Stable Diffusion - 2

    序言AI绘图已经火了有一段时间了,国外各种AI绘图,AI视频剪辑等已经被玩坏了。StableDiffusionInfinity免费开源的StableDiffusion已经能扩画了,StableDiffusionInfinity是其子功能,下面可以来看看这个开源项目。github克隆项目(使用镜像)如果有vpn的或者能上谷歌的同学直接上github上搜索该项目,如果没有的话,找到github镜像。镜像链接:gitclone.comvsCode打开项目该项目是python写的,可以使用vscode打开查看,vscode安装参考:RunningVisualStudioCodeonmacOS项目基本信

随机推荐