【Bug已解决】How to iterate over two dataloaders simultaneously using pytorch? 解决方案
【Bug已解决】How to iterate over two dataloaders simultaneously using pytorch? 解决方案问题描述在 PyTorch 深度学习开发中DataLoader是数据加载的核心工具。很多场景下开发者需要同时迭代两个 DataLoader——例如训练同时使用有标签数据和无标签数据半监督学习同时迭代图像数据集和对应的文本数据集多模态学习使用源域和目标域数据集域适应同时迭代训练集和验证集进行对比使用生成器和判别器的不同数据源GAN 变体融合两个不同来源的数据进行联合训练然而PyTorch 的DataLoader没有内置的同时迭代功能。直接使用两个for循环嵌套会导致一个数据集迭代完后另一个还在进行或者需要手动管理迭代器状态代码复杂且容易出错。具体问题表现为两个 DataLoader 长度不同短的迭代完后长的还有剩余数据需要在同一个训练步骤中同时获取两个 DataLoader 的 batch希望循环到较短 DataLoader 的长度或循环到较长 DataLoader 的长度需要交替或交错迭代两个 DataLoader使用zip时数据量被截断为较短的那个错误复现场景一使用 zip 导致数据截断import torch from torch.utils.data import DataLoader, TensorDataset # 创建两个不同长度的数据集 dataset1 TensorDataset(torch.arange(100), torch.arange(100)) dataset2 TensorDataset(torch.arange(150), torch.arange(150)) loader1 DataLoader(dataset1, batch_size10) loader2 DataLoader(dataset2, batch_size10) # 使用 zip 同时迭代 for batch1, batch2 in zip(loader1, loader2): print(fbatch1 size: {batch1[0].size()}, batch2 size: {batch2[0].size()}) print(fTotal iterations: {min(len(loader1), len(loader2))}) # loader2 的后 5 个 batch 被丢弃了输出batch1 size: torch.Size([10]), batch2 size: torch.Size([10]) ...共 10 次迭代 Total iterations: 10问题loader2有 15 个 batch但只迭代了 10 次后 5 个 batch 被丢弃。场景二手动管理迭代器出错loader1_iter iter(loader1) loader2_iter iter(loader2) for i in range(max(len(loader1), len(loader2))): try: batch1 next(loader1_iter) except StopIteration: loader1_iter iter(loader1) # 重新开始 batch1 next(loader1_iter) try: batch2 next(loader2_iter) except StopIteration: loader2_iter iter(loader2) batch2 next(loader2_iter) # 训练代码...问题代码冗长、容易出错且重新创建迭代器会重新洗牌数据可能导致数据不一致。场景三半监督学习中的数据加载# 有标签数据少量和无标签数据大量 labeled_loader DataLoader(labeled_dataset, batch_size32, shuffleTrue) unlabeled_loader DataLoader(unlabeled_dataset, batch_size32, shuffleTrue) # 希望每个 epoch 迭代无标签数据的所有 batch # 同时从有标签数据中循环采样 for unlabeled_batch in unlabeled_loader: # 如何同时获取 labeled_batch labeled_batch ??? # 需要手动管理根因分析1. Pythonzip函数的行为Python 内置的zip函数会在最短的迭代器耗尽时停止。这意味着如果两个 DataLoader 长度不同较长 DataLoader 的剩余数据不会被处理。2. DataLoader 迭代器的生命周期每次for batch in dataloader循环都会创建一个新的迭代器。迭代器在StopIteration后不能复用需要重新创建。重新创建迭代器会重新执行数据加载流程包括洗牌这可能导致行为不一致。3. DataLoader 的__len__方法DataLoader 的__len__返回的是 batch 数量ceil(dataset_size / batch_size)。两个不同大小的数据集会有不同的 batch 数量。4. 多进程数据加载的复杂性当num_workers 0时DataLoader 使用多进程加载数据。重新创建迭代器会重新启动 worker 进程开销较大。循环使用已有迭代器的数据更高效。5. 缺乏内置的循环迭代器PyTorch 没有提供类似itertools.cycle的内置循环 DataLoader 功能。开发者需要自己实现。解决方案方案一使用itertools.cycle循环较短的 DataLoaderimport torch from torch.utils.data import DataLoader, TensorDataset from itertools import cycle # 创建两个不同长度的数据集 dataset1 TensorDataset(torch.arange(100), torch.arange(100)) dataset2 TensorDataset(torch.arange(150), torch.arange(150)) loader1 DataLoader(dataset1, batch_size10, shuffleTrue) loader2 DataLoader(dataset2, batch_size10, shuffleTrue) # 使用 cycle 循环较短的 loader # 以较长的 loader 为主循环 if len(loader1) len(loader2): main_loader loader1 cycled_loader cycle(loader2) else: main_loader loader2 cycled_loader cycle(loader1) for batch_main, batch_cycled in zip(main_loader, cycled_loader): print(fMain batch: {batch_main[0][:3]}, Cycled batch: {batch_cycled[0][:3]}) print(fTotal iterations: {len(main_loader)})注意itertools.cycle会将整个迭代器缓存在内存中。对于大型 DataLoader这可能导致内存问题。此外cycle在多进程 DataLoader 上可能行为异常。方案二自定义cycle实现避免内存问题import torch from torch.utils.data import DataLoader, TensorDataset def safe_cycle(iterable): 安全的循环迭代器不缓存所有数据 while True: for item in iterable: yield item # 使用安全循环 loader1 DataLoader(dataset1, batch_size10, shuffleTrue) loader2 DataLoader(dataset2, batch_size10, shuffleTrue) main_loader loader1 if len(loader1) len(loader2) else loader2 cycled_loader safe_cycle(loader2 if len(loader1) len(loader2) else loader1) for batch_main, batch_cycled in zip(main_loader, cycled_loader): # 训练代码 pass方案三自定义ZipDataLoader类import torch from torch.utils.data import DataLoader from itertools import cycle class ZipDataLoader: 同时迭代多个 DataLoader 的包装器 def __init__(self, *loaders, modemax): Args: *loaders: 多个 DataLoader mode: max - 迭代到最长的 DataLoader 结束 min - 迭代到最短的 DataLoader 结束 self.loaders loaders self.mode mode self.lengths [len(loader) for loader in loaders] if mode max: self.length max(self.lengths) elif mode min: self.length min(self.lengths) else: raise ValueError(fUnknown mode: {mode}) def __len__(self): return self.length def __iter__(self): if self.mode min: # 简单 zip到最短的结束 for batches in zip(*self.loaders): yield batches else: # max 模式循环较短的 DataLoader iters [iter(loader) for loader in self.loaders] for i in range(self.length): batches [] for j, it in enumerate(iters): try: batch next(it) except StopIteration: # 重新创建迭代器 iters[j] iter(self.loaders[j]) batch next(iters[j]) batches.append(batch) yield tuple(batches) # 使用示例 loader1 DataLoader(dataset1, batch_size10, shuffleTrue) loader2 DataLoader(dataset2, batch_size10, shuffleTrue) # 迭代到最长的结束 zip_loader ZipDataLoader(loader1, loader2, modemax) for batch1, batch2 in zip_loader: print(fBatch1: {batch1[0].shape}, Batch2: {batch2[0].shape}) print(fTotal: {len(zip_loader)})方案四使用ConcatDataset或ChainDataset合并数据集如果两个数据集的结构相同可以在 DataLoader 之前合并数据集from torch.utils.data import ConcatDataset, DataLoader # 合并数据集 combined_dataset ConcatDataset([dataset1, dataset2]) combined_loader DataLoader(combined_dataset, batch_size10, shuffleTrue) for batch in combined_loader: # batch 包含来自两个数据集的混合数据 pass完整修复代码以下是一个完整的、生产可用的多 DataLoader 同时迭代方案 多 DataLoader 同时迭代的完整实现 支持多种模式max循环到最长、min截断到最短、interleaved交替 import torch from torch.utils.data import DataLoader, TensorDataset, Dataset from typing import Iterator, Tuple, List, Any import itertools class MultiDataLoader: 同时迭代多个 DataLoader 的通用包装器 模式: - max: 迭代到最长的 DataLoader 结束较短的循环 - min: 迭代到最短的 DataLoader 结束 - interleaved: 交替产生各 DataLoader 的 batch def __init__(self, *loaders: DataLoader, mode: str max): assert len(loaders) 2, 至少需要两个 DataLoader assert mode in (max, min, interleaved), \ f未知模式: {mode}支持: max, min, interleaved self.loaders loaders self.mode mode self.lengths [len(l) for l in loaders] if mode max: self._length max(self.lengths) elif mode min: self._length min(self.lengths) else: # interleaved self._length sum(self.lengths) def __len__(self) - int: return self._length def __iter__(self) - Iterator[Tuple[Any, ...]]: if self.mode min: yield from self._iter_min() elif self.mode max: yield from self._iter_max() else: yield from self._iter_interleaved() def _iter_min(self) - Iterator[Tuple[Any, ...]]: 迭代到最短的 DataLoader 结束 for batches in zip(*self.loaders): yield batches def _iter_max(self) - Iterator[Tuple[Any, ...]]: 迭代到最长的 DataLoader 结束较短的循环 iters [iter(loader) for loader in self.loaders] for _ in range(self._length): batches [] for j, it in enumerate(iters): try: batch next(it) except StopIteration: # 重新创建迭代器会重新洗牌 iters[j] iter(self.loaders[j]) batch next(iters[j]) batches.append(batch) yield tuple(batches) def _iter_interleaved(self) - Iterator[Tuple[Any, ...]]: 交替产生各 DataLoader 的 batch iters [iter(loader) for loader in self.loaders] active list(range(len(iters))) while active: new_active [] for j in active: try: batch next(iters[j]) yield (j, batch) # 返回 (loader_index, batch) new_active.append(j) except StopIteration: pass # 该 DataLoader 已耗尽 active new_active class CyclicDataLoader: 循环 DataLoader无限产生 batch 适用于需要从短数据集持续采样的场景 def __init__(self, loader: DataLoader, max_iterations: int None): self.loader loader self.max_iterations max_iterations def __iter__(self): iteration 0 while True: for batch in self.loader: yield batch iteration 1 if self.max_iterations is not None and iteration self.max_iterations: return def __len__(self): if self.max_iterations is not None: return self.max_iterations return len(self.loader) # 使用示例 def create_sample_loaders(): 创建示例 DataLoader # 数据集1100 个样本 data1 torch.randn(100, 3, 32, 32) labels1 torch.randint(0, 10, (100,)) dataset1 TensorDataset(data1, labels1) loader1 DataLoader(dataset1, batch_size16, shuffleTrue, drop_lastFalse) # 数据集2150 个样本 data2 torch.randn(150, 3, 32, 32) labels2 torch.randint(0, 10, (150,)) dataset2 TensorDataset(data2, labels2) loader2 DataLoader(dataset2, batch_size16, shuffleTrue, drop_lastFalse) return loader1, loader2 def demo_min_mode(): 演示 min 模式 print( * 60) print(Min 模式截断到最短) print( * 60) loader1, loader2 create_sample_loaders() print(fLoader1: {len(loader1)} batches, Loader2: {len(loader2)} batches) multi_loader MultiDataLoader(loader1, loader2, modemin) print(fMultiDataLoader: {len(multi_loader)} batches) for i, (batch1, batch2) in enumerate(multi_loader): print(f Step {i}: batch1{batch1[0].shape}, batch2{batch2[0].shape}) print(fTotal steps: {i 1}) def demo_max_mode(): 演示 max 模式 print(\n * 60) print(Max 模式循环到最长) print( * 60) loader1, loader2 create_sample_loaders() print(fLoader1: {len(loader1)} batches, Loader2: {len(loader2)} batches) multi_loader MultiDataLoader(loader1, loader2, modemax) print(fMultiDataLoader: {len(multi_loader)} batches) for i, (batch1, batch2) in enumerate(multi_loader): if i 3 or i len(multi_loader) - 2: print(f Step {i}: batch1{batch1[0].shape}, batch2{batch2[0].shape}) elif i 3: print(f ... (省略中间步骤)) print(fTotal steps: {i 1}) def demo_interleaved_mode(): 演示交替模式 print(\n * 60) print(Interleaved 模式交替产生) print( * 60) loader1, loader2 create_sample_loaders() multi_loader MultiDataLoader(loader1, loader2, modeinterleaved) print(fMultiDataLoader: {len(multi_loader)} total batches) counts {0: 0, 1: 0} for loader_idx, batch in multi_loader: counts[loader_idx] 1 if sum(counts.values()) 5 or sum(counts.values()) len(multi_loader) - 1: print(f Loader {loader_idx}: batch shape{batch[0].shape}) print(fLoader1 produced: {counts[0]} batches) print(fLoader2 produced: {counts[1]} batches) def demo_semi_supervised_training(): 演示半监督学习场景 print(\n * 60) print(半监督学习场景演示) print( * 60) # 有标签数据少量 labeled_data torch.randn(200, 3, 32, 32) labeled_labels torch.randint(0, 10, (200,)) labeled_dataset TensorDataset(labeled_data, labeled_labels) labeled_loader DataLoader(labeled_dataset, batch_size32, shuffleTrue) # 无标签数据大量 unlabeled_data torch.randn(2000, 3, 32, 32) unlabeled_dataset TensorDataset(unlabeled_data, torch.zeros(2000)) # 伪标签 unlabeled_loader DataLoader(unlabeled_dataset, batch_size32, shuffleTrue) print(f有标签: {len(labeled_loader)} batches, 无标签: {len(unlabeled_loader)} batches) # 使用 max 模式有标签数据循环使用 multi_loader MultiDataLoader(labeled_loader, unlabeled_loader, modemax) print(f训练步数: {len(multi_loader)}) # 模拟训练循环 for step, (labeled_batch, unlabeled_batch) in enumerate(multi_loader): labeled_x, labeled_y labeled_batch unlabeled_x, _ unlabeled_batch if step 3 or step len(multi_loader) - 1: print(f Step {step}: labeled{labeled_x.shape}, unlabeled{unlabeled_x.shape}) elif step 3: print(f ... (训练进行中)) print(f训练完成共 {step 1} 步) def demo_cyclic_loader(): 演示循环 DataLoader print(\n * 60) print(CyclicDataLoader 演示) print( * 60) dataset TensorDataset(torch.arange(20), torch.arange(20)) loader DataLoader(dataset, batch_size4, shuffleFalse) # 循环 10 次原始只有 5 个 batch cyclic CyclicDataLoader(loader, max_iterations10) for i, batch in enumerate(cyclic): print(f Iteration {i}: {batch[0].tolist()}) print(fTotal: {i 1} iterations (original: {len(loader)} batches)) def main(): 主函数 torch.manual_seed(42) demo_min_mode() demo_max_mode() demo_interleaved_mode() demo_semi_supervised_training() demo_cyclic_loader() print(\n * 60) print(所有演示完成) print( * 60) if __name__ __main__: main()常见陷阱与注意事项1.itertools.cycle的内存问题itertools.cycle会将迭代器产生的所有元素缓存在内存中。对于大型 DataLoader尤其是返回大型张量的 DataLoader这可能导致内存溢出。推荐使用自定义的safe_cycle或CyclicDataLoader。2. 多进程 DataLoader 的循环问题当num_workers 0时重新创建迭代器iter(loader)会重新启动 worker 进程开销较大。在max模式下较短的 DataLoader 会被重新迭代这可能导致性能下降。解决方案使用persistent_workersTrue保持 worker 存活预先将短数据集复制到较长数据集的长度使用CyclicDataLoader避免频繁重建迭代器3. 数据洗牌的一致性在max模式下当较短的 DataLoader 被重新迭代时会重新洗牌数据。这意味着同一批数据可能在不同 epoch 中以不同顺序出现。这在某些场景下是期望的行为增加随机性但在其他场景下可能导致问题。4.drop_last的影响如果 DataLoader 设置了drop_lastTrue最后一个不完整的 batch 会被丢弃。这会影响__len__的返回值和实际迭代次数。在多 DataLoader 场景中需要确保所有 DataLoader 的drop_last设置一致。5. 不同 batch_size 的处理两个 DataLoader 可以有不同的batch_size。在同时迭代时每个步骤会产生不同大小的 batch。确保下游代码能处理不同大小的 batch。6. 交替模式的数据顺序interleaved模式下数据是交替产生的不是同时的。每个 yield 只包含一个 DataLoader 的 batch。如果需要同时处理两个 DataLoader 的数据不要使用交替模式。7. 无限循环的风险CyclicDataLoader如果不设置max_iterations会无限循环。在训练循环中必须配合 epoch 数或 step 数使用否则训练不会停止。8. 分布式训练中的兼容性在DistributedSampler场景下每个进程只看到数据的一部分。重新创建迭代器时需要调用sampler.set_epoch(epoch)确保数据洗牌正确。MultiDataLoader需要额外处理这个情况。总结同时迭代两个 DataLoader 是 PyTorch 开发中的常见需求有多种实现方式方案适用场景优点缺点zip长度相同的 DataLoader简单截断到最短itertools.cycle短数据集循环内置函数内存缓存MultiDataLoader通用场景灵活多模式需自定义CyclicDataLoader无限采样不缓存需设上限ConcatDataset合并数据集简单不适用于不同结构推荐策略如果两个 DataLoader 长度相同直接使用zip如果需要循环较短的 DataLoader使用MultiDataLoader(modemax)如果需要交替产生 batch使用MultiDataLoader(modeinterleaved)对于半监督学习等需要持续采样的场景使用CyclicDataLoader如果两个数据集结构相同考虑使用ConcatDataset合并后用单个 DataLoader通过合理选择迭代策略可以优雅地处理多数据源的同时迭代问题使训练代码更简洁、更高效。

