基于Unet的LITS肝肿瘤分割实战:从数据预处理到模型训练验证
简介这是一份基于Unet的LITS肝肿瘤分割项目资源包面向医学图像分割方向的开发者与研究者。内容涵盖完整数据集、Python训练/测试代码与已训练10个epochs的结果文件网络在全局像素准确度达0.988、miou为0.838若加大训练轮数性能还可进一步提升。压缩包共2000个文件约680.5MB主体为1983张PNG格式的轴位面切片及mask图像另有8个py源码、xml配置、txt标签与README说明结构清晰便于直接复现与改造。代码支持多尺度随机缩放训练utils中的compute_gray函数会自动读取mask灰度值并写入txt同时自动设定Unet输出通道数适用于多分割目标扩展。训练阶段采用余弦衰减学习率run_results内保存了损失与iou曲线、训练日志及最优权重可查看每类iou、recall、precision等指标。目前已有302人学习下载适合希望快速上手肝肿瘤分割或基于Unet做多类别分割实验的读者。1. 基于Unet的肝肿瘤分割项目LITS切片分割跑起来并没有想象中难之前有位朋友让我帮忙估一个医学影像分割Demo能不能快速落地我拿到手就是这份基于Unet对肝肿瘤分割LITS切片的分割项目。第一反应是又要配环境、装各种软件打开代码包才发现数据集、完整代码、训练好的结果文件都齐了只要Python环境能跑几乎不需要额外插件。这份资源要解决的事很具体把LITS的CT体数据按轴向切成二维切片配对对应标签交给Unet模型分割出肝脏和肿瘤区域。适合两类人手里有LITS或类似CT数据、想快速验证Unet分割效果的开发者以及想把整套分割流程从数据到训练完整走通的新手。下面按我实际复现的顺序展开坑都写在对应章节里。2. LITS数据集预处理从三维体数据到能喂给Unet的切片对2.1 为什么LITS体数据不能直接塞进UnetLITS肝肿瘤分割挑战赛数据集的原始数据是一百多例CT体数据每个样本是一个三维的nii文件里面的数值是医学图像的CT值单位是HUHounsfield Unit。但Unet一般处理的是二维图像如果直接把三维数据压缩成一张二维图深度方向上肝组织和肿瘤信息会互相叠加分割精度几乎无法保证。所以拿到资源的第一个动作就是切片沿CT的轴状面切成一张张二维图每张图配一个二维标签图后续训练、验证都以切片对为单位进行。切片之后还要处理数值范围。人体CT值范围大约在-1000到3000之间但腹部扫描里肝脏和肿瘤主要落在-100到250这个区间。直接把原始数值丢给网络模型会拿大量参数去拟合骨骼、空气这些无关变化收敛速度肉眼可见地慢。常见做法是先做窗宽窗位截断再归一化。窗宽取[-200, 200]附近在保留肝实质与肿瘤灰度差异的同时把背景极值压掉。这套资源自带的预处理脚本就是按这个思路写的建议新手不要跳过这步直接训练跳过之后你会看到loss下降像爬坡。处理过程不需要装什么大型软件SimpleITK这个库就够用。资源里给出的预处理脚本会把每个病例切完的切片保存成npz文件图像和标签放同一个文件里这样后面写Dataset类时对齐起来非常省事。整个数据准备阶段的核心是两件事保证体数据和标签的层数一致保证归一化后数值范围稳定。2.2 切片与保存脚本把nii切成npzimport SimpleITK as sitk import numpy as np import os def window_ct(volume, low-200, high200): # 截断到肝脏/肿瘤常用窗宽范围去掉空气和骨骼极值 volume np.clip(volume, low, high) # 线性归一化到 [0, 1]方便网络输入 volume (volume - low) / (high - low) return volume def process_case(volume_path, label_path, save_dir, case_id): vol sitk.ReadImage(volume_path) lab sitk.ReadImage(label_path) vol_np sitk.GetArrayFromImage(vol) # 输出形状 (num_slices, H, W) lab_np sitk.GetArrayFromImage(lab) print(f[{case_id}] volume: {vol_np.shape}, label: {lab_np.shape}) assert vol_np.shape lab_np.shape, 体数据和标签层数不一致需检查文件是否配对 vol_np window_ct(vol_np) os.makedirs(f{save_dir}/{case_id}, exist_okTrue) for i in range(vol_np.shape[0]): slice_img vol_np[i].astype(np.float32) slice_lab lab_np[i].astype(np.uint8) np.savez_compressed( f{save_dir}/{case_id}/slice_{i:03d}.npz, imageslice_img, labelslice_lab)逻辑说明先读取体数据和标签通过assert检查两者的shape是否完全一致这一步能拦截掉文件配对错误。window_ct函数里先用np.clip把超出[-200,200]的数值截断再做最小值-最大值线性映射将数值压到0到1。最后按case_id分目录把每个切片的图像和标签封装进同一个npz文件。参数说明low-200、high200是按腹部CT肝区像素分布选的。如果数据里有动脉期增强扫描肝实质灰度整体抬升可以把上限放宽到250如果全部是平扫序列维持200更稳定。归一化到0到1而不是-1到1是因为后面Unet的ReLU输出和BCE损失天然适配0到1区间。2.3 Dataset类与数据增强保证训练时图像和标签永远同步import torch from torch.utils.data import Dataset import numpy as np import os import random class LiverSliceDataset(Dataset): def __init__(self, data_root, augmentFalse): self.files [] for case_id in os.listdir(data_root): case_dir os.path.join(data_root, case_id) for fname in os.listdir(case_dir): if fname.endswith(.npz): self.files.append(os.path.join(case_dir, fname)) self.augment augment def __len__(self): return len(self.files) def __getitem__(self, idx): data np.load(self.files[idx]) img data[image] # 形状 (H, W) lab data[label] # 形状 (H, W) if self.augment: # 随机水平翻转图像和标签施加完全相同的变换 if random.random() 0.5: img img[:, ::-1] lab lab[:, ::-1] # 随机旋转一定角度同样要保证标签同步旋转 angle random.uniform(-10, 10) # 实际项目中这里用 scipy.ndimage.rotate保持 order1 # 并设置 reshapeFalse避免旋转后尺寸改变 img_t torch.from_numpy(img.copy()).unsqueeze(0).float() lab_t torch.from_numpy(lab.copy()).long() return img_t, lab_t逻辑说明Dataset按文件路径逐个加载npz每次返回一个切片的图像和对应标签。增强只在训练时开启验证阶段必须关闭否则评估指标会被翻转和旋转干扰。增强的核心原则是图像做了什么变换标签就必须做完全相同的变换一旦某一帧翻转而标签不翻转模型看到的就是错位样本。参数说明图像用unsqueeze(0)加上单通道维度符合后面Conv2d的输入要求标签保持long型配合CrossEntropyLoss使用。随机旋转部分如果引入scipy.ndimage.rotate注意reshapeFalse否则旋转后尺寸变化会导致图像和标签错位。这份代码对应资源里的dataloader部分跑通之后训练集和验证集就是标准的“图像-标签”对。预处理做完数据集这块算是稳了。接下来就是模型部分Unet在这个任务里的优势值得展开说明。3. Unet结构与训练参数把分割网络理论落到可训练状态3.1 Unet为什么适合肝肿瘤切片分割Unet结构最早就是为医学图像分割设计的它的核心特点是编码器-解码器对称结构加跳跃连接。编码器部分通过四次下采样逐步提取高维特征从边缘纹理到器官语义解码器部分通过上采样恢复空间分辨率跳跃连接把编码器每一层的细节特征直接拼到解码器对应层弥补下采样丢失的边缘信息。医学图像分割任务里肿瘤边界往往模糊而且目标区域占整幅图像的比例很小Unet这种“既要语义准、又要细节全”的设计恰好对症。在处理LITS切片时有一个很现实的点切片尺寸。原始切片大约512x512如果直接输入网络显存压力很大。这份资源里统一缩放到256x256输入因为肿瘤在切片里通常不会小到看不见256分辨率下边界信息损失可控训练速度和显存占用都友好不少。如果想追求更高精度再上512输入但显存不够时优先考虑随机裁剪而不是等比缩放。模型层面还有一个选择理由参数量适中。经典Unet在64初始通道下参数量大约3100万比目前各种Transformer分割模型小一个数量级在普通单卡上就能训练。LITS切片的数据量不算大医生标注的边界本身也存在主观差异模型容量太大反而容易把标注噪声背下来Unet的容量对这个任务是够用且不易过拟合的。3.2 Unet模型定义与损失函数实现import torch import torch.nn as nn class ConvBlock(nn.Module): def __init__(self, in_ch, out_ch): super().__init__() self.conv1 nn.Conv2d(in_ch, out_ch, 3, padding1) self.conv2 nn.Conv2d(out_ch, out_ch, 3, padding1) self.relu nn.ReLU(inplaceTrue) def forward(self, x): x self.relu(self.conv1(x)) x self.relu(self.conv2(x)) return x class UNet(nn.Module): def __init__(self, in_channels1, num_classes2, init_feat64): super().__init__() self.enc1 ConvBlock(in_channels, init_feat) self.enc2 ConvBlock(init_feat, init_feat * 2) self.enc3 ConvBlock(init_feat * 2, init_feat * 4) self.enc4 ConvBlock(init_feat * 4, init_feat * 8) self.pool nn.MaxPool2d(2) self.center ConvBlock(init_feat * 8, init_feat * 16) self.up4 nn.ConvTranspose2d(init_feat * 16, init_feat * 8, 2, stride2) self.dec4 ConvBlock(init_feat * 16, init_feat * 8) self.up3 nn.ConvTranspose2d(init_feat * 8, init_feat * 4, 2, stride2) self.dec3 ConvBlock(init_feat * 8, init_feat * 4) self.up2 nn.ConvTranspose2d(init_feat * 4, init_feat * 2, 2, stride2) self.dec2 ConvBlock(init_feat * 4, init_feat * 2) self.up1 nn.ConvTranspose2d(init_feat * 2, init_feat, 2, stride2) self.dec1 ConvBlock(init_feat * 2, init_feat) self.out nn.Conv2d(init_feat, num_classes, 1) def forward(self, x): e1 self.enc1(x) e2 self.enc2(self.pool(e1)) e3 self.enc3(self.pool(e2)) e4 self.enc4(self.pool(e3)) center self.center(self.pool(e4)) d4 self.up4(center) d4 torch.cat([d4, e4], dim1) d4 self.dec4(d4) d3 self.up3(d4) d3 torch.cat([d3, e3], dim1) d3 self.dec3(d3) d2 self.up2(d3) d2 torch.cat([d2, e2], dim1) d2 self.dec2(d2) d1 self.up1(d2) d1 torch.cat([d1, e1], dim1) d1 self.dec1(d1) return self.out(d1)逻辑说明编码器四个ConvBlock逐层提取特征下采样用MaxPool2d完成。中心层用16倍初始通道数做最抽象的语义提取。解码器通过ConvTranspose2d上采样后在通道维上拼接对应编码器输出再经过ConvBlock融合。最后的1x1卷积把特征图映射到类别数。参数说明init_feat64是经典设置显存有压力时降到32参数量大约缩到四分之一精度会略有下降。num_classes2代表背景和前景二分类如果想把肝脏和肿瘤分开计算可以改成3类。输入通道in_channels1对应预处理得到的单通道灰度切片。损失函数这块直接用CrossEntropyLoss在肿瘤占比很小的切片上效果一般。我建议用Dice Loss和BCE的组合资源里给出的训练脚本正是这个思路def dice_loss(pred, target, smooth1.0): # pred 是 sigmoid 之后的概率图target 是 0/1 标签 pred pred.reshape(pred.size(0), -1) target target.reshape(target.size(0), -1) intersection (pred * target).sum(dim1) union pred.sum(dim1) target.sum(dim1) dice (2.0 * intersection smooth) / (union smooth) return 1.0 - dice.mean()逻辑说明把概率图和标签拉成二维按batch内每个样本独立计算Dice系数再对batch取平均。加平滑系数避免前景目标为空时除零。Dice Loss直接优化分割任务关心的交并指标对小目标比逐像素交叉熵更友好。实际训练时常见的做法是把Dice Loss和BCE按1:1加权既保留像素级梯度又让模型关注区域重叠度。3.3 训练参数速查表与调整方法参数推荐值说明输入尺寸256x256显存不足时改为192或128batch_size8单卡16G显存可扛住初始学习率1e-3AdamW配套使用学习率策略cosine衰减避免后期震荡训练轮数80-120以验证集Dice不再上升为准优化器AdamW权重衰减设为1e-4损失函数Dice BCE等权相加即可参数说明里值得强调两个点。batch_size不要为了追求稳定而开太大LITS切片里肿瘤区域小大batch会让少数含肿瘤的切片被大量背景切片稀释梯度方向偏向背景我一般用8到16配合normalization效果更稳。学习率用AdamW配cosine衰减是现在的主流组合前20轮保持较高学习率让模型快速看到肝脏轮廓后面逐渐降低让边界精细收敛。如果发现loss曲线中期开始震荡优先检查学习率是否过高而不是盲目调模型结构。训练时的显存管理可以提一下如果单卡显存只有8G把batch_size降到4同时把输入尺寸缩到224。如果还是溢出在Dataset里加入随机裁剪到192而不是用全局缩放这样能保留更多局部细节。4. LITS分割训练与验证中的常见问题排查五个实际翻车点训练这套模型过程中最容易翻车的不是模型本身而是数据配准和评估方式。下面这几个问题我都在实际运行里踩过每一条都按现象、原因、解决写清楚。4.1 切片后图像和标签错位loss卡住不动现象训练loss从初始值下降到0.6左右就再也不动验证集Dice始终在0.1上下徘徊预测结果几乎全是背景偶尔输出一些无意义的散点。原因预处理时读取体数据和标签分别用了两个文件列表其中一个按文件名排序时混入了其他病例导致某几个case的volume切片对应的是另一份label。神经网络对错位样本的拟合能力有限模型最终学到的是“不管输入是什么都输出背景”。解决强制在读取阶段打印每个病例的shape并做assert。我当时在process_case里加了一行断言shape不一致直接报错退出同时把volume和label放进同一个case目录杜绝跨目录配对。另一个做法是读完后随机抽三层做可视化叠加肉眼确认边界位置重合再进入训练。从那以后我每次换数据集都会先跑这个检查。4.2 数据增强导致标签平移错位现象训练loss能下降但验证集Dice出现周期性的暴跌每训练十几轮就掉一次然后恢复看起来像“抽风”。原因增强模块里使用了随机平移和旋转但写成先变换图像再变换标签两次变换的随机参数不是同一组标签并没有跟着图像移动。模型时而看到正确样本时而看到错位样本表现就是验证指标周期性波动。解决把所有增强函数封装成一个类图像和标签在同一个随机状态context下变换。最简单的办法是先生成旋转矩阵或平移量再对图像和标签分别调用相同的变换参数。做不到统一参数就只保留水平翻转这种天然对齐的增强宁少勿错。4.3 Dice Loss训练震荡小目标切片上梯度不稳现象验证loss曲线像锯齿每个epoch差异很大但最终平均Dice尚可。训练到后期含肿瘤面积很小的切片预测结果频繁在“全背景”和“小碎块”之间切换。原因Dice Loss在小目标上梯度变化剧烈。肿瘤只占切片不到5%像素时预测概率稍有波动Dice值就会大幅变化梯度幅度不稳定。叠加BCE能缓解但对占比极小的目标仍然敏感。解决改用Focal Loss和Dice Loss的组合Focal Loss通过调制因子降低易分样本的梯度权重让模型把注意力放在难分的小肿瘤区域。另一个可行做法是过滤掉完全没有肿瘤的纯背景切片让训练集里含肿瘤切片占比保持在30%以上避免模型被背景淹没。我当时过滤后训练稳定性明显提升。4.4 按切片划分训练验证集导致Dice虚高现象训练完模型验证集Dice高达0.93部署到新CT数据上却只有0.75差距大到没法解释。原因同一病例的相邻切片极其相似相邻层之间只有细微解剖变化如果随机划分把同一病例的切片同时放进训练集和验证集模型等于见过验证样本的“邻居”Dice虚高是典型的过度乐观评估。解决按病例划分而不是按切片划分即一个case的所有切片要么全在训练集、要么全在验证集。资源里的数据划分脚本默认就是这个逻辑但如果你自己重写了划分逻辑务必保留按case划分。评估时按病例分别报告Dice最终取均值这样得到的是可上线的真实指标。4.5 输出阈值固定0.5小病灶被切碎现象预测结果里肿瘤区域有大量空洞肉眼看到的是密密麻麻的碎点边缘锯齿感很强形态学上看起来不像真实病灶。原因模型的概率图在边界处是模糊过渡带简单用0.5一刀切会把一些低置信度的边界区域丢掉同时LITS原图里的肿瘤常伴随坏死区域内部灰度不均导致预测概率出现空洞。解决先用验证集做阈值扫描分别计算0.4到0.6之间的Dice选最优阈值。然后在预测图上做形态学后处理先用最大连通域保留主病灶再用闭运算填补内部空洞。这个操作不是造假而是把模型输出整理成符合临床标注习惯的结果资源里训练结果文件的预测后处理部分就是这么干的。这四个坑本质都是“数据没对齐、评估太乐观、小目标难收敛”。遇到验证指标和直觉不符时先怀疑数据划分和配准再怀疑模型结构。Unet本身很成熟问题通常不在网络结构上。5. 用训练结果文件验证分割效果Dice统计与可视化双确认代码包里的训练结果文件就是best_model.pth。加载它跑一遍验证集我习惯同时输出两个东西按病例统计的Dice表格和预测可视化叠加图只有两者都对上我才敢说模型真的训出来了。import torch import numpy as np import matplotlib.pyplot as plt from torch.utils.data import DataLoader device torch.device(cuda) model UNet().to(device) model.load_state_dict(torch.load(best_model.pth)) dataset LiverSliceDataset(./data/slices, augmentFalse) loader DataLoader(dataset, batch_size8, shuffleFalse) all_dice [] for img, lab in loader: with torch.no_grad(): pred torch.sigmoid(model(img.to(device))).cpu() pred_bin (pred 0.45).float() inter (pred_bin * lab.float()).sum(dim(1, 2)) union pred_bin.sum(dim(1, 2)) lab.float().sum(dim(1, 2)) dice (2 * inter 1e-6) / (union 1e-6) all_dice.extend(dice.numpy()) print(fmean Dice: {np.mean(all_dice):.3f})逻辑说明从最优训练结果文件加载模型权重关闭梯度做推理用0.45作为分割阈值。Dice计算直接按像素交并集统计最后打印全局平均。这个数字单独看没有意义配合下面可视化才有说服力。def visualize_case(img, lab, pred_bin, idx): plt.figure(figsize(12, 4)) plt.subplot(1, 3, 1) plt.imshow(img.squeeze(), cmapgray) plt.title(CT Slice) plt.subplot(1, 3, 2) plt.imshow(lab.squeeze(), cmapjet) plt.title(Ground Truth) plt.subplot(1, 3, 3) plt.imshow(pred_bin.squeeze(), cmapjet) plt.title(Prediction) plt.savefig(fresult_{idx}.png, dpi150)逻辑说明把原始切片、标注、预测图并排输出每张图单独命名保存。看可视化时重点关注三件事预测边缘是否贴着肝脏外轮廓、肿瘤内部是否有大面积空洞、小病灶层是否漏检。如果Dice均值高但可视化里大病灶形态明显不对说明模型是“碰运气”高的需要回查数据泄漏或后处理问题。最后一招是形态学后处理。用scipy.ndimage的binary_opening去掉碎点再binary_closing填补肿瘤内部空洞然后重新计算Dice。通常这一步能提升一到两个百分点的Dice更重要的是让分割结果更接近标注风格后续如果要接三维重建或者体积计算这一步不能省。这套验证流程走完我基本敢确定模型是真的会分割了。不过第一次拿到训练结果文件时我直接跑了个平均Dice就以为万事大吉后来部署到新数据才知道虚高有多坑。从那以后我每次训完分割模型都强制走一遍“按病例统计Dice 可视化抽样”的流程眼睛确认过的边比数字更能说明问题。希望这份拆解能帮你把这套资源跑得顺畅少在数据配准和评估上走弯路。本文还有配套的精品资源点击获取

