首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

一篇文章快速认识 YOLO11 | 目标检测 | 模型训练 | 自定义数据集

  • 25-02-18 14:02
  • 2642
  • 7093
blog.csdn.net

 本文分享YOLO11的目标检测,主要内容是自定义数据集、数据标注、标签格式转换、模型训练、模型推理等。

目录

1、数据标注

2、Labelme的json转为YOLO的txt

3、配置YOLO11代码工程

4、数据集yaml配置文件

5、YOLO11模型结构配置文件

6、编写训练代码

7、开始训练模型

 8、模型推理


1、数据标注

推荐使用Labelme工具进行标注,选择“创建矩形”,对物体进行标注。

Labelme官网地址:https://github.com/wkentaro/labelme

点击“打开目录”,然后加载图像,选择“创建矩形”,开始标注啦

标注完成后,点击“Save”,保存保存标注信息,生成和图片同名的json文件;

看一下示例的json文件里面的内容:

2、Labelme的json转为YOLO的txt

首先了解YOLO11的目标检测标签格式,如下所示:

YOLO11的标签文件是一个txt文件,每行表示一个物体的标签。

每一行的格式是: 。其中:

  • 是类别索引。
  • 和是目标的中心点坐标(归一化到0-1)。
  • 和是目标的宽度和高度(归一化到0-1)。
  • 说明:这个格式不但适用于YOLO11、YOLOv8、YOLOv5,还适用于ultralytics工程中其他版本的YOLO。  

txt标签示例数据,表示有两个物体:

0 0.5192 0.4512 0.3985 0.7572
3 0.5061 0.5921 0.2631 0.4561

  • 第一行表示物体1,类别为0,0.5192是中心点x坐标,0.4512是中心点y坐标,0.3985是宽度, 0.7572是高度。
  • 第二行表示物体2,类别为3,0.5061是中心点x坐标,0.5921是中心点y坐标,0.2631是宽度, 0.4561是高度。

了解YOLO11的检测标签txt文件后~

编写代码,把Labelme的json转为YOLO的txt

主要包括两个函数:convert_labelme_to_yolo( )、process_folder( )

函数解析:

convert_labelme_to_yolo(json_path, output_dir):

  • 功能: 将单个LabelMe格式的JSON文件转换为YOLO11格式。
  • 参数:
    • json_path (str): 输入的LabelMe格式JSON文件路径。
    • output_dir (str): 输出的YOLO11格式标注文件夹路径。
  • 操作:
    • 读取JSON文件,获取图像宽度和高度。
    • 遍历所有标注形状,提取标签和坐标,计算YOLO11所需的中心点和宽高。
    • 将结果写入以相同文件名命名的TXT文件中。

process_folder(input_folder, output_folder):

  • 功能: 处理输入文件夹中的所有JSON文件,转换为YOLO11格式。
  • 参数:
    • input_folder (str): 包含LabelMe格式JSON文件的输入文件夹路径。
    • output_folder (str): 用于保存YOLO11格式标注文件的输出文件夹路径。
  • 操作:
    • 创建输出文件夹(如果不存在)。
    • 遍历输入文件夹,调用转换函数处理每个以.json结尾的文件。

 示例代码如下所示:

  1. import json
  2. import os
  3. # 定义标签映射,将类别名称映射为ID
  4. label_map = {
  5. "car": 0, # 汽车
  6. "bus": 1 # 公交车
  7. }
  8. def convert_labelme_to_yolo(json_path, output_dir):
  9. """
  10. 将LabelMe格式的JSON文件转换为YOLO11格式的标注文件。
  11. 参数:
  12. json_path (str): 输入的LabelMe格式JSON文件路径。
  13. output_dir (str): 输出的YOLO11格式标注文件夹路径。
  14. """
  15. # 打开LabelMe格式的JSON文件
  16. with open(json_path, 'r') as f:
  17. labelme_data = json.load(f) # 读取JSON数据
  18. # 获取图像的宽度和高度
  19. image_width = labelme_data['imageWidth']
  20. image_height = labelme_data['imageHeight']
  21. yolo_annotations = [] # 存储YOLO11格式的标注
  22. # 遍历所有的标注形状
  23. for shape in labelme_data['shapes']:
  24. label = shape['label'] # 获取标签名称
  25. if label not in label_map:
  26. continue # 如果标签未定义,则忽略
  27. class_id = label_map[label] # 获取对应的类别ID
  28. points = shape['points'] # 获取标注的坐标点
  29. if shape['shape_type'] == 'rectangle': # 如果是矩形
  30. (x1, y1), (x2, y2) = points # 获取矩形的两个顶点
  31. elif shape['shape_type'] == 'polygon': # 如果是多边形
  32. x1, y1 = min(point[0] for point in points), min(point[1] for point in points) # 计算多边形的左上角
  33. x2, y2 = max(point[0] for point in points), max(point[1] for point in points) # 计算多边形的右下角
  34. else:
  35. continue # 其他类型不处理
  36. # 计算YOLO11格式所需的中心点和宽高
  37. x_center = (x1 + x2) / 2.0 / image_width # 计算中心点x坐标
  38. y_center = (y1 + y2) / 2.0 / image_height # 计算中心点y坐标
  39. width = (x2 - x1) / image_width # 计算宽度
  40. height = (y2 - y1) / image_height # 计算高度
  41. # 添加YOLO11格式的标注到列表中
  42. yolo_annotations.append(f"{class_id} {x_center} {y_center} {width} {height}")
  43. # 构建输出文件的路径
  44. output_file = os.path.join(output_dir, os.path.splitext(os.path.basename(json_path))[0] + '.txt')
  45. # 将YOLO11格式的标注写入输出文件
  46. with open(output_file, 'w') as f:
  47. f.write('\n'.join(yolo_annotations))
  48. def process_folder(input_folder, output_folder):
  49. """
  50. 处理输入文件夹中的所有JSON文件,并将其转换为YOLO11格式的标注文件。
  51. 参数:
  52. input_folder (str): 输入文件夹路径,包含LabelMe格式的JSON文件。
  53. output_folder (str): 输出文件夹路径,用于保存YOLO11格式的标注文件。
  54. """
  55. # 创建输出文件夹(如果不存在)
  56. os.makedirs(output_folder, exist_ok=True)
  57. # 处理输入文件夹中的每个 JSON 文件
  58. for filename in os.listdir(input_folder):
  59. if filename.endswith(".json"): # 只处理以 .json 结尾的文件
  60. json_path = os.path.join(input_folder, filename) # 获取完整的JSON文件路径
  61. convert_labelme_to_yolo(json_path, output_folder) # 调用转换函数
  62. # 示例使用
  63. input_folder = "/mnt/data/json_labels" # 输入json_labels文件夹路径
  64. output_folder = "/mnt/data/yolo11_txt_labels" # 输出txt_labels文件夹路径
  65. process_folder(input_folder, output_folder) # 处理文件夹中的所有JSON文件
  66. # 列出输出文件夹中的文件以确认
  67. os.listdir(output_folder) # 打印输出文件夹中的文件列表

我们使用上面代码时,需要设置输入的json_labels文件夹路径、输出txt_labels文件夹路径:

  1. input_folder = "/mnt/data/json_labels" # 输入json_labels文件夹路径
  2. output_folder = "/mnt/data/yolo11_txt_labels" # 输出txt_labels文件夹路径

3、配置YOLO11代码工程

首先到YOLO11代码地址,下载源代码:https://github.com/ultralytics/ultralytics

  • 在 GitHub 仓库页面上,用户点击绿色的 "Code" 按钮后,会弹出一个选项框。
  • 选择通过 HTTPS 或 GitHub CLI 克隆仓库,也可以点击框中的 "Download ZIP" 按钮,将整个仓库下载为 ZIP 压缩包到本地。

解压ultralytics-main.zip文件,在ultralytics同级目录中,

  • 新建文件:训练代码(train.py)、推理代码(infer.py)
  • 以及测试数据的文件夹:datasets,权重文件目录:weights
  1. ultralytics-main/
  2. .github/
  3. datasets/
  4. docker/
  5. docs/
  6. examples/
  7. runs/
  8. tests/
  9. ultralytics/
  10. weights/
  11. .gitignore
  12. CITATION.cff
  13. CONTRIBUTING.md
  14. LICENSE
  15. mkdocs.yml
  16. print_dir.py
  17. pyproject.toml
  18. README.md
  19. README.zh-CN.md
  20. train.py
  21. infer.py

weights目录可以存放不同任务的权重,比如:yolo11m-cls.pt、yolo11m-obb.pt、yolo11m-pose.pt、yolo11m-seg.pt、yolo11m.pt、yolo11n.pt等。

train.py文件是和ultralytics文件夹同一级目录的

后面可以直接调用ultralytics源代码中的函数、类和依赖库等,如果有需要直接修改ultralytics中的代码,比较方便。

4、数据集yaml配置文件

在ultralytics/cfg/datasets/目录下,新建一个yaml文件,比如:auto-parts-det.yaml

  1. # Ultralytics YOLO ?, AGPL-3.0 license
  2. path: ./datasets/det_auto_parts_20241020 # dataset root dir
  3. train: train/images # train images
  4. val: val/images # val images
  5. # Classes
  6. names:
  7. 0: person
  8. 1: bicycle
  9. 2: car

同级目录下还存在许多数据集配置文件

比如:coco128.yaml、coco.yaml、DOTAv1.5.yaml、VOC.yaml、Objects365.yaml、Argoverse.yaml等等

yaml文件中的path,需要根据实际数据路径进行修改,指定数据集的路径

5、YOLO11模型结构配置文件

YOLO11模型结构的配置文件,比如yolo11.yaml,它所在位置是

ultralytics/cfg/models/11/yolo11.yaml

里面有详细的模型结构参数信息 :

  1. # Ultralytics YOLO ?, AGPL-3.0 license
  2. # YOLO11 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect
  3. # Parameters
  4. nc: 80 # number of classes
  5. scales: # model compound scaling constants, i.e. 'model=yolo11n.yaml' will call yolo11.yaml with scale 'n'
  6. # [depth, width, max_channels]
  7. n: [0.50, 0.25, 1024] # summary: 319 layers, 2624080 parameters, 2624064 gradients, 6.6 GFLOPs
  8. s: [0.50, 0.50, 1024] # summary: 319 layers, 9458752 parameters, 9458736 gradients, 21.7 GFLOPs
  9. m: [0.50, 1.00, 512] # summary: 409 layers, 20114688 parameters, 20114672 gradients, 68.5 GFLOPs
  10. l: [1.00, 1.00, 512] # summary: 631 layers, 25372160 parameters, 25372144 gradients, 87.6 GFLOPs
  11. x: [1.00, 1.50, 512] # summary: 631 layers, 56966176 parameters, 56966160 gradients, 196.0 GFLOPs
  12. # YOLO11n backbone
  13. backbone:
  14. # [from, repeats, module, args]
  15. - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
  16. - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
  17. - [-1, 2, C3k2, [256, False, 0.25]]
  18. - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
  19. - [-1, 2, C3k2, [512, False, 0.25]]
  20. - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16
  21. - [-1, 2, C3k2, [512, True]]
  22. - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32
  23. - [-1, 2, C3k2, [1024, True]]
  24. - [-1, 1, SPPF, [1024, 5]] # 9
  25. - [-1, 2, C2PSA, [1024]] # 10
  26. # YOLO11n head
  27. head:
  28. - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  29. - [[-1, 6], 1, Concat, [1]] # cat backbone P4
  30. - [-1, 2, C3k2, [512, False]] # 13
  31. - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  32. - [[-1, 4], 1, Concat, [1]] # cat backbone P3
  33. - [-1, 2, C3k2, [256, False]] # 16 (P3/8-small)
  34. - [-1, 1, Conv, [256, 3, 2]]
  35. - [[-1, 13], 1, Concat, [1]] # cat head P4
  36. - [-1, 2, C3k2, [512, False]] # 19 (P4/16-medium)
  37. - [-1, 1, Conv, [512, 3, 2]]
  38. - [[-1, 10], 1, Concat, [1]] # cat head P5
  39. - [-1, 2, C3k2, [1024, True]] # 22 (P5/32-large)
  40. - [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)

如果需要修改模型结构,可以在这个文件进行修改。

6、编写训练代码

前面准备好了:数据集配置文件(auto-parts-det.yaml)、模型结构配置文件(yolo11.yaml)

  • 这里需要注意结构配置文件,虽然文件名是yolo11.yaml,但是需要再后面指定模型尺寸(n, s, m, l, x)
  • 比如需要m规模的模型,在加载模型时用YOLO("yolo11m.yaml");如果不指定,默认是n的,感觉怪怪的

下面编写训练代码,可以参考一下:

  1. from ultralytics import YOLO
  2. # 加载预训练的模型
  3. model = YOLO("yolo11m.yaml").load("weights/yolo11m.pt")
  4. # 定义训练参数,添加默认值、范围和中文注释
  5. train_params = {
  6. 'data': "auto-parts-det.yaml", # 数据集配置文件路径,需要自定义修改
  7. 'epochs': 100, # 总训练轮次,默认值 100,范围 >= 1
  8. 'imgsz': 640, # 输入图像大小,默认值 640,范围 >= 32
  9. 'batch': 8, # 批次大小,默认值 16,范围 >= 1
  10. 'save': True, # 是否保存训练结果和模型,默认值 True
  11. 'save_period': -1, # 模型保存频率,默认值 -1,表示只保存最终结果
  12. 'cache': False, # 是否缓存数据集,默认值 False
  13. 'device': None, # 训练设备,默认值 None,支持 "cpu", "gpu"(device=0,1), "mps"
  14. 'workers': 8, # 数据加载线程数,默认值 8,影响数据预处理速度
  15. 'project': None, # 项目名称,保存训练结果的目录,默认值 None
  16. 'name': None, # 训练运行的名称,用于创建子目录保存结果,默认值 None
  17. 'exist_ok': False, # 是否覆盖已有项目/名称目录,默认值 False
  18. 'optimizer': 'auto', # 优化器,默认值 'auto',支持 'SGD', 'Adam', 'AdamW'
  19. 'verbose': True, # 是否启用详细日志输出,默认值 False
  20. 'seed': 0, # 随机种子,确保结果的可重复性,默认值 0
  21. 'deterministic': True, # 是否强制使用确定性算法,默认值 True
  22. 'single_cls': False, # 是否将多类别数据集视为单一类别,默认值 False
  23. 'rect': False, # 是否启用矩形训练(优化批次图像大小),默认值 False
  24. 'cos_lr': False, # 是否使用余弦学习率调度器,默认值 False
  25. 'close_mosaic': 10, # 在最后 N 轮次中禁用 Mosaic 数据增强,默认值 10
  26. 'resume': False, # 是否从上次保存的检查点继续训练,默认值 False
  27. 'amp': True, # 是否启用自动混合精度(AMP)训练,默认值 True
  28. 'fraction': 1.0, # 使用数据集的比例,默认值 1.0
  29. 'profile': False, # 是否启用 ONNX 或 TensorRT 模型优化分析,默认值 False
  30. 'freeze': None, # 冻结模型的前 N 层,默认值 None
  31. 'lr0': 0.01, # 初始学习率,默认值 0.01,范围 >= 0
  32. 'lrf': 0.01, # 最终学习率与初始学习率的比值,默认值 0.01
  33. 'momentum': 0.937, # SGD 或 Adam 的动量因子,默认值 0.937,范围 [0, 1]
  34. 'weight_decay': 0.0005, # 权重衰减,防止过拟合,默认值 0.0005
  35. 'warmup_epochs': 3.0, # 预热学习率的轮次,默认值 3.0
  36. 'warmup_momentum': 0.8, # 预热阶段的初始动量,默认值 0.8
  37. 'warmup_bias_lr': 0.1, # 预热阶段的偏置学习率,默认值 0.1
  38. 'box': 7.5, # 边框损失的权重,默认值 7.5
  39. 'cls': 0.5, # 分类损失的权重,默认值 0.5
  40. 'dfl': 1.5, # 分布焦点损失的权重,默认值 1.5
  41. 'pose': 12.0, # 姿态损失的权重,默认值 12.0
  42. 'kobj': 1.0, # 关键点目标损失的权重,默认值 1.0
  43. 'label_smoothing': 0.0, # 标签平滑处理,默认值 0.0
  44. 'nbs': 64, # 归一化批次大小,默认值 64
  45. 'overlap_mask': True, # 是否在训练期间启用掩码重叠,默认值 True
  46. 'mask_ratio': 4, # 掩码下采样比例,默认值 4
  47. 'dropout': 0.0, # 随机失活率,用于防止过拟合,默认值 0.0
  48. 'val': True, # 是否在训练期间启用验证,默认值 True
  49. 'plots': True, # 是否生成训练曲线和验证指标图,默认值 True
  50. # 数据增强相关参数
  51. 'hsv_h': 0.2, # 色相变化范围 (0.0 - 1.0),默认值 0.015
  52. 'hsv_s': 0.7, # 饱和度变化范围 (0.0 - 1.0),默认值 0.7
  53. 'hsv_v': 0.4, # 亮度变化范围 (0.0 - 1.0),默认值 0.4
  54. 'degrees': 30.0, # 旋转角度范围 (-180 - 180),默认值 0.0
  55. 'translate': 0.1, # 平移范围 (0.0 - 1.0),默认值 0.1
  56. 'scale': 0.5, # 缩放比例范围 (>= 0.0),默认值 0.5
  57. 'shear': 0.0, # 剪切角度范围 (-180 - 180),默认值 0.0
  58. 'perspective': 0.0, # 透视变化范围 (0.0 - 0.001),默认值 0.0
  59. 'flipud': 0.0, # 上下翻转概率 (0.0 - 1.0),默认值 0.0
  60. 'fliplr': 0.5, # 左右翻转概率 (0.0 - 1.0),默认值 0.5
  61. 'bgr': 0.0, # BGR 色彩顺序调整概率 (0.0 - 1.0),默认值 0.0
  62. 'mosaic': 0.5, # Mosaic 数据增强 (0.0 - 1.0),默认值 1.0
  63. 'mixup': 0.0, # Mixup 数据增强 (0.0 - 1.0),默认值 0.0
  64. 'copy_paste': 0.0, # Copy-Paste 数据增强 (0.0 - 1.0),默认值 0.0
  65. 'copy_paste_mode': 'flip', # Copy-Paste 增强模式 ('flip' 或 'mixup'),默认值 'flip'
  66. 'auto_augment': 'randaugment', # 自动增强策略 ('randaugment', 'autoaugment', 'augmix'),默认值 'randaugment'
  67. 'erasing': 0.4, # 随机擦除增强比例 (0.0 - 0.9),默认值 0.4
  68. 'crop_fraction': 1.0, # 裁剪比例 (0.1 - 1.0),默认值 1.0
  69. }
  70. # 进行训练
  71. results = model.train(**train_params)

YOLO11模型训练,思路流程:

  • 加载模型:使用 YOLO 类指定模型的配置文件,并加载预训练权重 yolo11m.pt。
  • 定义训练参数:通过字典 train_params 定义了一系列训练参数,涵盖了训练过程中可能涉及的配置项,如数据集路径、训练轮数、图像大小、优化器、数据增强等。
  • 执行训练:使用 model.train(**train_params) 将定义的训练参数传入模型,开始训练。
  • 保存训练结果:训练完成后,结果保存在 results 中,包含损失和精度等信息。

在ultralytics工程中,没有了超参数文件了,需要从model.train( )函数参数设置,所以才会有上面的示例代码。

7、开始训练模型

直接运行train.py,就开始训练啦

  1. Transferred 649/649 items from pretrained weights
  2. Ultralytics 8.3.7 ? Python-3.9.16 torch-1.13.1 CUDA:0 (NVIDIA A30, 24062MiB)
  3. Starting training for 30 epochs...
  4. Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
  5. 1/30 4.68G 2.238 1.691 2.426 80 640: 100%|██████████| 16/16 [00:02<00:00, 5.91it/s]
  6. Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 8/8 [00:00<00:00, 12.18it/s]
  7. all 128 929 0.77 0.728 0.798 0.615
  8. ......
  9. Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
  10. 30/30 4.49G 1.171 0.7135 1.319 41 640: 100%|██████████| 16/16 [00:01<00:00, 8.80it/s]
  11. Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 8/8 [00:00<00:00, 13.42it/s]
  12. all 128 929 0.847 0.845 0.891 0.577
  13. 30 epochs completed in 0.027 hours.
  14. Optimizer stripped from runs/detect/train5/weights/last.pt, 40.7MB
  15. Optimizer stripped from runs/detect/train5/weights/best.pt, 40.7MB

训练完成后,可以在runs/detect/train5路径,可以看到保存的权重、训练记录表格和标签信息等

 8、模型推理

使用刚才训练好的模型权重,进行模型推理,看看目标检测效果

示例代码,如下所示:

  1. from ultralytics import YOLO
  2. # 加载预训练的YOLOv11n模型
  3. model = YOLO(r"runs/detect/train5/weights/best.pt")
  4. # 对指定的图像文件夹进行推理,并设置各种参数
  5. results = model.predict(
  6. source="datasets/det_num40/images/", # 数据来源,可以是文件夹、图片路径、视频、URL,或设备ID(如摄像头)
  7. conf=0.45, # 置信度阈值
  8. iou=0.6, # IoU 阈值
  9. imgsz=640, # 图像大小
  10. half=False, # 使用半精度推理
  11. device=None, # 使用设备,None 表示自动选择,比如'cpu','0'
  12. max_det=300, # 最大检测数量
  13. vid_stride=1, # 视频帧跳跃设置
  14. stream_buffer=False, # 视频流缓冲
  15. visualize=False, # 可视化模型特征
  16. augment=False, # 启用推理时增强
  17. agnostic_nms=False, # 启用类无关的NMS
  18. classes=None, # 指定要检测的类别
  19. retina_masks=False, # 使用高分辨率分割掩码
  20. embed=None, # 提取特征向量层
  21. show=False, # 是否显示推理图像
  22. save=True, # 保存推理结果
  23. save_frames=False, # 保存视频的帧作为图像
  24. save_txt=True, # 保存检测结果到文本文件
  25. save_conf=False, # 保存置信度到文本文件
  26. save_crop=False, # 保存裁剪的检测对象图像
  27. show_labels=True, # 显示检测的标签
  28. show_conf=True, # 显示检测置信度
  29. show_boxes=True, # 显示检测框
  30. line_width=None # 设置边界框的线条宽度,比如2,4
  31. )

看看简单场景的,目标检测效果:

看看密集重贴场景,目标检测效果:

 YOLO11相关文章推荐:

一篇文章快速认识YOLO11 | 关键改进点 | 安装使用 | 模型训练和推理-CSDN博客

一篇文章快速认识 YOLO11 | 实例分割 | 模型训练 | 自定义数据集-CSDN博客

YOLO11模型推理 | 目标检测与跟踪 | 实例分割 | 关键点估计 | OBB旋转目标检测-CSDN博客

YOLO11模型训练 | 目标检测与跟踪 | 实例分割 | 关键点姿态估计-CSDN博客

YOLO11 实例分割 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签-CSDN博客

YOLO11 实例分割 | 导出ONNX模型 | ONNX模型推理-CSDN博客

YOLO11 目标检测 | 导出ONNX模型 | ONNX模型推理-CSDN博客

YOLO11 目标检测 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签_yolo11 标注平台-CSDN博客

分享完成,欢迎大家多多点赞和收藏,谢谢~

注:本文转载自blog.csdn.net的一颗小树x的文章"https://blog.csdn.net/qq_41204464/article/details/143171760"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top