大模型入门实战 | 基于 YOLO 数据集微调 Qwen2.5-VL-3B-Instruct 的目标检测任务

大模型入门实战 | 基于 YOLO 数据集微调 Qwen2.5-VL-3B-Instruct 的目标检测任务

这篇就是新手向的“保姆级”实操文。你将把 YOLO 检测数据 转成 对话式 Grounding 数据,用 ms-swiftLoRA 微调,再用脚本 推理 + 可视化
但值得注意的是,一般的检测任务不推荐这么用哈,这仅仅是给大家学习使用,切勿“大炮打蚊子”

请添加图片描述


0. Grounding 是什么?

Grounding(定位 / 指向):给一张图 + 一段文字指令(如“找出 dog,并输出框”),模型用语言理解来完成检测式定位,并把结果以JSON形式吐出来。
区别于传统检测器(YOLO 等)只在固定类上训练,Grounding 可以用自然语言描述做更开放的目标定位。

在这里插入图片描述
在这里插入图片描述


1. 环境准备(一次性)

Python & CUDA

  • Python ≥ 3.9(3.10/3.11 更佳)
  • 已装好 PyTorch GPU 版本(torch.cuda.is_available() 为 True)

安装依赖

pip install "transformers>=4.43" accelerate peft pillow pyyaml
pip install ms-swift  # 微调工具
# 可选(内存更省、速度更快;没装也能训练):
# pip install flash-attn --no-build-isolation

模型权重

  • 基座:models/Qwen2.5-VL-3B-Instruct(本地或 huggingface 路径)
  • 也可用 AWQ 量化版:Qwen/Qwen2.5-VL-3B-Instruct-AWQ(更省显存)

2. 数据准备:把 YOLO 数据变成“对话式 Grounding”JSONL

我们希望每一行样本长这样(ms-swift 能直接吃):

{"images": ["images/train/0001.jpg"],"messages": [{"role":"user", "content":"<image>\n请在图中定位 camera,并以JSON返回 bbox_2d。只输出JSON。"},{"role":"assistant", "content":"{\"bbox_2d\":[x1,y1,x2,y2]}"}]
}

2.1 你的 YOLO 数据结构(典型)

root/data.yaml              # 里边有 names: ["classA","classB",...]images/train/*.jpg|pngimages/val/*.jpg|pnglabels/train/*.txt     # 每行: cls cx cy w h(归一化)labels/val/*.txt

2.2 转换脚本

将下面脚本存为 yolo2_ms_swift.py

  • 支持两种模式:

    • per-class(默认):每图每类产出一条样本,问“只找这一类”
    • all每图一条样本,让模型“找出所有目标”
  • 选项:

    • --include_negativesper-class该类不出现也产出,标成 {"bbox_2d":[]}(非常有助于减少“幻觉输出”)
    • --lang zh/en:提示语中英文
    • --image_path_prefix:把 images 字段写成带前缀的绝对路径(NFS/共享盘常用)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
把 YOLO 检测数据集转成 ms-swift 可微调用的标准格式(JSONL):
每行形如:
{"images": ["images/train/0001.jpg"],"messages": [{"role":"user", "content":"<image>\n请在图中定位 camera,并以JSON返回 bbox_2d。只输出JSON。"},{"role":"assistant", "content":"{\"bbox_2d\":[x1,y1,x2,y2]}"}   # 多框 -> {"bbox_2d":[[...],[...]]}]
}输入(典型 YOLO):
root/data.yaml              # names: [...]images/train/*.jpg|pngimages/val/*.jpg|pnglabels/train/*.txt     # YOLO: cls cx cy w h (归一化)labels/val/*.txt支持两种生成模式:
- per-class(默认):每张图、每个类别一条样本(只让模型找该类,答案只给该类的框)
- all:每张图一条样本(不区分类,返回所有框)可选:
- --include_negatives:per-class 时,即使该类不在图中也产出(bbox_2d = [])
- --image_path_prefix:把 image 字段写成绝对(NFS)前缀
- --lang zh/en:提示语语言
"""import argparse, json
from pathlib import Path
from typing import List, Tuple, Dict, Any, Optional
from PIL import Image
import yamldef load_class_names(p: Path) -> List[str]:meta = yaml.safe_load(p.read_text(encoding="utf-8"))names = meta.get("names") or meta.get("class_names")assert isinstance(names, list) and len(names) > 0, "data.yaml 里需要 names 列表"return [str(x) for x in names]def yolo_line_to_xyxy(line: str, W: int, H: int) -> Optional[Tuple[int, List[int]]]:ps = line.strip().split()if len(ps) != 5: return Nonetry:cid = int(float(ps[0])); cx, cy, w, h = map(float, ps[1:])except: return Nonebw, bh = w*W, h*Hx1 = int(round(cx*W - bw/2)); y1 = int(round(cy*H - bh/2))x2 = int(round(cx*W + bw/2)); y2 = int(round(cy*H + bh/2))x1 = max(0, min(x1, W-1)); y1 = max(0, min(y1, H-1))x2 = max(0, min(x2, W-1)); y2 = max(0, min(y2, H-1))if x2 <= x1 or y2 <= y1: return Nonereturn cid, [x1,y1,x2,y2]def iter_image_label_pairs_from_yaml(root: Path, split: str, yaml_path: Path):cfg = yaml.safe_load(yaml_path.read_text())img_dirs = cfg.get(split)if not img_dirs:return []if isinstance(img_dirs, str):img_dirs = [img_dirs]pairs = []exts = {".jpg",".jpeg",".png",".bmp",".webp"}for d in img_dirs:d = Path(d)for p in d.rglob("*"):if p.suffix.lower() in exts:# 找对应 labelrel = p.relative_to(d)lbl_dir = Path(str(d).replace("images", "labels"))lbl_path = (lbl_dir/rel).with_suffix(".txt")pairs.append((p, lbl_path))return pairsdef zh_user_prompt_one(label_name: str) -> str:return f"<image>\n请在图中定位 {label_name},并以JSON返回 bbox_2d。只输出JSON。"
def en_user_prompt_one(label_name: str) -> str:return f"<image>\nLocate {label_name} in this image and return bbox_2d as JSON. Output JSON only."
def zh_user_prompt_all() -> str:return "<image>\n请在图中定位所有目标,并以JSON返回 bbox_2d。只输出JSON。"
def en_user_prompt_all() -> str:return "<image>\nLocate all objects and return bbox_2d as JSON. Output JSON only."def gpt_value_from_boxes(boxes: List[List[int]]) -> str:# 紧凑 JSON(不缩进,减少训练时token)if len(boxes) == 1:return json.dumps({"bbox_2d": boxes[0]}, ensure_ascii=False)else:return json.dumps({"bbox_2d": boxes}, ensure_ascii=False)def main():ap = argparse.ArgumentParser("YOLO -> ms-swift JSONL")ap.add_argument("--root", required=True, help="YOLO 数据集根目录")ap.add_argument("--split", required=True, choices=["train","val","test"])ap.add_argument("--out", required=True, help="输出 JSONL 路径")ap.add_argument("--mode", default="per-class", choices=["per-class","all"])ap.add_argument("--include_negatives", action="store_true", help="per-class 下也产出缺类样本(bbox_2d=[])")ap.add_argument("--lang", default="zh", choices=["zh","en"])ap.add_argument("--image_path_prefix", default="", help="把 image 字段写成带此前缀的路径(绝对/NFS)")args = ap.parse_args()root = Path(args.root).resolve()names = load_class_names(root/"data.yaml")pairs = iter_image_label_pairs_from_yaml(root, args.split, root/"data.yaml")if not pairs:raise SystemExit(f"没有找到图片:{root}/images/{args.split}")outp = Path(args.out); outp.parent.mkdir(parents=True, exist_ok=True)if args.lang == "zh":prompt_one = zh_user_prompt_oneprompt_all = zh_user_prompt_allelse:prompt_one = en_user_prompt_oneprompt_all = en_user_prompt_alln = 0with outp.open("w", encoding="utf-8") as fout:for img_path, lbl_path in pairs:# 读尺寸try:with Image.open(img_path) as im: W,H = im.sizeexcept: continue# 解析标签cls2boxes: Dict[int, List[List[int]]] = {}if lbl_path.exists():for line in lbl_path.read_text(encoding="utf-8").splitlines():r = yolo_line_to_xyxy(line, W, H)if not r: continuecid, box = rcls2boxes.setdefault(cid, []).append(box)# image 字段:相对 root 或带 prefix 的绝对路径if args.image_path_prefix:try:image_field = str((Path(args.image_path_prefix)/img_path.relative_to(root)).resolve())except Exception:image_field = str((Path(args.image_path_prefix)/img_path.name).resolve())else:image_field = str(img_path.relative_to(root))if args.mode == "per-class":for cid, cname in enumerate(names):boxes = cls2boxes.get(cid, [])if not boxes and not args.include_negatives:continueuser = prompt_one(cname)asst = gpt_value_from_boxes(boxes)rec = {"images":[image_field],"messages":[{"role":"user","content":user},{"role":"assistant","content":asst}]}fout.write(json.dumps(rec, ensure_ascii=False)+"\n"); n += 1else:  # allall_boxes: List[List[int]] = []for b in cls2boxes.values(): all_boxes.extend(b)user = prompt_all()asst = gpt_value_from_boxes(all_boxes)rec = {"images":[image_field],"messages":[{"role":"user","content":user},{"role":"assistant","content":asst}]}fout.write(json.dumps(rec, ensure_ascii=False)+"\n"); n += 1print(f"Done. wrote {n} samples -> {outp}")if __name__ == "__main__":main()

2.3 一键生成 JSONL

# 例:转训练集(每图每类一条)
python yolo2_ms_swift.py \--root /home/q/nfs_share/datasets/your_yolo_dataset \--split train \--out   /home/q/nfs_share/datasets/your_yolo_dataset/train_ms.jsonl \--mode per-class \--lang zh \--image_path_prefix /home/q/nfs_share/datasets/your_yolo_dataset# 转验证集
python yolo2_ms_swift.py \--root /home/q/nfs_share/datasets/your_yolo_dataset \--split val \--out   /home/q/nfs_share/datasets/your_yolo_dataset/val_ms.jsonl \--mode per-class \--lang zh

我这个数据集是检测的 ,所以我只有一类 dog

单类数据同样可用names: ["camera"] 时,每张图就会得到“找 dog”的样本;多实例会自动写成 {"bbox_2d":[[...],[...]]}

样例

{"images": ["/home/q/.../images/07_alldatasets/202506291136004523.jpg"],"messages": [{"role": "user", "content": "<image>\n请在图中定位 dog,并以JSON返回 bbox_2d。只输出JSON。"},{"role": "assistant", "content": "{\"bbox_2d\": [2738, 522, 2844, 616]}"}]}

3. 开始微调:用 ms-swift 做 LoRA

多卡训练用环境变量控制可见 GPU,梯度累积可以在小 batch 下堆出更大的有效 batch。

命令行

CUDA_VISIBLE_DEVICES=1,2,3,4,5,6 swift sft \--model models/Qwen2.5-VL-3B-Instruct \--dataset train_ms.jsonl \--val_dataset val_ms.jsonl \--output_dir qwen25vl_camera_lora \--lora_rank 16 \--lora_alpha 32 \--lora_dropout 0.05 \--learning_rate 1e-4 \--num_train_epochs 3 \--per_device_train_batch_size 2 \--gradient_accumulation_steps 8 \--per_device_eval_batch_size 2 \--logging_steps 20 \--save_steps 500 \--eval_strategy steps \--eval_steps 500 \--bf16 true \--gradient_checkpointing true \--max_length 4096 \--max_pixels 921600 \--truncation_strategy delete

关键参数怎么调?

  • --lora_rank/alpha/dropout:LoRA 容量与正则,16/32/0.05是不错的起点。

  • --per_device_train_batch_size + --gradient_accumulation_steps

    • 有效 batch ≈ batch_size × 累积步数 × GPU数
  • --bf16 true + --gradient_checkpointing true:省显存。

  • --max_pixels强相关显存(图像 token 数),小显存就把它调低(如 512×512 ≈ 262k pixels)。

  • --eval_strategy steps / --save_steps:定期评估与保存。

日志长这样

{"loss": 0.9062, "token_acc": 0.7087, "memory(GiB)": 46.95, "global_step/max_steps": "20/3669", ...}
...
{"eval_loss": 0.6329, "eval_token_acc": 0.7492, "epoch": 3.0, "global_step/max_steps": "3669/3669", ...}
{"train_loss": 0.5660, "train_steps_per_second": 0.072, "epoch": 3.0, ...}
  • token_acc:生成时“下一个 token 预测正确”的比例,能反映模型是否学会按格式输出 JSON(但它不是检测 IoU 指标,下文会讲怎么评估 IoU)。

  • 训练结束时 ms-swift 会告诉你:

    • best_model_checkpoint(最优)
    • last_model_checkpoint(最后)

4. 推理:让模型按你的“文字指令”输出 JSON 框

把下面脚本存成 qwen_vl_grounding_infer.py 直接跑:

from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info  # 来自 Qwen-VL 项目# 1) 加载基座(或加载 AWQ 量化版)
model = Qwen2_5_VLForConditionalGeneration.from_pretrained("models/Qwen2.5-VL-3B-Instruct",torch_dtype="auto",device_map="auto",# attn_implementation="flash_attention_2",  # 若已安装 flash-attn 再开启
)# 2) Processor(可用 min/max_pixels 控制视觉 token 开支)
processor = AutoProcessor.from_pretrained("models/Qwen2.5-VL-3B-Instruct")messages = [{"role": "user","content": [{"type": "image", "image": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"},{"type": "text",  "text": "Locate dog in this image and output the bbox coordinates in JSON format."}
]}]# 3) 组批 & 上卡
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)
inputs = processor(text=[text], images=image_inputs, videos=video_inputs,padding=True, return_tensors="pt").to("cuda")# 4) 生成
out_ids = model.generate(**inputs, max_new_tokens=128)
trimmed = [o[len(i):] for i, o in zip(inputs.input_ids, out_ids)]
print(processor.batch_decode(trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False))

预期输出

在这里插入图片描述

['json\n[\n\t{"bbox_2d": [456, 587, 1183, 1214], "label": "dog"}\n]\n']

如果你训练的是“只返回 bbox_2d 不带 label”的格式,请确保推理时的文字提示与训练保持一致,比如明确“只输出 JSON,不要多余文本”。


5. 可视化:把预测框画回图片

把下面脚本存为 viz_simple.py,用 PIL 画框:

python viz_simple.py \--image demo.jpeg \--pred-str '[{"bbox_2d":[456,587,1183,1213],"label":"dog"}]' \--out demo_boxed.jpg

找不到 DejaVuSans.ttf 时脚本会自动回落默认字体,能正常出图。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-from PIL import Image, ImageDraw, ImageFont
import json, argparsedef main():parser = argparse.ArgumentParser()parser.add_argument("--image", required=True, help="原始图片路径")parser.add_argument("--pred-str", required=True,help="预测结果JSON字符串,例如 '[{\"bbox_2d\":[456,587,1183,1213],\"label\":\"dog\"}]'")parser.add_argument("--out", required=True, help="输出图片路径")args = parser.parse_args()# 解析预测结果preds = json.loads(args.pred_str)im = Image.open(args.image).convert("RGB")draw = ImageDraw.Draw(im)# 尝试加载字体try:font = ImageFont.truetype("DejaVuSans.ttf", 20)except:font = ImageFont.load_default()for obj in preds:bbox = obj.get("bbox_2d")label = obj.get("label", "")if not bbox or len(bbox) != 4:continuex1,y1,x2,y2 = bbox# 画框draw.rectangle([x1,y1,x2,y2], outline="red", width=8)if label:# 获取文本尺寸try:# 新Pillow推荐 textbboxtw, th = draw.textbbox((0,0), label, font=font)[2:]except:# 兼容旧版本tw, th = font.getsize(label)# 绘制文字背景+文字draw.rectangle([x1, y1-th-4, x1+tw+4, y1], fill="red")draw.text((x1+2, y1-th-2), label, fill="white", font=font)im.save(args.out)print(f"saved -> {args.out}")if __name__ == "__main__":main()'''
python viz_simple.py \--image demo.jpeg \--pred-str '[{"bbox_2d":[456,587,1183,1213],"label":"dog"}]' \--out demo_boxed.jpg
'''

6. 评估思路(从“会说 JSON”到“框得准”)

训练日志里的 token_acc 说明模型学会了 JSON 话术,但定位效果还要看 IoU:

  • 简易评估:把模型输出的 bbox_2d 与 YOLO 标签(换算到 xyxy)做 IoU,统计 mAP@0.5Recall/Precision

  • 实操要点:

    1. 解析 JSON 时做好容错(有时模型会多给一层 json\n[...] 前缀,strip 再 json.loads)。
    2. 多框匹配用匈牙利匹配或贪心按 IoU 最大配。
    3. 负样本bbox_2d=[])很关键,能明显降低“幻觉预测”。

7. 常见坑与排查

  • data.yaml 里需要 names 列表
    转换脚本依赖 names。没有就补上或改为 class_names
  • 图片路径不对
    训练机和标注机不在一台?用 --image_path_prefix 写绝对路径(NFS 前缀)。
  • 显存爆掉 / OOM
    降低 --max_pixels(如 921600 → 589824)、把 per_device_train_batch_size 调 1、增大 --gradient_accumulation_steps,或上 AWQ 基座。
  • 没装 Flash-Attention
    attn_implementation="flash_attention_2" 去掉即可;想用就先装兼容版本。
  • 输出不是纯 JSON
    提示词务必包含“只输出 JSON”;训练数据和推理提示要风格统一
  • 字体报错
    viz_simple.py 已内置默认字体兜底,或你额外放一份 DejaVuSans.ttf
  • 多 GPU 没生效
    CUDA_VISIBLE_DEVICES=0,1,2,... 控制卡,ms-swift 会自动并行。
    有效 batch ≈ per_device_bs × grad_acc × GPU数

8. 你可以直接复用的完整代码

  • yolo2_ms_swift.py:YOLO → JSONL 转换(已包含中英提示、per-class/all、负样本)
  • qwen_vl_grounding_infer.py:推理脚本(按指令吐 JSON)
  • viz_simple.py:可视化脚本(画框/文字)

以上三个脚本你在题面都给了完整版本,按需直接落盘即可使用。


9. 参考训练记录(帮助你对齐预期)

你的一次训练收敛片段(节选):

Train: ... 3669/3669
Eval:  eval_loss=0.6329, eval_token_acc=0.7492
Train: train_loss=0.5660
best_model_checkpoint: .../checkpoint-3000
last_model_checkpoint:  .../checkpoint-3669

这说明:

  • 模型已稳定学会“按 JSON 说话”(token_acc ~ 0.75)
  • 你可以用 best checkpoint 做下游评估与部署

10. 小结 & 你的下一步

  • 你已经完成:数据转换 → LoRA 微调 → 指令化推理 → 可视化与评估

  • 下一步建议:

    1. 多负样本include_negatives)与多风格提示词混合,增强鲁棒性。
    2. 引入困难样本挖掘(高误检/漏检图)做二次微调。
    3. min/max_pixels分辨率分级训练,兼顾精度与速度。

Grounding 的优势在于“语言可控”。当你的业务只检测“摄像头”等少数类时,小规模 LoRA 就能把 Qwen2.5-VL-3B 调得很“乖”,而且有了语言接口,后续加类、改描述都更灵活。

祝你首训即收敛,推理一路绿灯!如果需要,我可以把评估 IoU 的脚本也给你补上(含 mAP@0.5/0.5:0.95 计算与日志汇总)。

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

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

相关文章

基于Python+MySQL实现物联网引论课程一个火警报警及应急处理系统

物联网引论课程大作业设计报告一、选题、内容及功能说明我们大作业选择的是题目三&#xff1a;一个火警报警及应急处理系统。主要需要实现四个功能&#xff1a;感知环境温度&#xff0c;当环境温度超过阈值&#xff0c;自动触发报警&#xff1a;终端 led 以固定频率闪烁&#x…

基于印染数据的可视化系统设计与实现

标题:基于印染数据的可视化系统设计与实现内容:1.摘要 随着印染行业的快速发展&#xff0c;印染数据呈现爆发式增长。为了更好地管理和分析这些数据&#xff0c;提高印染生产的效率和质量&#xff0c;本研究旨在设计并实现一个基于印染数据的可视化系统。通过收集印染生产过程中…

实验1 第一个微信小程序

实验1 第一个微信小程序一、实验目标二、实验步骤1. 自动生成小程序2. 手动创建小程序三、程序运行结果四、问题总结与体会chunk的博客地址一、实验目标 1、学习使用快速启动模板创建小程序的方法&#xff1b; 2、学习不使用模板手动创建小程序的方法。 二、实验步骤 1. 自…

(计算机网络)JWT三部分及 Signature 作用

JWT&#xff08;JSON Web Token&#xff09;是一种用于 无状态认证 的轻量级令牌&#xff0c;广泛用于分布式系统、单页应用&#xff08;SPA&#xff09;和移动端登录。JWT 结构概览JWT 由 三部分组成&#xff0c;用 . 分隔&#xff1a;xxxxx.yyyyy.zzzzz Header&#xff08;头…

LangGraph

LangGraph 是由 LangChain 团队开发的开源框架&#xff0c;专为构建​​复杂、有状态、多主体&#xff08;Multi-Agent&#xff09;的 LLM 应用​​而设计。它通过​​图结构&#xff08;Graph&#xff09;​​ 组织工作流&#xff0c;支持循环逻辑、动态分支、状态持久化和人工…

STM32物联网项目---ESP8266微信小程序结合OneNET平台MQTT实现STM32单片机远程智能控制---MQTT篇(三)

一、前言本篇文章通过发送AT指令&#xff0c;与云平台建立通讯&#xff1a;1.创建云平台2.烧录AT固件3.MQTT订阅&#xff08;本篇&#xff09;4.单片机代码编写5.微信小程序&#xff08;下载微信开发者工具即可使用&#xff09;二、AT指令集介绍AT指令是一种文本序列&#xff0…

Apache Ozone 2.0.0集群部署

单机部署参考&#xff1a;Apache Ozone 介绍与部署使用(最新版2.0.0)-CSDN博客 安装部署 官方参考&#xff1a;Documentation for Apache Ozone 准备环境 环境准备参考&#xff1a;Linux环境下Hadoop3.4.0集群部署-CSDN博客 1->4-b 参考&#xff1a;Apache Ozone 介绍与部…

【计算机网络 | 第9篇】信道的极限容量

文章目录探秘信道的极限容量&#xff1a;从奈氏准则到香农定理一、信道极限容量的基本概念&#x1f914;二、奈氏准则&#xff1a;无噪声情况下的码元速率限制&#x1f426;‍&#x1f525;&#xff08;一&#xff09;带宽与信号传输的关系&#xff08;二&#xff09;码间串扰问…

深入理解Linux iptables防火墙:从核心概念到实战应用

一、概述&#xff1a;什么是iptables&#xff1f; 在Linux系统中&#xff0c;网络安全防护的核心工具之一便是iptables。它绝非一个简单的命令&#xff0c;而是一个功能强大的用户态工具&#xff0c;与Linux内核中的netfilter框架协同工作&#xff0c;共同构建了Linux的防火墙体…

WebRTC音频QoS方法一.1(NetEQ之音频网络延时DelayManager计算补充)

一、整体简介 NetEQ计算的网络延时&#xff0c;直接影响变速算法的决策。在变速算法里面启动关键的作用。 网络延时计算需要考虑两种情况&#xff1a; 1、单纯抖动的网络延时计算&#xff0c;在UnderrunOptimizer类中实现&#xff1b; 2、在丢包乱序场景下的网络延时计算。…

实时操作系统FreeRTOS移植到STM32VGT6

一、前言 下载平台:STM32F407VGT6 代码使用平台:VSCode 编译器:arm-none-aebi-gcc 程序下载工具:STlink 批处理工具:make 移植的FreeRTOS版本:V11.2.0 其实此方法并不局限在arm-none-aebi-gcc中&#xff0c;此方法对于Keil5也是可以使用的&#xff0c; 只不过复制的一些文件不同…

从线到机:AI 与多模态交互如何重塑 B 端与 App 界面设计

当下&#xff0c;界面设计已经不再是单纯的“画屏幕”。AI 的快速发展让我们不得不重新审视&#xff1a;交互和视觉究竟会走向什么样的未来&#xff1f;无论是移动端 App&#xff0c;还是复杂的 B 端产品&#xff0c;设计的核心都在于让界面更懂用户。本文尝试从三个角度切入&a…

【智能化解决方案】大模型智能推荐选型系统方案设计

大模型智能推荐选型系统方案设计0 背景1 问题分析与定义2 模型假设与简化3 核心模型构建3.1 决策变量与参数定义3.2 目标函数3.3 约束条件4 模型求解与验证4.1 求解策略4.2 验证方法4.3 模型迭代优化5 方案实施与系统设计5.1 系统架构设计5.2 工作流程5.3 关键算法实现5.4 时序…

【Java基础】HashMap、HashTable与HashSet:区别、联系与实践指南

Java中HashMap、HashTable与HashSet的深度解析&#xff1a;区别、联系与实践指南 引言 在Java集合框架中&#xff0c;HashMap、HashTable与HashSet是最常用的哈希型数据结构。它们因高效的查找、插入与删除性能&#xff08;平均时间复杂度O(1)&#xff09;&#xff0c;广泛应用…

互联网大厂Java面试实战:核心技术栈与场景化提问解析(含Spring Boot、微服务、测试框架等)

互联网大厂Java面试实战&#xff1a;核心技术栈与场景化提问解析 本文通过模拟面试官与求职者谢飞机的对话&#xff0c;深入探讨互联网大厂Java开发的核心技术栈面试问题&#xff0c;涵盖Java SE、Spring生态、微服务、大数据等多个领域&#xff0c;结合音视频、电商、AIGC等业…

人工智能-python-深度学习-参数初始化与损失函数

文章目录参数初始化与损失函数一、参数初始化1. 固定值初始化1.1 全零初始化1.2 全1初始化1.3 任意常数初始化2. 随机初始化2.1 均匀分布初始化2.2 正态分布初始化3. Xavier初始化4. He初始化5. 总结二、损失函数1. 线性回归损失函数1.1 MAE&#xff08;Mean Absolute Error&am…

Android Glide常见问题解决方案:从图片加载到内存优化

全面总结Glide使用中的典型问题与解决方案&#xff0c;助力提升应用性能与用户体验作为Android开发中最流行的图片加载库之一&#xff0c;Glide以其简单易用的API和强大的功能深受开发者喜爱。然而&#xff0c;在实际使用过程中&#xff0c;我们往往会遇到各种问题&#xff0c;…

linux系统ollama监听0.0.0.0:11434示例

docker应用如dify访问本地主机部署的ollama&#xff0c;base_url不管配"http://localhost:11434"&#xff0c;还是"http://host_ip:11434"都会报错。这是因为1&#xff09;docker容器访问http://localhost:11434&#xff0c;其实访问的是docker容器自身的服…

Java微服务AI集成指南:LangChain4j vs SpringAI

今天想再完善一下做的微服务项目&#xff0c;想着再接入一个人工客服&#xff0c;于是学习了一下langchan4j的内容&#xff0c;未完一、技术定位辨析&#xff1a;LangChain4j vs Spring AI vs OpenAIOpenAI&#xff1a;AI模型提供商 提供大语言模型API&#xff08;如GPT-4o&…

华为光学设计面试题

16. 题目&#xff1a;设计一个用于机器视觉检测的光学系统时&#xff0c;如何保证在高速运动下成像的清晰度和稳定性&#xff1f;(出处&#xff1a;华为智能制造光学检测项目组招聘面试题)17. 题目&#xff1a;请说明在光学系统设计中&#xff0c;如何权衡景深和分辨率的关系&a…