新闻详情

新闻详情

首页 / 资讯中心 / 详情

TensorFlow 2.x实战:安装、建模、部署与踩坑全解析

发布时间:2026/9/30 22:11:53来源:尧图网络
TensorFlow 2.x实战:安装、建模、部署与踩坑全解析
1. TensorFlow到底是什么现在学它还来得及吗说到TensorFlow很多人第一反应是“老牌深度学习框架”“现在都转PyTorch了学它还有意义吗”。我的答案很直接如果你做的是生产环境、移动端、大规模分布式训练TensorFlow依然是绕不开的选项甚至可以说“tensorflow安装”这个搜索词到现在都没凉本身就说明需求还在。TensorFlow是Google在2015年开源的一套端到端机器学习平台覆盖面远不止“写个神经网络”从数据加载、模型训练、超参数调优到模型导出、服务部署、端侧推理TensorFlow全都给了完整链路。这篇文章就来拆一拆2024年TensorFlow的实际玩法怎么装、怎么上手、怎么少踩坑以及它和PyTorch之间的流行趋势到底是怎么回事。对于刚入门的朋友TensorFlow最大的价值是“一站到底”你可以只学一个框架就完整走完“数据-训练-部署”的全流程社区里教程多工作岗位上需求也稳定。对于已经有PyTorch基础的人了解TensorFlow的部署生态也能帮你把“实验模型”变成“可运行系统”。所以我建议这几类人都可以认真看看准备用深度学习做实际项目的开发者、想在简历上补全生产部署经验的后端工程师、以及对“框架选型”感到纠结的小白。接下来我会按照自己实际动手的路径来写尽量把能直接复制的东西给你也会把那些容易劝退人的坑提前标出来。2. 安装TensorFlow环境准备与一步步实操2.1 先确定Python版本别一上来就装最新版我见过太多人卡在安装这一步原因不是命令敲错而是Python版本太新。TensorFlow的预编译wheel包并不是所有Python版本都能匹配尤其每年新发布的Python大版本官方适配总是慢半拍。2024年这个时间点最稳的组合是Python 3.10或3.11TensorFlow 2.15及以后版本对Python 3.12的兼容才逐渐齐全。我的建议如果你是为了跑现有代码直接用Python 3.10无论装TF还是后面配CUDA相关工具踩坑都最少。另外有一个细节非常容易忽略32位Python根本不能装TensorFlow必须用64位。还有虚拟环境真的非常重要。我习惯用conda创建独立环境先执行conda create -n tf python3.10再执行conda activate tf这样就算把环境折腾坏了也不会牵连系统Python。这一步花两分钟后面至少省两小时。而且同一个机器上往往要同时维护TF和PyTorch两套环境用虚拟环境隔离是最省心的做法。2.2 CPU版和GPU版的安装命令不要混着装TensorFlow的安装命令看起来很简单pip install tensorflow。但在GPU机器上很多人以为再装一个tensorflow-gpu包就行这是早年间1.x版本的老黄历。从TensorFlow 2.1开始官方就取消了tensorflow-gpu这个独立包名GPU支持直接包含在tensorflow包内部。所以正确的做法是先装好NVIDIA驱动和CUDA环境再正常pip install tensorflowTF会通过CUDA与cuDNN来调用显卡。如果是纯CPU跑直接pip install tensorflow即可没有额外操作。我的习惯是CPU环境用一个conda环境GPU环境另建一个然后在GPU环境里通过conda安装cudatoolkit和cudnn再装TensorFlow。这样最不容易出现版本错乱。以下是2024年比较稳的安装命令示例# CPU环境 conda create -n tf-cpu python3.10 conda activate tf-cpu pip install tensorflow2.15.0 # GPU环境前提已装好NVIDIA驱动 conda create -n tf-gpu python3.11 conda activate tf-gpu conda install -c conda-forge cudatoolkit11.8 cudnn8.6 pip install tensorflow2.15.0说个容易混淆的地方NVIDIA驱动自带的CUDA版本不一定要跟TensorFlow编译用的CUDA完全一致因为TensorFlow是运行时动态加载libcuda和libcudnn只要驱动版本足够新conda里的cudatoolkit就能正常工作。很多人一看到nvidia-smi显示的CUDA Version是12.x就以为自己必须装CUDA 12.x的包其实完全不必要。2.3 安装后怎么判断是不是装成功了不要直接开始训练先做几个20秒能完成的自检。第一步打开Python交互环境执行import tensorflow as tf确保不报错第二步打印版本号tf.__version__第三步GPU用户执行tf.config.list_physical_devices(GPU)能看到一列物理GPU说明TensorFlow已经找到显卡。如果看不到GPU常见原因是CUDA、cuDNN版本不匹配或者驱动太老。我通常会再跑一个极小的矩阵运算来验证GPU真的在工作import tensorflow as tf print(tf.config.list_physical_devices(GPU)) with tf.device(/GPU:0): a tf.random.normal([1000, 1000]) b tf.matmul(a, a) print(GPU计算正常)这个自检很有必要。我之前遇到过list_physical_devices(GPU)返回空列表但训练也没报错模型就在CPU上硬跑速度慢得离谱。后来才发现是conda环境里没装好cudnnTensorFlow自动选择退回了CPU。如果提前跑了这个矩阵计算至少能立马知道自己配置出了问题。2.4 安装常见报错的排查逻辑安装阶段的报错其实就那么几类没必要全部记住遇到的时候照着排查就行。报错关键词大概率原因处理方式ModuleNotFoundError: No module named tensorflow装错环境或没装成功确认当前激活的环境重新执行pip installCould not load dynamic library libcudnn.so.xcuDNN版本和TF不匹配用conda安装与TF配套的cudnn版本Illegal instructionCPU不支持AVX等指令集常见于老CPU换2.15以下版本或用源码编译安装OOM when allocating tensor模型或batch太大显存不足减小batch_size或开启混合精度训练这里我想特别讲一下Illegal instruction。TensorFlow 2.16之后默认安装包引入了Intel oneDNN优化很多老CPU跑起来直接报“非法指令”。遇到这种情况很多人以为是系统坏了实际上就是CPU太老不支持代码里编译进去的新指令集。最简单的处理方式不是四处找编译参数而是固定安装TensorFlow 2.15.0等官方调整适配范围。这个经验我在几台老服务器上实测过非常管用。3. 十分钟上手用Keras搭建你的第一个图像分类模型3.1 选一个不需要下载大数据集的开局入门最怕“环境搭好却不知道跑什么”。我推荐直接从Keras内置数据集开始比如Fashion MNIST它是服装图片的10分类数据集比手写数字更贴近真实场景模型结构也简单。内置数据集的好处是第一次运行时会自动下载不用你自己准备文件夹省去大量数据工程的前置工作。代码就三行import tensorflow as tf from tensorflow.keras.datasets import fashion_mnist (x_train, y_train), (x_test, y_test) fashion_mnist.load_data()数据本身就是28x28的灰度图共7万张。直接喂给模型之前需要做两件事一是把像素值从0-255缩放到0-1之间二是把标签从整数转成one-hot或者直接保留整数配合SparseCategoricalCrossentropy损失函数。我的习惯是用后者因为内存占用小还不容易写错维度。缩放像素值看似不重要但如果不做模型训练初期梯度会非常大收敛很不稳定。3.2 三种建模型的方式建议从Sequential开始Keras提供了三种构建模型的方式Sequential顺序模型、Functional函数式模型、Subclassing自定义类模型。对新手或者90%的常规任务Sequential就够用模型就是一层层堆叠。Functional适合像多输入多输出、残差连接这类有分支的模型。Subclassing则适合需要完全自己控制前向逻辑的研究场景。下面这个例子用Sequential搭一个三层网络model tf.keras.Sequential([ tf.keras.layers.Flatten(input_shape(28, 28)), tf.keras.layers.Dense(128, activationrelu), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activationsoftmax) ])这里Flatten把二维图片拉成一维向量Dense是全连接层Dropout用来抑制过拟合最后的Dense输出10个类别的概率分布。为什么加Dropout因为全连接层参数量大很容易记住训练集噪声加一个0.2的Dropout会随机丢弃20%的神经元让网络学到更鲁棒的特征。当然这个模型放到2024年已经谈不上先进但作为理解Keras工作流的载体它足够清晰而且能跑得很快。3.3 训练和评估的每一步都在做什么模型建好后需要compile指定优化器、损失函数和评价指标model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy])然后再用fit开始训练。fit里的关键参数是batch_size和epochs。batch_size表示每次更新参数用多少张图epochs表示把整个训练集过几遍。如果你用的是CPU建议batch_size设32或64epochs设5训练大概也就几分钟。训练时输出的loss和accuracy要一起看loss下降而accuracy上升说明正常如果accuracy抖动很大可能是学习率太高或者数据没打乱。Keras的fit默认会在每个epoch开始前打乱数据所以一般不用自己管。评估阶段用model.evaluate(x_test, y_test)它不会更新参数只计算损失和指标。注意测试集不仅用来测准确率更重要的是看模型有没有过拟合。如果你发现训练accuracy接近98%测试只有85%就该加Dropout、减小网络容量或者引入数据增强。不要看到训练集accuracy很高就高兴过拟合恰恰是深度学习入门者最容易犯的错。3.4 怎么让训练过程更可控回调函数与历史曲线很多新人训练完只看一个最终准确率就结束了我强烈建议把训练过程中的history拿出来看history model.fit(x_train, y_train, epochs10, validation_split0.2)然后画loss曲线。如果训练loss持续下降而验证loss先降后升就是典型的过拟合信号。Keras还提供了一组回调函数可以在训练过程中自动干预。比如EarlyStopping监控验证集指标连续几个epoch不提高就自动停止ReduceLROnPlateau在loss卡住时自动降低学习率ModelCheckpoint每次指标变好就把模型保存下来。这三个是我最常用的黄金组合能节省大量试错时间。不要小看这些基础操作后面遇到部署问题拆到根上往往都是因为早期对“训练和验证差异”缺乏敏感度。4. TensorFlow进阶数据管道、模型保存与性能优化4.1 用tf.data替代手动循环数据加载速度提升明显刚入门时把整个数组一次性扔进fit就可以但真实项目里的数据往往无法全部加载进内存。TensorFlow为此提供tf.data.Dataset核心思想是把数据读取变成一个流水线从文件读、做预处理、打乱、分批、预取。最常用的API是from_tensor_slices和map。比如你有两个numpy数组x和ydataset tf.data.Dataset.from_tensor_slices((x, y)) dataset dataset.shuffle(10000).batch(64).prefetch(tf.data.AUTOTUNE)shuffle的buffer_size不是越大越好它表示“随机采样时先从数据池里缓冲多少条”。设太大启动变慢且内存压力大设太小打乱不彻底。一般建议设为总样本数的1/10到1/5左右。prefetch(AUTOTUNE)的意思是让数据准备和模型计算重叠起来CPU在GPU计算的同时就把下一批数据准备好了能明显减少训练等待时间。这里有个容易踩的坑不要为了“乱序”在数据集已经batch之后再shuffle那样只会打乱批次顺序而批次内的数据可能高度相似。正确顺序是先读取原始数据shuffle再batch最后prefetch。如果你还需要做复杂的图像增强比如随机裁剪、旋转可以用dataset.map配合tf.image实现但要注意这些操作在CPU上跑如果太复杂反而会成为瓶颈。4.2 模型保存从训练到部署的关键一步训练完模型很多人习惯直接model.save(model.h5)但2024年的首选格式是SavedModel用model.save(saved_model_dir)导出。SavedModel不只包含权重还包含网络结构和计算图后续无论用TensorFlow Serving、TensorFlow Lite还是直接用Python加载都是同一套格式。部署到生产环境时SavedModel是最可靠的。你还可以把模型转成TFLite用于移动端converter tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) tflite_model converter.convert()转换时有个参数很容易忽略——优化选项。默认转换会保留float32精度适合CPU如果要在手机NPU上加速一般会启用后量化converter.optimizations [tf.lite.Optimize.DEFAULT]量化后模型体积可能缩小到原来的1/4但精度会有一点损失。实际项目中建议先做量化感知训练或者至少用验证集评估量化后的指标不要直接上线。我在一个移动端缺陷检测项目里量化后准确率掉了0.8个百分点肉眼基本看不出差异但模型体积从120MB降到30MB加载速度也快了很多非常值得。4.3 训练加速混合精度与XLA编译如果GPU是NVIDIA的Volta、Ampere或更新的架构大概率支持Tensor Core通过混合精度训练可以少则提速30%多则翻倍。TensorFlow里启用方式非常简单tf.keras.mixed_precision.set_global_policy(mixed_float16)不过要注意mixed_float16跑起来快但也更容易出现loss变成NaN或精度不稳定的问题。我的习惯是先用float32把模型跑通确认逻辑无误后再开启混合精度如果开了就不稳定就把自定义loss里涉及的敏感部分保留float32。这个策略看起来保守实际上能帮你少走很多弯路。XLAAccelerated Linear Algebra是另一招。在模型编译时加上jit_compileTruemodel.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy], jit_compileTrue)XLA会把多个算子融合编译显著减少kernel启动开销。对于3.2节里那种小CNN模型XLA提速可能不明显但如果你用的是Transformer、ResNet这类大模型效果会直观很多。XLA也不是万能的有些自定义算子不支持遇到报错时可以退回普通模式。还有一点开了XLA后首次运行会有一个编译过程看起来像卡住了其实是在做图优化耐心等一下就好。4.4 怎么判断性能瓶颈到底在哪训练慢的时候先别急着换机器。打开nvidia-smi看GPU利用率如果一直低于50%说明数据管道或预处理成了瓶颈。解决方案通常是加大prefetch、减少map中重复CPU计算、或者把图片打包成TFRecord存储。如果GPU利用率高但训练仍然慢再考虑显存带宽和模型结构本身。这个排查顺序能帮你把精力花在正确的地方。我见过有人在GPU利用率只有20%的情况下直接换卡结果还是慢因为瓶颈一直在数据加载那里。如果你用的是CPU训练还可以通过环境变量控制线程数或者把inter_op_parallelism_threads和intra_op_parallelism_threads调一调。但说到底CPU训练更考验数据管道的效率能用tf.data预处理的数据尽量不要在Python层做循环否则GIL会把你拖死。5. TensorFlow vs PyTorch2024年的真实趋势与选型建议5.1 热搜关键词背后的生态变化最近一年网上关于“TensorFlow和PyTorch谁更流行”的讨论又多了起来。从论文复现和科研圈看PyTorch的占优趋势确实明显动态图机制灵活debug方便学术界很多新模型都优先以PyTorch发布。但“流行”要分层看学术论文里多不等于生产环境里多。在Google、Intel、Arm等公司主导的移动端、嵌入式、服务端推理领域TensorFlow的TFLite和TF Serving生态依然有不可替代的位置。这也是为什么“tensorflow安装”的搜索热度一直没降需求一点都没少只是大家的关注点从“怎么跑通”变成了“怎么部署到真实场景”。5.2 核心差异动态图、静态图与部署链路两个框架最本质的区别在于计算图的构建方式。PyTorch默认是“define-by-run”代码执行到哪图就建到哪这让打印变量、打断点、用Python原生语法调试变得非常顺滑。TensorFlow 2.x虽然默认也开Eager Execution体验上接近动态图但它的另一个核心能力是tf.function——把Python函数转成静态计算图以获得更好的性能优化和部署表现。这也是为什么TensorFlow在大规模分布式训练上更“稳”因为静态图更容易做跨设备优化。生产部署层面的差异更实际。TensorFlow有完整的SavedModel格式和TensorFlow Serving可以比较简单地完成模型版本管理、灰度发布、GPU推理并发。PyTorch的TorchServe起步晚整体工具链不如TF Serving成熟。如果是做在线推理服务、需要长期维护模型系统TensorFlow这套东西更省心。很多团队说“PyTorch更流行”但真正到了交付节点还是会考虑转成TensorFlow或ONNX Runtime原因就在这里。5.3 学习成本到底差多少很多文章说PyTorch更简单但以我带过几个新人的经验看这个“简单”主要体现在小规模实验阶段。PyTorch写起来像普通Python代码很快就能跑通一个demoTensorFlow一开始会遇到Dataset、SavedModel、SignatureDef这些抽象概念会让人感觉到门槛。但当你到了部署环节PyTorch仍然要学TorchScript、TorchServe、ONNX导出等额外内容总学习成本并没有少。真正想清楚自己目标再选框架比纠结谁流行更重要。为了看得更清楚我列一个简单的对照对比维度TensorFlowPyTorch实验调试体验Eager模式下接近PyTorch但tf.function有额外学习成本动态图原生调试直观生产部署工具链TF Serving、TFLite、TF.js更成熟TorchServe、ONNX生态逐渐补齐移动端/嵌入式TFLite支持范围广部署链路完整ExecuTorch在推进中但生态还不够学术论文复现相对少大部分新模型首发PyTorch大规模分布式训练静态图优化成熟企业案例多分布式方案较新但社区迭代很快5.4 2024年我的选型结论我把自己的选择标准写成一个简单判断如果做科研、发论文、快速验证idea选PyTorch因为它社区迭代快复现方便。如果做企业级系统、要上线稳定模型服务、要部署到手机或嵌入式设备选TensorFlow因为工具链更闭环。如果是纯新手没有明确目标可以从TensorFlow 2.x起步。理由很朴素Keras的接口抽象度高能让你先建立“数据-模型-训练-评估-部署”的全景认知后续再转PyTorch也不难。这不是非黑即白。现在很多团队两个框架都在用调研阶段用PyTorch落地阶段转到TensorFlow或ONNX Runtime。我在实际项目里就这么实践过几次转换工具成熟之后这种“混搭”在未来会越来越常见。6. 踩坑实录TensorFlow实战中那些让人抓狂的细节6.1 常见问题速查表我把自己和身边人踩过的问题整理成一张速查表希望能帮你省点时间。现象排查思路解决建议import tensorflow直接崩溃多半是protobuf版本冲突使用官方requirements里的版本或者降级protobufmodel.fit跑着跑着卡死数据管道里有blocking操作删除map里的Python print改用tf.print自定义loss里用了numpy导致梯度断掉改成tf原生API实现GPU显存一直不释放进程退出但显存被占用用nvidia-smi找到进程并kill训练结果不稳定随机种子未固定设置tf.random.set_seed必要时固定numpy.random.seed这里面最容易被忽略的是“自定义loss用了numpy”。因为TensorFlow的自动求导只对tf运算有效你在loss函数里写x.numpy()梯度瞬间断掉轻则训练不收敛重则直接checkpoint救不回来。我的经验法则是凡是出现在tf.function或自定义训练步骤里的逻辑一律只用TensorFlow原生API。这个规则看起来简单但真的能帮你避免大量莫名其妙的bug。6.2 CPU环境跑训练的几个优化技巧很多人一开始只能在CPU上练习。如果是个人笔记本优先用小batch比如32同时开启prefetch。Keras的fit默认不会自动用满所有CPU核心你可以通过数据集的预取来提升利用。另一个技巧是减少验证频率比如validation_freq2不是每个epoch都跑一次验证集。这些琐碎设置不会改变模型效果但能显著提升你来回复试的节奏。试过几次你会发现优化训练流程比调模型参数更能节省整体时间。还有一个小技巧在fit里加callbacks[tf.keras.callbacks.TensorBoard()]训练过程中可以实时看loss曲线而且TensorBoard本身也能帮你定位训练停滞的时间点。虽然现在很多人觉得TensorBoard老旧但在无头服务器上排查问题它依然是最直观的工具。6.3 关于“版本强迫症”的一点提醒TensorFlow迭代速度快官方文档的示例常常基于最新版。我刚入门时喜欢把所有包都升到最新结果经常遇到“照着文档跑不通”的情况。后来养成的习惯是固定大版本在项目根目录写死requirements.txt每次升级前先看release note里的Breaking Changes。对做项目的人来说“稳定的旧版本”远比“最新的新特性”更重要。这个原则不仅在TensorFlow上适用在PyTorch、Paddle等其他框架里也一样。另外不要迷信“最新版性能一定更好”。TensorFlow 2.16之后启用了oneDNN确实对Intel CPU有优化但在老CPU上反而可能触发非法指令TensorFlow 2.15对很多生产环境的old CUDA驱动更友好。选版本之前先确认目标机器的硬件和驱动再决定是升还是降。6.4 我最想提醒新人的一件事如果只能给你一条建议那就是动手之前先想清楚“这个模型最终会在哪里跑”。是手机App是服务器API还是课堂作业这个问题决定了你用TensorFlow的哪些模块、要不要做量化、要不要学TF Serving。我见过太多人被“先跑通再说”这句话害了跑通之后发现部署根本无从下手又回头补工具链。早期多花十分钟做规划比后期返工省太多时间。我自己第一次接项目时只想着把准确率调到95%以上完全没考虑模型体积和推理延迟后来发现客户端手机内存根本装不下只能从头优化。如果当时先问一句“部署目标是什么”至少能避免整整一周的返工。做技术的人很容易被“准确率”这个指标绑架但实际工程里可用的模型远比好看的分数重要。TensorFlow最吸引我的地方就是它把“训练”和“部署”放在同一个平台里逼着你在早期就思考完整链路。希望这篇文章能帮你在学习TensorFlow的路上少踩一点坑把时间花在真正有价值的工程实践上。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

胶粘剂可靠性三大测试维度:TC冷热循环、双85湿热偏压与Tg塌陷 2026/9/30 22:58:56

胶粘剂可靠性三大测试维度:TC冷热循环、双85湿热偏压与Tg塌陷

在芯片封装、功率模块和传感器产品里,胶粘剂从来不是主角,可一旦可靠性试验出了问题,背锅的往往就是它。芯片贴片胶、底部填充胶、导电胶、结构胶、灌封硅凝胶,这些材料平时“默默无闻”,室温下测试数据漂亮得很&#…

阅读更多 →
OpenClaw 模型配置指南:用 TaoToken 统一 Key 管理多模型切换 2026/9/30 22:58:56

OpenClaw 模型配置指南:用 TaoToken 统一 Key 管理多模型切换

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
无人机集群路径规划实战:用SFOA、APO、GOOSE、CO、PIO五种优化算法对比求解(附Matlab代码) 2026/9/30 22:58:49

无人机集群路径规划实战:用SFOA、APO、GOOSE、CO、PIO五种优化算法对比求解(附Matlab代码)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
一文讲清楚 Claude Code Skills、MCP工具,看完小白变大神!(附保姆级教程) 2026/9/30 22:58:43

一文讲清楚 Claude Code Skills、MCP工具,看完小白变大神!(附保姆级教程)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Claude Code 实战手册:用 TaoToken 统一 Key 打通终端 AI 编程配置 2026/9/30 22:58:43

Claude Code 实战手册:用 TaoToken 统一 Key 打通终端 AI 编程配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
mysql专栏 06.pymysql 01.基本使用:TaoToken 统一 Key 接入前的 config.toml 骨架与报错排查 2026/9/30 22:57:57

mysql专栏 06.pymysql 01.基本使用:TaoToken 统一 Key 接入前的 config.toml 骨架与报错排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