相关新闻

高保真训练场:让强化学习策略从仿真顺利迁移到真实机器人

高保真训练场:让强化学习策略从仿真顺利迁移到真实机器人

做机器人和自主无人系统的强化学习,有个绕不开的现实:算法在仿真环境里跑得飞起,放到真实设备上却像换了脑子。我第一次被这问题折磨,是用一个带视觉的机械臂抓取项目,算法在仿真里成功率已经能到九成,真机…

2026/10/9 15:21:58 阅读更多 →
全国县级shp文件处理全攻略:从坐标系体检到重投影避坑指南

全国县级shp文件处理全攻略:从坐标系体检到重投影避坑指南

简介:全国县级行政区划shp文件是GIS领域常用的基础地理数据,面向地理信息专业学生、规划人员及数据分析师,用于获取中国县级行政单元的精确边界。Shapefile基于Esri标准格式,由几何、属性、索引三类子文件协同工作,本资…

2026/10/9 15:20:57 阅读更多 →
ADO封装库实战:从Connection到Recordset的核心用法与避坑指南

ADO封装库实战:从Connection到Recordset的核心用法与避坑指南

简介:面向商业开发场景的 ADO 源代码示例包 Ado_Aok_demo.zip,聚焦微软 ActiveX Data Objects 在 C 工程中的实际应用,适合需要在财务、库存、客户关系管理等业务系统中完成数据库连接的开发者参考学习。压缩包共收录 26 个文件,以…

2026/10/9 15:20:56 阅读更多 →

最新新闻

Python 光伏功率预测系统实战:从数据对齐到 LightGBM 建模

Python 光伏功率预测系统实战:从数据对齐到 LightGBM 建模

简介:这份资源面向高校学生与机器学习初学者,提供一套基于Python的光伏发电功率预测系统完整实现,可用于毕业设计、课程结业作业及专题研究等场景。包内共20个文件,以csv训练与测试数据集、py程序脚本为主,另含ipynb交…

2026/10/9 17:08:44 阅读更多 →
GFPGAN老照片修复实战:人脸先验生成与Python落地指南

GFPGAN老照片修复实战:人脸先验生成与Python落地指南

简介:这是一套基于GFPGAN算法的老照片修复Python设计源码,面向图像处理开发者与老照片修复爱好者,用于解决旧照片模糊、噪点、人脸细节失真等问题,通过深度学习模型对人脸先验进行引导,提升修复后的清晰度与真实感。源…

2026/10/9 17:08:44 阅读更多 →
PB远程连接SQL Server:动态IP下的配置与排查全指南

PB远程连接SQL Server:动态IP下的配置与排查全指南

简介:面向使用PowerBuilder的开发者,这份资源包聚焦客户端远程访问SQL Server数据库时因公网IP动态变化导致的连接中断问题,适用于外网、异地等网络环境。内容完整涵盖数据访问接口配置、动态域名解析、数据库远程连接启用、防火墙端口放行、…

2026/10/9 17:08:44 阅读更多 →
Dynamo节点包从安装到排错:结构、部署、验证与实战全解析

Dynamo节点包从安装到排错:结构、部署、验证与实战全解析

简介:面向建筑、工程与设计领域Dynamo用户的定制节点包,内含一批预封装节点,用于扩展Dynamo原生功能,覆盖几何建模、数据处理、参数化设计等常见场景,帮助非程序员通过拖拽连线完成自动化与复杂计算。压缩包采用rar格式…

2026/10/9 17:08:43 阅读更多 →
OpenSCA开源组件分析工具:离线精准扫描与SBOM合规实践

OpenSCA开源组件分析工具:离线精准扫描与SBOM合规实践

简介:本资源为OpenSCA开源软件成分分析工具(CLI版)的完整源码包,面向中高级程序开发者、安全工程师及DevSecOps实践者,用于在项目开发与CI/CD流程中自动化识别第三方组件、检测已知漏洞(如CVE)、…

2026/10/9 17:08:42 阅读更多 →
每个注册用户都有自已的二级域名:泛解析+IIS URL重写+Session 共享的落地配置

每个注册用户都有自已的二级域名:泛解析+IIS URL重写+Session 共享的落地配置

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

2026/10/9 17:07:40 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/9 6:17:20 阅读更多 →