相关新闻

一键式安装python+anaconda

一键式安装python+anaconda

装 Python 环境不用再看教程了,把这几句话发给 AI 就行 装环境这事卡在两个地方:一是步骤碎(下载、配PATH、装 Anaconda、换源、装包),二是不知道装完到底算不算成功。 现在这两个问题可以一起省掉——**把下面的提示词…

2026/10/13 16:46:33 阅读更多 →
Linux批量删除性能瓶颈与优化实战

Linux批量删除性能瓶颈与优化实战

1. 项目概述:当“删文件”变成一场系统级压力测试你有没有试过在终端里敲下rm -rf *,然后盯着光标一动不动地等?不是卡死,不是假死,就是那种——明明命令发出去了,系统却像被按了慢放键,连进度条…

2026/10/13 16:46:33 阅读更多 →
文件系统删除性能瓶颈深度解析:ext4、XFS与Btrfs对比

文件系统删除性能瓶颈深度解析:ext4、XFS与Btrfs对比

1. 项目概述:当“删除”变成一场系统级压力测试你有没有试过在终端里敲下rm -rf,然后盯着光标一动不动地等?不是卡死,是真等——等它把几万个文件逐个从磁盘上抹掉。这次不是误操作,而是一次有预谋的极限压测&#xff…

2026/10/13 16:46:33 阅读更多 →

最新新闻

高效离职面谈:四种实战方法搞定主动与被动离职

高效离职面谈:四种实战方法搞定主动与被动离职

离职面谈这事儿,说大不大,说小不小。很多业务负责人和刚入行的HR伙伴把它当成一个“过场”,员工提离职了,约个时间聊二十分钟,问问“为啥走啊”“下家去哪啊”,然后填张表就算交差了。但真正在组织里待久了…

2026/10/13 17:30:42 阅读更多 →
离职面谈怎么做?四类场景实操方法与避坑指南

离职面谈怎么做?四类场景实操方法与避坑指南

做离职面谈这些年,我最大的感触是:大多数HR和管理者根本不会谈。不是话术不行,而是脑子里只有一套模板——不管是核心骨干提离职,还是试用期员工说走就走,开口都是"为什么离职啊,有什么困难可以沟通嘛…

2026/10/13 17:30:42 阅读更多 →
ANSYS模态分析+对称边界:让汉字‘春节快乐’振动起来

ANSYS模态分析+对称边界:让汉字‘春节快乐’振动起来

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

2026/10/13 17:30:42 阅读更多 →
FPGA图像缩放与移动实战:坐标变换、DDR3带宽与调试解析

FPGA图像缩放与移动实战:坐标变换、DDR3带宽与调试解析

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

2026/10/13 17:30:42 阅读更多 →
前端面试刷题:把题库变成面试模拟器的正确方法

前端面试刷题:把题库变成面试模拟器的正确方法

简介:面向准备前端求职面试的开发者,资料包系统覆盖Html、Css、JavaScript、Vue、React、Node、TypeScript、Webpack、算法、网络与安全、浏览器等前端核心方向,既适合刚入门的新人建立知识框架,也适合有一定项目经验的开发者针对…

2026/10/13 17:30:42 阅读更多 →
PL/SQL智能补全插件实战:解决Oracle开发命名、跳转与上下文感知难题

PL/SQL智能补全插件实战:解决Oracle开发命名、跳转与上下文感知难题

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

2026/10/13 17:29:40 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →