TensorFlow从入坑到上手的完整记录以及和PyTorch的账到底怎么算做深度学习这几年TensorFlow一直是我绕不过去的一环。从最早接触TF 1.x那种写个计算图还要开session的别扭日子到现在Keras一把梭的顺手程度说真的这套框架演进来的每一步我都踩过坑。最近不少朋友问我TensorFlow到底还值不值得学以及新手第一套框架该选它还是PyTorch所以这篇文章就做个阶段性的项目复盘——我把这几年用TensorFlow做图像识别、文本分类、以及上线模型服务的经验连同安装配置、调参避坑和2024年框架选型的思考一次性整理出来。这篇文章适合刚准备入门的同学也适合那些正在纠结要不要从PyTorch迁回TensorFlow的人。我会尽量讲清楚为什么不光是怎么做。毕竟装环境这种事儿任何教程都能抄但装完跑不通、跑通又训不动、训好了又部署不了——这些坎儿光看官方文档是躲不过的。1. 项目整体设计与思路拆解1.1 我从哪里开始认识TensorFlow坦白讲我最早接触TensorFlow是被它的名气吸引的——Google出品生态庞大论文代码多社区活跃。但那时候正是TF 1.x最叛逆的时期计算图、会话、占位符、变量初始化这些概念对刚入门的人来说简直是一堵墙。我记得第一次写完一个线性回归模型以为万事大吉结果忘了session.run()愣是看了半天内存不断增加的怪现象。后来TF 2.0发布Keras被官方转正动态图模式成了默认TensorFlow才算是终于说人话了。现在的TensorFlow写起来跟PyTorch一样是即时执行、Python化你不需要再去理解那套底层的静态图逻辑也可以正常地开发、调试、训练。换句话说如果你今天从零学TensorFlow面对的已经完全不是当年那个劝退无数人的框架了。1.2 这个框架解决了什么实际问题TensorFlow的核心价值我觉得可以浓缩成三句话从研究到生产路径最短你在Notebook里用Keras搭好的模型可以直接用tf.saved_model保存然后丢给TensorFlow Serving上生产中间不需要任何额外的代码翻译。在移动端和嵌入式端套件最全TensorFlow Lite把模型压缩成.tflite格式可以在Android、iOS、树莓派上跑这一块PyTorch的生态目前仍不如它。在数据管线层面工程化能力最强tf.data这个API虽然是很多人吐槽的对象但真正处理过几百万条样本的同学会明白它做并行读取、预取、乱序、分片的能力比手写DataLoader要稳定得多。我自己的项目里多数情况是把TensorFlow当作从调研到上线的全能型选手来用的。不是说它每个环节都最强而是整体链路最省事。1.3 技术选型背后的核心考量如果你只是在做一个学术实验想在GPU上快速验证一个想法TensorFlow和PyTorch现在体验很接近。但如果是做生产系统我觉得考虑维度会完全不同要不要上多机多卡训练TensorFlow的分布式策略tf.distribute.MirroredStrategy、MultiWorkerMirroredStrategy配置方式非常统一代码侵入性低而PyTorch在这方面需要你手动处理DistributedDataParallel的多进程细节。要不要做模型压缩TensorFlow的pruning、quantization工具直接集成在生态里PyTorch虽然有torch.quantization但周边配套零散不少。你的团队熟什么这一点其实是最关键的。2024年了框架本身都够成熟真正的瓶颈不是框架能力而是团队经验和你需要踩的坑的数量。我见过很多团队因为PyTorch学术界流行就一窝蜂切过去结果在部署环节发现还要引一堆额外依赖反而耽误进度。框架选型这事儿终究是看你的整体链路不是看某个单项指标。2. 环境部署与TensorFlow安装全记录2.1 安装前必做的三个准备动作TensorFlow安装看起来简单网上一搜一大把教程但真正稳的安装方式其实和网上很多快装版教程不一样。我建议所有人在执行pip install tensorflow之前先问自己三个问题你的Python版本是多少TensorFlow的轮子对Python版本有明确的支持范围。当前主流版本2.15/2.16支持Python 3.9到3.12但如果你用的是3.13很可能会遇到No matching distribution found的错误。这不是你网络的问题是版本匹配的问题。你机器上有没有NVIDIA显卡有显卡并且想用它训练就必须区分tensorflowCPU版和tensorflow[and-cuda]GPU版。如果说错了装上了CPU版模型也能跑但速度会慢到让你怀疑人生而且你大概率不会第一时间发现问题只会觉得怎么这么卡。你是不是用了condaConda环境里如果混装了不同版本的cudnn和cudatoolkit很容易出现libcudnn.so.8: cannot open shared object file的幺蛾子。我建议能干净虚拟环境就干净虚拟环境不想折腾的话直接安装官方带CUDA依赖的tensorflow[and-cuda]。这三条只要有一个没确认好后面大概率会花好几个小时在排查环境上面而不是在写模型。2.2 CPU版和GPU版的精确安装步骤我这里给出的是我自己实测过的最省心方案适用Ubuntu 20.04/22.04、Windows 10/11和macOSApple Silicon。CPU版安装绝大数情况下一句话就够了pip install tensorflowCPU版的好处是零依赖、零冲突任何一台上网电脑都能跑。缺点也明显——训练一个ResNet50跑一个epoch都要几分钟对于认真做实验的人来说不够用。CPU版的价值更多在于写代码、调结构、过Pipeline以及在没有GPU的同事电脑上做代码评审。GPU版安装重点如果你用的是NVIDIA显卡2024年我的建议是直接用带CUDA绑定版本的安装方式pip install tensorflow[and-cuda]这是我在TF 2.11版本之后最推荐的方式。因为它会把跟TensorFlow匹配的CUDA、cuDNN版本直接用pip拉下来放到你的虚拟环境里不需要你再手动去NVIDIA官网下载和配置系统级的CUDA。这个变化极大改善了TF安装体验以前我装一次GPU环境至少要折腾半天各种环境变量、路径软链现在几分钟就搞定了。装完之后务必做一次验证import tensorflow as tf print(tf.config.list_physical_devices(GPU))如果输出里带GPU字样恭喜你正常了。如果只看到一个空列表问题基本出在三个地方驱动版本太低、tensorflow-...whl装错版本、或CUDA运行时没被正确加载。2.3 我踩过的三个经典环境坑这些年我在环境配置上踩过的坑随便拧出三个就够人喝一壶坑一CUDA版本跟驱动不匹配。有一次新买了一张显卡装了最新驱动结果旧版CUDA跑不起来。明明驱动是最新的但TF报错说找不到libcudart.so原因是我驱动太高反而不兼容老CUDA runtime。后来我才意识到现在TF内置的CUDA版本会要求驱动不低于某个最低版本建议直接用官方nvidia-smi看驱动版本再对应TF官方的Tested build configurations表格。坑二tf-nightly装完不能正常导入。有一阵子为了用某个新特性我傻乎乎地装了tf-nightly结果隔几天TF官方更新一个commit我的代码就开始出现奇怪的Keras warning。后来学乖了——研究原型可以用nightly但凡有任何正经训练任务赶紧退回稳定版。坑三Windows上安装很顺利但训练时cpu占用100%。这个问题其实不是bug而是TF默认会把所有CPU核心都用在数据输入管线的并行处理上。如果你同时开着其他吃CPU的服务可以给它限制线程数import tensorflow as tf tf.config.threading.set_intra_op_parallelism_threads(4) tf.config.threading.set_inter_op_parallelism_threads(4)3. TensorFlow与PyTorch2024年流行趋势下的选型思路3.1 为什么最近总有TensorFlow凉了的说法这是我这两年被问到最多的问题几乎每个想入行的人都会刷到各种帖子说PyTorch已经统治学术界、TensorFlow没有未来了。真相到底是什么先看学术界。PyTorch在顶会论文复现代码里的占比确实从2019年开始逐年上升到今天已经超过80%。这个趋势很真实没什么好争辩的。因为PyTorch的调试体验、动态图灵活性、以及HuggingFace生态的深度绑定让做研究的人用起来非常顺手。如果是做研究、发论文、快速试ideaPyTorch确实是更自然的选择。再看工业界。TensorFlow的TFLite、TFLite Micro、TensorFlow Serving、TFX数据管线覆盖了服务器端到移动端的完整链路。在很多大厂的生产系统里TensorFlow依旧是主力。因果推断、推荐系统、广告点击率预估这类大规模业务场景TF的分布式训练稳定性经过了很多次实战验证工程团队对它很放心。所以凉了的说法更多是学术圈热度转移被热搜放大的结果离真实淘汰还远得很。3.2 什么时候该坚持TensorFlow我给一个直接的判断框架你可以对号入座你的情况更推荐的框架核心理由高校研究生、发论文、快速验证ideaPyTorch论文复现多、HuggingFace生态强、调试直观企业上线图像/文本模型要走TensorFlow ServingTensorFlow部署链路完整saved_model直接服务化移动端/嵌入式端做AI应用TensorFlow Lite算子覆盖广、Android集成度高、量化工具成熟个人学习、打比赛、尝鲜哪个顺手用哪个两者都是必需品会一个再学另一个并不难公司已有TF历史代码库TensorFlow迁移成本极高不是技术选型问题是成本问题我自己见过太多因为PyTorch酷就换框架的项目最后多花了两三个星期在迁移代码、重新对齐指标上。框架迁移的隐性成本比大家想象中大得多。3.3 两者生态的真实差距在哪如果你问我现在TensorFlow比PyTorch差在哪我觉得最明显的还是学术前沿的适配速度。像Transformer刚火那阵子大量新组件代码都是PyTorch首发TF这边要等Keras官方实现或者自己手动移植确实慢半拍。那些第二天就能拿到开源预训练模型直接跑的体验在PyTorch生态里更常见。但如果你问TensorFlow比PyTorch强在哪我的回答会是部署一体的体验从训练到上线TensorFlow的工具链都是一套用model.save()保存整个项目tensorflow-serving加载就能出API。PyTorch则需要额外搭配ONNX、TorchServe等中间层链路更碎。对生产环境的考量更系统TF从设计之初就考虑了分布式训练、模型版本管理、线上回滚这些工程问题。这不是说PyTorch做不了而是你需要在PyTorch里自己拼轮子才能在TF里直接开箱用。所以2024年的结论我觉得很清晰做研究跟着PyTorch走做产品跟着TensorFlow走个人则是两者都要会。这不是和稀泥是生态分化后的客观现实。4. 用TensorFlow实战搭建一个图像分类模型4.1 数据准备用tf.data写出专业数据管线凡是上来就用ImageDataGenerator.flow_from_directory写死全套流程的人我只能说等数据集上百万样本时你会回来补课。tf.data在我这里一直是TF最被低估的模块——它写起来有点啰嗦但性能和可控性真的强。一个标准的tf.data流水线长这样import tensorflow as tf # 读取图片路径和标签 file_paths [...] # 你的图片路径列表 labels [...] # 对应标签列表 # 构建Dataset dataset tf.data.Dataset.from_tensor_slices((file_paths, labels)) # 定义预处理函数 def preprocess(path, label): img tf.io.read_file(path) img tf.image.decode_jpeg(img, channels3) img tf.image.resize(img, [224, 224]) img tf.cast(img, tf.float32) / 255.0 return img, label # 关键配置 dataset dataset.map(preprocess, num_parallel_callstf.data.AUTOTUNE) dataset dataset.shuffle(buffer_size10000) dataset dataset.batch(32) dataset dataset.prefetch(buffer_sizetf.data.AUTOTUNE)这里有三个点可能不是一眼能看懂的我说一下我的体会map里面的num_parallel_callstf.data.AUTOTUNE意思是让TF自动决定用多少线程做并发读图。如果不写默认是串行的一张张图慢慢处理你会看到GPU利用率只有百分之十几但CPU跑满——问题就出在这。prefetch绝对是让训练提速的最简单方法。它让CPU在GPU算完当前batch之前提前准备下一个batch。你不需要理解太多只要知道不写这一行每个batch之间都会出现一段CPU忙着处理数据GPU闲着等数据的空白等待。shuffle的buffer_size不是越大越好。取值太大会吃内存太小则做不成真正的随机。我现在习惯把buffer_size设成至少一个epoch样本数的10%左右。4.2 模型构建从Keras到自定义训练循环模型部分我现在习惯从Keras的Sequential入手简单任务直接搭from tensorflow.keras import layers, models model models.Sequential([ layers.Conv2D(32, (3, 3), activationrelu, input_shape(224, 224, 3)), layers.MaxPooling2D((2, 2)), layers.Conv2D(64, (3, 3), activationrelu), layers.MaxPooling2D((2, 2)), layers.Conv2D(128, (3, 3), activationrelu), layers.MaxPooling2D((2, 2)), layers.Flatten(), layers.Dense(128, activationrelu), layers.Dropout(0.5), layers.Dense(10, activationsoftmax) ]) model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy])但如果你要处理的任务复杂一点比如做多输入、注意力模块、自定义损失函数我建议直接走tf.keras.Model子类化路线。很多人一听到子类化就紧张其实核心就是重写两个函数class MyModel(tf.keras.Model): def __init__(self): super().__init__() self.conv1 layers.Conv2D(32, 3, activationrelu) self.flatten layers.Flatten() self.dense1 layers.Dense(128, activationrelu) self.out layers.Dense(10, activationsoftmax) def call(self, inputs): x self.conv1(inputs) x self.flatten(x) x self.dense1(x) return self.out(x)这样的方式自由度更高而且可以很自然地记录中间层的输出方便做可视化。4.3 训练策略回调函数才是真神器训练过程我几乎离不开ModelCheckpoint、EarlyStopping和ReduceLROnPlateau这三个回调。它们不像模型结构那么炫但真正决定了你训练10个epoch还是100个epoch以及最终能不能拿到一份好模型。callbacks [ tf.keras.callbacks.ModelCheckpoint( best_model.h5, monitorval_accuracy, save_best_onlyTrue, verbose1 ), tf.keras.callbacks.EarlyStopping( monitorval_loss, patience10, restore_best_weightsTrue ), tf.keras.callbacks.ReduceLROnPlateau( monitorval_loss, factor0.5, patience5, min_lr1e-6 ) ] model.fit( train_ds, validation_dataval_ds, epochs100, callbackscallbacks )这里最容易被忽略的是restore_best_weightsTrue。如果你只开了EarlyStopping不恢复最佳权重训练会在过拟合的那个点停止但模型参数停留在最后一次epoch的状态而不是验证集最好的那个状态这会导致你的模型效果明显打折扣。我身边至少有三个人踩过这个坑全程怪数据不行最后发现只是参数没回滚。4.4 模型保存与部署前检查训练收尾阶段我强烈建议统一用saved_model格式保存而不是只存h5model.save(saved_model/my_model)保存完以后一定要做一个加载测试loaded_model tf.keras.models.load_model(saved_model/my_model)这个步骤看着简单但它能帮你提前发现两个问题一是自定义层/自定义损失函数在load时会不会报错二是object配置里有没有意想不到的依赖。很多人训练完直接把h5文件丢给部署团队结果加载失败回头又来找模型文件——多花一天时间都是可以提前一分钟避开的。5. 常见问题与排查技巧实录5.1 训练时显存不足的三种解法这个报错基本是每个TF用户都会碰到的ResourceExhaustedError: OOM when allocating tensor with shape ...。解决办法优先级从高到低调小batch_size。直接砍半看能不能跑通。如果跑通再把batch_size慢慢加回去。这招能解决80%的OOM。使用混合精度。TF的mixed_precision策略用起来几乎无损但对显存占用减半效果极明显from tensorflow.keras import mixed_precision mixed_precision.set_global_policy(mixed_float16)检查是不是有历史session没释放。如果你在写代码时反复在Notebook中执行训练但又没重启kernel那显存大概率已经被以前的graph残留占满。重启环境永远是排查OOM最值得先做的事。5.2 GPU利用率低但CPU飙升这个表现通常出现在数据管线写得不够好的情况下。第一反应永远是看数据管线的prefetch有没有加map里面有没有写num_parallel_calls。如果你已经加了还是很慢我建议在prefetch之后再加一步dataset dataset.apply(tf.data.experimental.ignore_errors())这个操作会把个别损坏图片导致的读取异常给跳过去。否则整个Dataset在读到一个坏文件时会直接崩溃你花一晚上查为什么训练每次都停在同一批数据都查不出来。5.3 Keras自定义损失函数踩坑记录自定义损失函数是TensorFlow新手最容易被绊倒的地方。我见过最典型的错误# 错误示范 def my_loss(y_true, y_pred): return tf.reduce_mean(tf.square(y_true - y_pred)) 0.1这个看起来没问题但如果你在损失里用到了模型内部的某个变量比如做正则化项直接引用外部变量在保存模型时会序列化失败。正确的方式是定义一个包含__call__的类或者用add_loss把额外损失加进模型内部。这个坑在我第一次写带正则的模型时整整卡了半天才反应过来。5.4 常见问题速查表现象可能原因解决建议安装时找不到匹配版本Python版本过新/过旧切换Python到3.9~3.12libcudnn无法加载CUDA运行时缺失重装tensorflow[and-cuda]GPU列表为空驱动版本低或TF装成CPU版用nvidia-smi检查驱动tf.config.list_physical_devices(GPU)确认加载模型报Unknown layer自定义层未注册在加载前导入自定义层类或改用custom_objects训练损失出现NaN学习率过高/数据含异常值降低学习率检查数据预处理是否含log(0)tensorboard打不开日志路径版本问题先tensorboard --logdir指定正确文件夹再确认端口未被占用6. 个人实操经验与总结建议其实写到最后我最想说的反而是不要被框架绑架。TensorFlow和PyTorch在2024年都已是成熟到让人挑不出毛病的工具。你选TensorFlow收获的是从开发到部署的一体化体验你选PyTorch收获的是灵活快速的学术迭代。两者的学习曲线已经趋同真正拉开差距的是你对模型本身、数据管线、训练策略和工程链路的理解。我个人的习惯是主力用TensorFlow做产品模型用PyTorch做快速调研和复现论文。这样既能吃到TF生产链路的红利又能跟上前沿算法的步伐。如果你正处在入门阶段与其花时间纠结哪个框架更流行不如挑一个装好环境拿真实数据把全流程跑通一遍——跑通了你才有资格讨论优缺点。另外分享一个小技巧无论用哪个框架都把每次训练的完整配置记录下来包括batch_size、学习率、数据增强策略、随机种子和硬件环境。我见过太多实验对比最后没法复现就是因为当时没记录随机种子。一行tf.random.set_seed(42)能省掉的返工时间远比你以为的多。
企业数字化 ERP 产品动态
相关推荐
PHP+WebSocket双模式实时聊天室架构设计与实现 1. 项目概述:双模式架构的PHPWebSocket实时聊天室 这个项目实现了一个基于PHP和WebSocket技术的高性能实时聊天室系统,其核心创新点在于采用了"双模式架构"设计。所谓双模式,指的是系统同时支持传统的HTTP轮询和现代的WebSocket协议… · 2026/11/3 13:21:04
Elementor模板套件Baha:高转化率着陆页设计指南 1. Baha模板套件概述:Elementor生态中的专业着陆页解决方案Baha是一款专为Elementor页面构建器设计的免费应用类产品着陆页模板套件(Template Kit),主要面向移动应用开发者、SaaS服务商和数字产品创作者。这个模板套件包含了完整的… · 2026/11/3 13:21:04
安卓开发实战:独居老人安全监测工具技术解析 1. 项目概述:独居老人安全监测工具的技术实现 "死了么APP"这个看似戏谑的名称背后,实际上是一个严肃的社会需求解决方案。作为一款专为独居老人设计的安全监测工具,Keep Alive Lite安卓版通过轻量级的技术手段实现了对用户生命状态… · 2026/11/3 13:21:04
IDEA新版UI问题分析与旧版还原指南 1. 项目背景与需求分析JetBrains家的IDEA作为Java开发者最常用的IDE工具,每次UI更新都会引发广泛讨论。2023年推出的新UI设计采用了更扁平化的风格,虽然视觉上更现代,但不少老用户反馈操作效率反而下降。根据我的实际体验和社区调研ÿ… · 2026/11/3 13:58:50
传统煤企数字化转型:从巨亏到盈利的实战策略 1. 项目概述:从巨亏到盈利的华丽转身 贵州恒鼎实业这家曾经的"亏损王"在最新财报中交出了一份令人惊艳的成绩单——精煤业务毛利直接翻正达到9400万元。这个数字背后,是一家传统煤企在行业寒冬中逆势突围的完整故事。作为深耕能源行业十余年的… · 2026/11/3 13:58:50
Model-Optimizer:大模型推理部署的端到端工程方法论 1. 项目概述:Model-Optimizer 不是工具名,而是一类工程实践的统称 “Model-Optimizer”这个名称乍看像某个开源库或商业软件,但实际在工业级AI推理部署一线,它根本不是一款现成可下载的App,而是指代一套 围绕模型压缩… · 2026/11/3 13:58:50
STM32以太网开发实战:MAC、DMA、PHY与lwIP调试 1. 先把ETH外设这件事拆开看:MAC、DMA、PHY到底谁干什么很多人第一次在STM32上点以太网,卡住的地方往往不是代码,而是压根没搞明白这颗芯片里的ETH外设边界在哪。STM32的ETH是一个MAC控制器,它负责的是数据链路层那一摊事… · 2026/11/3 13:58:50
状态迁移技术优化LLM推理效率的实践与原理 1. 状态迁移技术如何提升LLM推理效率 大语言模型推理过程中的计算冗余问题一直困扰着开发者。传统方法需要为每个新输入重新计算整个模型的隐藏状态,这种重复计算严重拖慢了推理速度。阿里团队提出的状态迁移技术,本质上是通过缓存和复用中间计算结果来避… · 2026/11/3 13:58:50
物理世界与场景树的同步机制解析 1. 项目概述:物理世界与场景树的平行宇宙 "物理世界与场景树——两个平行宇宙的故事"这个标题揭示了计算机图形学中一个深刻的技术隐喻。在三维图形开发领域(如游戏引擎、虚拟现实系统),开发者需要同时管理两种截然不同… · 2026/11/3 13:57:48
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46