拓冰建站拓冰建站
首页 / 资讯中心 / 正文

AI大模型自学路线:打通机器学习、OpenCV到部署的实践链路

在收藏夹里吃灰的 AI 学习资料中存在大量类似标题“浙江大学 136 小时讲完 AI 人工智能大模型”“整整 200 集从入门到精通”“机器学习-深度学习-OpenCV”。这类标题看起来非常有吸引力仿佛只要跟着刷完就能自然学会大模型。但真实情况是很多人刷了几十集视频后环境还没搭起来代码也跑不出结果。问题不在于这些概念太玄而在于学习路径中没有把“概念理解、环境搭建、代码实现、报错排查”放在同一个闭环里。真正值得投入时间的路线通常是这样先用机器学习知识建立“数据、模型、损失、优化”的直觉再用深度学习理解神经网络和 CNN 的训练过程接着把 OpenCV 作为图像处理工具解决视觉任务中的读取、预处理和轮廓分析最后再进入大模型微调、部署和上层应用。本文会按照这条主线展开每一步都会给出命令、代码片段、验证方式和常见坑。它不是要你按视频集数硬刷而是要你形成一条可复现、可检查、可扩展的学习链路。1. 先想清楚大模型、机器学习、深度学习、OpenCV 是四件事还是一条链路1.1 四个概念处于不同层级先搭层级再装知识很多人看到“机器学习、深度学习、OpenCV、大模型”出现在同一门课里第一反应是“这四个东西都需要学会”。但如果把所有概念平等排列学习时很容易迷失方向。实际上它们并不在一个层级上。可以从工程视角用一张表理解它们的边界概念通俗理解主要解决什么典型技术或工具AI人工智能让机器表现出智能行为的学科总称感知、决策、语言理解、规划等搜索、知识图谱、机器学习、深度学习机器学习让计算机从数据中自动总结规律分类、回归、聚类、异常检测scikit-learn、XGBoost、逻辑回归深度学习使用多层神经网络自动提取特征图像识别、语音识别、文本建模PyTorch、TensorFlow、CNN、Transformer大模型规模更大、任务覆盖面更广的神经网络模型文本生成、代码补全、多模态理解、Agent 规划GPT、Qwen、DeepSeek、LlamaOpenCV计算机视觉的底层图像处理工具库图像读写、滤波、边缘检测、几何变换OpenCV、Pillow、scikit-image从学习路径看机器学习和深度学习是“方法论”OpenCV 是“工具箱”大模型是“更复杂的深度学习模型及其工程形态”。如果还没有任何机器学习基础直接研究大模型的注意力机制、分词表和推理优化通常会被大量数学符号和不熟悉的训练流程劝退。反过来愿意先用小模型跑通训练流程再去理解大模型难度会平滑很多。1.2 为什么“先机器学习、再深度学习、然后 OpenCV、最后大模型”是合理顺序一条常见但有效的顺序是机器学习基础 - 神经网络与 CNN - OpenCV 图像处理 - 大模型微调与部署。它的合理性来自依赖关系。机器学习基础知识里包含了数据划分、特征标准化、损失函数、梯度下降、过拟合与欠拟合等概念。这些概念直接复用到深度学习中。CNN 训练又需要使用图像数据和数据增强图像数据的读入、裁剪、颜色空间转换正是 OpenCV 的强项。当完成一个小型视觉任务后再看大模型相关概念比如 Token、上下文窗口、量化、LoRA、推理服务就更容易理解它们是“工程复杂度增加后的解决方案”。反过来看如果完全不理解梯度下降、训练集和测试集的区别就开始部署一个 7B 参数的大模型只会得到两个结果要么把模型下载下来启动失败要么调用远程 API 成功了但完全不清楚后续微调和性能优化该从哪里下手。1.3 OpenCV 不是深度学习的替代品而是视觉工程中的“前置工具”常见误区是将 OpenCV 和深度学习并列看待。实际上OpenCV 无法替代深度学习模型因为传统视觉算法不能理解复杂语义。它也不能解决所有工程问题因为 OpenCV 的基础算子依赖人工设计规则。在真实视觉项目中OpenCV 更多承担三类工作采集和预处理读取摄像头、图片缩放、颜色空间转换、滤波去噪。几何分析边缘寻找、轮廓提取、棋盘格标定、透视变换。前后处理把模型输出结果画框、计算目标坐标、统计面积和数量。因此学习 OpenCV 时不要陷入“必须记住几百个函数”的误区。更合理的做法是记住图像在 OpenCV 中是 BGR 格式的 NumPy 数组掌握通道转换、几何变换、轮廓处理、相机标定这几个常见环节再把剩余函数当作字典去查。2. 建一个可复用的 AI 实验环境把机器学习、深度学习、OpenCV 装在一起2.1 先固定 Python 版本避免包与包互相冲突学习环境里的依赖冲突非常多最常见原因是 Python 环境混乱、pip 安装到了错误解释器、OpenCV 与 NumPy 版本不匹配。为了减少这类问题第一步是创建独立虚拟环境。常用的环境中Python 3.10 或 3.11 仍然有较好的兼容性PyTorch、NumPy、OpenCV 对大版本的支持比较充分。具体是否选择 3.10 还是 3.11要看目标框架的官方文档。先创建虚拟环境并激活conda create -n ai-study python3.10 -y conda activate ai-study不使用 Conda 时也可以用 venv 创建虚拟环境python3.10 -m venv .venv source .venv/bin/activate虚拟环境的核心价值是隔离。把机器学习依赖、深度学习依赖、图像处理依赖放进同一个环境中如果项目升级导致冲突可以快速销毁重建不会影响系统 Python。2.2 安装 PyTorch、scikit-learn、OpenCV、Jupyter 和常用视觉库安装 PyTorch 时需要注意 CPU 版和 GPU 版的区别。如果只是为了理解原理CPU 版本足够跑通 MNIST 这类小实验。如果计划训练真实数据集则建议安装对应 CUDA 版本的 PyTorch。这里给出比较通用的安装顺序pip install --upgrade pip pip install numpy scikit-learn pandas matplotlib jupyter pip install torch torchvision pip install opencv-python安装 OpenCV 时需要注意不要同时安装opencv-python和opencv-contrib-python因为两者会覆盖同一个cv2包容易造成诡异报错。常规课程和实验使用opencv-python即可。如果需要使用 SIFT、SURF 等扩展模块再单独使用opencv-contrib-python。2.3 用一段脚本验证环境是否真的可用许多人在安装完成后直接开始写模型代码等训练时报错才回头检查依赖。更合适的做法是安装完成后立刻执行一次最小验证。import sys import numpy as np import sklearn import cv2 import torch print(python:, sys.version) print(numpy:, np.__version__) print(sklearn:, sklearn.__version__) print(opencv:, cv2.__version__) print(torch:, torch.__version__) print(cuda available:, torch.cuda.is_available()) print(device name:, torch.cuda.get_device_name(0) if torch.cuda.is_available() else cpu)预期结果如表所示检查项成功标志失败时的常见原因Python 版本当前创建的虚拟环境路径未激活虚拟环境NumPy能打印版本号安装不完整或静默失败OpenCV能打印版本号包名错误、Python 解释器不对PyTorch能打印版本号安装源、网络或依赖问题CUDA 可用返回 True安装的 PyTorch 是 CPU 版、显卡驱动过旧如果上方脚本中torch.cuda.is_available()返回False不要直接认为显卡坏了。先执行nvidia-smi查看驱动适不适配当前 CUDA 版本再确认安装命令里的 CUDA 版本与驱动版本是否匹配。2.4 学习环境可以轻量跑通生产环境还需要额外保障学习阶段只要保证代码能跑、能观察结果即可。到了生产环境仅仅有一个 Python 虚拟环境是不够的还需要考虑依赖锁定、配置外置化、日志、监控、模型版本管理和回滚策略。比如训练代码通常用requirements.txt或environment.yml固定版本部署模型时还要把模型文件、推理脚本、预处理逻辑一起打包并检查输入输出的链路。3. 用一个最小分类任务打通机器学习闭环再谈大模型训练3.1 机器学习不是背算法而是理解“数据进入模型到输出指标”的完整循环很多视频课程会用大量时间讲不同算法公式但初学者最容易获得正反馈的方式是先跑通一个最小的分类任务。以鸢尾花分类为例完整流程包括加载数据、划分训练集和测试集、选择模型、训练、评估。from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report X, y load_iris(return_X_yTrue) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) scaler StandardScaler() X_train scaler.fit_transform(X_train) X_test scaler.transform(X_test) model LogisticRegression(max_iter500) model.fit(X_train, y_train) y_pred model.predict(X_test) print(accuracy:, accuracy_score(y_test, y_pred)) print(classification_report(y_test, y_pred))这里有几个关键动作train_test_split用来避免模型在见过的数据上评估否则会高估模型效果。StandardScaler只对训练集调用fit_transform对测试集只调用transform。原因是测试集不能参与均值和方差计算否则会造成信息泄漏。LogisticRegression虽然名字里有回归但在分类任务中是最常用的线性分类器之一。学习机器学习的重点不是记住每个算法步骤而是理解为什么“训练集、测试集、特征缩放、损失评估”是任何监督学习任务都必须考虑的环节。这个判断力会延续到大模型微调和评估阶段。3.2 从“训练精度”到“泛化精度”是初学者最容易忽略的跳跃小数据集里经常出现训练集正确率接近 100%测试集正确率却很低的现象对应的是过拟合。解决方向通常有数据增强、正则化、简化模型、增加训练样本。这里可以先建立一条检查清单训练集和测试集是否来自同一分布。特征是否做了合适的标准化或归一化。模型复杂度是否高于数据规模能支撑的范围。验证指标是否只看准确率而忽略了类别不均衡。是否用测试集反复调参导致测试集信息泄漏。3.3 多学一点分类问题之外的监督任务用相同逻辑迁移机器学习中的回归任务同样遵循这个闭环。把load_iris换成房价预测把评估指标从准确率换成均方误差或平均绝对误差主流程不会变化。有了这个最小闭环后进入深度学习时会发现增加网络层数、改变激活函数、调整优化器本质上还是在控制特征提取能力和拟合程度。4. CNN 和训练轮数背后是整个深度学习的训练逻辑4.1 神经网络和传统机器学习最大的差异是自动特征提取传统机器学习需要人工构造特征比如图像的颜色直方图、纹理统计量。卷积神经网络做得更多的是“让网络在训练中自己学习滤波核”因此可以从原始像素出发完成分类。一个经典的最小案例是 MNIST 手写数字识别。图像是 28x28 的灰度图类别有 10 种。用 PyTorch 实现时可以先用一个简单 CNN 完成端到端训练import torch import torch.nn as nn from torch.utils.data import DataLoader from torchvision import datasets, transforms transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_ds datasets.MNIST(root./data, trainTrue, downloadTrue, transformtransform) test_ds datasets.MNIST(root./data, trainFalse, downloadTrue, transformtransform) train_loader DataLoader(train_ds, batch_size64, shuffleTrue) test_loader DataLoader(test_ds, batch_size256, shuffleFalse) class SimpleCNN(nn.Module): def __init__(self): super().__init__() self.features nn.Sequential( nn.Conv2d(1, 32, kernel_size3, padding1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(32, 64, kernel_size3, padding1), nn.ReLU(), nn.MaxPool2d(2), ) self.classifier nn.Sequential( nn.Flatten(), nn.Linear(64 * 7 * 7, 128), nn.ReLU(), nn.Linear(128, 10), ) def forward(self, x): return self.classifier(self.features(x)) model SimpleCNN() optimizer torch.optim.Adam(model.parameters(), lr1e-3) loss_fn nn.CrossEntropyLoss() def train_one_epoch(): model.train() total_loss 0.0 for x, y in train_loader: pred model(x) loss loss_fn(pred, y) optimizer.zero_grad() loss.backward() optimizer.step() total_loss loss.item() return total_loss / len(train_loader) def evaluate(): model.eval() correct 0 total 0 with torch.no_grad(): for x, y in test_loader: pred model(x).argmax(dim1) correct (pred y).sum().item() total y.size(0) return correct / total for epoch in range(3): train_loss train_one_epoch() acc evaluate() print(fepoch{epoch 1}, train_loss{train_loss:.4f}, test_acc{acc:.4f})这段代码中最重要的不是卷积层参数而是完整训练逻辑数据进入网络得到预测结果损失函数计算预测与真实标签的差距反向传播把梯度传给网络参数优化器更新参数。每一轮训练结束后用测试集评估就是为了观察模型是否出现过拟合。4.2 训练轮数、批次大小和学习率如何影响精度很多人会问“训练轮数越多精度越高吗”。答案并不绝对。轮数增加到一定程度后训练损失会继续降低但测试精度可能不再提升甚至因为过拟合而下降。真正需要观察的是验证集或测试集上的指标而不是训练集指标。超参数取值偏小取值偏大日常调试建议epoch训练轮数模型欠拟合损失尚未收敛模型可能在训练集上过度拟合保存每轮验证指标选择最佳轮数batch_size批大小梯度更新频繁训练波动大显存压力大训练速度不一定更快常见 16、32、64按显存调整learning_rate学习率收敛太慢可能停在局部极小值损失发散出现 NaN起步用 1e-3 或 1e-4再按曲线调整像 MNIST 这种小任务即使使用 CPU三轮训练通常也能在几十秒到几分钟内结束。因此不必追求“把网络改得很深”或者“训练 100 轮”先把超参数变化对损失曲线的影响看明白才是更重要的学习收益。4.3 建议用“损失曲线”而不是只记最终精度训练脚本里打印最终精度只是一个结果调参时更需要观察每个 epoch 的训练损失和测试精度。一般建议把每轮数据保存到列表或写入 CSV再用 matplotlib 绘制曲线。如果发现训练损失下降很慢可以先检查数据是否归一化、学习率是否过小。如果发现损失在训练中途突然变成 NaN则优先怀疑学习率过大、数据中存在异常值或梯度爆炸。先定位是哪一个环节再修改参数不推荐用随机试参的方式碰运气。5. OpenCV 在视觉任务里到底解决哪一环预处理、轮廓与标定5.1 图像进入深度学习模型之前OpenCV 是必经的数据加工车间摄像头采集的原始图像通常是 BGR 格式尺寸参差不齐还可能包含噪声。深度学习模型往往需要固定尺寸的 RGB 输入。OpenCV 的价值就是把原始图像转换成模型能吃的格式。下面的代码展示了一条典型的预处理链读取图像、转灰度、高斯模糊、Canny 边缘检测、阈值化然后寻找轮廓。import cv2 img cv2.imread(demo.jpg) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur cv2.GaussianBlur(gray, (5, 5), 0) edges cv2.Canny(blur, 50, 150) _, binary cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY) contours, hierarchy cv2.findContours( binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) for cnt in contours: area cv2.contourArea(cnt) if area 100: continue x, y, w, h cv2.boundingRect(cnt) cv2.rectangle(img, (x, y), (x w, y h), (0, 255, 0), 2) cv2.imwrite(demo_with_boxes.jpg, img)代码里的Canny负责找边缘threshold生成二值图findContours寻找连通区域。实际项目中不一定每一步都必须使用通常的做法是先尝试把目标区域变成高对比度二值图再用轮廓分析去框出目标。如果图像光照不均阈值就会失效可以改用自适应阈值或背景差分。5.2 OpenCV 4 之后findContours 的返回值发生了变化OpenCV 的早期教程中常见写法是img, contours, hierarchy cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)在 OpenCV 3 之后findContours不再返回图像本身而是只返回两个值轮廓列表和层级关系。因此很多从老课程复制下来的代码会报 ValueError。正确写法是contours, hierarchy cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)如果确实需要在原图上绘制请使用cv2.drawContours(img, contours, ...)或先复制原图不要在未保留图像引用的情况下直接尝试从返回值中取图。这也是“看视频学习不如看报错学习”的典型例子。5.3 棋盘格标定不是深度学习但它是相机成像质量的基础机器视觉项目中常常需要把像素坐标映射到真实物理坐标棋盘格标定就是获取相机内参和畸变系数的一种标准方法。标定的目标并不是训练出一个模型而是计算相机的内参矩阵、畸变系数和外参。标定的关键步骤是检测棋盘格角点。以 Python 为例核心流程如下import cv2 import numpy as np # 这里以 9x6 内角点棋盘为例 pattern_size (9, 6) criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) objp np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32) objp[:, :2] np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) object_points [] image_points [] img cv2.imread(checkerboard.jpg) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) found, corners cv2.findChessboardCorners(gray, pattern_size, None) if found: corners cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) object_points.append(objp) image_points.append(corners) cv2.drawChessboardCorners(img, pattern_size, corners, found) cv2.imshow(checker, img) cv2.waitKey(0) cv2.destroyAllWindows()如果是从 C 工程介入视觉另一种常见方式是使用cv::findChessboardCorners与cv::calibrateCamera例如采集若干张角点图之后统一求解相机参数。示例思路与 Python 版本一致cv::Size patternSize(9, 6); std::vectorcv::Point3f objectPoints; for (int i 0; i patternSize.height; i) { for (int j 0; j patternSize.width; j) { objectPoints.push_back(cv::Point3f(j, i, 0.0f)); } } std::vectorcv::Point2f corners; cv::Mat gray; cv::cvtColor(colorImage, gray, cv::COLOR_BGR2GRAY); bool found cv::findChessboardCorners(gray, patternSize, corners); if (found) { cv::cornerSubPix(gray, corners, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(cv::TermCriteria::EPS cv::TermCriteria::MAX_ITER, 30, 0.001)); cv::drawChessboardCorners(colorImage, patternSize, corners, found); }注意上面代码中的patternSize是内角点数量不是棋盘格方块数量。实际拍摄时通常需要 10 到 20 张不同角度、不同距离的棋盘图才能获得比较稳定的标定结果。5.4 传统视觉与深度学习在工业场景中如何配合“深度学习是否一定能替代 OpenCV”是视觉方向经常被讨论的问题。实际工程结论通常是两者互补。需求场景推荐方向原因固定光照下的尺寸测量传统视觉 亚像素边缘规则明确速度快便于验证复杂纹理缺陷检测深度学习语义分割或分类缺陷形态多变人工规则难覆盖OCR 文字识别深度学习检测 识别需要语义理解能力目标计数与定位传统轮廓或深度学习目标检测结合先缩小候选区再让模型识别对于工业视觉项目如果缺陷种类固定、光照可控很多时候先用 OpenCV 预处理再通过面积、灰度、几何特征筛选已经能满足需求。深度学习模型更适合缺陷形态复杂、无法用固定阈值描述的场景。6. 从图像模型过渡到大模型微调、本地部署与 Spring AI 接入6.1 Transformer 为什么能成为大模型的底层结构CNN 通过卷积核提取局部特征适合图像。大模型大多基于 Transformer核心优势是通过注意力机制让每个位置都能关注序列中其他位置的信息。这种机制让模型可以处理长距离依赖从而在文本、代码、多模态任务上表现出更强的能力。从学习角度不必一开始就把注意力公式背下来。可以把它理解为“模型在计算每个词和句子中其他词的相关程度”。相关程度越高注意力权重越大。大模型的训练过程和前面的 CNN 没有本质区别仍然是前向传播、计算损失、反向传播、更新参数只是数据规模、参数量和并行策略大幅增加。6.2 微调不等于重新训练基础模型LoRA 是最容易上手的入口市面上会看到“大模型微调”和“全量预训练”这些词。全量预训练需要海量数据和昂贵算力绝大多数个人开发者无法复现。日常说的微调更多指在已经训练好的基础模型上用领域数据做继续训练。LoRA 是一种低秩适配方法它不会对全部参数做大更新而是在原始权重旁增加少量可训练参数从而把微调成本降下来。下面是一段基于 peft 库的示意代码用来演示操作结构实际训练还需要结合数据集、分词器和训练脚本from peft import LoraConfig, get_peft_model lora_config LoraConfig( r8, lora_alpha16, target_modules[q_proj, v_proj], lora_dropout0.05, biasnone, task_typeCAUSAL_LM ) model get_peft_model(base_model, lora_config) model.print_trainable_parameters()从工程角度看LoRA 带来的直接收益是显存占用更小、训练更快并且微调后得到的权重文件通常比原模型小很多便于保存和分发。初学者即使不训练大模型也建议先理解“冻结原参数、只训练少量适配参数”的思想。6.3 本地部署大模型不是把模型文件塞进内存而是选量化、推理框架和 API 封装本地部署大模型的难点主要在于显存或内存不足、推理速度慢、依赖环境复杂。不同参数规模的模型对硬件要求差异很大常见策略如下模型规模常见硬件要求参考部署方式1B 到 3B 参数8GB 到 16GB 内存或 4GB 以上显存直接推理必要时量化7B 到 14B 参数一般需要 16GB 以上内存量化后更友好GGUF 量化 llama.cpp 或 Ollama70B 以上参数通常需要多卡或大内存服务器分布式推理或量化 服务化框架很多入门项目会先在本地启动一个 Ollama 服务然后拉取对应模型并调用。模型下载尽量从可访问的国内模型仓库或官方提供的方式获取生产环境还需要加一层权限控制、限流和日志。不要把所有内容都写死在代码里。6.4 Spring AI 让 Java 工程可以统一接入大模型能力如果团队技术栈是 Java大模型应用不一定只能写 Python。Spring AI 是 Java 生态中用于对接 AI 模型的框架。它把聊天、向量存储、提示词模板等能力抽象成统一接口让应用层不需要关心底层是 OpenAI 兼容服务还是本地 Ollama。在 Spring Boot 项目中通常会先在 Maven 中引入 BOM 和对应 Starter。由于 Spring AI 的版本迭代较快落地前要确认当前 Spring Boot 版本和 Spring AI 版本是否兼容。配置层面调用本地 Ollama 的 OpenAI 兼容接口时可以使用类似下面的结构spring: ai: openai: base-url: ${AI_BASE_URL:http://localhost:11434/v1} api-key: ${AI_API_KEY:EMPTY}这个配置的含义是应用通过 OpenAI 兼容协议访问本地大模型接口。只要base-url指向本地推理服务就能把大模型能力接入 Java 业务系统。对初学者来说先用 Python 跑通模型推理再切换到 Spring AI 构建 Rest API是比较顺畅的路径。6.5 大模型应用层正在走向 RAG 和 Agent大模型不只会做文本生成。实际业务中经常需要模型回答私有知识库内容这就用到了 RAG即检索增强生成。RAG 先把文档切块、向量化再根据用户问题检索相关片段最后把检索结果交给模型生成答案。Agent 则进一步把模型从“对话引擎”变成“任务执行器”。Agent 可以调用工具、读取数据库、访问外部服务再根据反馈决定下一步操作。这个趋势意味着学习大模型时除了关注模型结构和训练还要关注业务流程、工具调用、提示词工程、上下文长度管理和结果校验。真正有工程价值的不是“模型会说话”而是“模型在一个受控流程中能稳定完成任务”。7. 从安装到训练最容易卡住的问题和排查顺序7.1 cv2 安装成功却报 libGL 或导入错误现象pip install opencv-python安装成功但import cv2报错常见信息包括libGL.so.1: cannot open shared object file。原因OpenCV 的 Python 包依赖系统的 libGL 等图形库某些精简服务器镜像没有安装这些依赖。排查顺序确认是否在正确的虚拟环境中。执行python -c import cv2复现。如果是 Linux 环境尝试安装系统依赖库。例如在 Debian/Ubuntu 服务器上可以安装如下基础依赖apt-get update apt-get install -y libgl1 libglib2.0-0 libsm6 libxext6 libxrender-dev这类系统依赖属于环境基础部分安装后需要重新启动 Python 进程。预防建议是“先按官方安装说明准备好系统依赖再安装 cv2”。7.2 findContours 报 not enough values to unpack现象运行旧教程代码时出现ValueError: not enough values to unpack (expected 3, got 2)。原因OpenCV 不同大版本中findContours返回值数量不同。OpenCV 2 返回三个值包括原图、轮廓、层级。OpenCV 3 之后只返回轮廓和层级。解决方式把img, contours, hierarchy cv2.findContours(...)改为contours, hierarchy cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)如果代码是从老项目迁移建议先确认项目当前依赖的 OpenCV 版本再决定是否保留原返回值格式。7.3 PyTorch 安装成功但 CUDA 不可用现象torch.cuda.is_available()返回False。排查顺序执行nvidia-smi确认驱动是否正常。对比nvidia-smi中显示的最高 CUDA 版本和当前 PyTorch 编译时的 CUDA 版本。确认安装命令是否带cpu字样。如果使用了 CPU 版本即使有显卡也无法使用 CUDA。检查虚拟环境中是否安装过多个 PyTorch 版本。解决思路不是无脑重装而是先确认“驱动支持的 CUDA 版本”和“PyTorch 依赖的 CUDA 版本”匹配。如果只是学习小任务CPU 环境也能继续不需要在显卡问题上花费过多时间。7.4 深度学习训练 loss 不下降或者变成 NaN现象模型训练多次 epochloss 始终不下降或者 loss 突然变成nan。常见原因和检查方式如下表现象可能原因检查方式处理建议loss 下降缓慢学习率太小、数据未归一化打印每个 batch 的平均 loss调大学习率确认输入数据范围正常loss 发散或变成 NaN学习率过大、梯度爆炸查看 loss 是否出现剧增调小学习率检查是否存在异常值训练 loss 低但测试 acc 不升过拟合每个 epoch 输出验证指标增加数据增强、降低模型复杂度、早停网络输出恒为某一类类别不均衡、损失权重不合理统计每个类别的样本数量调整损失函数权重或采样策略排查时不要同时改多个参数。每次只修改一个变量否则无法定位是哪个改动带来的效果。7.5 本地部署大模型时显存或内存不足现象模型加载过程中进程被系统杀掉或者推理时显存溢出。原因模型参数占用的显存只是基准推理时的激活值、KV Cache 也会占用显存。高精度参数类型会让资源需求进一步上升。处理思路选择更小的模型。使用量化模型例如把半精度权重转换为 4bit 或 8bit 表示。减少上下文长度。使用主内存推理但需要接受较慢的速度。部署前先查看模型说明中的硬件要求不要在资源不足的环境中反复硬试。8. 大规模视频课程不应该按“集数”硬刷按阶段验收才是关键8.1 把学习过程拆成四个阶段每个阶段有明确验收标准学习 AI 大模型最大的问题不是资料少而是资料太多缺乏停止点。更合理的做法是每个阶段完成一个“最小实验”然后停下来检查是否掌握关键结论。阶段核心任务验收标准第一阶段机器学习基础能独立完成一个分类或回归任务能解释训练集、测试集、过拟合第二阶段深度学习与 CNN能在 MNIST 或 CIFAR-10 上训练 CNN能绘制 loss 曲线第三阶段OpenCV 图像处理能完成图像预处理、轮廓检测理解棋盘格标定流程第四阶段大模型应用部署能启动本地模型用 Python 或 Spring AI 完成一次对话请求不要因为视频有 200 集就要求自己 50 集内看完。很多视频材料为了覆盖完整目录会有大量重复铺垫。如果某个章节的环境你已经跑通并理解了输出就可以跳转到下一个未知模块。8.2 每个实验都要做到“可重复运行”而不是“跟着视频敲一遍”打开课程边看边敲代码通常只是形成短期记忆。真正有效的方法是把每个实验整理成独立目录包含完整的依赖文件。可以直接运行的脚本。输入样例和预期输出。运行失败时的常见问题和解决方案。例如视觉项目可以按如下结构组织vision-demo/ ├── requirements.txt ├── data/ ├── scripts/ │ ├── preprocess.py │ ├── train_cnn.py │ └── detect_contours.py ├── output/ └── README.md这样做的价值在于如果一个月后重新运行某个实验不需要回忆当初装过哪些包。依赖文件、README 和脚本本身就是最好的笔记。8.3 生产环境要在大模型实验跑通后补齐工程保障在本地跑通推理不等于可以上线生产。真实系统通常还需要把所有模型地址、密钥、环境配置放到环境变量或配置中心。在模型接口前增加超时、重试、限流和熔断。对模型输入做内容安全过滤和长度限制。记录每次请求的日志包括调用模型、耗时、返回状态和错误信息。提供版本管理让模型文件和业务代码可以一起回滚。建立监控关注推理延迟、token 消耗、显存和错误率。如果只是学习阶段可以先忽略这些复杂项。但当项目从实验转向演示再转向正式业务时这些点都是必须补上的工程纪律。8.4 自查清单学完这条路线后应该能回答的问题机器学习和深度学习的核心区别是什么训练集和测试集如果混在一起会造成什么问题train loss 下降、val loss 不降下一步应该调整什么OpenCV 中图像为什么用 BGR 表示findContours 在 OpenCV 4 中返回几个值棋盘格标定为什么要收集多张不同角度的图像LoRA 为什么能在较少显存占用下完成微调本地部署大模型时量化解决了什么问题代价是什么Spring AI 在大模型应用层扮演什么角色如果上游模型服务超时业务代码应不应该无限等待这些问题的答案能在自己的代码和日志里找到而不是只能在别人的视频里听到。这个标准比“看完 200 集”更能衡量是否真正上手了 AI 大模型这条技术路线。下一组小实验的推荐顺序是把 MNIST CNN 换成自己的摄像头数据把目标检测模型接进一个 OpenCV 推理脚本再尝试用本地大模型接口做一个带日志和限流的 Java REST 服务。每一步都会比单纯增加观看集数带来更明显的工程成长。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门