Python神经网络赛车游戏实战:从零搭建到训练避坑
简介这份资源面向神经网络与强化学习入门者以及希望用Python动手实践AI控制游戏的开发者核心是用两种方式实现神经网络操纵赛车游戏一是基于TensorFlow框架搭建训练模型二是不依赖框架、从零手写DNN帮助读者理解前向传播、激活函数与模型训练流程。包内共54个文件以16个py源码为主辅以pyc编译文件、txt说明、xml工程配置、png素材图与wmv演示视频还包含checkpoint、index、meta等模型权重文件压缩包约8.9MB目录按游戏逻辑、AI逻辑、素材与模型数据分模块组织结构清晰。目前已有2062人学习下载。读者可获取完整可运行的赛车游戏工程、两套神经网络实现代码、训练与测试脚本、地图与车辆素材以及人机对战和人工操作的录屏便于对照调试、复现训练过程并迁移到自己的小游戏项目中。1. 用 Python 从零搭一个能开赛车游戏的神经网络先搞清楚它到底在学什么很多人第一次听到「用 Python 自己实现神经网络操纵赛车游戏」脑子里浮现的是自动驾驶那种复杂系统觉得门槛高得离谱。其实拆开看这件事的本质非常朴素游戏画面是一堆像素键盘操作是几个离散动作神经网络要做的就是学会「看到什么样的画面该按哪个键」。它不关心物理引擎怎么算轮胎摩擦力也不关心赛道怎么建模它只做一件事——把输入映射成输出。这跟前馈神经网络做人脸识别图像到高维向量的过程在结构上是一回事只不过输出从「这是谁」变成了「往左还是往右」。这个方向适合两类人一类是刚学完 BP 神经网络反向传播推导、想找个能跑起来的东西练手的另一类是写过一些 Python 脚本、想理解「神经网络到底怎么跟真实程序交互」的。你不需要 GPU 集群一台普通笔记本就够因为我们要操纵的不是 3A 大作而是一个轻量级的 2D 赛车环境。核心难点不在网络多大而在「怎么把游戏画面喂进去、怎么把网络输出变成按键、怎么让它自己变强」这条链路上。下面按这条链路一层层拆。2. 环境选型与游戏接口为什么我不建议一上来就接真实游戏2.1 用 Gymnasium 的 CarRacing 还是自己写一个简化赛道直接接《极品飞车》这类真实游戏第一道坎是画面抓取和按键模拟Windows 上要用 win32api 或 pydirectinputLinux 上要折腾 X11 或虚拟显示光是让游戏窗口稳定接收模拟按键就能耗掉你两天。更麻烦的是真实游戏一帧渲染几十毫秒你采集一万条样本要跑几个小时调试周期长得让人崩溃。所以常见做法是先用 Gymnasium 自带的 CarRacing-v2 环境它本身就是为强化学习设计的画面是 96x96 的俯视赛道动作空间是连续的转向、油门、刹车三维向量。但如果你只是想验证「神经网络能不能学会开车」这个命题CarRacing 的连续动作空间反而增加了难度因为你要处理回归问题而不是分类问题。我一般会建议先自己写一个极简的 2D 赛道环境用 pygame 画几条弯道车只有左转、右转、直行三个动作碰撞边界就重置。这样输入是低分辨率灰度图输出是三分类整个链路清晰可控。等你把这套跑通了再换成 CarRacing 或真实游戏只是替换环境接口的事。下面是一个最小环境的骨架代码重点看它怎么把状态表示成图像、怎么接收动作。import pygame import numpy as np class SimpleRaceEnv: def __init__(self, width200, height200): pygame.init() self.screen pygame.display.set_mode((width, height)) self.width width self.height height self.clock pygame.time.Clock() self.reset() def reset(self): # 车初始位置在底部中间朝向正上方 self.car_x self.width // 2 self.car_y self.height - 30 self.angle 0 # 0 表示朝上正数右转 self.done False return self._get_observation() def _get_observation(self): # 把当前画面转成灰度数组作为网络输入 surface pygame.Surface((self.width, self.height)) surface.fill((0, 0, 0)) # 画赛道边界简化成两条曲线这里用矩形代替 pygame.draw.rect(surface, (255, 255, 255), (20, 0, 10, self.height)) pygame.draw.rect(surface, (255, 255, 255), (self.width-30, 0, 10, self.height)) # 画车 pygame.draw.circle(surface, (0, 255, 0), (int(self.car_x), int(self.car_y)), 5) # 转成 numpy 数组并归一化 obs pygame.surfarray.array3d(surface).mean(axis2) / 255.0 return obs.T # 转置成 (height, width) def step(self, action): # action: 0 左转, 1 直行, 2 右转 if action 0: self.angle - 5 elif action 2: self.angle 5 # 根据角度更新位置简化处理只改变 x 坐标 self.car_x np.sin(np.radians(self.angle)) * 3 self.car_y - np.cos(np.radians(self.angle)) * 3 # 碰撞检测 if self.car_x 25 or self.car_x self.width - 25 or self.car_y 0: self.done True reward 1.0 if not self.done else -1.0 return self._get_observation(), reward, self.done, {}这段代码里_get_observation返回的是(height, width)的二维数组值在 0 到 1 之间这就是神经网络的输入。step接收一个整数动作更新车的位置返回下一帧观测、奖励和是否结束。参数上width和height设成 200 是为了让全连接网络也能处理如果你要用卷积神经网络可以设成 96 或 84跟 CarRacing 保持一致。angle每次变化 5 度、速度固定 3 像素这些数值决定了游戏的难度调大了车会瞬间冲出赛道调小了学起来太慢建议先用这个值跑通再微调。2.2 动作空间设计离散三分类比连续回归更适合入门为什么强调用离散动作因为分类问题的损失函数是交叉熵输出层用 softmax梯度性质好网络容易收敛。连续动作空间你要预测转向角度的具体数值损失函数用均方误差网络输出稍微偏一点车就撞墙训练信号非常稀疏。我见过不少人卡在 CarRacing 的连续控制上跑了十几个小时奖励还是负的换成离散动作后两小时就能稳定跑完一圈。所以如果你目标是「先跑通」离散三分类是性价比最高的选择。等你有经验了再上连续控制或混合动作空间那是后话。3. 网络结构怎么定全连接、CNN 还是 LSTM3.1 输入维度与第一层设计把图像展平还是保留空间结构假设你的观测是 200x200 的灰度图展平后是 40000 维向量。如果直接接全连接层第一层权重矩阵就是 40000 x 256参数量超过一千万训练慢且容易过拟合。更合理的做法是先降采样比如用 4x4 的池化把 200x200 降到 50x50再展平是 2500 维接一个 256 维的全连接层参数量降到 64 万可接受。但更好的方式是直接用卷积神经网络因为图像的空间结构对判断赛道边界至关重要全连接层展平后丢失了「相邻像素属于同一条边」这个信息。下面是一个轻量 CNN 的定义输入是单通道灰度图输出三个动作的概率。import torch import torch.nn as nn class RaceCNN(nn.Module): def __init__(self, input_h200, input_w200, n_actions3): super().__init__() self.conv nn.Sequential( nn.Conv2d(1, 16, kernel_size5, stride2, padding2), # 200x200 - 100x100 nn.ReLU(), nn.MaxPool2d(2), # 100x100 - 50x50 nn.Conv2d(16, 32, kernel_size3, stride2, padding1), # 50x50 - 25x25 nn.ReLU(), nn.MaxPool2d(2), # 25x25 - 12x12 nn.Conv2d(32, 64, kernel_size3, stride1, padding1), # 12x12 - 12x12 nn.ReLU(), ) self.fc nn.Sequential( nn.Linear(64 * 12 * 12, 256), nn.ReLU(), nn.Linear(256, n_actions) ) def forward(self, x): # x shape: (batch, 1, H, W) x self.conv(x) x x.view(x.size(0), -1) return self.fc(x)这里卷积层的通道数从 16 到 32 到 64是常见的递增模式目的是让网络先学局部边缘再学全局形状。kernel_size5, stride2的第一层把 200x200 快速降到 100x100减少计算量。最后的全连接层输入维度是 6412129216输出 3 个动作的 logits。参数上如果你显存紧张可以把第一层通道数降到 8或者把输入分辨率降到 96x96。注意forward里没有加 softmax因为训练时用CrossEntropyLoss内部会做推理时再手动加。3.2 要不要加 LSTM时序信息对赛车游戏到底有没有用赛车游戏里单帧画面往往不足以判断该往哪转比如车在直道上左右都是赛道只看一帧你不知道前方是左弯还是右弯。这时候循环神经网络就能派上用场它能把过去几帧的信息压缩到隐藏状态里。LSTM 是常见选择因为它能记住较长的依赖。但加了 LSTM 后训练复杂度上升你需要处理序列采样和截断反向传播。我的经验是如果你的赛道弯道比较缓CNN 看单帧加上足够的感受野就能应付如果弯道很急或者有连续 S 弯LSTM 带来的提升很明显。一个折中方案是用帧堆叠把最近 4 帧灰度图在通道维度拼起来输入变成 4 通道这样 CNN 也能感知短时时序实现比 LSTM 简单得多。class FrameStack: def __init__(self, k4): self.k k self.frames [] def reset(self, obs): self.frames [obs] * self.k return np.stack(self.frames, axis0) # shape: (k, H, W) def step(self, obs): self.frames.pop(0) self.frames.append(obs) return np.stack(self.frames, axis0)这个FrameStack类把最近 4 帧堆叠成(4, H, W)的数组送进网络时把输入通道改成 4 即可。参数k4是 Atari 游戏里的经典值赛车游戏也可以沿用。如果你发现车在弯道里反应迟钝可以试着加到 6 或 8但计算量会线性增长。4. 训练闭环怎么让网络自己学会开车4.1 用行为克隆先跑通采集人类操作数据做监督学习最稳的起步方式不是直接上强化学习而是行为克隆。你先手动玩几十局把每一帧画面和对应的按键存下来然后用监督学习训练网络模仿你的操作。这样损失函数明确训练过程稳定一两个小时就能看到车能沿着赛道走。采集数据时要注意平衡左转、直行、右转的样本数量尽量接近否则网络会偏向预测多数类。下面是一个采集和训练的简化流程。# 采集数据 observations [] actions [] env SimpleRaceEnv() obs env.reset() for _ in range(5000): env.screen.fill((0, 0, 0)) env._get_observation() # 刷新画面 pygame.display.flip() action None for event in pygame.event.get(): if event.type pygame.KEYDOWN: if event.key pygame.K_LEFT: action 0 elif event.key pygame.K_RIGHT: action 2 elif event.key pygame.K_UP: action 1 if action is None: action 1 # 默认直行 observations.append(obs) actions.append(action) obs, _, done, _ env.step(action) if done: obs env.reset() env.clock.tick(30) # 训练 import torch.optim as optim from torch.utils.data import TensorDataset, DataLoader X torch.tensor(np.array(observations), dtypetorch.float32).unsqueeze(1) # (N,1,H,W) y torch.tensor(actions, dtypetorch.long) dataset TensorDataset(X, y) loader DataLoader(dataset, batch_size32, shuffleTrue) model RaceCNN(input_h200, input_w200, n_actions3) optimizer optim.Adam(model.parameters(), lr1e-3) criterion nn.CrossEntropyLoss() for epoch in range(20): total_loss 0 for batch_x, batch_y in loader: optimizer.zero_grad() logits model(batch_x) loss criterion(logits, batch_y) loss.backward() optimizer.step() total_loss loss.item() print(fepoch {epoch}, loss {total_loss/len(loader):.4f})采集部分用 pygame 的事件循环读取键盘把每一帧的观测和动作存进列表。训练部分用 Adam 优化器学习率 1e-3批量大小 32跑 20 个 epoch。注意X要unsqueeze(1)加一个通道维度因为 CNN 期望输入是(N, C, H, W)。如果你的数据里直行样本远多于转弯可以在损失函数里加类别权重或者对转弯样本过采样。4.2 从行为克隆到强化学习用奖励信号微调策略行为克隆的局限在于它只能模仿你你开得不好它也学不好而且遇到你没见过的场景它会懵。这时候可以接一个简单的策略梯度方法比如 REINFORCE 或 A2C用游戏给的奖励信号继续优化。奖励设计很关键撞墙给 -1每存活一帧给 0.1跑完一圈给 10。这样网络会倾向于活得久、跑得远。下面是一个 REINFORCE 的核心循环假设你已经有了一个预训练的行为克隆模型。def reinforce(env, model, optimizer, episodes1000, gamma0.99): for ep in range(episodes): obs env.reset() log_probs [] rewards [] done False while not done: obs_tensor torch.tensor(obs, dtypetorch.float32).unsqueeze(0).unsqueeze(0) logits model(obs_tensor) probs torch.softmax(logits, dim-1) action torch.multinomial(probs, 1).item() log_probs.append(torch.log(probs[0, action])) obs, reward, done, _ env.step(action) rewards.append(reward) # 计算折扣回报 returns [] G 0 for r in reversed(rewards): G r gamma * G returns.insert(0, G) returns torch.tensor(returns) returns (returns - returns.mean()) / (returns.std() 1e-8) loss 0 for log_prob, G in zip(log_probs, returns): loss - log_prob * G optimizer.zero_grad() loss.backward() optimizer.step()这里gamma0.99是折扣因子越接近 1 表示越看重长期回报。returns做标准化是为了降低方差让训练更稳。注意 REINFORCE 的方差很大通常要跑几千局才能看到明显提升所以建议先用行为克隆初始化再用 REINFORCE 微调这样起步快很多。5. 避坑与排查那些让我熬夜的翻车现场5.1 现象损失降到 0.3 就不动了车一直在原地打转原因通常是学习率太大网络在最优解附近震荡或者数据里直行样本太多网络学会了「一直直行」这个偷懒策略。解决方法是把学习率降到 1e-4同时在损失函数里给转弯类别加权重权重可以设成直行的 3 到 5 倍。另外检查一下观测归一化如果像素值没除以 255输入范围在 0 到 255 之间梯度会爆炸。5.2 现象训练时奖励很高一测试就撞墙这是典型的过拟合。你的网络记住了训练赛道的具体像素布局换一条赛道就失效。解决办法是数据增强比如对观测做随机平移、旋转、加噪声或者干脆多采集几条不同赛道的 safety 数据。另一个原因是训练和测试的帧率不一致训练时 30fps测试时 60fps车的行为会完全不同。确保两边用同一个clock.tick值。5.3 现象显存不够batch size 降到 8 还是 OOM检查你的输入分辨率200x200 的单通道图在 CNN 里经过几层后特征图仍然很大。把输入降到 96x96或者把第一层卷积的 stride 改成 3能大幅减少显存。另外 PyTorch 默认会缓存梯度可以在训练循环里加torch.cuda.empty_cache()但根本办法还是减小模型。如果实在不行用梯度累积batch size 设 4累积 8 次再更新效果接近 batch size 32。5.4 现象车在直道上左右抖动像喝醉了一样这是动作平滑度不够。网络每一帧独立预测相邻帧的动作可能相反。解决办法是加一个动作平滑滤波器比如最近 3 帧的动作投票或者用 LSTM 让网络自己学平滑。更简单的做法是在奖励里加一个惩罚项动作变化时给一个小负奖励比如 -0.01这样网络会倾向于保持动作连贯。5.5 现象训练了几千局奖励还是负的完全没进步先检查奖励函数是不是太稀疏如果只有撞墙才给 -1其他时候都是 0网络很难学到东西。改成每帧给 0.1 的存活奖励撞墙给 -1跑完一圈给 10。然后检查动作空间如果动作是连续的试试离散化。最后检查网络输出用torch.softmax看看三个动作的概率是不是差不多如果是说明网络没学到东西可能需要更大的网络或更多的数据。6. 进阶技巧用课程学习和帧预测让训练快一倍当你跑通基础版本后可以试试课程学习。先在一个没有弯道的直道赛道上训练等网络能稳定直行后再换成缓弯赛道最后换成急弯赛道。这样网络从简单任务开始逐步适应复杂场景训练效率比直接上最难赛道高很多。实现上就是准备多个环境每个环境有不同的弯道曲率当当前环境的平均奖励超过阈值时切换到下一个。另一个技巧是加一个辅助任务让网络在预测动作的同时也预测下一帧的观测。这个辅助损失会迫使网络学习画面的动态变化相当于自监督学习。具体做法是在网络里加一个解码器分支把中间特征图上采样回原图大小用均方误差计算预测帧和真实帧的差异然后把这个损失乘以一个系数加到主损失上。系数一般设 0.1 到 0.5太大会干扰动作预测。class RaceCNNWithAux(nn.Module): def __init__(self, input_h200, input_w200, n_actions3): super().__init__() self.conv nn.Sequential( nn.Conv2d(1, 16, 5, stride2, padding2), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(16, 32, 3, stride2, padding1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(32, 64, 3, stride1, padding1), nn.ReLU(), ) self.fc_action nn.Sequential( nn.Linear(64 * 12 * 12, 256), nn.ReLU(), nn.Linear(256, n_actions) ) # 辅助解码器把特征图上采样回原图 self.decoder nn.Sequential( nn.ConvTranspose2d(64, 32, 3, stride2, padding1, output_padding1), nn.ReLU(), nn.ConvTranspose2d(32, 16, 3, stride2, padding1, output_padding1), nn.ReLU(), nn.ConvTranspose2d(16, 1, 3, stride2, padding1, output_padding1), nn.Sigmoid() ) def forward(self, x): features self.conv(x) action_logits self.fc_action(features.view(features.size(0), -1)) reconstructed self.decoder(features) return action_logits, reconstructed训练时把reconstructed和真实下一帧做 MSE系数设 0.2。这个辅助任务在数据少的时候特别有用相当于让网络从画面本身挖掘更多信息。我实测在 5000 条样本的情况下加了辅助任务后收敛速度快了将近一倍最终奖励也更高。最后说一个我自己的习惯每次改完网络结构或奖励函数先跑 100 局看趋势不要一上来就几千局。如果 100 局内奖励没有上升趋势大概率是超参或数据有问题早点回头比硬跑省时间。这个方向入门不难难的是耐心调参和观察现象希望帮到你。本文还有配套的精品资源点击获取

相关新闻

基于Python的虚假新闻检测多模态识别:源代码与文档说明

基于Python的虚假新闻检测多模态识别:源代码与文档说明

简介:这份资源面向计算机相关专业的本科生与研究生,提供一套基于Python的虚假新闻检测多模态识别完整项目源码,可用于毕业设计、期末大作业或课程设计场景,帮助解决多模态特征融合与虚假新闻分类的实践难题。压缩包共39个文件&…

2026/10/10 14:31:25 阅读更多 →
Python金融大数据风控建模实战:机器学习评分卡与树模型全流程

Python金融大数据风控建模实战:机器学习评分卡与树模型全流程

简介:这份资源面向金融风控方向的学生与开发者,提供一套基于机器学习的Python大数据风控建模完整项目,可直接用于毕业设计、期末大作业或课程设计。项目围绕信贷违约预测等典型风控场景展开,涵盖数据清洗、特征工程、模型训练与评…

2026/10/10 14:31:25 阅读更多 →
保单OCR工程实践:PDF/扫描件/纸质拍照三种输入下的字段结构化方案

保单OCR工程实践:PDF/扫描件/纸质拍照三种输入下的字段结构化方案

保单识别在工程上比发票难,主要难在输入不收敛。同一类业务单证,你会同时收到三种东西: 原生PDF——有文本层,但字段排版是"视觉排版",不是结构化的;扫描版PDF——整页是一张图,必须走…

2026/10/10 14:31:25 阅读更多 →

最新新闻

Java八种基本类型全解析:从内存布局到线上避坑实战

Java八种基本类型全解析:从内存布局到线上避坑实战

Java的八种基本类型,这个话题放在互联网上一搜一大把,但相信我,很多人在第一年学完就忘得干干净净。我自己带过几个人,面试时问int占几个字节,有人能回答上来,再问int的上限是多少、为什么负数下限比正数上…

2026/10/10 20:55:38 阅读更多 →
给AI对话助手外挂长期记忆:claude-mem架构与实战

给AI对话助手外挂长期记忆:claude-mem架构与实战

claude-mem 这名字起得相当直白——mem 就是 memory,把这个小工具和主流通用对话助手(下文就统一叫“模型助手”吧)放在一起,它的定位立刻清晰:给没有长期记忆的对话系统补上一块“外挂记忆”。我自己长期重度使用这类…

2026/10/10 20:55:38 阅读更多 →
微信点餐小程序毕设:SSM+MySQL全栈实战指南

微信点餐小程序毕设:SSM+MySQL全栈实战指南

简介:这是一套面向计算机专业本科生的微信点餐小程序毕业设计全栈开发资源,适用于课程设计、毕设选题与Java小程序技术栈综合实践。项目采用微信小程序前端(WXML/WXSS/JS) SSM(SpringSpringMVCMyBatis)后端…

2026/10/10 20:55:38 阅读更多 →
AnyPS5技术解析:PS5硬件约束下的跨运行时抽象实践

AnyPS5技术解析:PS5硬件约束下的跨运行时抽象实践

项目标题:“AnyPS5”这个名称本身带有强烈的指向性与模糊性并存的特征——它既像一个技术代号,又像一句口号;既暗示兼容性、泛用性(“Any”),又锚定在特定硬件生态(“PS5”)。但必须…

2026/10/10 20:55:38 阅读更多 →
Java Web动漫之家系统实战:从设计到部署避坑指南

Java Web动漫之家系统实战:从设计到部署避坑指南

简介:Java动漫之家系统设计与实现是一套面向动漫爱好者在线互动平台的完整开发设计方案,适用于JavaWeb课程设计、毕业设计或快速搭建动漫资源社区的项目预研。该方案以SSM框架为核心,结合MySQL数据存储与HTML5前端交互,从系统背景…

2026/10/10 20:55:38 阅读更多 →
免费开源 vs 截图 API 月入 2000 美金:独立开发的两条变现路线

免费开源 vs 截图 API 月入 2000 美金:独立开发的两条变现路线

免费开源 vs 截图 API 月入 2000 美金:独立开发的两条变现路线 【免费下载链接】tendedero Screenshots, hung out to dry. A tiny native macOS app that hangs every screenshot on a line at the top of your screen. 项目地址: https://gitcode.com/gh_mirror…

2026/10/10 20:54:37 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

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/10 11:14:25 阅读更多 →
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/10 1:36:08 阅读更多 →
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/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →