最完整的Web视频加密播放技术实现(含技术调研和Demo源码)

原文来源于:程序员成长指北,作者:然燃 如有侵权,联系删除 最近又遇到了web视频化的场景,之前也有过调研:H5视频化调研浅析1 但这次稍微复杂一些,这次解决的是: 视频播放的技术方案调研 服务端实现: 视频转码 生成不同码率的视频 进行视频标准加密 不同码率视频合并,用于动态码率播放 web端实现 web端播放器的设计 web端播放器的自定义扩展 可拖拽进度条 音量控制 根据当前带宽自适应码率切换 手动清晰度切换 倍速播放 样式自定义覆盖 标准加密视频播放 基于原生开发,可在所有框架运行,统一跨框架情况 各浏览器控件统一 其中web端源码已添加MIT协议并完全开源,如果看完对大家有帮助的话,欢迎大家star,issue,pr,也希望能友好交流~ demo地址:⇲https://chaxus.github.io/ran/src/ranui/player/ 源码地址:⇲https://github.com/chaxus/ran/tree/main/packages/ranui demo文档做了国际化,可切换到中文 任何一个项目,立项肯定先是技术调研,我们先看看一些大公司的视频播放方案 #一.一些知名公司的web视频播放方案 #1.B站 我们先看看B站的,毕竟B站的主营业务就是视频弹幕网站,简直专业对口。 先找一个例子:⇲www.bilibili.com/video/BV1FM…⇲2 访问它。 打开控制台,可以看到,视频在播放的时候,会不断的请求m4s的视频文件。 毕竟一整个视频文件往往比较大,不可能先请求完视频文件,再进行播放。因此将一个大的视频文件分割成很多小的片段,边加载边播放,是一种更好的方式。 每次请求的m4s文件大概在几十kb到几百kb不等。 那为什么不采用http的range呢,可以请求一个文件的部分内容,而且粒度更细,可以设置字节范围。在http请求的header中,类似这样 Range: bytes=3171375-3203867 我们可以检查这个链接请求https://upos-sz-mirror08c.bilivideo.com/upgcxcode/67/92/1008149267/1008149267-1-30064.m4s的请求头,就能发现,B站采用的是,即分片加载,同时还用了range的方式。 #2. 爱奇艺:(爱奇艺、土豆、优酷) 爱奇艺这里就不贴视频链接了,因为随便点一个视频,都要先看广告。 爱奇艺的视频主要请求的是f4v格式,也是分片加载。 播放一个视频时,请求多个f4v文件。 也采用Range。但和B站不一样的是,B站的Range属性是在m4s请求的请求头里面,而爱奇艺的看起来是在querystring上,在请求query上带着range参数。 因为没发现这个请求的header里面有range参数。比如: https://v-6fce1712.71edge.com/videos/other/20231113/6b/bb/3f3fe83b89124248c3216156dfe2f4c3.f4v?dis_k=2ba39ee8c55c4d23781e3fb9f91fa7a46&dis_t=1701439831&dis_dz=CNC-BeiJing&dis_st=46&src=iqiyi.com&dis_hit=0&dis_tag=01010000&uuid=72713f52-6569e957-351&cross-domain=1&ssl=1&pv=0.1&cphc=arta&range=0-9000 #3.抖音: 抖音的方案简单粗暴,访问的链接是这个: ⇲m.ixigua.com/douyin/shar…⇲3 通过查看控制台,我们可以发现,直接请求了一个视频的地址 没有进行分片,但用到了请求range,所以可以看到视频,是边播放边缓冲一部分。 不过我在开发的时候发现,目前租用的服务云厂商,默认会帮我们实现这项技术。 因为我把mp4视频上传到云服务器,通过链接进行播放的时候,就是边缓冲边播放的。 我们可以直接把这个视频地址拿出来,放到浏览器里面能直接播放,这样观察更明显。 但B站和爱奇艺却不能这样,因为他们采用的m4s和f4v都不是一种通用的视频格式,需要使用专门的软件或工具才能打开和编辑。 #4.小红书: 测试用的例子链接:⇲www.xiaohongshu.com/discovery/i…⇲4 小红书的方案更加简单粗暴,打开控制台,直接告诉你就是请求一个mp4,然后直接播放就完事了。 #5.总结 看完了以上的各家大厂的方案,我们可以看到,基本原理都是边播放边加载,减少直接加载大视频文本的成本。并且通过分片传输,还能动态控制视频码率(清晰度)。做到根据网速,加载不同码率的分片文件,做到动态码率适应。 同时采用的视频格式,比如f4v,m4s,都不是能直接播放的媒体格式,需要一定的处理。增加盗取视频的成本,增加一定的安全性。 如果没有强要求,也可以直接采用mp4,或者直接用video播放一个视频文件地址。 #二.常见的视频格式与协议 我们知道视频的常见格式有mp4,同时上面介绍了B站播放用的m4s格式,爱奇艺用的f4v格式 •除了这些还有哪些视频格式? •为什么有这么多视频格式,有哪些不同点呢? •为什么这些公司会采用这种格式来播放视频呢? #1. B站用的m4s M4S格式不是一种通用的视频格式,需要使用专门的软件或工具才能打开和编辑。

vitest-前端单元测试

简介 Vitest 是一个轻量级、快速且功能强大的测试框架,它基于 Vite 提供了一种极速的测试体验。Vitest 尤其适合用于 Vite 项目,但同样可以与其他前端项目(如使用 webpack 构建的项目)集成使用。 安装 npm I vitest -D 为了执行测试,请将以下部分添加到你的 package.json 文件中: 通常会在src目录下常见一个tests目录来存放编写的测试样例,一般情况下,执行测试的文件名中必须包含 “.test.” 或 “.spec.” (当我们执行测试时,vitest会自动获取到".test." 或 ".spec."后缀名的文件)如图: 样例 简单说明一下测试样例中出现的vitestAPI: describe: • 作用:将一组相关的测试用例组合在一起,并给这组测试起一个名字。 • 用途:用于组织测试代码,使得测试结构更清晰。 it 或 test: • 作用:定义一个具体的测试用例。 • 用途:编写实际的测试逻辑,并指定一个描述性的名字。 expect: • 作用:用于编写断言,即验证某个值或表达式是否满足预期。 • 用途:在测试用例中,使用 expect 函数来验证实际结果与预期结果是否一致。 beforeEach: • 作用:在每个 it 或 test 块之前运行指定的代码。(it是test的简写) • 用途:通常用于设置测试环境或初始化测试中所需的变量和状态。 1、 普通函数 描述:在测试样例中我们给函数传递了a =1,b =1,验证结果是否等2 测试:npm run test 结果:测试通过,符合预期 2、 类 描述:在测试样例中实例化了一个MyClass并传入参数value = 1,调用increment函数,最后验证myClassInstance的结果是否等于2

linux下chromium/chrome中文字体粗体渲染问题

估计不少人更新后都遇到这个情况了吧,粗体渲染如然变得很模糊,很奇怪,Google下说是字体实现方式变了,国内一些网站用的中文字体都是宋体,但是宋体本身没有粗体,Win下的粗体是微软自己通过某种方式实现的,linux下自然没可能了,解决办法很简单,不过有点繁琐,就是只要碰到页面粗体不正常的,查看元素,记下该字体名,然后在文件夹/etc/fonts/conf.d文件夹里添加文件s99-local.conf,替换改字体粗体为某个独立的粗体字体,这里我用的是微软雅黑,反正机器上有win的合法拷贝,字体自己拿出来不算侵权。你如果没有win的合法拷贝,上网自己找去。。。。 相关代码如下: 01<?xml version="1.0"?> 02<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> 03<fontconfig> 04 <!-- 用微软雅黑粗体替代宋体的粗体 --> 05 <match target="pattern"> 06 <test name="family"><string>Simsun</string></test> 07 <test name="weight" compare="more_eq"><const>bold</const></test> 08 <edit name="family" mode="assign"><string>微软雅黑</string></edit> 09 </match> 10 <match target="pattern"> 11 <test name="family"><string>宋体</string></test> 12 <test name="weight" compare="more_eq"><const>bold</const></test> 13 <edit name="family" mode="assign"><string>微软雅黑</string></edit> 14 </match> 15</fontconfig> 然后重新启动机器即可,打开浏览器,只要是宋体的粗体字体都替换成了微软雅黑的粗体,解决了宋体粗体字体的渲染BUG 作者: Yong Man 出处: 极客来 GeekCome 原文: linux下chromium/chrome中文字体粗体渲染问题 提示:本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。 如果对文章有任何问题,都可以在评论中留言,我会尽可能的答复您,谢谢你的阅读

LoReFT——大语言模型的表示微调

引言 参数高效的微调或 PeFT 方法寻求通过更新少量权重来适应大型语言模型。然而,大多数现有的可解释性工作已经证明,表示编码了丰富的语义信息,这表明它可能是编辑这些表示的更好、更强大的替代方案。预先训练的大型模型通常经过微调以用于新的领域或任务,并且在微调过程中,即使只有少量的域内数据可用,单个基础模型也可以适应各种任务到模型。然而,微调整个模型的过程是消耗资源且昂贵的,特别是对于具有大量大小和参数的语言模型。 参数有效的微调或 PeFT 方法建议通过仅更新少量可用的总权重来解决与微调整个模型相关的高成本,这一过程有助于减少训练时间和内存使用。更重要的是,参数有效的微调或 PeFT 方法已经在多种实际设置中展示了与微调类似的性能。适配器是参数高效微调或 PeFT 方法的常见系列,它可以学习一种编辑,可以将其添加到与冻结基础模型一起运行的一组附加权重中,最近的适配器(例如 LoRA)减少了学习中可训练参数的数量在训练适配器时,通过使用低秩近似而不是全权重矩阵来更新权重。 之前的工作证明编辑表示可能是参数高效微调或 PeFT 方法的更好替代方案,在本文中,我们将讨论在冻结模型上运行的表示微调或 ReFT 方法,并学习特定于任务的方法对隐藏表征的干预。本文旨在深入介绍 ReFt 或表示微调框架,我们探讨了该框架的机制、方法、架构,以及它与最先进框架的比较。那么让我们开始吧。 ReFT:语言模型的表示微调 为了尝试将预训练的语言模型应用于新的领域和任务,当前的框架经常对这些预训练的语言模型进行微调,随着微调过程的实施,单个基本模型可以适应各种任务,甚至当处理少量域内数据时。尽管微调过程确实提高了整体性能,但这是一个昂贵的过程,尤其是在语言模型具有大量参数的情况下。为了解决这个问题并降低相关成本,PeFT 或参数高效 微调框架仅更新总权重的一小部分,这一过程不仅减少了训练时间,还减少了内存使用量,使 PeFT 框架在实际场景中与完全微调方法相比能够实现类似的性能。适配器是 PeFT 的常见家族,它通过学习编辑来工作,该编辑可以添加到一组附加权重以及与具有冻结权重的基本模型一致运行的权重子集。最近的适配器框架如 LoRA 和 QLoRA 已经证明可以在降低精度的模型上训练全精度适配器而不影响性能。与引入新模型组件的其他方法相比,适配器通常更加高效和有效。 当前最先进的参数高效微调框架的一个主要亮点是,它们不是修改表示,而是修改权重。然而,处理可解释性的框架已经证明,表示编码了丰富的语义信息,这表明与权重更新相比,表示编辑可能是更好、更强大的方法。这种表示编辑是更好方法的假设构成了 ReFT 或表示微调框架的基础,该框架训练干预措施而不是调整模型权重,允许模型操纵所有表示的一小部分以尝试引导模型行为在推理过程中解决下游任务。 ReFT 或表示微调方法是基于权重的 PeFT 或参数高效微调框架的直接替代品。 ReFT 方法从最近具有大型模型可解释性的模型中汲取灵感,这些模型会干预表示以找到忠实的因果机制,并在推理过程中引导模型的行为,因此可以被视为表示编辑模型的泛化。在此基础上,LoReFT 或低秩子空间 ReFT 是 ReFT 的强大且有效的实例,并且是 ReFT 的参数化,它干预由低秩投影矩阵跨越的线性空间中的隐藏表示,并直接构建在 DAS 上或分布式对齐搜索框架。 与完全微调相反,PeFT 或参数高效微调框架仅训练模型参数的一小部分,并设法使模型适应下游任务。参数高效微调框架可分为三大类: 基于适配器的方法: 基于适配器的方法训练附加模块,例如具有冻结权重的预训练模型之上的全连接层。串联适配器在多层感知器或 MLP 和 LM 或大型模型注意层之间插入组件,而并行适配器则在现有组件旁边添加模块。由于适配器添加的新组件无法轻松折叠到现有模型权重中,因此它们在推理过程中造成了额外的负担。 洛拉: LoRA 及其最新变体通过使用低秩矩阵在训练期间近似附加权重,并且它们在推理期间不需要额外的开销,因为权重更新可以合并到模型中,这就是它们被认为是当前模型的原因最强大的 PeFT 框架。 基于提示的方法: 基于提示的方法将随机初始化的软标记添加到输入中,并训练它们的嵌入,同时保持语言模型的权重冻结。与其他 PeFT 方法相比,这些方法提供的性能通常并不令人满意,而且它们还带来巨大的推理开销成本。 ReFT 框架不是更新权重,而是学习干预措施来修改总表示的一小部分。此外,最近关于表示工程和激活引导的工作已经证明,向残差流添加固定引导向量可能有助于对预训练的大型模型生成进行一定程度的控制,而无需占用大量资源 微调。其他框架已经证明,使用学习的缩放和平移操作编辑表示可以尝试匹配但不能超越 LoRA 适配器在学习参数较少的各种任务上提供的性能。此外,这些框架在一系列任务中的成功表明,预训练语言模型引入的表示具有丰富的语义,尽管这些模型的性能不是最优的,导致 PeFT 继续作为最先进的方法没有额外的推理负担。

星戈瑞FITC-Cytochrome C:荧光标记细胞色素C的研究与应用

细胞色素C(Cytochrome C)是一种位于线粒体内膜上的蛋白质。为了深入地研究细胞色素C在细胞生物学和病理学中的功能,科学家们常常采用荧光标记技术对其进行追踪和观察。其中,异硫氰酸荧光素(FITC)作为一种常用的荧光染料,因其高亮度和良好的稳定性而被应用于细胞色素C的荧光标记。 FITC-Cytochrome C的制备与特性 制备FITC-Cytochrome C通常涉及将FITC与细胞色素C进行共价连接,从而赋予细胞色素C荧光特性。这种荧光标记的细胞色素C不仅保留了原有的生物学功能,还具备了荧光示踪的能力,使得研究者能够直观地观察到其在细胞内的分布和动态变化。 FITC-Cytochrome C的特性主要表现在以下几个方面:首先,它具有强烈的荧光信号,可以在显微镜下清晰地观察到标记的细胞色素C;其次,其荧光稳定性较好,能够在较长时间内保持荧光强度,有利于长时间观察实验;此外,FITC-Cytochrome C的生物相容性较好,对细胞无明显毒性,适用于细胞生物学研究。 FITC-Cytochrome C在细胞生物学研究中的应用 **细胞色素C定位与分布研究:**通过FITC-Cytochrome C荧光标记,研究者可以清晰地观察到细胞色素C在细胞内的定位与分布。这有助于了解细胞色素C在细胞呼吸链中的具体位置,以及与其他细胞器的相互作用关系,从而揭示其在细胞功能中的作用。 **细胞凋亡与线粒体功能研究:**细胞色素C的释放是细胞凋亡过程中的步骤之一。利用FITC-Cytochrome C荧光标记技术,可以实时监测细胞色素C从线粒体释放到细胞质的过程,从而研究细胞凋亡的分子机制。此外,还可以观察线粒体在细胞凋亡过程中的形态和功能变化,为揭示线粒体在细胞凋亡中的作用提供证据。 **药物筛选:**FITC-Cytochrome C荧光标记技术还可应用于药物筛选和疾病治疗研究。通过观察药物对细胞色素C分布和功能的影响,可以评估药物的疗效和副作用,为药物研发提供参考。 FITC-Cytochrome C荧光标记技术为细胞色素C的研究提供科研工具。通过该技术,我们可以更深入地了解细胞色素C在细胞生物学和病理学中的功能,揭示其在细胞呼吸、凋亡中的作用机制。。 【星戈瑞stargraydye】以上数据均来自文献资料,星戈瑞暂未进行独立验证, 仅供参考!(以上文中所述仅限于科研实验及实验室环境)

【Python】类和对象的深入解析

目录 前言 什么是类? 定义一个类 创建对象 访问和修改属性 方法 类的继承 多态 封装 特殊方法 属性装饰器 总结 前言 Python 是一种面向对象的编程语言,它允许程序员通过类和对象来组织和管理代码。面向对象编程(OOP)是一种编程范式,它使用"对象"来设计软件,对象可以包含数据和代码,即属性和方法。本文将详细介绍 Python 中的类和对象,包括它们的定义、使用和一些高级特性。 什么是类? 在 Python 中,类是创建对象的蓝图或模板。它定义了一组属性和方法,这些属性和方法可以被类的对象所共享。类本身不包含数据,它只是一个构造函数,用于创建具有初始状态的对象。 定义一个类 在 Python 中,使用 class 关键字来定义一个类。下面是一个简单的类定义示例: class Car: def __init__(self, brand, model): self.brand = brand self.model = model 这个 Car 类有两个属性:brand 和 model。__init__ 方法是一个特殊的方法,被称为类的构造器,它在创建新对象时被调用。 创建对象 使用类定义,我们可以创建对象,这些对象是类的实例。创建对象使用类名后跟括号,括号中可以传递构造器需要的参数: my_car = Car("Toyota", "Corolla") 这行代码创建了一个 Car 类的实例,名为 my_car,其 brand 属性为 "Toyota",model 属性为 "Corolla"。 访问和修改属性 对象的属性可以通过点号(.)访问和修改: print(my_car.brand) # 输出: Toyota my_car.model = "

go测试问题记录

Running tool: /home/lexfan/goroot/bin/go test -timeout 30s -run ^TestMlegOrderCreate$ gitlab.futunn.com/institutional-trading-center/futc-oms/oms_write_service/stub_test/futc_oms_write_service ok gitlab.futunn.com/institutional-trading-center/futc-oms/oms_write_service/stub_test/futc_oms_write_service (cached) 我在单测,突然就变成运行很快,但是不生效,直接ok了,不知道为什么 当 Go 测试输出显示 (cached) 时,这意味着 Go 测试框架没有实际运行测试,而是返回了之前测试运行的结果。Go 1.10 引入了测试结果缓存,目的是为了加快测试的速度。如果自上次成功测试以来源代码和测试代码都没有发生变化,并且测试所依赖的环境(如环境变量和文件)也没有变化,Go 测试框架就会使用缓存的结果。 如果您希望强制重新运行测试并忽略任何缓存的结果,可以使用 -count=1 参数,如下所示: /home/lexfan/goroot/bin/go test -timeout 30s -run ^TestMlegOrderCreate$ gitlab.futunn.com/institutional-trading-center/futc-oms/oms_write_service/stub_test/futc_oms_write_service -count=1 这将告诉 Go 测试框架忽略缓存,并重新运行指定的测试。-count=1 指定测试至少运行一次,这也意味着不使用任何缓存的结果。 另外,请确保你的测试确实触发了一些代码的变动,因为如果测试无法检测到代码变动(包括测试中依赖的任何文件或环境变量的变动),它可能会直接使用缓存的结果。如果你在测试中有一些动态生成的数据或者外部依赖,你应该确保这些因素在测试运行时能够正确反映。

【AI大模型】在健康睡眠监测中的深度融合与实践案例

文章目录 1. 应用方案2. 技术实现2.1 数据采集与预处理2.2 构建与训练模型2.3 个性化建议生成 3. 优化策略4. 应用示例:多模态数据融合与实时监测4.1 数据采集4.2 实时监测与反馈 5. 深入分析模型选择和优化5.1 LSTM模型的优势和优化策略5.2 CNN模型的优势和优化策略5.3 Transformer模型的优势和优化策略 6. 数据隐私与安全策略7. 深入探讨未来发展方向7.1. 多模态数据融合7.2. 自适应学习7.3. 跨平台集成 8. 深度学习模型优化9. 总结 随着穿戴设备的普及和AI技术的发展,利用AI大模型在睡眠监测中的应用成为可能。这种深度融合应用能够提供更准确、更个性化的睡眠分析与建议,帮助用户更好地管理睡眠健康。以下是AI大模型在穿戴设备睡眠监测中的应用方案、技术实现和优化策略。 1. 应用方案 多模态数据融合: 生理数据:心率、呼吸率、体温等。环境数据:光照、噪音、温度等。行为数据:运动数据、睡眠姿势等。 高级数据分析: 睡眠阶段分类:利用深度学习模型对数据进行分析,分类出浅睡、深睡、REM睡眠等阶段。异常检测:检测睡眠呼吸暂停、失眠等异常情况。 个性化建议: 基于用户的历史数据和模型分析结果,提供个性化的睡眠改善建议。 实时监测与反馈: 实时监测用户睡眠状态,及时提供反馈和建议。 2. 技术实现 2.1 数据采集与预处理 首先,需要从穿戴设备中获取各类数据,并进行预处理。 import numpy as np import pandas as pd # 模拟数据采集 heart_rate_data = np.random.normal(60, 5, 1000) respiration_rate_data = np.random.normal(16, 2, 1000) temperature_data = np.random.normal(36.5, 0.5, 1000) movement_data = np.

零刻SER8 AMD 8845Hs Ryzen AI 本地部署大语言模型教程!

零刻SER8 8845HS,配备了一个内置的 NPU(神经网络处理单元),可以通过LM Studio语言大模型来部署自己的 GPT 模型 AI 聊天机器人,AI 助手已迅速成为提高生产力、效率,甚至是头脑风暴的关键资源。在本地机器上运行 AI 聊天机器人不仅不需要互联网连接,而且你的对话也保存在本地机器上。 AMD 8845Hs Ryzen AI AI 引擎性能:最高可达 16 TOPS(每秒万亿次操作) 总处理器性能:最高可达 38 TOPS 零刻SER8 IPU默认状态为开启状态,无需再进行二次开启操作,可在设备管理器中查看相关的设备状态。 操作步骤: 1.下载LM Studio大模型部署软件,点击链接进入官网,https://lmstudio.ai/,下载Windows版本 2.下载完成后,双击进行启动进入软件界面 3.AMD官方这里提供了两个大语言模型,Mistral 7b(TheBloke/OpenHermes-2.5-Mistral-7B-GGUF)和LLAMA v2 7b(TheBloke/Llama-2-7B-Chat-GGUF),这里的7b指的是70亿参数训练出来的大模型,我们选择LLAMA v2 7b语言大模型进行下载,点击左侧搜索按钮(如果搜索提示网络报错,可查看LM Studio语言大模型部署软件搜索语言模型报错“Error searching for models ‘Network error’”解决办法) 4.在搜索栏中复制并粘贴以下搜索词:“TheBloke/Llama-2-7B-Chat-GGUF”,在右侧选择’Q4 K M’模型文件点击’Download’进行下载 5.耐心等待下载完成 6.下载完成后,点击左侧的聊天按钮,切换到聊天模式 7.点击顶部,切换刚刚下载的语言大模型包 8.等待模型加载完成就可以使用了,LLAMA v2 7b模型只支持英文,如果需要中文可以使用其他的大语言模型。 9.推荐中文语言大模型"TheBloke/openHermes-2.5-Mistral-7B-GGUF"搜索后,可在右侧选择’Q4 K M’模型文件点击’Download’进行下载 10.下载完成后,点击聊天按钮,在顶部选择大语言模型进行切换 更多其它大语言模型: “PrunaAI/Llama3-8B-Chinese-Chat-GGUF-smashed” 来源 https://zhuanlan.zhihu.com/p/696250131 “zhouzr/Llama3-8B-Chinese-Chat-GGUF”

抽卡机小程序:设计与开发全攻略

在移动互联网时代,小程序以其轻便、易用、无需安装的特点,迅速成为用户日常使用的重要工具。其中,抽卡机小程序因其独特的娱乐性和互动性,受到广大用户的喜爱。本文将为大家详细介绍抽卡机小程序的设计与开发全攻略。 一、需求分析 在开始设计和开发抽卡机小程序之前,我们需要先进行详细的需求分析。这包括确定小程序的目标用户群体、功能需求、性能要求等。例如,目标用户可能是喜欢收集、喜欢抽卡游戏的年轻人;功能需求可能包括抽卡、查看卡片详情、分享卡片等;性能要求则需要保证小程序的流畅运行和快速响应。 二、界面设计 界面设计是抽卡机小程序的重要组成部分。一个美观、易用、符合用户习惯的界面设计,能够提升用户的使用体验和满意度。 1.首页设计:首页应该简洁明了,突出抽卡功能。可以设计一个醒目的抽卡按钮,并展示一些热门或新推出的卡片作为吸引。同时,还可以设置一些用户信息展示区,如用户等级、已收集卡片数量等。 2.抽卡页面设计:抽卡页面是用户最关心的部分。我们需要设计一个富有动感和吸引力的抽卡动画,让用户感受到抽卡的乐趣。同时,抽卡结果应该清晰展示,包括卡片名称、图片、属性等信息。 3.卡片详情页面设计:当用户点击某张卡片时,应跳转到卡片详情页面。这个页面需要详细展示卡片的各项信息,如名称、描述、属性、技能等。同时,还可以设置一些互动功能,如点赞、评论等。 4.其他页面设计:除了以上几个主要页面外,还需要设计一些辅助页面,如用户中心、帮助中心等。这些页面应该简洁明了,方便用户查找和使用。 三、功能开发 在界面设计完成后,我们就可以开始功能开发了。以下是一些抽卡机小程序的基本功能: 1.抽卡功能:这是抽卡机小程序的核心功能。我们需要编写代码实现抽卡逻辑,包括随机生成卡片、展示抽卡结果等。同时,还需要考虑如何处理用户连续抽卡、重复抽卡等情况。 2.卡片管理功能:用户需要对自己的卡片进行管理,如查看已收集卡片、删除不需要的卡片等。我们需要编写相应的代码实现这些功能,并确保数据的准确性和安全性。 3.用户信息展示功能:在首页和其他页面中,我们需要展示一些用户信息,如用户等级、已收集卡片数量等。这些信息需要从服务器获取并实时更新。 4.分享功能:用户可以将自己的抽卡结果分享到社交媒体上,吸引更多人来使用小程序。我们需要实现分享功能,并支持多种社交媒体平台。 四、性能优化 在功能开发完成后,我们还需要对小程序进行性能优化,确保它能够流畅运行并快速响应。以下是一些常见的性能优化方法: 1.减少网络请求:通过缓存数据、合并请求等方式减少网络请求次数和时间。 2.压缩图片资源:对图片进行压缩处理,减少图片加载时间和内存占用。 3.使用异步加载:对于非关键性数据和资源,可以使用异步加载方式提高页面加载速度。 4.代码优化:优化代码结构、减少冗余代码、使用高效算法等方式提高代码执行效率。 五、测试与发布 在开发完成后,我们需要对小程序进行测试,确保其功能正常、性能稳定、无安全漏洞等问题。测试包括功能测试、性能测试、安全测试等。通过测试后,我们就可以将小程序发布到各大平台上供用户使用了。 总之,抽卡机小程序的设计与开发需要综合考虑多个方面因素,包括需求分析、界面设计、功能开发、性能优化等。只有不断优化和改进才能提升用户体验和满意度,吸引更多用户来使用小程序。

【代码随想录算法训练营第四十三天|卡码网52.携带研究材料、18.零钱兑换II、377.组合总和Ⅳ、卡码网57.爬楼梯】

文章目录 卡码网52.携带研究材料518.零钱兑换II377.组合总和Ⅳ卡码网57.爬楼梯 卡码网52.携带研究材料 这题是完全背包问题,完全背包问题在01背包问题的基础上其实主要是三个不同,第一个是初始化的时候不能再和01背包一样对第一个物品让背包大小大于物品重量的时候全部初始化为物品价值,因为现在的物品可以无限放。第二个就是动态规划内部的循环推导的时候不用倒序而是正序了,因为之前提过正序会导致物品的重复使用,而现在正好是要重复使用。还有一个就是内外循环现在是可以交换的,只要保证dp前面的状态先于后面的状态计算出来就可以。 NV = input().split() N, V = int(NV[0]), int(NV[1]) weights = [] values = [] for i in range(N): wv = input().split() weights.append(int(wv[0])) values.append(int(wv[1])) dp = [0] * (V+1) for i in range(N): for j in range(weights[i], V+1): dp[j] = max(dp[j], dp[j-weights[i]]+values[i]) print(dp[-1]) 518.零钱兑换II 就是一个完全背包问题,但是要注意只能外层硬币内层背包,不然会有重复的硬币组合。初始dp[0]要设置为1,相当于对dp[i-coin]当i为coin的时候设置为1。 class Solution: def change(self, amount: int, coins: List[int]) -> int: dp = [0] * (amount + 1) dp[0] = 1 for coin in coins: for i in range(coin, amount+1): dp[i] += dp[i-coin] return dp[-1] 377.

CSDN 蒋涛:AI 开源平民化,人人都能为自己创造数百个专属应用

创造软件将不再受编程语言能力约束,创造和使用软件的方式将发生巨大的改变。 整理 | 王启隆 出品丨AI 科技大本营(ID:rgznai100) GitHub CEO Thomas Dohmke 曾在今年的 TED 演讲上分享了他通过 AI 编程开发的一款专属应用,用来记录他一生中乘坐的所有航班。他自己吐槽说这是一款无聊的应用,但这却是属于他自己一个人的 App,且整个开发过程仅用自然语言完成,只花了喝一杯酒的时间。 Thomas 紧接着强调:“不久之后,每个人都能像我一样,开发出专属于自己的 App。” 这句话的“每个人”并不是指“每一名程序员”,而是世界上的“每一位普通人”。 这一切,并不是仅靠 OpenAI ChatGPT 的驱动,而是与紧随其后的开源 AI 浪潮息息相关。如今开源 AI 大模型层出不穷,不仅有企业巨头 Meta 开发的 Llama,还出现了法国独角兽 Mistral、马斯克谋划已久的 Grok、英伟达最新开源的 Nemotron、登顶 Hugging Face 的国产阿里云 Qwen2……开源的风吹进了千家百户,让每个人都能享受到这场正在进行的 AI 革命。 作为国内最早推广开源文化的技术社区,CSDN 团结了我国最早的一批开源贡献者与数千万华人开发者,历经了移动互联网时代和云原生时代两大变革。如今面对 AI 技术的迅猛发展,CSDN 创始人、总裁蒋涛在北京智源大会的“AI 开源”分论坛上带来了自己的思考与观察,以开发者的视角总结了当前开源大模型时代的范式变化与 AI 应用的爆发趋势,观点提炼如下: 我们正从程序员的“2G 时代”进入真正的智能时代,即所谓的 3G 时代。随着大模型在本地设备上的运行,对应的“4G 时代”也将加速到来,AI 应用产生巨大爆发。 开源和闭源的工具在不断涌现,AI 技术生态的演进速度是过去云计算的十倍以上。每一次新技术带来范式的转移,应用的渗透速度都会加倍。 智能体(Agent)写代码只是临时的热点,未来智能体将彻底改变人机交互的方式,我们身边的每一个设备都会智能化。 所有的电脑用户都将能够从零开始开发小型软件工具,创造软件将不再受编程语言能力约束,创造和使用软件的方式将发生巨大的改变。每个人都可以创作数百个专属应用,每家企业都可以拥有专属个性化应用市场。 以下为演讲全文整理: AI 大模型是一场新生态革命 我从事编程很多年,经历了行业的很多演变周期。但这两年我发现,我们其实原本处于程序员的“2G 时代”,现在才开始进入真正的智能时代,即所谓的 3G 时代。 CSDN 在这些年里积累了超过 5300 万的注册用户,每天新增约两万用户。如今全球开发者数量持续增加,根据 GitHub 截止到 5 月份的数据,全球开发者数量达 1.

SpringBoot整合JWT(JSON Web Token)生成token与验证

目录 JWT 什么是JWT JWT使用流程 确定要传递的信息: 生成JWT: JWT传输: 客户端保存JWT: 客户端发送JWT: 服务器验证JWT: 服务器响应: Token的使用示例: 工具类 R结果集 返回一个生成的token 创建拦截器 JWT 什么是JWT JWT(JSON Web Token)是是目前最流行的跨域认证解决方案。它通常被用于对用户进行身份验证和授权。JWT由三部分组成,每个部分之间使用"."进行分隔,这三部分分别是: Header: 包含了声明类型和JWT的加密算法 Payload: 负载,存放有效信息的地方。这些有效信息包含三个部分:标准中注册的声明、公共的声明 和 私有的声明。 Signature: 签名信息。 官网地址:https://jwt.io/introduction JWT使用流程 确定要传递的信息: 首先,确定您想在JWT中传递的信息。这通常包括用户的唯一标识符(如用户ID)、角色、用户名等。 生成JWT: 生成Header:Header是JWT的第一部分,它描述了JWT的类型("typ")和加密算法("alg")。生成Payload:Payload是JWT的第二部分,包含了编码后的信息。在Payload中,通常还会添加一个"iat"字段,表示JWT的签发时间(Issued At)生成Signature:使用一个密钥(Secret Key)对Header和Payload进行签名,以确保它们的完整性和真实性。签名是通过指定的算法(如HMAC SHA256)生成的。将Base64编码后的Header、Payload和Signature用点号(.)连接起来,形成一个完整的JWT字符串。例如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c JWT传输: 服务器将生成的JWT发送给客户端,通常通过在HTTP响应的头部设置Authorization字段的值为Bearer JWT。 客户端保存JWT: 客户端在接收到JWT后,将其保存在本地,通常存储在Cookie、LocalStorage或SessionStorage中。 客户端发送JWT: 客户端在每次请求服务器时,将JWT带在请求的头部,通过Authorization字段将JWT发送给服务器。请求头的格式通常为:Authorization: Bearer JWT 服务器验证JWT: 服务器接收到请求后,从请求的头部中获取JWT,并进行验证。验证的过程包括解析JWT、验证签名的完整性和真实性、检查JWT是否过期等。如果验证通过,服务器会进一步解析Payload中的数据,获取用户的相关信息。 服务器响应: 如果JWT验证通过,服务器会继续处理请求,并返回相应的数据。如果JWT验证失败,服务器会返回相应的错误信息。 通过以上流程,JWT实现了一种安全、紧凑、自包含的令牌传递机制,用于在客户端和服务器之间安全地传输用户信息。 springboot引入jwt相关依赖 要在Spring Boot项目中引入jjwt,你需要在你的pom.xml(如果你使用Maven)或build.gradle(如果你使用Gradle)文件中添加相应的依赖。 maven: <!--引入jwt相关包来生成token--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.

如何用大模型+知识库打造微信群里的AI问答神器!

想象一下,你的微信群或公众号中,有一个AI问答专家随时待命,帮助你和你的朋友们解答各种问题,是不是很酷? 现在,让我们来看看这个项目的技术框架,一步步了解它是如何构建的: 基础起点: 首先,确保你有一个Python环境。这就像是我们的魔法工坊,所有的魔法都从这里开始。 项目核心: 接着是我们的主角——chatgpt-on-wechat。这个项目就像是我们的魔杖,帮助我们在微信世界中施展魔法。 智慧之源: 我们需要连接到具有API接口的各种大型语言模型。你可以把它们想象成我们的魔法书,里面充满了知识和智慧。 知识宝库: 最后,我们的知识库,它是基于LinkAI构建的。这就像是我们的魔法药水,给我们的问答专家提供了额外的力量。 在下文中,我会详细介绍如何将这些组件融合在一起,创造出一个能在你的微信群中自如交流的AI问答专家。准备好了吗?让我们开始这趟魔法之旅! 1.Python环境准备: 首先,我们得确保有一个Python环境作为我们的基础。如果你已经准备好了,那就可以跳到下一步;如果没有,跟着我来,一步步搭建起来。 前往清华大学的镜像网站下载Anaconda,这是一个包含了Python和许多常用包的发行版。 2. 克隆主体项目: 把我们的项目代码从GitHub上拿下来:chatgpt-on-wechat。这就像是获取了一份魔法书的副本,接下来我们要做的是填写魔法咒语。 3. 关键参数配置: 解压你下载的项目,找到config-template.json文件,复制它并重命名为config.json。现在,我们来填写魔法咒语: open_ai_api_base:填入一个国内可以使用的API URL,比如文心或者星火。open_ai_api_key: 填入你的API密钥。text_to_image:微信现在不支持图片生成,这一项我们先跳过。proxy:如果你有代理服务器,填在这里;没有就留空。hot_reload:设置为true,这样就不用每次重启都扫码登录了。single_chat_prefix:设定一个前缀,比如“@AI”,当别人用这个召唤你的AI助手时,它就会回答。group_name_white_list: 决定你的AI助手在哪些群聊中活跃。如果填ALL_GROUP,它就会在所有群里工作。speech_recognition:设置为false,除非你想让它识别语音消息。use_linkai:决定是否启用知识库功能。 注意:检查config.json的格式是否正确,以免引起不必要的错误。 4. 安装依赖: 使用清华大学提供的Python包镜像,这样可以加速下载过程。 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 如果你遇到因为Python版本不兼容而导致的问题,可以尝试手动安装出错的包,或者调整Python的版本。 5. 运行程序: 一切准备就绪后,进入项目目录,运行下面的命令: python app.py 屏幕上会显示一个二维码,用微信扫一扫,登录你的AI助手。注意,这会导致你的PC端微信下线,反之亦然。 现在,我们已经成功搭建了你的微信群AI问答专家,接下来我们将其与知识库结合,以便它能提供更加专业和深入的回答。下面是如何实现这一步骤的详细指南。 6. 知识库的链接: 目前,你的AI助手已经能够通过连接到大型语言模型来回答一般性问题,这些回答基于模型训练时所使用的数据。但如果你希望它在特定领域提供更为精准的信息,接入知识库是关键所在。我们将通过Link-AI平台来实现这一功能。 登录平台:访问https://link-ai.tech/ 并登录。在控制台中,你会看到“知识库”选项,这里展示了你已有的知识库或可以创建新的知识库。 创建知识库:点击创建知识库,这一步允许你导入自己的知识文档并进行解析。这个过程类似于给你的AI助手注入新的知识血液。 解析无结构文档:Link-AI会采用类似于RAG(Retrieval-Augmented Generation)的方法来解析你的文档,建立起一个向量数据库。文档会被分割成小段,每段都会被嵌入到模型中,以便在需要时被检索和调用。 获取API密钥:在应用接入部分创建一个API密钥,并将其复制下来。 获取API密钥:在应用接入部分创建一个API密钥,并将其复制下来。 配置文件更新:回到你的config.json文件,用你刚刚复制的信息更新以下字段,以此来完成知识库的接入。 "use_linkai": true, "linkai_api_key": "xxxx", "linkai_app_code": "xxxxx" 确保保存文件。现在,你的AI助手不仅能够回答一般性问题,还可以访问知识库中的信息,为你提供更加专业的答案。 完成这些步骤后,你的微信群AI问答专家就不仅仅是一个普通的聊天伙伴了,它已经变成了一个拥有深厚知识储备的专业顾问。现在,就让它在群聊中大展身手吧! 为什么要学AI大模型? 2024人工智能大模型的技术岗位与能力培养随着人工智能技术的迅速发展和应用 , 大模型作为其中的重要组成部分 , 正逐渐成为推动人工智能发展的重要引擎 。大模型以其强大的数据处理和模式识别能力, 广泛应用于自然语言处理 、计算机视觉 、 智能推荐等领域 ,为各行各业带来了革命性的改变和机遇 。

71. UE5 RPG 实现敌人召唤技能

在这一篇文章中,我们要实现敌人的召唤师能够召唤自己的仆从进行作战。 要实现这个技能,我们首先创建新的敌人蓝图,用于召唤。接着,我们将实现一个召唤技能基类,在基类中实现在召唤师的周围获取到可以生成的位置点,然后在技能蓝图中在对应的位置生成敌人的Actor,并在后续对其进行优化。接下来,我们将一步步实现此功能。 创建新的敌人 我们首先创建两个新的敌人,这两个恶魔类型的敌人,用于召唤使用。 这里也不仔细讲解如何创建,我们在64. UE5 RPG 创建新的双手攻击怪物中也专门讲解了如何创建一个新的敌人,这里只说一下项目源码的改动。 由于黑色的恶魔是远程释放火球的,但是它没有武器,我们之前释放火球的都是带有武器的角色(萨满,玩家英雄)为了兼容没有武器的角色,我们又增加了一个可以通过骨骼标签和骨骼名称去获取位置的。 在角色基类里面实现它 FVector ARPGCharacter::GetCombatSocketLocationByTag_Implementation(const FGameplayTag SocketTag, const FName SocketName) const { if(SocketTag.MatchesTagExact(FRPGGameplayTags::Get().CombatSocket_Weapon)) { return Weapon->GetSocketLocation(SocketName); } return GetMesh()->GetSocketLocation(SocketName); } 然后将生成投掷物的技能接口修改掉 在敌人的技能里,蓝图修改 在玩家英雄技能里,修改蓝图 生成位置点 我们要实现召唤技能,首先创建一个新的召唤技能基类,由于它不是一个攻击性的技能,也不会造成伤害,所以,我们基于技能基类创建即可 创建一个名为RPGSummonAbility的召唤技能 在.h文件中,我们需要添加一个获取随机位置的函数,并添加一些可以自定义的配置项 UCLASS() class AURA_API URPGSummonAbility : public URPGGameplayAbility { GENERATED_BODY() public: UFUNCTION(BlueprintCallable) TArray<FVector> GetSpawnLocations(); UPROPERTY(EditDefaultsOnly, Category="Summoning") int32 NumMinions = 5; // 召唤的数量 UPROPERTY(EditDefaultsOnly, Category="Summoning") TArray<TSubclassOf<APawn>> MinionClasses; //召唤生成的角色类 UPROPERTY(EditDefaultsOnly, Category="Summoning") float MinSpawnDistance = 50.f; //召唤物距离召唤师最近的距离 UPROPERTY(EditDefaultsOnly, Category="Summoning") float MaxSpawnDistance = 250.

C#结合JS 修改解决 KindEditor 弹出层问题

目录 问题现象 原因分析 范例运行环境 解决问题 修改 kindeditor.js C# 服务端更新 小结 问题现象 KindEditor 是一款出色的富文本HTML在线编辑器,关于编辑器的详细介绍可参考我的文章《C# 将 TextBox 绑定为 KindEditor 富文本》,这里我们讲述在使用中遇到的一个问题,在部署到某些 WEB 应用项目中,点击类似弹出层功能时,只显示了遮罩层,而内容层则定位无法正确显示,下面所列是一些有关弹出层的功能,正确显示如下图: 但某些时候,会只显示遮罩层,无法显示弹出层,如下图: 原因分析 在浏览器显示内容中右击审查元素(360极速,edge则为检查元素),如下图: 发现遮罩层输出正常,为绝对定位,并设置正确了 left 、top、width、height 值,但排查到 css class 为 ke-dialog 的弹出层时,发现 position 定位缺失了 top 值,这应该是弹出层问题之所在。 范例运行环境 操作系统: Windows Server 2019 DataCenter .net版本: .netFramework4.0 或以上 KindEditor version 4.1.7 (2013-04-21) 开发工具:VS2019 C# 解决问题 修改 kindeditor.js 如下图,我们发现遮罩层的 z-index 值为 811212,弹出层的 z-index 值为 811213: 因此打开 kindeditor.js 核心文件进行查找修改,该文件存在于插件应用的根目录: 按 811213 进行查找,发现如下图代码: 可试图在 options 选项里增加初始的 top 属性值为 '100px',保存文件再试。 C# 服务端更新 在我的文章《C# 将 TextBox 绑定为 KindEditor 富文本》里我们创建了 KindEditor 类,可修改类代码,通过时间戳引入更新后的js版本,重写后的代码如下:

使用LlamaFactory进行模型微调:参数详解

在深度学习和自然语言处理领域,模型微调是提升预训练模型性能的重要手段。本文将介绍如何使用LlamaFactory进行模型微调,并详细解析一些关键参数,包括 --cutoff_len 1024、--flash_attn auto、--lora_rank 8、--lora_alpha 16、--lora_dropout 0 和 --lora_target all。 基础命令 首先,让我们看看基本的训练命令: llamafactory-cli train \ --stage sft \ --do_train True \ --model_name_or_path /data1/models/Llama3-8B-Chinese-Chat \ --preprocessing_num_workers 16 \ --finetuning_type lora \ --template llama3 \ --flash_attn auto \ --dataset_dir /data1/workspaces/llama-factory/data/fiance-neixun \ --dataset yinlian-sharegpt-neixun \ --cutoff_len 1024 \ --learning_rate 5e-05 \ --num_train_epochs 3.0 \ --max_samples 100000 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps 8 \ --lr_scheduler_type cosine \ --max_grad_norm 1.0 \ --logging_steps 5 \ --save_steps 100 \ --warmup_steps 0 \ --optim adamw_torch \ --packing False \ --report_to none \ --output_dir saves/LLaMA3-8B-Chat/lora/train_2024-06-18-09-02-25 \ --fp16 True \ --plot_loss True \ --ddp_timeout 180000000 \ --include_num_input_tokens_seen True \ --lora_rank 8 \ --lora_alpha 16 \ --lora_dropout 0 \ --lora_target all \ --deepspeed cache/ds_z3_config.

目标检测——YOLOv8算法解读

作者:Ultralytics公司 代码:https://github.com/ultralytics/ultralytics YOLO系列算法解读: YOLOv1通俗易懂版解读、SSD算法解读、YOLOv2算法解读、YOLOv3算法解读、YOLOv4算法解读、YOLOv5算法解读、YOLOR算法解读、YOLOX算法解读、YOLOv6算法解读、YOLOv7算法解读、YOLOv8算法解读、YOLOv9算法解读、YOLOv10算法解读 PP-YOLO系列算法解读: PP-YOLO算法解读、PP-YOLOv2算法解读、PP-PicoDet算法解读、PP-YOLOE算法解读、PP-YOLOE-R算法解读 文章目录 1、算法概述2、YOLOv8细节2.1 YOLOv8的C2f结构2.2 YOLOv8的SPPF模块2.3 YOLOv8的neck和head2.4 YOLOv8的损失函数 1、算法概述 YOLOv8和YOLOv5都是由小型初创公司Ultralytics创建并维护的,和YOLOv5一样,也没有形成论文,但工程readme里面链接了参考文档(https://docs.ultralytics.com/models/yolov8/),该文档非常丰富,包含如何快速运行、训练、验证、预测及导出其他格式模型,还包含除检测任务的其他任务的扩展如:分割、分类和姿态估计,同时也包含YOLO系列其他模型的汇总介绍。 YOLOv8的主要特点有: 1、模型更快更准确; 2、模型除了能完成目标检测任务,也可以无缝衔接到实例分割、图像分类以及姿态估计任务; 3、与之前的YOLO版本兼容可扩展,ultralytics相当于一个YOLO统一框架; 4、YOLOv8采用新的backbone,与YOLOv5相比采用了anchor-free策略,模型也采用了新的损失函数; 5、YOLOv8支持导出多种格式的模型,并且可以在CPU/GPU上运行。 2、YOLOv8细节 YOLOv8网络结构如下所示,图片来自github用户@RangeKing 对比YOLOv8和YOLOv5的yaml格式网络结构配置 可以看到网络规模n/s/m/l/x的深度、宽度配置比例没有改变,但max_channels,YOLOv8的减少了。 Backbone部分,YOLOv8将YOLOv5采用的C3结构升级成了C2f,其余通道数配置均未改变 Head部分,相对于YOLOv5,上采样之前减少了卷积操作,同样将C3升级成了C2f 2.1 YOLOv8的C2f结构 YOLOv8中的C2f结构如下图红框部分: 由子模块ConvModule和多个DarknetBottleneck所组成,而DarknetBottleneck又包含两个3x3卷积的ConvModule; 对比YOLOv5的C3结构,如下: 其中ConvModule对应CBS,结构没有改变,DarknetBottleneck相对于YOLOv5的Bottleneck结构,将其第一个1x1的CBS换成了3x3的CBS结构,即YOLOv8的DarknetBottleneck包含两个3x3卷积,值得注意的是,YOLOv8和YOLOv5一样,都在backbone部分的Bottleneck应用了shortcut连接,而neck部分没有应用shortcut。最大的不同是C2f中每个DarknetBottleneck均分出一半通道的特征图直接连接到最后,多个DarknetBottleneck分出来的通道以及最后一个DarknetBottleneck的输出通过Concat操作合并在一起,并经过1x1的ConvModule得到想要的输出通道,这有点像YOLOv7的E-ELAN结构,优化了梯度在网络之间的传播路径,下面具体看代码实现: 2.2 YOLOv8的SPPF模块 之前YOLOv5以及YOLO其他系列均采用SPP模块,结构如下: 而YOLOv8采用的SPPF是将池化操作的并行分支改为了串行操作,并在每个池化后接了shortcut,结构如下: 代码对应如下: 2.3 YOLOv8的neck和head Neck部分变化得比较少,一是上采样之前减少了卷积操作,二是将C3升级成了C2f。 变化比较大的是head部分,像YOLOv6一样,YOLOv8解耦了分类和回归分支,并且取消了obj分支(为什么这么做,请参阅论文[1]),并且变成了anchor-free,如下: 当为YOLOv8l模型时,w=1.0,最大通道数为512 而YOLOv5l的耦合方式检测头结构如下: 2.4 YOLOv8的损失函数 由上部分可知,检测头解耦后,每个特征尺度的检测头有两个分支:分类分支和回归分支,结构如下: 分类分支还是采用BCE损失,回归分支是采用CIoU与DFL(Distribution Focal Loss)共同控制。 参考文献: [1] Generalized Focal Loss(https://arxiv.org/pdf/2006.04388.pdf) 知乎:大白话 Generalized Focal Loss(https://zhuanlan.zhihu.com/p/147691786)

[保姆级教程]uniapp配置vueX

文章目录 注意新建文件简单的使用 注意 uniapp是支持vueX的只需配置一下就好 新建文件 在src文件中,新建一个store(如果有的话跳过) 在store中新建一个js文件,修改js文件名称和选择模板为default 在 uni-app 项目根目录下,新建 store 目录,在此目录下新建 index.js 文件。在 index.js 文件配置如下 // 页面路径:store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex);//vue的插件机制 //Vuex.Store 构造器选项 const store = new Vuex.Store({ state:{//存放状态 "username":"foo", "age":18 } }) export default store 在 main.js 中导入文件 import store from './store' Vue.prototype.$store = store const app = new Vue({ store, ...App }) 简单的使用 通过属性访问,需要在根节点注入 store 。 <template> <view> <text>用户名:{{username}}</text> </view> </template> <script> import store from '@/store/index.

SpringBoot整合Qwen(通义千问)模型API进行多轮对话

前期准备工作 在阿里云DashScope灵积模型服务注册账号,申请api-key。 每个模型会有试用体验,详见:https://dashscope.console.aliyun.com/billing 开发 此处采用SDK模式,即引入依赖的形式进行接口的调用。 pom添加 <!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dashscope-sdk-java</artifactId> <version>2.13.0</version> </dependency> java代码 package com.hao; import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationParam; import com.alibaba.dashscope.aigc.generation.GenerationResult; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.utils.JsonUtils; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { public static void callWithMessage() throws NoApiKeyException, ApiException, InputRequiredException { Generation gen = new Generation(); Scanner sc = new Scanner(System.in); List<Message> messages = new ArrayList<>(); Message systemMsg = Message.