- 引言
- 1. 图像基础:像素、通道、卷积
- 2. CNN 架构发展史
- 3. 目标检测:YOLO、DETR、Faster R-CNN
- 4. 分割:DeepLab、Mask R-CNN、SAM
- 5. Vision Transformer:ViT、Swin、DINOv2
- 6. 生成模型:GAN、Diffusion、ControlNet
- 7. 实战流水线:从 DataLoader 到 TensorRT
- 测验:深入理解计算机视觉
- 结语:学习路线图
引言
计算机视觉(Computer Vision)是让机器理解图像和视频的 AI 核心领域。智能手机人脸解锁、自动驾驶汽车的障碍物识别、医学影像诊断辅助——这些都在依靠计算机视觉技术运作。
本指南将从像素级基础出发,系统讲解到最新的 Vision Transformer、Stable Diffusion为止。
1. 图像基础:像素、通道、卷积
1.1 数字图像的结构
数字图像是像素(pixel)构成的 2D 网格。
- 灰度图像:H x W 形状的 2D 数组,每个像素值 0~255
- 彩色图像(RGB):H x W x 3 形状的 3D 张量,R/G/B 每个通道 0~255
- 分辨率:图像尺寸(例如 1920x1080)、像素密度(DPI)
import torch
import torchvision.transforms as T
from PIL import Image
# 加载图像并转换为张量
img = Image.open("sample.jpg").convert("RGB")
transform = T.Compose([
T.Resize((224, 224)),
T.ToTensor(), # [0,255] -> [0.0,1.0], HWC -> CHW
T.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
tensor = transform(img) # shape: [3, 224, 224]
print(f"Shape: {tensor.shape}, dtype: {tensor.dtype}")
1.2 卷积与主要滤波器
卷积(Convolution)是将一个小的核(滤波器)在整幅图像上滑动,以提取特征的操作。
import torch
import torch.nn.functional as F
# 3x3 Sobel 边缘检测核(水平方向)
kernel = torch.tensor([
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]
], dtype=torch.float32).unsqueeze(0).unsqueeze(0) # [1, 1, 3, 3]
# 对灰度图像应用卷积
gray_tensor = T.ToTensor()(T.Grayscale()(img)).unsqueeze(0)
edges = F.conv2d(gray_tensor, kernel, padding=1)
| 核类型 | 目的 | 应用场景 |
|---|---|---|
| Sobel | 边缘检测(水平/垂直) | 自动驾驶车道识别 |
| Gaussian | 模糊、去噪 | 图像预处理 |
| Laplacian | 边缘强化 | 锐化 |
| Average | 平均模糊 | 下采样 |
1.3 Albumentations 数据增强流水线
import albumentations as A
from albumentations.pytorch import ToTensorV2
import cv2
train_transform = A.Compose([
A.RandomResizedCrop(224, 224, scale=(0.7, 1.0)),
A.HorizontalFlip(p=0.5),
A.ColorJitter(brightness=0.4, contrast=0.4,
saturation=0.4, hue=0.1, p=0.8),
A.GaussianBlur(blur_limit=(3, 7), p=0.2),
A.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.1,
rotate_limit=15, p=0.5),
A.Normalize(mean=(0.485, 0.456, 0.406),
std=(0.229, 0.224, 0.225)),
ToTensorV2(),
])
image = cv2.cvtColor(cv2.imread("sample.jpg"), cv2.COLOR_BGR2RGB)
augmented = train_transform(image=image)["image"]
2. CNN 架构发展史
2.1 主要架构年表
| 年份 | 架构 | 核心贡献 | ImageNet Top-1 |
|---|---|---|---|
| 1998 | LeNet-5 | 首个实用 CNN,卷积+池化结构 | - |
| 2012 | AlexNet | ReLU、Dropout、GPU 训练 | 63.3% |
| 2014 | VGGNet | 深层堆叠 3x3 核 | 74.4% |
| 2015 | ResNet-50 | Skip Connection,残差学习 | 76.0% |
| 2017 | DenseNet | 所有层直接连接 | 77.4% |
| 2019 | EfficientNet-B7 | 复合缩放 | 84.4% |
| 2022 | ConvNeXt-L | 将 Transformer 设计原则应用于 CNN | 86.6% |
2.2 ResNet:残差学习的革命
ResNet 的核心是skip connection(残差连接)。通过将输入 x 直接加到输出上,解决了梯度消失问题。残差块的输出为 F(x) + x,求导后得到 dF/dx + 1,从而保证最小梯度为 1。
import torch
import torch.nn as nn
import torchvision.models as models
class ResNetClassifier(nn.Module):
def __init__(self, num_classes: int, pretrained: bool = True):
super().__init__()
weights = models.ResNet50_Weights.IMAGENET1K_V2 if pretrained else None
self.backbone = models.resnet50(weights=weights)
in_features = self.backbone.fc.in_features
self.backbone.fc = nn.Sequential(
nn.Dropout(0.3),
nn.Linear(in_features, num_classes)
)
def forward(self, x):
return self.backbone(x)
def train_one_epoch(model, loader, optimizer, criterion, device):
model.train()
total_loss, correct = 0.0, 0
for images, labels in loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item() * images.size(0)
correct += (outputs.argmax(1) == labels).sum().item()
return total_loss / len(loader.dataset), correct / len(loader.dataset)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = ResNetClassifier(num_classes=10).to(device)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-2)
criterion = nn.CrossEntropyLoss()
2.3 EfficientNet:复合缩放
EfficientNet 引入了同时缩放宽度(width)、深度(depth)、分辨率(resolution)的复合系数(compound coefficient)。
import timm
# EfficientNet-B4 微调
model = timm.create_model(
"efficientnet_b4",
pretrained=True,
num_classes=100,
drop_rate=0.3
)
# 冻结主干网络(特征提取模式)
for name, param in model.named_parameters():
if "classifier" not in name:
param.requires_grad = False
2.4 ConvNeXt:CNN 的现代化
ConvNeXt 将 Transformer 的设计原则(大核、LayerNorm、GELU、更少的激活函数)应用于纯 CNN,达到了与 Swin Transformer 相当的性能。
model = timm.create_model(
"convnext_large",
pretrained=True,
num_classes=1000
)
# 使用 7x7 depthwise conv、LayerNorm、GELU 激活函数
3. 目标检测:YOLO、DETR、Faster R-CNN
3.1 检测方式对比
| 方式 | 模型 | 速度 | 准确率 | 特点 |
|---|---|---|---|---|
| Anchor-based 2-stage | Faster R-CNN | 慢 | 高 | RPN + 分类器分离 |
| Anchor-based 1-stage | YOLOv8 | 快 | 中-高 | 单次前向推理 |
| Anchor-free 1-stage | YOLOv10, FCOS | 非常快 | 高 | 无需 NMS,去除锚框 |
| Transformer | DETR | 中等 | 高 | 端到端,关系建模 |
3.2 YOLOv8 实战使用
from ultralytics import YOLO
# 加载预训练模型
model = YOLO("yolov8n.pt") # nano:速度优先
# model = YOLO("yolov8x.pt") # extra-large:准确率优先
# 单张图像推理
results = model("image.jpg", conf=0.25, iou=0.45)
for result in results:
for box in result.boxes:
cls = int(box.cls[0])
conf = float(box.conf[0])
x1, y1, x2, y2 = box.xyxy[0].tolist()
print(f"Class: {result.names[cls]}, Conf: {conf:.2f}")
# 在自定义数据集上微调
model.train(
data="custom.yaml",
epochs=100,
imgsz=640,
batch=16,
lr0=0.01,
device=0
)
# 评估
metrics = model.val()
print(f"mAP50: {metrics.box.map50:.3f}")
print(f"mAP50-95: {metrics.box.map:.3f}")
3.3 YOLOv10:无需 NMS 的检测
YOLOv10 去除了非极大值抑制(Non-Maximum Suppression,NMS)后处理步骤,通过双重标签分配(dual label assignment)实现了端到端学习。它利用一致性匹配(consistency matching),同时运用 one-to-one 预测和 one-to-many 预测。
from ultralytics import YOLO
model = YOLO("yolov10n.pt")
# 无需 NMS,直接返回最终结果 — 降低延迟
results = model.predict("video.mp4", stream=True)
for frame_result in results:
print(frame_result.boxes)
3.4 DETR:Detection Transformer
DETR 通过二分图匹配损失(bipartite matching loss),无需锚框和 NMS,直接预测最终的边界框集合。
import torch
from transformers import DetrImageProcessor, DetrForObjectDetection
from PIL import Image
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
img = Image.open("image.jpg")
inputs = processor(images=img, return_tensors="pt")
outputs = model(**inputs)
target_sizes = torch.tensor([img.size[::-1]])
results = processor.post_process_object_detection(
outputs, target_sizes=target_sizes, threshold=0.9
)[0]
for score, label, box in zip(
results["scores"], results["labels"], results["boxes"]
):
name = model.config.id2label[label.item()]
print(f"{name}: {score:.3f} at {[round(i,2) for i in box.tolist()]}")
4. 分割:DeepLab、Mask R-CNN、SAM
4.1 分割类型
- 语义分割(Semantic):为每个像素分配类别标签(汽车、道路、天空……)
- 实例分割(Instance):区分同一类别中的各个独立对象(汽车1、汽车2……)
- 全景分割(Panoptic):语义分割 + 实例分割的整合
4.2 SAM:Segment Anything Model
Meta 的 SAM 接收提示(prompt)(点、框、掩码)来对任意对象进行分割。它由 Image Encoder(ViT-H)、Prompt Encoder、Mask Decoder 3 个模块构成,是在 SA-1B 数据集(1 亿个掩码)上训练出的通用分割模型。
import torch
import numpy as np
import cv2
from segment_anything import sam_model_registry, SamPredictor
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
sam.to("cuda")
predictor = SamPredictor(sam)
# 设置图像
image = cv2.cvtColor(cv2.imread("image.jpg"), cv2.COLOR_BGR2RGB)
predictor.set_image(image)
# 点提示分割
input_point = np.array([[500, 375]]) # 点击位置 (x, y)
input_label = np.array([1]) # 1=前景,0=背景
masks, scores, logits = predictor.predict(
point_coords=input_point,
point_labels=input_label,
multimask_output=True # 返回多个候选掩码
)
best_mask = masks[scores.argmax()]
print(f"Mask shape: {best_mask.shape}, Score: {scores.max():.3f}")
# 框提示
input_box = np.array([100, 100, 400, 400])
masks_box, _, _ = predictor.predict(
box=input_box[None, :],
multimask_output=False
)
4.3 DeepLabV3+ 语义分割
DeepLabV3+ 使用 ASPP(Atrous Spatial Pyramid Pooling)捕获多尺度的上下文信息。
import torch
import torchvision.models.segmentation as seg_models
model = seg_models.deeplabv3_resnet101(
weights=seg_models.DeepLabV3_ResNet101_Weights.COCO_WITH_VOC_LABELS_V1
)
model.eval()
with torch.no_grad():
output = model(tensor.unsqueeze(0))["out"] # [1, num_classes, H, W]
pred = output.argmax(dim=1).squeeze() # [H, W]
print(f"Segmentation map shape: {pred.shape}")
4.4 Mask R-CNN 实例分割
from torchvision.models.detection import maskrcnn_resnet50_fpn_v2
from torchvision.models.detection import MaskRCNN_ResNet50_FPN_V2_Weights
from torchvision.utils import draw_segmentation_masks
import torchvision.transforms.functional as TF
from PIL import Image
weights = MaskRCNN_ResNet50_FPN_V2_Weights.DEFAULT
model = maskrcnn_resnet50_fpn_v2(weights=weights, box_score_thresh=0.75)
model.eval()
img = Image.open("people.jpg").convert("RGB")
inp = weights.transforms()(img).unsqueeze(0)
with torch.no_grad():
predictions = model(inp)
pred = predictions[0]
masks = (pred["masks"] > 0.5).squeeze(1)
img_uint8 = (TF.to_tensor(img) * 255).byte()
result = draw_segmentation_masks(img_uint8, masks, alpha=0.5)
5. Vision Transformer:ViT、Swin、DINOv2
5.1 ViT 核心原理
ViT(Vision Transformer)将图像划分为固定大小的图块(16x16),把每个图块当作 token 输入 Transformer。与 CNN 不同,它不依赖局部性归纳偏置(locality inductive bias),而是学习全局关系。
import timm
import torch
# ViT-Base/16 微调
model = timm.create_model(
"vit_base_patch16_224",
pretrained=True,
num_classes=10,
img_size=224
)
# ViT 搭配更强的数据增强 + AdamW + cosine 调度效果更好
data_config = timm.data.resolve_model_data_config(model)
transforms_train = timm.data.create_transform(**data_config, is_training=True)
transforms_val = timm.data.create_transform(**data_config, is_training=False)
optimizer = torch.optim.AdamW(
model.parameters(), lr=1e-3, weight_decay=0.05
)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer, T_max=100
)
5.2 Swin Transformer:层级化 ViT
Swin Transformer 通过层级化特征图和Shifted Window Attention,将 CNN 的局部性引入了 ViT。每个阶段将分辨率减半、通道数翻倍,因此与 FPN 兼容。
| 模型 | 分辨率 | 参数量 | ImageNet Top-1 |
|---|---|---|---|
| ViT-B/16 | 224 | 86M | 81.8% |
| Swin-T | 224 | 28M | 81.3% |
| Swin-B | 224 | 88M | 83.5% |
| Swin-L | 384 | 197M | 87.3% |
| DINOv2-L | 518 | 307M | 86.3% |
5.3 DINOv2:自监督学习的巅峰
DINOv2 是在无标签的大规模图像数据上训练出的通用视觉编码器。通过自监督学习(self-supervised learning),其性能超越了基于 ImageNet 的监督学习模型。
import torch
# DINOv2 特征提取器(无需训练即可直接使用)
dinov2 = torch.hub.load("facebookresearch/dinov2", "dinov2_vitl14")
dinov2.eval().cuda()
# 处理任意尺寸的图像
import torchvision.transforms as T
preprocess = T.Compose([
T.Resize(518),
T.CenterCrop(518),
T.ToTensor(),
T.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
with torch.no_grad():
# [B, 3, 518, 518] -> [B, 1024] 特征
features = dinov2(preprocess(img).unsqueeze(0).cuda())
print(f"Feature dim: {features.shape}") # [1, 1024]
# DINOv2 用 k-NN 分类器也能展现出强大的性能
6. 生成模型:GAN、Diffusion、ControlNet
6.1 生成模型对比
| 生成模型 | 代表模型 | 训练方式 | 优点 | 缺点 |
|---|---|---|---|---|
| GAN | StyleGAN3 | 对抗训练 | 生成速度快 | 训练不稳定,模式崩溃 |
| VAE | VQ-VAE-2 | 重构 + KL | 训练稳定 | 图像模糊 |
| Diffusion | DDPM, DDIM | 去噪 | 质量最高 | 生成速度慢 |
| LDM | Stable Diffusion | 潜在空间扩散 | 质量与速度均衡 | GPU 显存占用高 |
6.2 Stable Diffusion:潜在扩散模型
Stable Diffusion 是一种Latent Diffusion Model(LDM,潜在扩散模型)。U-Net 在潜在空间中逐步去除噪声。
- Forward process(正向过程):在 T 个步骤中向图像逐步添加高斯噪声
- Reverse process(逆向过程):U-Net 接收 noisy latent z_t、timestep t、文本嵌入,预测噪声 epsilon
- VAE decoder:将最终的潜在向量还原为像素空间
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
import torch
# SDXL 1.0 文本生成图像
pipe = StableDiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
use_safetensors=True,
)
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
pipe.scheduler.config
)
pipe.to("cuda")
image = pipe(
prompt="a photorealistic cat on a desk, 8k, studio lighting",
negative_prompt="blurry, low quality, cartoon",
num_inference_steps=25,
guidance_scale=7.5,
width=1024,
height=1024
).images[0]
image.save("generated.png")
6.3 ControlNet:结构条件生成
ControlNet 利用边缘图、深度图、姿态等结构条件,对图像生成进行精细控制。
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from diffusers.utils import load_image
import cv2
import numpy as np
from PIL import Image
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/sd-controlnet-canny",
torch_dtype=torch.float16
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
controlnet=controlnet,
torch_dtype=torch.float16
).to("cuda")
# 生成 Canny 边缘图
ref_image = np.array(load_image("reference.jpg"))
edges = cv2.Canny(ref_image, 100, 200)
edges_rgb = np.stack([edges] * 3, axis=-1)
result = pipe(
"a beautiful landscape painting",
image=Image.fromarray(edges_rgb),
num_inference_steps=20
).images[0]
result.save("controlnet_output.png")
7. 实战流水线:从 DataLoader 到 TensorRT
7.1 自定义 Dataset 与 DataLoader
from torch.utils.data import Dataset, DataLoader
from pathlib import Path
import albumentations as A
from albumentations.pytorch import ToTensorV2
import cv2
class CustomDataset(Dataset):
def __init__(self, root: str, split: str = "train"):
self.root = Path(root)
self.image_paths = list(
(self.root / split / "images").glob("*.jpg")
)
self.label_paths = [
self.root / split / "labels" / p.with_suffix(".txt").name
for p in self.image_paths
]
self.transform = self._get_transforms(split)
def _get_transforms(self, split: str):
if split == "train":
return A.Compose([
A.RandomResizedCrop(224, 224, scale=(0.7, 1.0)),
A.HorizontalFlip(p=0.5),
A.ColorJitter(brightness=0.4, contrast=0.4,
saturation=0.4, hue=0.1, p=0.8),
A.GaussianBlur(blur_limit=(3, 7), p=0.2),
A.Normalize(mean=(0.485, 0.456, 0.406),
std=(0.229, 0.224, 0.225)),
ToTensorV2(),
])
return A.Compose([
A.Resize(256, 256),
A.CenterCrop(224, 224),
A.Normalize(mean=(0.485, 0.456, 0.406),
std=(0.229, 0.224, 0.225)),
ToTensorV2(),
])
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
image = cv2.cvtColor(
cv2.imread(str(self.image_paths[idx])), cv2.COLOR_BGR2RGB
)
label = int(self.label_paths[idx].read_text().strip())
augmented = self.transform(image=image)
return augmented["image"], label
train_dataset = CustomDataset("data/", split="train")
train_loader = DataLoader(
train_dataset, batch_size=32, shuffle=True,
num_workers=4, pin_memory=True, persistent_workers=True
)
7.2 ONNX 转换
import torch
import torch.onnx
model.eval()
dummy_input = torch.randn(1, 3, 224, 224, device="cuda")
torch.onnx.export(
model,
dummy_input,
"model.onnx",
export_params=True,
opset_version=17,
do_constant_folding=True,
input_names=["input"],
output_names=["output"],
dynamic_axes={
"input": {0: "batch_size"},
"output": {0: "batch_size"}
}
)
print("ONNX 转换完成:model.onnx")
# 用 ONNX Runtime 验证
import onnxruntime as ort
import numpy as np
sess = ort.InferenceSession(
"model.onnx", providers=["CUDAExecutionProvider"]
)
input_name = sess.get_inputs()[0].name
result = sess.run(None, {input_name: dummy_input.cpu().numpy()})
print(f"ONNX 推理结果 shape: {result[0].shape}")
7.3 TensorRT 优化
# 使用 trtexec 进行 TensorRT 转换
trtexec \
--onnx=model.onnx \
--saveEngine=model_fp16.engine \
--fp16 \
--workspace=4096 \
--optShapes=input:8x3x224x224
import tensorrt as trt
import numpy as np
import pycuda.driver as cuda
import pycuda.autoinit
def trt_inference(engine_path: str, input_data: np.ndarray) -> np.ndarray:
logger = trt.Logger(trt.Logger.WARNING)
with open(engine_path, "rb") as f:
engine = trt.Runtime(logger).deserialize_cuda_engine(f.read())
context = engine.create_execution_context()
input_mem = cuda.mem_alloc(input_data.nbytes)
output = np.empty((input_data.shape[0], 1000), dtype=np.float32)
output_mem = cuda.mem_alloc(output.nbytes)
cuda.memcpy_htod(input_mem, input_data)
context.execute_v2([int(input_mem), int(output_mem)])
cuda.memcpy_dtoh(output, output_mem)
return output
测验:深入理解计算机视觉
Q1. ResNet 的 skip connection 是如何解决 vanishing gradient 问题的?
答案:反向传播时,梯度通过 skip connection 直接传递,因此即使在深层网络中也不会消失。
解析:在普通的深层神经网络中,反向传播的梯度会随着层数增加而以乘法方式逐渐变小。ResNet 的残差块 F(x) + x 求导后为 dF/dx + 1,从而始终保证最小梯度为 1。正因如此,即使超过 100 层也能稳定训练。
Q2. 为什么 YOLO 比 Faster R-CNN 更适合实时推理?
答案:YOLO 通过单次前向传播(single forward pass)就能完成检测,而 Faster R-CNN 需要 Region Proposal Network 和分类器两个阶段。
解析:Faster R-CNN 是(1)RPN 生成候选区域,(2)RoI Pooling,(3)分类与回归的多阶段结构。YOLO 将图像划分为网格,通过一次 CNN 前向传播同时预测所有边界框和类别。YOLOv8n 在 A100 GPU 上可以达到 80+ FPS。
Q3. 为什么 Vision Transformer 在大规模数据上的表现优于 CNN?
答案:ViT 的 Self-Attention 学习所有图块之间的全局关系,在没有 inductive bias 的情况下直接从数据中学习最优表示。
解析:CNN 内置了局部性(locality)和平移等变性(translation equivariance)这两种 inductive bias。在数据较少时,这种偏置是有帮助的,但在大规模数据(如 JFT-300M)上会限制表达能力。ViT 不受偏置约束,可以自由学习全局模式,因此在数据充足时会全面超越 CNN。
Q4. 在 Stable Diffusion 的 denoising diffusion process 中,U-Net 起什么作用?
答案:U-Net 在每个 timestep 预测并去除添加到潜在向量中的噪声,并通过 cross-attention 融合文本条件(CLIP 嵌入)。
解析:在正向过程(forward process)中,会在 T 个步骤中向图像添加高斯噪声。在逆向过程(reverse process)中,U-Net 接收 noisy latent z_t、timestep t 和文本嵌入作为输入,预测噪声成分 epsilon。最后由 VAE 解码器将最终的潜在向量还原为像素空间。
Q5. SAM 的 prompt-based segmentation 与传统方法有何不同?
答案:SAM 接收点、框、掩码等多种提示,无需额外训练即可以零样本方式分割任意对象。
解析:传统的分割模型(DeepLab、Mask R-CNN)是针对特定类别集合进行监督训练的。SAM 是在 SA-1B 数据集(1 亿个掩码)上训练出的通用模型,不受类别限制,可以分割用户指定的任意区域。它由 Image Encoder(ViT-H)、Prompt Encoder、Mask Decoder 3 个模块构成。
结语:学习路线图
计算机视觉是一个快速发展的领域。推荐的学习路径如下:
- 基础:OpenCV、NumPy 图像处理 → torchvision 实践
- 分类:ResNet/EfficientNet 微调 → 应用于自定义数据集
- 检测:YOLOv8 实验 → 自定义训练 → ONNX/TensorRT 部署
- 分割:SAM 实验 → Mask R-CNN/DeepLabV3+ 自定义训练
- 进阶:ViT/DINOv2 特征提取 → Stable Diffusion 微调
在每个阶段都通过Kaggle 竞赛或实际项目加以应用,是最快的学习方法。
현재 단락 (1/390)
计算机视觉(Computer Vision)是让机器理解图像和视频的 AI 核心领域。智能手机人脸解锁、自动驾驶汽车的障碍物识别、医学影像诊断辅助——这些都在依靠计算机视觉技术运作。