从零开始的stable diffusion

abc66c28fb1916c76b0e2d52b3829345.gif

stable diffusion真的是横空出世,开启了AIGC的元年。不知你是否有和我一样的困惑,这AI工具好像并不是那么听话?

48af653f2c3daa6b0dbc6c9b83b98baf.png

前言

我们该如何才能用好stable diffusion这个工具呢?AI究竟在stable diffusion中承担了什么样的角色?如何能尽可能快、成本低地得到我们期望的结果?

源于这一系列的疑问,我开始了漫长的论文解读。High-Resolution Image Synthesis with Latent Diffusion Models(地址:https://arxiv.org/abs/2112.10752?spm=ata.21736010.0.0.7d0b28addsl7xQ&file=2112.10752)

当然这论文看的云里雾里的,加篇读了How does Stable Diffusion work?(地址:https://stable-diffusion-art.com/how-stable-diffusion-work/?spm=ata.21736010.0.0.7d0b28addsl7xQ)

先简要概括下,stable diffusion的努力基本是为了2个目的:

  1. 低成本、高效验证。设计了Latent Space

  2. Conditioning Mechanisms。条件控制,如果不能输出我们想要的图片,那这就像Monkey Coding。耗费无限的时间与资源。

这是整个内容里最重要最核心的两个部分。

24987e946e7126efe4446a0de409605a.png

图片生成的几种方式

随着深度神经网络的发展,生成模型已经有了巨大的发展,主流的有以下几种:

  1. 自回归模型(AutoRegressive model):按照像素点生成图像,导致计算成本高。实验效果还不错

  2. 变分自编码器(Variational Autoencoder):Image to Latent, Latent to Image,VAE存在生成图像模糊或者细节问题

  3. 基于流的方法(Glow)

  4. 生成对抗网络(Generative adversarial network):利用生成器(G)与判别器(D)进行博弈,不断让生成的图像与真实的图像在分布上越来越接近。

其中AR与GAN的生成都是在pixel space进行模型训练与推理。

  模型是如何生成图片的?

以一只猫作为案例。当我们想画一只猫的时候,也都是从一个白板开始,框架、细节不断完善。

对于AI来说,一个纯是noise的image就是一个理想的白板,类似下图展示的这样。

83831de615429bf129b807773363e439.png

从图中的流程,我们可以看到推理的过程如下:

  1. 生成一个随机的noise image图片。这个noise取决于Random这个参数。相同的Random生成的noise image是相同的。

  2. 使用noise predictor预测这个图里加了多少noise,生成一个predicted noise。

  3. 使用原始的noise减去predicted noise。

  4. 不断循环2、3,直到我们的执行steps。

最终我们会得到一只猫。

在这个过程中,我们会以下疑问:

  1. 如何得到一个noise predictor?

  2. 怎么控制我们最终能得到一只猫?而不是一只狗或者其他的东西?

在回答这些疑问之前,我先贴一部分公式:

我们定义一个noise predictor:055a36f1cd181eaf5a54cbfa11c2dbe7.png36f237d2bd292bcbc354835cf8510630.png是第 t 个step过程中的noise image,t 表示第t个stop。

  如何得到一个noise predictor?

这是一个训练的过程。过程如下图所示:

264d55cb995db9f609669a741d91e085.png

  1. 选择一张训练用的图片,比如说一张猫

  2. 生成一个随机的noise图片

  3. 将noise图叠加到训练用的图片上,得到一张有一些noise的图片。(这里可以叠加1~T步noise

  4. 训练noise predictor,告诉我们加了多少noise。通过正确的noise答案来调整模型权重。

最终我们能得到一个相对准确的noise-predictor。这是一个U-Net model。在stable-diffusion-model中。

通过这一步,我们最终能得到一个noise encoder与noise decoder。

PS: noise encoder在image2image中会应用到。

以上noise与noise-predictor的过程均在pixel space,那么就会存在巨大的性能问题。比如说一张1024x1024x3的RBG图片对应3,145,728个数字,需要极大的计算资源。在这里stable diffusion定义了一个Latent Space,来解决这个问题。

  Latent Space

Latent Space的提出基于一个理论:Manifold_hypothesis

它假设现实世界中,许多高维数据集实际上位于该高维空间内的低维Latent manifolds。像Pixel Space,就存在很多的难以感知的高频细节,而这些都是在Latent Space中需要压缩掉的信息。

那么基于这个假设,我们先定义一个在RGB域的图片eb59f92b8c684ef93c6a6c491b79218a.png

然后存在一个方法z=varepsilon(x),973c830ec0f4f999bc2b160f848c2dad.jpeg,z是x在latent space的一种表达。

这里有一个因子f=H/h=W/w,通常我们定义5e330f721ffc5ab9e55ef0c486954f18.png,比如说stable-diffusion v1.5训练与推理图片在512x512x3,然后Latent Space的中间表达则是4x64x64,那么我们会有一个decoder D能将图片从Latent Space中解码出来。

f8bdad0f3ac6280c8e0d99aebb61ae97.png在这个过程中我们期望aecc1153b8dcbf658582d53c5f0a935d.png,这俩图片无限接近。

整个过程如下图所示:

55babbd97d73b27c1150fde01461db78.png

而执行这个过程的就是我们的Variational Autoencoder,也就是VAE。

那么VAE该怎么训练呢?我们需要一个衡量生成图像与训练图像之间的一个距离指标。

也就是3ac131972fb030699e2b8c0ca167b4f7.jpeg

细节就不关心了,但这个指标可以用来衡量VAE模型的还原程度。训练过程与noise encoder和noise-predictor非常接近。

贴一个stable diffusion在FID指标上,与其他方法的对比。下面的表格来自于无条件图片生成。基本就是比较Latent Space是否有丢失重要信息。

578f685174c2d516164b882c3d1e6cc9.png

  • 为什么Latent Space是可行的?

你可能在想,为什么VAE可以把一张图片压缩到更小的latent space,并且可以不丢失信息。

其实和人对图片的理解是一样的,自然的、优秀的图片都不是随机的,他们有高度的规则,比如说脸上会有眼睛、鼻子。一只狗会有4条腿和一个规则的形状。

图像的高维性是人为的,而自然的图像可以很容易地压缩为更小的空间中而不丢失任何信息。

可能说我们修改了一张图片的很多难以感知的细节,比如说隐藏水印,微小的亮度、对比度的修改,但修改后还是同样的图像吗?我们只能说它表达的东西还是一样的。并没有丢失任何信息。

  结合Latent Space与noise predictor的图像生成过程

  1. 生成一个随机的latent space matrix,也可以叫做latent representation。一种中间表达

  2. noise-predictor预测这个latent representation的noise.并生成一个latent space noise

  3. latent representation减去latent space noise

  4. 重复2~3,直到step结束

  5. 通过VAE的decoder将latent representation生成最终的图片

直到目前为止,都还没有条件控制的部分。按这个过程,我们最终只会得到一个随机的图片。

c71694a4c68f71cd34d033fbe87c045f.png

条件控制

非常关键,没有条件控制,我们最终只能不断地进行Monkey Coding,得到源源不断的随机图片。

相信你在上面的图片生成的过程中,已经感知到一个问题了,如果只是从一堆noise中去掉noise,那最后得到的为什么是有信息的图片,而不是一堆noise呢?

noise-predictor在训练的时候,其实就是基于已经成像的图片去预测noise,那么它预测的noise基本都来自于有图像信息的训练数据。

在这个denoise的过程中,noise会被附加上各种各样的图像信息。

怎么控制noise-predictor去选择哪些训练数据去预测noise,就是条件控制的核心要素。

这里我们以tex2img为案例讨论。

  Text Conditioning

下面的流程图,展示了一个prompt如何处理,并提供给noise predictor。

5e4546b9206582e6705a9c72570100ce.png


  • Tokenizer

从图中可以看到,我们的每一个word,都会被tokenized。stable diffusion v1.5使用的openai ViT-L/14 Clip模型来进行这个过程。

tokenized将自然语言转成计算机可理解的数字(NLP),它只能将words转成token。比如说dreambeach会被CLIP模型拆分成dreambeach。一个word,并不意味着一个token。同时dreambeach也不等同于dream<space>beach,stable diffusion model目前被限制只能使用75个tokens来进行prompt,并不等同于75个word。

  • Embedding


同样,这也是使用的openai ViT-L/14 Clip model. Embedding是一个768长度的向量。每一个token都会被转成一个768长度的向量,如上案例,我们最后会得到一个4x768的矩阵。

为什么我们需要embedding呢?

比如说我们输入了man,但这是不是同时可以意味着gentlemanguysportsmanboy。他们可能说在向量空间中,与man的距离由近而远。而你不一定非要一个完全准确无误的man。通过embedding的向量,我们可以决定究竟取多近的信息来生成图片。对应stable diffusion的参数就是(Classifier-Free Guidance scale)CFG。相当于用一个scale去放大距离,因此scale越大,对应的能获取的信息越少,就会越遵循prompt。而scale越小,则越容易获取到关联小,甚至无关的信息。

如何去控制embedding?

我们经常会遇到stable diffusion无法准确绘制出我们想要的内容。那么这里我们发现了第一种条件控制的方式:textual inversion

将我们想要的token用一个全新的别名定义,这个别名对应一个准确的token。那么就能准确无误地使用对应的embedding生成图片。

这里的embedding可以是新的对象,也可以是其他已存在的对象。

比如说我们用一个玩具猫训练到CLIP模型中,并定义其Tokenizer对应的word,同时微调stable diffusion的模型。而90ced4a02b6d15f373b421079c9ec373.jpeg对应toy cat就能产生如下的效果。

988ade378a73d03010f0d3564d4ef6b4.png

感觉有点像Lora的思路,具体还得调研下lora。

text transformer

在得到embedding之后,通过text transformer输入给noise-predictor

transformer可以控制多种条件,如class labels、image、depth map等。

Cross-attention

具体cross-attention是什么我也不是很清楚。但这里有一个案例可以说明:

比如说我们使用prompt "A man with blue eyes"。虽然这里是两个token,但stable diffusion会把这两个单词一起成对。

这样就能保证生成一个蓝色眼睛的男人。而不是一个蓝色袜子或者其他蓝色信息的男人。

(cross-attention between the prompt and the image)

LoRA models modify the cross-attention module to change styles。后面在研究Lora,这里把原话摘到这。

感觉更像是存在blueeyes,然后有一个集合同时满足blueeye。去取这个交叉的集合。问题:对应的embedding是不是不一样的?该如何区分blue planet in eyeblue eye in planet的区别?感觉这应该是NLP的领域了。

  • 总结下tex2img的过程

  1. stable diffusion生成一个随机的latent space matrix。这个由Random决定,如果Random不变,则这个latent space matrix不变。

  2. 通过noise-predictor,将noisy image与text prompt作为入参,预测predicted noise in latent space

  3. latent noise减去predicted noise。将其作为新的latent noise

  4. 不断重复2~3执行step次。比如说step=20

  5. 最终,通过VAE的decoder将latent representation生成最终的图片

这个时候就可以贴Stable diffusion论文中的一张图了

d1c13cf1ed21661bb9c422773a565812.png

手撕一下公式:

左上角的f151536100c3d5bbcf07b4e5a0e4c569.png定义为一张RGB像素空间的图。经过8d8d8520a2e12bf2b2d0f6c25ed3c85d.png的变化,生成73c5887e07673264fdc4f5f9efd5b849.jpeg这个latent space representation。再经过一系列的noise encoder,得到29505082e6ddea09dffab1447b5cab2f.png,T表示step。

而这个过程则是img2img的input。如果是img2img,那么初始的noise latent representation就是这个不断加noise之后的8a51dfd49d526aff222aab248166a53f.png

如果是tex2img,初始的noise latent representation则是直接random出来的。

再从右下角的a107e1f36a2cb5f565f232de1f41127b.jpeg4ee4170ba4880fb5673cff70eae1bb58.jpeg开始,y 表示多样的控制条件的入参,如text prompts。通过a8ea9e71822f0dab045509f198f45017.png(domain specific encoder)将 y 转为intermediate representation(一种中间表达)。而840c730938196cde0618c08276286ecb.jpeg70ff9786b6bb84051002cb3723b26e88.png将经过cross-attention layer的实现:

11387359c8332ae5032b548f53ff8b91.png

具体的细节说实话没看懂,而这一部分在controlnet中也有解释,打算从controlnet的部分进行理解。

图中cross-attention的部分可以很清晰的看到是一个由大到小,又由小到大的过程,在controlnet的图中有解释:

SD Encoder Block_1(64x64) -> SD Encoder Block_2(32x32) -> SD Encoder Block_3(16x16) -> SD Encoder(Block_4 8x8) -> SD Middle(Block 8x8) -> SD Decoder(Block_4 8x8) -> SD Decoder Block_3(16x16) -> SD Decoder Block_2(32x32) -> SD Decoder Blocker_1(64x64)

是一个从64x64 -> 8x8 -> 64x64的过程,具体为啥,得等我撕完controlnet的论文。回到过程图中,我们可以看到denoising step则是在Latent Space的左下角进行了一个循环,这里与上面的流程一直。

最终通过VAE的decoder D,输出图片641282945b46642af46c6ca83e614c72.png

最终的公式如下:

e6802ac5e5c689782238e78b556a3b61.png

结合上面的图看,基本还是比较清晰的,不过这个:=和8810ba13607df406e1e7ba7800e6ce35.png代表了啥就不是很清楚了。结合python代码看流程更清晰~删掉了部分代码,只留下了关键的调用。

pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", torch_dtype=torch.float16
)
vae = AutoencoderKL.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="vae")
tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14")
text_encoder = CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14")
unet = UNet2DConditionModel.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="unet"
)
scheduler = LMSDiscreteScheduler.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="scheduler"
)
prompt = ["a photograph of an astronaut riding a horse"]
generator = torch.manual_seed(32)
text_input = tokenizer(prompt,padding="max_length",max_length=tokenizer.model_max_length,truncation=True,return_tensors="pt",
)
with torch.no_grad():text_embeddings = text_encoder(text_input.input_ids.to(torch_device))[0]
max_length = text_input.input_ids.shape[-1]
uncond_input = tokenizer([""] * batch_size, padding="max_length", max_length=max_length, return_tensors="pt"
)
with torch.no_grad():uncond_embeddings = text_encoder(uncond_input.input_ids.to(torch_device))[0]
text_embeddings = torch.cat([uncond_embeddings, text_embeddings])
latents = torch.randn((batch_size, unet.in_channels, height // 8, width // 8), generator=generator
)
scheduler.set_timesteps(num_inference_steps)
latents = latents * scheduler.init_noise_sigmafor t in tqdm(scheduler.timesteps):latent_model_input = torch.cat([latents] * 2)latent_model_input = scheduler.scale_model_input(latent_model_input, t)with torch.no_grad():noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings).samplenoise_pred_uncond, noise_pred_text = noise_pred.chunk(2)noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)latents = scheduler.step(noise_pred, t, latents).prev_samplelatents = 1 / 0.18215 * latentswith torch.no_grad():image = vae.decode(latents).sample

还是很贴合图中流程的。
在代码中有一个Scheduler,其实就是noising的执行器,它主要控制每一步noising的强度。
由Scheduler不断加噪,然后noise predictor进行预测减噪。
具体可以看Stable Diffusion Samplers: A Comprehensive Guide(地址:https://stable-diffusion-art.com/samplers/)

  Img2Img

这个其实在上面的流程图中已经解释了。这里把步骤列一下:

  1. 输入的image,通过VAE的encoder变成latent space representation

  2. 往里面加noise,总共加T个noise,noise的强度由Denoising strength控制。noise其实没有循环加的过程,就是不断叠同一个noise T次,所以可以一次计算完成。

  3. noisy image和text prompt作为输入,由noise predictor U-Net预测一个新的noise

  4. noisy image减去预测的noise

  5. 重复3~4 step次

  6. 通过VAE的decoder将latent representation转变成image


  Inpainting

基于上面的原理,Inpainting就很简单了,noise只加到inpaint的部分。其他和Img2Img一样。相当于只生成inpaint的部分。所以我们也经常发现inpaint的边缘经常无法非常平滑~如果能接受图片的细微变化,可以调低Denoising strength,将inpaint的结果,再进行一次img2img

05a8f69c621d3aa6701441193db2914e.png

Stable Diffusion v1 vs v2

v2开始CLIP的部分用了OpenClip。导致生成的控制变得非常的难。OpenAI的CLIP虽然训练集更小,参数也更少。(OpenClip是ViT-L/14 CLIP的5倍大小)。但似乎ViT-L/14的训练集更好一些,有更多针对艺术和名人照片的部分,所以输出的结果通常会更好。导致v2基本没用起来。不过现在没事了,SDXL横空出世。

e74cd782128cd5bcc98941f1cb299144.png

SDXL model

SDXL模型的参数达到了66亿,而v1.5只有9.8亿

153341f695423d6a53a8e00401b964bc.png

由一个Base model和Refiner model组成。Base model负责生成,而Refiner则负责加细节完善。可以只运行Base model。但类似人脸眼睛模糊之类的问题还是需要Refiner解决。

SDXL的主要变动:

  1. text encoder组合了OpenClip和ViT-G/14。毕竟OpenClip是可训练的。

  2. 训练用的图片可以小于256x256,增加了39%的训练集

  3. U-Net的部分比v1.5大了3倍

  4. 默认输出就是1024x1024

展示下对比效果:

9fa790d44435aa70c1e37e1c247e94dd.png

从目前来看,有朝一日SDXL迟早替代v1.5。从效果来说v2.1确实被时代淘汰了。

a8e1d221e150f4b654a3dc97fa36ae5f.png

Stable Diffusion的一些常见问题

  脸部细节不足,比如说眼部模糊

可以通过VAE files进行修复~有点像SDXL的Refiner

  多指、少指

这个看起来是一个无解的问题。Andrew给出的建议是加prompt比如说beautiful handsdetailed fingers,期望其中有部分图片满足要求。或者用inpaint。反复重新生成手部。(这个时候可以用相同的prompt。)

5758b6c25373e67e4d7533e1e31c572a.png

团队介绍

我们是淘天集团-场景智能技术团队,作为一支专注于通过AI和3D技术驱动商业创新的技术团队, 依托大淘宝丰富的业务形态和海量的用户、数据, 致力于为消费者提供创新的场景化导购体验, 为商家提供高效的场景化内容创作工具, 为淘宝打造围绕家的场景的第一消费入口。我们不断探索并实践新的技术, 通过持续的技术创新和突破,创新用户导购体验, 提升商家内容生产力, 让用户享受更好的消费体验, 让商家更高效、低成本地经营。

¤ 拓展阅读 ¤

3DXR技术 | 终端技术 | 音视频技术

服务端技术 | 技术质量 | 数据算法

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

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

相关文章

【EI会议征稿】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于202…

文心一言 4.0 ERNIE-Bot 4.0 :ERNIE-Bot 4.0 大模型深度测试体验报告

本心、输入输出、结果 文章目录 文心一言 4.0 ERNIE-Bot 4.0 &#xff1a;ERNIE-Bot 4.0 大模型深度测试体验报告前言相关跳转文心一言 4.0 ERNIE-Bot 4.0 接口简介Bash 请求示例代码Windows 模式使用 Python 请求如果直接使用官方提供的代码文心一言 4.0 ERNIE-Bot 4.0 API 在…

最新百度统计配置图文教程,获取siteId、百度统计AccessToken、百度统计代码教程

一、前言 很多网友开发者都不知道百度统计siteId、百度统计token怎么获取&#xff0c;在网上找的教程都是几年前老的教程&#xff0c;因此给大家出一期详细百度统计siteId、百度统计token、百度统计代码获取详细步骤教程。 二、登录到百度统计 1.1 登录到百度统计官网 使用…

服务日志性能调优,由log引出的巨坑

只有被线上服务问题毒打过的人才明白日志有多重要&#xff01; 谁赞成&#xff0c;谁反对&#xff1f;如果你深有同感&#xff0c;那恭喜你是个社会人了&#xff1a;&#xff09; 日志对程序的重要性不言而喻&#xff0c;轻巧、简单、无需费脑&#xff0c;程序代码中随处可见…

Ubuntu:Arduino IDE 开发环境配置【保姆级】

物联网开发学习笔记——目录索引 本章主要介绍在Ubuntu系统搭建Arduino IDE 开发环境&#xff0c;windows系统请移步&#xff1a;Windows&#xff1a;Arduino IDE 开发环境配置【保姆级】 参考官网&#xff1a;Arduino - Home 有关更多详细信息&#xff0c;请参阅 Arduino I…

Centos7 安装 MySQL5.7 步骤

Centos7 安装 MySQL5.7 步骤 前言&#xff1a;一 .使用yum源方式安装1、卸载系统自带 mariadb查看并卸载系统自带的 Mariadb 2、下载并安装MySQL官方的 Yum2.1 下载mysql的yum源配置2.2 安装mysql的yum源2.3 使用yum方式安装mysql2.3.1 安装过程中报错解决问题描述解决方案 3、…

python爬虫练习,爬取iview,element组件库图标名称

简单的爬虫 先举一个爬取图片网站图片保存到本地文件夹的例子 原博客&#xff1a;http://t.csdnimg.cn/Cjv3o 这是一个图片网站 https://pic.netbian.com/ 在空白处右键&#xff0c;查看页面源代码&#xff0c;我们发现有具体内容的 我们使用下面的代码可以爬取这个页面所…

如何使用Python抓取PDF文件并自动下载到本地

目录 一、导入必要的库 二、发送HTTP请求并获取PDF文件内容 三、将PDF文件内容写入到本地文件中 四、完整代码示例 五、注意事项 六、错误处理和异常处理 七、进一步优化 总结 在Python中&#xff0c;抓取PDF文件并自动下载到本地需要使用几个不同的库。首先&#xff0…

工业交换机的应用场景

在选择工业交换机的时候&#xff0c;很多人会疑惑自己的场景是否适用工业交换机&#xff0c;工业交换机广泛应用于以下场景&#xff0c;大家可以参考了解 1. 工业自动化&#xff1a;工业交换机用于连接各种工业设备&#xff0c;如PLC&#xff08;可编程逻辑控制器&#xff09;、…

MSQL系列(四) Mysql实战-索引 Explain实战

Mysql实战-索引 Explain实战 前面我们讲解了索引的存储结构&#xff0c;我们知道了BTree的索引结构&#xff0c;也了解了索引最左侧匹配原则&#xff0c;到底最左侧匹配原则在我们的项目中有什么用&#xff1f;或者说有什么影响&#xff1f;今天我们来实战操作一下&#xff0c…

IDEA如何拉取gitee项目?

1.登录gitee 说明&#xff1a;打开idea&#xff0c;在设置上面搜索框输入gitee&#xff0c;然后登录gitee注册的账号。 2. 创建gitee仓库 说明&#xff1a;创建idea中的gitee仓库。 3.寻找项目文件 说明&#xff1a;为需要添加gitee仓库的项目进行添加。 4.项目右键 说明&a…

百度地图高级进阶开发:圆形区域周边搜索地图监听事件(覆盖物重叠显示层级\图像标注监听事件、setZIndex和setTop方法)

百度地图API 使用百度地图API添加多覆盖物渲染时&#xff0c;会出现覆盖物被相互覆盖而导致都无法触发它们自己的监听&#xff1b;在百度地图API里&#xff0c;map的z-index为0&#xff0c;但是触发任意覆盖物的监听如click时也必定会触发map的监听&#xff1b; 项目需求 在…

L2-030 冰岛人

2018年世界杯&#xff0c;冰岛队因1:1平了强大的阿根廷队而一战成名。好事者发现冰岛人的名字后面似乎都有个“松”&#xff08;son&#xff09;&#xff0c;于是有网友科普如下&#xff1a; 冰岛人沿用的是维京人古老的父系姓制&#xff0c;孩子的姓等于父亲的名加后缀&#x…

AI系统ChatGPT源码+详细搭建部署教程+支持GPT4.0+支持ai绘画(Midjourney)/支持OpenAI GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…

基于梯度优化的BP神经网络(分类应用) - 附代码

基于梯度优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于梯度优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.梯度优化BP神经网络3.1 BP神经网络参数设置3.2 梯度算法应用 4.测试结果&#xff1a;5.M…

一、初识 Elasticsearch:概念,安装,设置分词器

文章目录 01、初识 Elasticsearch正向索引和倒排索引索引MySQL与ES的概念映射安装ES分词器分词器的设置结束语 01、初识 Elasticsearch 本次ES基于&#xff1a;7.12.1 版本 学习资源为&#xff1a;https://www.bilibili.com/video/BV1Gh411j7d6 什么是ES&#xff08;Elastics…

解决jmeter软件显示为英文、返回数据乱码、设置编码格式的问题

一.jmeter软件每次打开都需要手动切换中文 1.修改配置文件&#xff0c;可以把jmeter设置成中文&#xff1a; 2.打开jmeter.properties配置文件&#xff0c;修改languagezh_CN 二.返回数据乱码 改配置文件 进入Jmeter的bin目录下&#xff0c;找到jmeter.properties文件&#…

Java构建Web项目

对无底线服务型的系统&#xff0c;业务代码和界面代码脚本化是及其重要的。一是脚本化能确保部署本地就是再用的代码&#xff0c;不存在为每个项目管理代码的问题。然后脚本化不需要人为编译和投放程序库。极大的简化维护难度和成本。能不能脚本化直接决定了能否全面铺开运维&a…

【爬虫教程】2023最详细的爬虫入门教程~

初识爬虫 学习爬虫之前&#xff0c;我们首先得了解什么是爬虫。 来自于百度百科的解释&#xff1a; 网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&a…

React之受控组件和非受控组件以及高阶组件

一、受控组件 受控组件&#xff0c;简单来讲&#xff0c;就是受我们控制的组件&#xff0c;组件的状态全程响应外部数据 举个简单的例子&#xff1a; class TestComponent extends React.Component {constructor (props) {super(props);this.state { username: lindaidai }…