深度学习入门:Python与NumPy手写神经网络实战解析

简介:鱼书《深度学习入门:基于Python的理论与实现》的配套代码包,面向深度学习初学者和希望从原理层面掌握神经网络实现的读者。代码按原书章节组织,覆盖第一章至第八章全部示例,包括感知机、神经网络前向反向传播、数值微分、误差反向传播、训练技巧(权重初始化、批归一化、正则化、随机失活、优化器比较)以及卷积神经网络和简单深度网络等内容,可配合理论推导边读边跑。资源共67个文件,压缩包大小约4.44MB,以59个Python脚本为主体,另含3个pkl预训练权重文件、2个Markdown说明文档和2张示例图片,结构清晰,适合本地Python环境直接运行。除源码外,还附有common公共函数模块与dataset数据加载脚本,能够再现MNIST手写数字识别、梯度检查、超参数优化等经典实验,方便边运行边对照书中的原理与图表。目前已有2534人学习,是一套系统学习深度学习原理并手动验证代码逻辑的实用工具。

1. 这份鱼书《深度学习入门》代码:用纯 Python 和 NumPy 手搓深度学习

第一次在服务器上跑鱼书《深度学习入门》的配套代码时,我一度怀疑自己下错了资源:没有加载任何现代深度学习框架,连 GPU 都不需要,前向传播、反向传播、损失函数全部写在 Python 脚本里,最终却能把 MNIST 手写数字识别准确率稳稳推到 96% 以上。这就是这份源码最值得拆解的地方——它把深度学习从“调框架 API”还原成了“你能看懂的矩阵运算”。这份代码适合两类人:一类是被各种框架封装成黑匣子之后仍然一头雾水的初学者,另一类是打算把教科书实现改造成自己实验脚手架的开发。只要你具备基础 Python 语法和 NumPy 意识,跟着这份代码走一遍,很多东西会比背十篇博客更清晰。

2. 代码结构拆解:八个章节文件夹如何串起一条训练链路

2.1 章节目录与依赖关系:ch01 到 ch08 的进阶路线

拿到资源包并解压后,第一眼看到的是八个数字开头的目录,外加 common 与 dataset 两个公共目录。ch01 讲 Python 基础,ch02 讲感知机,真正的深度学习内容从 ch03 开始:神经网络前向传播、损失函数、数值梯度、反向传播、学习技巧、卷积神经网络、深层网络。目录编号直接对应原书章节,建议阅读顺序就是文件夹的编号顺序,不要从 ch08 倒着跑。

目录对应主题关键内容
ch01Python 与 NumPy 基础数组操作、Matplotlib 画图
ch02感知机与门、或门、异或门的实现
ch03神经网络激活函数、Softmax、MNIST 推理
ch04神经网络的学习损失函数、数值微分、两层网络训练
ch05反向传播计算图、链式法则、Affine/ReLU 层
ch06学习技巧权重初始化、Batch Normalization、Dropout
ch07卷积神经网络im2col、卷积层、池化层、CNN 训练
ch08深度学习深层卷积网络、GPU 加速与数据增强

如果只是想把代码跑起来,直接看 ch03 和 ch04 就够;想完整理解训练机制,至少要把 ch04 到 ch06 连起来读。ch07、ch08 的抽象层级比前面高,依赖 common/layers.py 里的卷积和池化实现,所以不建议跳得太快。

整份代码的目录结构很清晰:

. ├── ch01/ ├── ch02/ ├── ch03/ ├── ch04/ ├── ch05/ ├── ch06/ ├── ch07/ ├── ch08/ ├── common/ │ ├── layers.py │ ├── optimizer.py │ ├── trainer.py │ ├── gradient.py │ ├── multi_layer_net.py │ └── util.py └── dataset/ ├── mnist.py └── spiral.py

common 与 dataset 是整份资源真正的核心复用层。ch03 到 ch08 里大量脚本都写了一句sys.path.append(os.pardir),目的就是让父目录下的 common 和 dataset 可以直接 import。很多初学者第一次跑挂,就是把自己写的新脚本放在资源根目录之外,又没手动加入路径。

2.2 公共模块与数据集加载:mnist.py 不只是读文件

dataset/mnist.py 提供的 load_mnist 函数可以看成整片实验森林的入口。它把 MNIST 原文件缓存成 pickle 格式,之后每次加载都直接读缓存,避免重复下载和解压。函数签名长这样:

from dataset.mnist import load_mnist (x_train, t_train), (x_test, t_test) = load_mnist( normalize=True, flatten=True, one_hot_label=False )

这里的三个参数值得仔细理解。normalize=True 会把 0 到 255 的像素值缩放到 0 到 1 之间,避免大数值输入让神经元的加权求和一下就饱和;flatten=True 会把二维图片拉成一维向量,因为全连接层输入需要是向量;one_hot_label=False 表示标签直接返回 0 到 9 的数字,训练时如果使用 SoftmaxWithLoss,则建议改成 True,让函数返回 one-hot 编码的标签向量。

参数默认值作用踩坑点
normalizeTrue像素归一化关闭后准确率会明显下降
flattenTrue图片展平卷积网络请设 False
one_hot_labelFalse标签格式与损失函数要匹配

ch03 的 neuralnet_mnist.py 只做推理,所以 one_hot_label 设为 False 没问题;但从第 4 章开始用 SoftmaxWithLoss 后,训练脚本一般会显式指定 True。如果你把模型输出维度和标签维度对不上,多半是这里没改。

2.3 公共模块不是一次性脚本:common 是全书可复用的层仓库

章节源码只是鱼书的例子,真正可复用的是 common 目录。common/layers.py 实现了 Affine、ReLU、Sigmoid、SoftmaxWithLoss、Convolution、Pooling 等类,每个类都有 forward 和 backward 方法;common/optimizer.py 实现了 SGD、Momentum、AdaGrad、Adam;common/trainer.py 则把训练循环抽成了一个小引擎,输入网络、数据、优化器和超参数即可自动训练并在指定 epoch 调用回调函数。看到这里你会发现,二次开发时优先改 common,而不是把每个章节脚本复制一遍再改。

common/optimizer.py 中的 SGD 类,本质就是把params[key] -= learning_rate * grads[key]包成了一个 update 方法。trainer.py 的 train 方法内部会调用 optimizer.update,并且把每轮 loss 和可选的 epoch 回调记录到日志里。如果你想把模型换成自己定义的网络,只要保证网络对象像 TwoLayerNet 一样暴露 params、gradient(x, t) 和 accuracy(x, t) 三个接口,trainer 就能直接驱动。所以 common 目录看起来只有几个文件,实际上承担了小框架的系统角色,这也是这份资源比普通示例代码更有二次开发价值的原因。

3. 核心算法实现:手写反向传播与两层神经网络的训练闭环

3.1 损失函数与梯度计算:数值微分的两重循环到底慢在哪

第 4 章为了解释梯度概念,先用数值微分实现梯度计算。它的原理是中心差分公式:对每个参数取极小增量,分别求正向和负向的函数值,然后近似导数。核心代码只有十行:

def numerical_gradient(f, x): h = 1e-4 # 避免过小导致舍入误差 grad = np.zeros_like(x) for idx in range(x.size): tmp_val = x[idx] x[idx] = tmp_val + h fxh1 = f(x) x[idx] = tmp_val - h fxh2 = f(x) x[idx] = tmp_val grad[idx] = (fxh1 - fxh2) / (2 * h) return grad

说明一下:h 取 1e-4 而不是 1e-8,是因为浮点数精度有限,步长太小反而会让前后两次函数值之差被舍入误差吞掉。grad 数组需要逐元素循环,等于每算一个权重都要跑一遍完整的前向传播。假设第一层权重是 784×50 的矩阵,数值梯度就要循环 39200 次,即使每次只算一次前向,也会慢到让人怀疑人生。所以书中第 4 章拿数值梯度作为教学,到了第 5 章马上换成反向传播。

3.2 两层神经网络的前向与反向:一份可以直接抄的代码骨架

第 5 章里的 TwoLayerNet 很适合作为骨架。代码把网络结构拆成 OrderedDict 里的层对象,前向就是按顺序调用各层的 forward,反向就逆序调用各层的 backward。

import numpy as np from collections import OrderedDict from common.layers import Affine, Relu, SoftmaxWithLoss class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01): self.params = {} self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size) self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size) self.params['b2'] = np.zeros(output_size) self.layers = OrderedDict() self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1']) self.layers['Relu1'] = Relu() self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2']) self.lastLayer = SoftmaxWithLoss() def predict(self, x): for layer in self.layers.values(): x = layer.forward(x) return x def loss(self, x, t): y = self.predict(x) return self.lastLayer.forward(y, t) def gradient(self, x, t): # 先做一次前向,拿到损失和中间缓存 self.loss(x, t) # 反向传播 dout = 1 dout = self.lastLayer.backward(dout) layers = list(self.layers.values()) layers.reverse() for layer in layers: dout = layer.backward(dout) grads = {} grads['W1'] = self.layers['Affine1'].dW grads['b1'] = self.layers['Affine1'].db grads['W2'] = self.layers['Affine2'].dW grads['b2'] = self.layers['Affine2'].db return grads

初始化里 W 用 0.01 标准差的高斯随机数打底,b 全零。self.layers 用 OrderedDict 保证迭代顺序稳定,Affine 层内部会在 forward 时缓存输入,这样 backward 时 dW、db 才能根据缓存算出来。gradient 方法的关键点是先调用 self.loss(x, t),它顺便执行了前向链,让每个层都准备好了反向所需的中间变量;然后从 loss 层 backward 拿到 dout=1 的起始梯度,逆序遍历层列表,最终把梯度写入 grads 字典。

这里有一个很多初学者会忽略的细节:Affine 层的权重 self.params['W1'] 和层对象内部的 self.W 指向同一个数组对象。训练时你用 network.params[key] -= learning_rate * grads[key] 更新 params,实际上层对象 Affine1 里的权重也会同步更新。正因为如此,训练循环里不用重新构造网络,只要改 params 字典即可。

3.3 训练循环与超参数:把学习率从 0.1 调到 1e-4 会发生什么

有了前面的 gradient,训练循环就变得非常机械:随机采样一个 batch,算梯度,更新参数,记录损失。书里第 4 章的训练脚本核心如下:

iters_num = 10000 batch_size = 100 learning_rate = 0.1 train_size = x_train.shape[0] loss_history = [] for i in range(iters_num): batch_mask = np.random.choice(train_size, batch_size) x_batch = x_train[batch_mask] t_batch = t_train[batch_mask] grad = network.gradient(x_batch, t_batch) for key in ('W1', 'b1', 'W2', 'b2'): network.params[key] -= learning_rate * grad[key] loss = network.loss(x_batch, t_batch) loss_history.append(loss)

np.random.choice(train_size, batch_size) 会从全部样本中随机抽取 100 个索引,这样每次迭代都用小批量样本估计真实梯度,省内存又能引入随机性。学习率 0.1 是这一章示例里比较顺的值:太大,比如 1.0,会让损失在巨大步长下震荡发散;太小,比如 1e-4,则更新幅度过小,训练 10000 次后损失下降得很慢。你不妨把 learning_rate 改成 1.0 跑一次,输出损失曲线会像一把乱梳子;再改回 0.1,就正常。这种对比实验比任何理论描述都直观。

network.params[key] - learning_rate * grad[key]是手动梯度下降。后续第 6 章的 common/optimizer.py 会把这个操作抽象成 SGD、Momentum、Adam,但底层逻辑和这里没有区别。理解这个循环,是理解后面所有训练代码的关键。

4. 运行与复现:从环境搭建到命令行跑通 MNIST

4.1 环境准备:Python 版本、NumPy 和 Matplotlib 的兼容选择

这份资源不需要 pip 安装任何插件,它本身就是源码,而不是一个可安装的第三方包。运行它只需要 Python 解释器加上两个数值库。建议新建虚拟环境,避免系统 Python 被搞乱:

cd <资源根目录> python -m venv .venv source .venv/bin/activate pip install "numpy<2" matplotlib

Windows 上把 source 换成.venv\Scripts\activate。numpy 版本先约束在 1.x,主要是为了省事:老代码数量多,没必要为了追新库去排查潜在的不兼容;matplotlib 用于画损失曲线和可视化权重。如果你的环境里没有 jupyter,也不需要专门装,书里绝大多数脚本都能用python xxx.py直接运行。资源包里涉及图像处理的可选依赖只有 Pillow,但 MNIST 那几章用不到。

4.2 单文件运行验证:一条命令看梯度下降在真实数据上工作

推荐先跑 ch03 里的 MNIST 推理脚本,因为它不需要训练,加载预置权重后直接预测,输出准确率:

cd ch03 python neuralnet_mnist.py

正常输出类似Accuracy:0.9352。这个数字代表参数未经训练,只靠加载好的样例权重,已经能到 93% 左右;它验证环境和数据加载都没有问题。接下来进入真正训练:

cd ../ch04 python train_neuralnet.py

脚本会初始化两层网络,开始 10000 次迭代,并在每 100 次打印一次训练损失。首次运行时如果终端看上去“卡住”,多半是在解压 MNIST 缓存,耐心等几十秒。训练完成后控制台会打印测试准确率,大概在 0.96 附近。如果你看到的是 0.1 上下,先去检查 4.3 里的欠收敛问题。

4.3 常见问题排查与避坑指南:五个跑不起来的高频原因

  1. 现象:执行时提示No module named 'dataset'。
    原因:脚本运行时的工作目录不在资源根目录,Python 找不到 dataset 包。
    解决:在资源根目录下执行命令,不要用 IDE 的“直接运行当前文件”按钮;如果非要在子目录运行,手工加一行sys.path.append('..')。

  2. 现象:Matplotlib 弹出图片窗口后脚本卡住不动。
    原因:服务器或容器无显示环境,plt.show() 进入了阻塞状态。
    解决:把脚本中的plt.show()改成plt.savefig('output.png'),或者改用无图形后端。

  3. 现象:训练了很久准确率一直徘徊在 0.09 左右。
    原因:最常见的是学习率设得过大,参数更新后损失变成 NaN;再就是迭代次数不够,还没有发生明显收敛。
    解决:先打印 loss_history 图像,确认损失是否下降;把 learning_rate 降到 0.01 或 0.001,重新训练。

  4. 现象:第一次运行耗时极长,或反复读网络数据。
    原因:MNIST 原始数据集不在本地,代码会在首次加载时下载并缓存;网络不稳定或资源包缺少 mnist.pkl 就会卡住。
    解决:提前确认 dataset 目录下有 mnist.pkl;如果没有,手动放置已经下载好的 pkl 文件后再跑,并保证运行目录没有多套一层不受管控的目录结构。

  5. 现象:ch08 跑着跑着把内存吃满。
    原因:深层卷积网络在纯 NumPy 实现下会产生大量中间数组,batch size 设太大时内存会成倍上涨。
    解决:先用小 batch size,比如 32 或 64,验证能跑通再调大;不要一上来就复刻大 batch 训练。

5. 二次开发与改造思路:把教科书代码变成自己的实验工具箱

5.1 把数值梯度替换为反向传播:同一套接口,性能差出两个数量级

如果你已经照着第 4 章写法实现了 numerical_gradient,最直接的升级就是换成 common 里基于层的反向传播。两种梯度返回的 dict 结构几乎一致,都有 W1、b1、W2、b2 四个 key,所以训练循环主体可以完全不动:

# 第 4 章教学写法:慢,适合核对公式 grads = network.numerical_gradient(x_batch, t_batch) # 第 5 章以后写法:快,适合训练 grads = network.gradient(x_batch, t_batch) for key in network.params: network.params[key] -= learning_rate * grads[key]

切换之后我一般会加一个梯度校验函数,防止“改快了但改错了”。做法是用一个小数据批次,同时调用数值梯度和反向传播,比较两者的最大绝对误差:

def check_gradient(net, x_batch, t_batch): g_num = net.numerical_gradient(x_batch, t_batch) g_back = net.gradient(x_batch, t_batch) for key in g_num: diff = np.max(np.abs(g_num[key] - g_back[key])) print(key, diff)

如果 diff 在 1e-4 量级以内,说明反向传播实现正确;如果 diff 到了 0.1 甚至更大,通常是 Affine 层缓存写错或 ReLU 的 mask 没对上。这个检查很值得保留,后续加卷积层或自定义损失函数时,每次改完都跑一遍。

5.2 改造数据流:加入 shuffle、验证集与训练历史曲线

书里第 4 章的随机采样是np.random.choice有放回抽样,严格说不算常见的 shuffle。实际开发中我通常会把训练集拆出一部分做验证集,并记录训练损失与验证准确率,防止只盯着训练集。

def train_with_validation(net, x_train, t_train, x_test, t_test, iters_num=10000, batch_size=100, learning_rate=0.1): log = [] for i in range(iters_num): batch_mask = np.random.choice(x_train.shape[0], batch_size) x_batch = x_train[batch_mask] t_batch = t_train[batch_mask] grads = net.gradient(x_batch, t_batch) for key in net.params: net.params[key] -= learning_rate * grads[key] if i % 1000 == 0: test_acc = net.accuracy(x_test, t_test) train_acc = net.accuracy(x_train, t_train) log.append((i, train_acc, test_acc)) return log

这样改造后的日志比书里只记录训练损失更接近真实的实验习惯。每次打印三个值:迭代步数、训练准确率、测试集准确率。如果训练准确率一直上升而测试准确率停滞,就能意识到过拟合已经开始了;验证集则可以进一步用于早停。逻辑说明:accuracy 方法是书中的网络类自带的,内部把概率输出转成 argmax,再与标签逐位比较取平均值。

5.3 从单脚本到模块化:把超参数写进配置,别散落在代码里

书中的训练脚本有很多超参数直接写在 for 循环外面,比如 iters_num、batch_size、learning_rate。做二次开发时我习惯把它们收拢到一个 dict 里,避免改一个实验就得翻脚本。这种改造不依赖任何插件,用一个普通 dict 就行。

config = { "input_size": 784, "hidden_size": 50, "output_size": 10, "iters_num": 10000, "batch_size": 100, "learning_rate": 0.1, "weight_init_std": 0.01, }

训练时net = TwoLayerNet(config['input_size'], config['hidden_size'], config['output_size']),以后要跑对照组,只需复制 config 改一个字段。这个习惯看似简单,却能省掉大量“忘了上一次用的是什么参数”的麻烦。甚至可以顺手把 config 序列化成 JSON 文件,和实验曲线存到一起,回看结果时一目了然。

6. 从跑通到工程化:三个值得继续深挖的改造点

当代码从“能跑”变成“要反复用”的时候,我一般会做三件事。第一,把 gradient check 固化成独立函数,凡是新增层或改动层实现,先跑一轮,让它成为项目里的基础工具。第二,每次实验都落一份超参数日志,包括学习率、隐藏层大小、梯度法类型、数据是否归一化;不只是记在脑子里,而是写到文件名或 JSON 配置里。第三,把数据加载的 normalize、flatten、one_hot_label 参数从随意调用改成显式传入,避免不同脚本混用不同的数据格式。

实验学习率隐藏层最优测试准确率备注
基线0.1500.96书中两层网络
改造A0.011000.97增大隐藏层
改造B0.1500.95未归一化

把实验版本号写进配置,或者用一个 dict 记录每次训练的假设,都行。刚用这份代码的时候,我为了调出“更好看”的准确率,连续改了好几次隐藏层大小,却忘了记录每一轮对应的超参数。后来看到损失曲线只能猜到大概,既分不清是学习率影响还是权重初始化影响。从那以后,我每次跑新实验都强制先打印一份超参配置,再让训练循环出发,这个习惯一直留到现在。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

Qwen3.5-35B-A3B本地部署实战:vllm+Docker高效推理方案

Qwen3.5-35B-A3B本地部署实战:vllm+Docker高效推理方案

1. 项目概述与核心需求1.1 Qwen3.5-35B-A3B 是什么&#xff0c;为什么值得自己部署先说结论&#xff1a;Qwen3.5-35B-A3B 是一个 35B 总参数量的 MoE&#xff08;混合专家&#xff09;架构大语言模型&#xff0c;但每次推理只激活约 3B 参数。这类“大参数、小激活”的模型&…

2026/10/19 16:28:04 阅读更多 →
从零自研轻量级CRM系统:架构设计、数据模型与落地实践

从零自研轻量级CRM系统:架构设计、数据模型与落地实践

1. 项目概述与设计思路DeskcommCRM&#xff0c;这个项目我印象很深。它不是一个给大厂做的定制化大系统&#xff0c;而是一个自己做决策、自己搭架构、自己跑通业务闭环的轻量级客户管理平台项目。整个项目的出发点很朴素&#xff1a;公司当时用的是Excel表格加微信群管理客户&…

2026/10/19 16:27:02 阅读更多 →
open-code-review:构建开放透明的代码审查方法论与团队协作实践

open-code-review:构建开放透明的代码审查方法论与团队协作实践

1. 为什么我们需要重新审视代码审查这件事代码审查这件事&#xff0c;做了十几年&#xff0c;我最大的感受是&#xff1a;它从来不是技术问题&#xff0c;而是协作问题。很多人以为代码审查就是找bug&#xff0c;其实找bug只是副产品&#xff0c;真正的价值在于知识传递、规范对…

2026/10/19 16:27:02 阅读更多 →

最新新闻

《呆呆虫源代码阅读》前言:一份解释器学习者的源码阅读路线图

《呆呆虫源代码阅读》前言:一份解释器学习者的源码阅读路线图

有些学习项目&#xff0c;代码还没开始读&#xff0c;光是《前言》这一节就够你来回翻三遍。我说的这个项目&#xff0c;就是《呆呆虫源代码阅读》。先说清楚它是什么&#xff1a;呆呆虫是一套用Go实现的教学型脚本语言解释器&#xff0c;语法轻巧、结构清晰&#xff0c;代码库…

2026/10/19 17:02:18 阅读更多 →
Visual Studio四种命令行窗口怎么选?环境变量与编译工具链一次说清

Visual Studio四种命令行窗口怎么选?环境变量与编译工具链一次说清

装好 Visual Studio 后&#xff0c;想编译一个 C 文件&#xff0c;却在开始菜单里看到一堆长得几乎一模一样的命令行入口&#xff1a;“Developer Command Prompt”、“Developer PowerShell”、“PowerShell”、“命令提示符”&#xff0c;有的版本还会在名字后面带 x86、x64、…

2026/10/19 17:02:18 阅读更多 →
从零搭建地图数据管理平台:PostGIS+Tippecanoe+MapLibre完整实战

从零搭建地图数据管理平台:PostGIS+Tippecanoe+MapLibre完整实战

最近我在折腾一个叫atlas的项目——严格来说&#xff0c;它是一套轻量级的“自助地图集”系统。起因很简单&#xff1a;团队里每次做数据分析、业务汇报&#xff0c;总要翻来覆去找地图资源&#xff0c;有的在网盘、有的在数据库、有的干脆是隔壁同事电脑里的一个 GeoJSON 文件…

2026/10/19 17:02:18 阅读更多 →
开放式Code Review流程搭建实践:从规则设计到自动化落地

开放式Code Review流程搭建实践:从规则设计到自动化落地

从零搭建一套开放式的Code Review流程&#xff0c;我踩过的坑和沉淀下来的方案这几年带过不少团队&#xff0c;也见过很多种代码审查的做法。有的团队用GitHub的Pull Request天然流程&#xff0c;有的用Gerrit那套严格的merge前审查&#xff0c;还有的直接靠leader一个人在群里…

2026/10/19 17:02:18 阅读更多 →
open-code-review:轻量级自动化代码审查工具的设计与实践

open-code-review:轻量级自动化代码审查工具的设计与实践

1. 项目背景与核心思路代码审查这件事&#xff0c;几乎所有开发团队都在做&#xff0c;但真正做得好的没几个。不是大家不重视&#xff0c;而是传统的代码审查流程里有几个绕不开的坎&#xff1a;人工检查容易遗漏细节、评审标准不统一、新人不知道从哪里看起、跨团队协作时沟通…

2026/10/19 17:02:18 阅读更多 →
基于STC12C5A60S2的智能油烟机毕业设计:ADC、PWM与状态机实战

基于STC12C5A60S2的智能油烟机毕业设计:ADC、PWM与状态机实战

简介&#xff1a;面向单片机、嵌入式方向的本科毕业设计人员&#xff0c;这份智能油烟机项目以STC12C5A60S2单片机为核心&#xff0c;完整覆盖油烟机控制系统的程序编写、硬件设计与联调环节&#xff0c;适合作为课程设计、毕业设计或入门级嵌入式项目的参考资料。 压缩包共21…

2026/10/19 17:01:18 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54: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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →