Jiale's Blog - Jiale
type: channel
link: https://jiale.domcer.com/index.php/author/1/
description: Jiale
items: 「转载」北京大学计算机基础能力手册
items: 分布式数据库原理及技术
items: 深度学习（DL）-经典卷积神经网络-测试(model_test)模板代码
items: 深度学习（DL）-经典卷积神经网络-训练(model_train)模板代码
items: 深度学习（DL）-经典卷积神经网络-输入（输出）通道数与卷积核的关系
items: 深度学习（DL）-经典卷积神经网络-以VGG16理解合理设置通道数的原理
items: 深度学习（DL）-经典卷积神经网络-概念理解-通道数到底是什么
items: Anaconda Prompt 中创建虚拟环境
items: 深度学习（DL）-代码探究-张量怎么变成二维矩阵
items: 深度学习（DL）-原理探究-从ReLu函数理解何为反向传播

「转载」北京大学计算机基础能力手册
type: item
date: 2026-06-29T19:22:00+08:00
description: 本网站仅做转载，最终解释权仍在原作者。点击下载main.pdf北京大学计算机基础能力手册

分布式数据库原理及技术
type: item
date: 2026-06-23T19:49:00+08:00
description: 前言：本文基于数学与大数据学院2024级数据科学与大数据技术专业课程《分布式数据库原理及技术》。该课程考核难度较大，需特别用心认真听课！我将个人笔记开源，旨在为后续的新同学提供复习参考，欢迎交流与讨论（虽然我也可能忘记了（（Chiale2026.8.1资料下载： https://pan.baidu.com/s/1k6hAS7tVlPAeOwbevS7b7A?pwd=t2uv 提取码: t2uv第一篇 概论与基础第一章 分布式数据库概述1.1 前沿技术科普以下技术作为通识了解即可，构成本课程的学习背景：技术理解数据中台把企业内分散的数据资产汇聚、加工、服务化，向业务统一供给数据湖仓（Lakehouse）同时具备数据湖的灵活存储与数据仓库的事务/Schema 能力数据脱敏对敏感字段（如身份证、手机号）做变形或替换以保护隐私分布式数据库的雏形（ICBC Bank）工商银行早期基于大型机的分布式账务系统区块链多方参与的链式账本，依赖共识算法与不可篡改结构TCP 三次握手四次挥手面向连接的传输层建连与断连流程联邦学习 / 深度学习多方在不共享原始数据的前提下联合训练模型结论：以上内容了解即可，作为科普知识看待，本课程重点在分布式数据库系统（Hive / Hadoop）。1.2 分布式数据库与传统 RDBMS 的对比Q1：传统的三级模式 / 两级映像在分布式数据库中是否改变？A：保留原有结构，但增加了新内容——引入了 全局模式（Global Schema） 和 分片模式（Fragmentation Schema）。全局模式：从用户视角看，"整库"长什么样分片模式：说明全局关系如何被切分到不同节点原有"外模式 / 模式 / 内模式 + 映像"仍在，但被扩展以适配分布式存储Q2：分布式数据库在存储/检索效率上通过何种指标与传统 RDBMS 进行对比？A：两个核心指标——存储空间大小：分布式能否减少单点膨胀检索效率：是否仍能满足查询延迟与吞吐Q3：HDFS（GFS）在存储体系上如何实现共享服务？课堂问答留作思考。补充资料：02 Hadoop与HIve.pptx、0 hdfs shell操作.txtQ4：HIVE 的三种部署方式及使用环境部署方式metastore 存储适用场景内嵌模式（Derby）嵌入式 Derby 数据库单人本地调试；只允许一个会话本地模式（Local）MySQL/PostgreSQL 等独立 RDBMS单人开发 / 教学实验，HIVE 与 metastore 在同一进程远程模式（Remote）独立的 MySQL 服务多客户端并发访问同一 metastore，生产环境图中标注：内模式对应"存储"，模式对应"放表的"，外模式对应"逻辑独立"；映像体现了 create view as select ... 的位置——逻辑独立、存储独立。1.3 数据分类类型典型代表处理方式结构化MySQL、Oracle、关系表传统 SQL 数据库半结构化JSON、XML可用 Hive JSON SerDe、Spark 解析非结构化视频、图片YOLO 等模型识别 → 输出 JSON/CSV → 落入数据库第二章 Hadoop 与 HIVE 体系结构2.1 HDFS（GFS）存储体系HDFS（Hadoop Distributed File System）：源自 Google GFS 论文核心特性：分块存储、多副本容错、一次写多次读默认存储路径：/warehousedir/home/xxx.db/表名/（Hive on HDFS 默认行为）2.2 HIVE 三种工作模式模式metastore 位置是否允许多会话Derby嵌入式（每个客户端独立）否本地（Local）同节点 MySQL/PG单客户端远程（Remote）远程独立 MySQL是2.3 集群环境与启停流程集群环境：角色IP用户master192.168.5.134root / 123123slave1192.168.5.135root / 123123slave2192.168.5.136root / 123123MySQL 安装在 slave2，HIVE 启用本地模式；统一数据库名 bigdata2024；本地数据目录 /data。集群启动流程：关闭防火墙（三台虚拟机）systemctl stop firewalld启动 Zookeeper（三台虚拟机）cd $ZOOKEEPER_HOME bin/zkServer.sh start bin/zkServer.sh status # 1 个 leader，2 个 follower启动 Hadoop（master）cd $HADOOP_HOME sbin/start-all.sh在三台机器上 jps 查看进程。启动 HIVE（slave2 启动 M…

深度学习（DL）-经典卷积神经网络-测试(model_test)模板代码
type: item
date: 2026-01-31T19:45:00+08:00
description: 一、导入依赖模块import torch import torch.utils.data as Data from torchvision import transforms from torchvision.datasets import FashionMNIST from model import LeNet代码行逻辑与作用关键补充import torch导入PyTorch核心库提供张量计算、设备管理（CPU/GPU）、模型前向传播等基础能力import torch.utils.data as Data导入PyTorch数据加载工具封装数据集为可迭代的DataLoader，简化批次读取、打乱、多进程加载等逻辑from torchvision import transforms导入图像预处理工具用于对FashionMNIST的图像做标准化、尺寸调整、格式转换（如PIL→Tensor）from torchvision.datasets import FashionMNIST导入FashionMNIST数据集服装分类数据集（10类，如T恤、裤子），替代MNIST的手写数字分类，更贴近实际场景from model import LeNet导入自定义的LeNet模型model.py中定义的LeNet卷积神经网络，是本次要测试的模型二、测试数据处理函数 test_data_process作用：加载并预处理测试集，返回可迭代的DataLoader（数据加载器）def test_data_process(): test_data = FashionMNIST(root='./data', train=False, transform=transforms.Compose([transforms.Resize(size=28), transforms.ToTensor()]), download=True) test_dataloader = Data.DataLoader(dataset=test_data, batch_size=1, shuffle=True, num_workers=0) return test_dataloader代码行逻辑与作用关键补充def test_data_process():定义测试数据处理函数（无入参）封装数据加载逻辑，提高代码复用性test_data = FashionMNIST(...)加载FashionMNIST测试集+ root='./data'：数据集保存到当前目录的data文件夹 + train=False：指定加载测试集（train=True为训练集） + transform=...：图像预处理管道（组合多个变换）： - transforms.Resize(size=28)：强制将图像缩放到28×28（确保输入模型的尺寸统一） - transforms.ToTensor()：将PIL图像转为PyTorch张量，同时把像素值从0-255归一化到0-1 + download=True：如果data文件夹无数据集，自动从官网下载test_dataloader = Data.DataLoader(...)封装测试集为DataLoader+ dataset=test_data：指定要加载的数据集 + batch_size=1：批次大小为1（测试时批次不影响准确率，设1方便逐样本验证） + shuffle=True：打乱测试集顺序（测试时shuffle不影响最终准确率，仅改变遍历顺序） + num_workers=0：数据加载的子进程数（Windows系统推荐设0，避免多进程冲突）return test_dataloader返回构建好的测试数据加载器供后续模型测试函数调用三、模型测试函数 test_model_process作用：用测试集评估模型的预测准确率，核心是仅前向传播、不计算梯度def test_model_process(model, test_dataloader): device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model = model.to(device) #初始化参数 test_correct = 0.0 test_num = 0 #只进行前向传播计算，不计算梯度，从而节省内存，加快运行速度 with torch.no_grad(): for test_data_x, test_data_y in test_dataloader: # 将特征放入到测试设备中 test_data_x = test_data_x.to(device) # 将标签放入到测试设备中 test_data_y =…

深度学习（DL）-经典卷积神经网络-训练(model_train)模板代码
type: item
date: 2026-01-31T19:36:00+08:00
description: 一、核心逻辑先明确整体训练框架：数据准备→模型 / 优化器 / 损失函数初始化→多轮次训练（训练 + 验证）→保存最优模型→可视化，以下按函数拆分讲解。（一）数据处理函数 train_val_data_processdef train_val_data_process(): train_data = FashionMNIST(root='./data', train=True, transform=transforms.Compose([transforms.Resize(size=28), transforms.ToTensor()]), download=True) # 划分训练/验证集（8:2） train_data, val_data = Data.random_split(train_data, [round(0.8*len(train_data)), round(0.2*len(train_data))]) # 构建训练集DataLoader train_dataloader = Data.DataLoader(dataset=train_data, batch_size=32, shuffle=True, num_workers=2) # 构建验证集DataLoader val_dataloader = Data.DataLoader(dataset=val_data, batch_size=32, shuffle=True, num_workers=2) return train_dataloader, val_dataloader逻辑：加载 FashionMNIST 训练集：transform将图片转为模型可接受的 Tensor 格式，download=True自动下载数据集；拆分训练 / 验证集：避免用测试集验证，保证评估客观性；封装 DataLoader：核心是batch_size=32（批次加载）、shuffle=True（打乱数据）、num_workers=2（多线程加速）。（二）核心训练函数 train_model_process1. 初始化核心组件def train_model_process(model, train_dataloader, val_dataloader, num_epochs): # 自动选择GPU/CPU device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Adam优化器（自适应学习率，更新模型参数） optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 分类损失函数：交叉熵 criterion = nn.CrossEntropyLoss() # 模型迁移到指定设备（GPU/CPU） model = model.to(device) # 保存最优模型参数（避免过拟合覆盖） best_model_wts = copy.deepcopy(model.state_dict())关键：所有计算（模型 / 数据 / 损失）必须在同一设备，否则报错。2. 训练过程参数初始化best_acc = 0.0 # 最优验证准确率 train_loss_all = [] # 训练损失记录 val_loss_all = [] # 验证损失记录 train_acc_all = [] # 训练准确率记录 val_acc_all = [] # 验证准确率记录 since = time.time() # 训练开始时间（统计耗时）逻辑：每轮 epoch 重置累加变量，避免跨轮污染；记录指标用于后续可视化。3. 多轮次（epoch）训练循环for epoch in range(num_epochs): print("Epoch {}/{}".format(epoch, num_epochs-1)) print("-"*10) # 每轮重置累加变量 train_loss = 0.0 train_corrects = 0 val_loss = 0.0 val_corrects = 0 train_num = 0 val_num = 0epoch：每轮完整遍历一次训练集 + 验证集，是训练的基本单位。4. 训练阶段（核心：前向→反向→参数更新）for step, (b_x, b_y) in enumerate(train_dataloader): # 数据迁移到设备（和模型同设备） b_x = b_x.to(device) b_y = b_y.to(device) # 模型设为训练模式（启用Dropout/BatchNorm训练行为） model.train(…

深度学习（DL）-经典卷积神经网络-输入（输出）通道数与卷积核的关系
type: item
date: 2026-01-31T12:57:09+08:00
description: 输入通道数 → 决定「每个卷积核的通道数」（硬性匹配，没得选）人为设定的输出通道数 → 决定「卷积核的总个数」（超参数，自己定）简单说，卷积核有两个关键维度，输入通道数只管其中一个（每个卷积核的深度），不管另一个（卷积核的总数）先明确：卷积核不是 “单个小方块”，而是 “多层小方块叠成的小积木”你可以把一个卷积核想象成「叠起来的多层滤镜」，层数就是这个卷积核的通道数—— 这个层数必须和输入特征图的通道数完全一样，这是卷积运算的硬性规则（维度对不上，根本没法计算）。而卷积层的卷积核总个数，是另一回事，它和输入通道数无关，完全由你想得到的输出通道数决定（就是我们之前说的人为设定的超参数）。举最直观的例子（VGG16 首层，输入 3 通道 RGB 图）输入特征图：224×224×3（3 是输入通道数）我们要的输出通道数：64（人为设定）对应的卷积核设计：卷积核总个数：64 个（和输出通道数一致，人为定的）；每个卷积核的规格：3×3×3（最后一个 3 是卷积核的通道数，和输入通道数 3 硬性匹配，没得选）。卷积的运算过程（为什么必须匹配）：每个 3×3×3 的卷积核，会把自己的 3 层滤镜，分别和输入特征图的 3 个通道做卷积（逐元素相乘求和），然后把 3 个通道的卷积结果加起来，得到1 张单通道的特征图；64 个这样的卷积核，就会得到 64 张单通道特征图，叠在一起就是输出的 224×224×64 特征图（64 个输出通道）。如果输入通道数是 64（比如 VGG16 第一层池化后），要的输出通道数是 128（人为定），那卷积核就是：128 个 3×3×64 的卷积核（64 是卷积核通道数，匹配输入；128 是个数，匹配输出）。核心关系总结维度由什么决定？性质例子（输入 64 通道→输出 128 通道）单个卷积核的通道数输入通道数硬性匹配64（和输入通道数一致）卷积层的卷积核总个数输出通道数（人为定）可调整超参数128（人为设定的输出通道数）再补一个反例，彻底打消疑问如果输入是 64 通道，你想输出 256 通道，那卷积核就是256 个 3×3×64—— 输入通道数还是 64，但卷积核个数直接跳到 256，和输入通道数完全无关，只看你要的输出通道数。反之，如果输入通道数变了（比如从 3 变成 1，黑白图），那卷积核的个数可以不变（还是 64），但每个卷积核的通道数必须从 3 变成 1（3×3×3→3×3×1）。总结输入通道数管 “单个卷积核的深度”（必须匹配），输出通道数管 “卷积核的总数”（人为设定），二者毫无决定关系，只是卷积核的两个不同属性

深度学习（DL）-经典卷积神经网络-以VGG16理解合理设置通道数的原理
type: item
date: 2026-01-31T12:42:31+08:00
description: VGG16 设计通道数（64→128→256→512，后两段保持 512）的核心初衷，是围绕「视觉特征提取的天然规律」，适配自身「小卷积核 + 深度堆叠」的核心结构，同时在「特征表达能力、计算量、训练稳定性、泛化能力」之间做最优的工程平衡—— 这个通道数序列不是单纯的 “拍脑袋实验值”，而是把视觉认知逻辑、网络结构特点、硬件工程限制三者结合后的精准设计，每一个通道数的梯度和上限，都对应着明确的设计目标。初衷 1贴合视觉特征「从简到繁、从少到多」的天然提取规律这是最根本的初衷，所有卷积网络的通道数设计都基于此，VGG16 把这个规律做到了极致简洁的「翻倍式适配」。图片的视觉特征提取是层层组合的过程：「浅层」只能提取低级基础特征（竖线、横线、斜纹、颜色块、明暗交界），这些特征的种类极少、模式固定，根本不需要多通道 ——64 个通道足以把所有基础特征 “抓全”，再多就是计算量浪费（比如用 128 个通道抓竖线，大部分通道会学到重复的特征）；「深层」会把浅层的低级特征拼接、融合成高级语义特征（比如 “竖线 + 横线” 拼成角、“多个角” 拼成眼睛、“眼睛 + 鼻子” 拼成人脸，还有车轮、树叶、桌腿等无数物体部件），这些高级特征的种类呈指数级暴增，必须用更多通道来「分门别类编码」——256→512 的通道数，就是为了给每一种复杂的高级特征分配一个 “专属编码通道”，保证网络能精准区分不同的语义特征，不会把 “眼睛” 和 “车轮” 的特征混在一起。简单说：VGG16 的通道数翻倍，就是跟着特征的 “复杂程度 / 种类数” 翻倍走，让通道数刚好匹配特征的实际需求，不多余、不不足。初衷 2支撑 VGG16「小卷积核 + 深度堆叠」的核心结构（专属设计初衷）VGG16 的标志性设计是放弃大卷积核（如 7×7、5×5），用多个 3×3 小卷积核堆叠（比如 2 层 3×3 卷积代替 1 层 5×5，3 层 3×3 代替 1 层 7×7），这个设计的目的是用更少的参数，获得更多的非线性激活（ReLU），提升特征表达的灵活性。但这个结构有个「硬需求」：必须有足够的通道数，才能避免 “信息瓶颈”——如果深层通道数和浅层一样（比如全程 64），那么多层 3×3 卷积堆叠后，浅层的低级特征会在传递中不断 “挤压”，根本无法充分融合成高级特征，就像用一根细管子传大量水，水会不断溢出，深度堆叠的优势会完全消失。而 64→128→256→512 的通道数递增，就是为深度堆叠的小卷积核 “铺好信息通道”：每一层卷积堆叠前，先增加通道数，让特征融合有足够的 “空间”，保证 VGG16 的深度堆叠能真正发挥作用（更多非线性、更好的特征提取）。初衷 3精准平衡「模型容量」和「计算量 / 硬件限制」深度学习中，通道数是提升模型容量（学习能力）的核心手段（比单纯加深网络更高效），但通道数越多，计算量、显存占用就越大 —— 而 VGG16 诞生时（2014 年），硬件算力和显存还远不如现在（当时主流显卡显存只有 2-4G），通道数设计必须兼顾 “能训、能跑”。VGG16 用 「通道数翻倍 + 池化层尺寸减半」的组合 ，实现了计算量的「动态平衡」，这是最精妙的工程设计：池化层把特征图的长、宽各减半，特征图面积变为原来的 1/4，计算量会大幅下降；紧接着的卷积层把通道数翻倍，计算量会小幅上升；一降一升后，整体计算量基本保持稳定，不会呈指数级爆炸。比如从 64 通道→池化→128 通道：池化让面积减 1/4，卷积核翻倍让通道数 ×2，最终计算量只有原来的2/4=1/2，显存占用也可控；而把深层通道数定在 512，不是不想升到 1024，而是512 是当时硬件能支撑的 “性价比上限”——1024 通道会让显存溢出、训练无法进行，而 512 通道已经能让网络学到足够的高级特征，模型精度和工程实现达到最优平衡。初衷 4保证网络「训练稳定性」，避免梯度消失 / 特征重复如果通道数设计混乱（比如浅层 128、深层 64，或突然从 64 跳到 512），会出现两个问题：梯度消失：深层通道数过少，特征信息在反向传播时会不断丢失，梯度无法有效传回到浅层，网络学不到东西；特征重复：浅层通道数过多，有限的低级特征会让大量通道学到重复的内容，网络出现 “冗余学习”，不仅浪费计算量，还会导致过拟合。而 VGG16缓慢、均匀的翻倍式通道数递增（64→128→256→512），让特征信息在正向传播时能「平稳融合」，反向传播时梯度能「平稳传递」，既避免了梯度消失，又减少了特征重复，保证了网络在深度堆叠的情况下，依然能稳定训练、收敛。同时，深层保持 512 通道不变（最后两段卷积都是 512），也是为了让高级特征的提取更 “聚焦”—— 到了网络最深层，特征已经是最复杂的全局语义特征，不需要再增加通道数，保持 512…

深度学习（DL）-经典卷积神经网络-概念理解-通道数到底是什么
type: item
date: 2026-01-31T12:36:36+08:00
description: 通道数就是特征图的「特征种类数」，也可以理解成网络看图片的「专属视角数」—— 每个通道只盯着图片里的一种特定特征，通道数越多，网络能同时捕捉的特征种类就越全。再往简单说，把卷积网络想象成一群 “特征侦探”，通道数就是「侦探的人数」，每个侦探只负责找一种特定线索，所有侦探的结果合在一起，就是网络对图片的完整特征理解。以「输入图片通道」为例平时看的 RGB 彩色图，就是3 个通道：红色通道（R）：只保留图片里红色的明暗信息（不管绿、蓝）；绿色通道（G）：只保留绿色的明暗信息；蓝色通道（B）：只保留蓝色的明暗信息。这 3 个通道叠在一起，就是你看到的彩色画面。如果是黑白图，就是1 个通道，只有明暗信息，没有颜色种类。通道的本质就是「把信息按种类分开存」，方便后续针对性处理。以VGG16为例，卷积的「网络通道数」是什么卷积层的输出通道数 = 卷积核个数，其实就是给网络新增了对应数量的 “专属侦探”：比如 VGG16 首层 64 个卷积核→64 个通道，就是 64 个侦探，每个侦探只找一种简单特征（有的专找竖线、有的专找横线、有的专找斜纹、有的专找颜色块，都是最基础的视觉线索）；到了深层 512 个卷积核→512 个通道，就是 512 个侦探，每个侦探只找一种复杂特征（有的专找眼睛、有的专找车轮、有的专找树叶轮廓、有的专找桌面边缘，都是浅层简单特征拼出来的 “高级线索”）。每个通道最终会输出一张「特征图」，这张图里越亮的地方，代表图片对应位置越符合这个通道的特征（比如 “竖线通道” 的特征图，图片里竖线的位置会特别亮，其他地方暗）。通道数的「核心作用」：1. 「分门别类存特征」，不混不乱，方便后续融合如果把所有特征都揉在 1 个通道里，网络根本分不清 “这里是竖线”“那里是纹理”，就像把所有侦探的线索堆在一个盒子里，越往后越乱。而通道就是给每个特征配一个 “专属文件夹”，竖线放竖线的文件夹，眼睛放眼睛的文件夹，后续网络可以轻松把这些文件夹里的信息拼起来，还原出图片里的物体（比如 “眼睛 + 鼻子 + 嘴巴” 拼出人脸）。2. 「通道越多，能抓的特征越全」，网络看得越 “明白”浅层用少通道（64/128）：因为图片里的简单特征就那么几种（线、纹、色块），多了也是浪费，相当于没必要找 100 个侦探都去查竖线；深层用多通道（256/512）：因为深层要抓的复杂特征特别多（不同的物体部件、不同的组合方式），需要更多侦探各司其职，才能把图片里的细节都查清楚，相当于查一个复杂案件，需要不同领域的侦探（法医、痕迹、刑侦）一起上。VGG16 里池化层不改变通道数，就是因为池化只是 “把侦探的线索图缩小（去掉无用细节）”，但不会删掉任何侦探（还是原来的 64/128/512 个），线索的种类数没变，只是线索图更简洁了；而卷积层增加通道数，就是新增一批更专业的侦探，从查简单线索升级为查复杂线索。终极大白话总结通道数 = 网络的特征种类数 / 侦探人数；每个通道管一种特征，通道越多，网络能捕捉的特征越全，对图片的理解就越深刻；VGG16 逐层加通道，就是让网络从 “看简单线条” 慢慢升级为 “看复杂物体”。

Anaconda Prompt 中创建虚拟环境
type: item
date: 2026-01-22T08:26:40+08:00
description: 一、基础准备（Anaconda Prompt 中）# 1. 清屏，让界面更整洁 cls二、环境管理（base 环境下执行）# 2. 查看当前系统中所有已创建的conda环境（确认环境列表） conda env list # 3. 方式1：创建指定名称的虚拟环境（推荐，简单易记） # 替换【你的环境名】为自定义名称，比如data_analysis conda create -n 你的环境名 python=3.9 # 3. 方式2：创建指定安装路径的虚拟环境（按需选择） # 替换【你的安装路径】和【你的环境名】，比如D:\conda_env\data_analysis conda create --prefix=你的安装路径\你的环境名 python=3.9 # 4. 激活创建好的虚拟环境（方式1创建的环境） conda activate 你的环境名 # （可选）如果是方式2创建的路径型环境，激活命令如下 # conda activate 你的安装路径\你的环境名三、虚拟环境内的库安装与验证# 5. 查看当前环境已安装的库（激活环境后执行） conda list # 6. 安装指定版本的NumPy（使用清华源加速） pip install numpy==1.21.5 -i https://pypi.tuna.tsinghua.edu.cn/simple # 7. 安装指定版本的Pandas pip install Pandas==1.2.4 -i https://pypi.tuna.tsinghua.edu.cn/simple # 8. 安装指定版本的Matplotlib pip install Matplotlib==3.5.1 -i https://pypi.tuna.tsinghua.edu.cn/simple # 9. 验证NumPy版本（确认安装成功） pip show numpy # （可选）验证其他库版本，替换numpy即可 # pip show pandas # pip show matplotlib四、环境退出与删除（按需执行）# 10. 退出当前虚拟环境，回到base环境 conda deactivate # 11. 删除指定名称的虚拟环境（需先退出该环境） conda remove -n 你的环境名 --all # （可选）删除路径型环境 # conda remove --prefix=你的安装路径\你的环境名 --all

深度学习（DL）-代码探究-张量怎么变成二维矩阵
type: item
date: 2026-01-08T16:21:00+08:00
description: 在深度学习代码中出现了张量如何转化为二维矩阵的例子，用AI整理过后形成了本文。一、先理解：为什么要把张量展平成二维矩阵？全连接层（仿射层）的核心运算是矩阵乘法：y = X · W + b，而矩阵乘法有严格的维度要求：输入X必须是二维矩阵（形状：[样本数, 输入特征数]）权重W是二维矩阵（形状：[输入特征数, 输出特征数]）但实际场景中，输入往往不是二维的：比如批量图片：形状是 [批量数, 通道数, 高, 宽]（例：(100, 3, 28, 28) → 100 张 3 通道 28×28 的图片）比如批量序列数据：形状是 [批量数, 序列长度, 特征维度]（例：(50, 10, 128)）这些高维张量无法直接和权重矩阵做乘法，必须先展平成二维——固定 “样本数” 为第一维，把剩下的所有维度合并成 “特征数” 一维。二、核心操作：X.reshape(X.shape[0], -1) 详解reshape是 NumPy/PyTorch 中重塑数组 / 张量形状的函数，这里的关键是X.shape[0]和-1的组合：部分作用X.shape[0]固定第一维为样本数（批量大小），保证每个样本的特征独立，不混淆。-1NumPy 的 “自动计算维度” 标记：让程序自动计算这一维的大小，等于「总元素数 ÷ 样本数」。例子假设输入是 100 张 3 通道 28×28 的图片，张量形状为 X.shape = (100, 3, 28, 28)：import numpy as np # 模拟输入：100张3通道28×28的图片 X = np.random.randn(100, 3, 28, 28) print("原始形状：", X.shape) # 输出：(100, 3, 28, 28) # 展平成二维矩阵 X_flat = X.reshape(X.shape[0], -1) print("展平后形状：", X_flat.shape) # 输出：(100, 2352) # 2352 = 3 × 28 × 28，刚好是单张图片的所有像素数（特征数）再比如输入是 50 条序列数据（形状(50, 10, 128)）：X = np.random.randn(50, 10, 128) X_flat = X.reshape(X.shape[0], -1) print(X_flat.shape) # 输出：(50, 1280) → 1280 = 10 × 128三、original_x_shape 的关键作用：恢复梯度形状反向传播时，我们计算出的输入梯度dX一开始是展平后的二维形状（比如(100, 2352)），但前一层的输出是高维的（比如卷积层输出是(100, 3, 28, 28)），如果直接把二维的梯度传给前一层，维度会不匹配，导致计算错误。所以original_x_shape的作用就是保存输入的原始形状，反向传播时用它把梯度恢复成原始维度：python运行# 反向传播时恢复梯度形状 dX = np.dot(dy, self.W.T) # 计算出的梯度是二维：(100, 2352) dX = dX.reshape(*self.original_x_shape) # 恢复成(100, 3, 28, 28)这里的*self.original_x_shape是 Python 的 “解包” 操作，把保存的形状元组(100, 3, 28, 28)拆解成参数传给reshape，等价于dX.reshape(100, 3, 28, 28)。总结X.reshape(X.shape[0], -1) 是高维张量适配全连接层的核心：固定样本数维度，自动展平剩余维度为一维，得到 “样本数 × 总特征数” 的二维矩阵。original_x_shape 是反向传播的 “维度桥梁”：保存原始形状，确保梯度能恢复成前一层需要的维度，避免维度不匹配错误。-1 在 reshape 中是 “懒人神器”：无需手动计算展平后的特征数，由程序自动推导，适配任意高维输入。

深度学习（DL）-原理探究-从ReLu函数理解何为反向传播
type: item
date: 2026-01-07T21:48:00+08:00
description: 前排提醒：阅读本文时记得要动脑子和动笔，不要想当然。一、反向传播是什么“反向传播”（Backpropagation） 是深度学习中训练神经网络的核心算法神经网络训练时，从损失函数（最终误差）出发，沿着神经网络的层反向计算每个参数的梯度，并利用梯度下降法更新参数，最终让损失函数变小（模型预测更准）的过程。 前向传播：“输入数据→经过各层计算→输出预测值→计算损失（误差）”（从输入到输出）； 反向传播：“从损失出发→反向算出每一层参数该怎么调整→更新参数”（从输出回到输入）；一般而言，需要做一次前向传播才能做一次反向传播。核心目的：求参数的梯度神经网络的参数（权重 W、偏置 b）需要不断调整，而调整的依据是梯度（参数变化对损失的影响程度）。 反向传播的本质就是用链式法则（微积分里的复合函数求导），把 “损失对最终输出的梯度” 一步步传递回每一层，算出 “损失对每一个参数的梯度”。二、结合ReLu函数假设我们有一个极简网络：输入x → 全连接层（W,b） → ReLU层 → 输出y → 损失L步骤 1：前向传播（正向算结果） 全连接层：z = x*W + bReLU 层：y = max(z, 0)（就是我们写的 ReLU.forward）损失：L = (y - 真实值)²（比如均方误差损失）步骤 2：反向传播（反向算梯度） 我们的目标是算dL/dW（损失对权重 W 的梯度）和dL/db（损失对偏置 b 的梯度），用链式法则拆解： 最终，反向传播就是把这些梯度 “从后往前” 乘起来，得到每个参数的梯度，再用W = W - 学习率*dL/dW更新参数。 逐个拆解（结合 ReLU 类）：dL/dy：损失对 ReLU 输出 y 的梯度（比如L=(y-t)²，则dL/dy=2*(y-t)）；dy/dz：ReLU 的导数（z>0 时 = 1，z≤0 时 = 0）—— 这就是后续 ReLU.backward 里用mask清零梯度的逻辑；dz/dW：全连接层对 W 的导数（=x），dz/db=1；最终，反向传播就是把这些梯度 “从后往前” 乘起来，得到每个参数的梯度，再用W = W - 学习率*dL/dW更新参数。 结合我们写的 ReLU.backward 理解我们的 ReLU 类的backward函数，就是反向传播中 “ReLU 层” 的梯度计算步骤：输入dout：其实就是dL/dy（损失对 ReLU 输出的梯度）；dout[self.mask] = 0：就是计算dy/dz * dout（因为 z≤0 时dy/dz=0，所以梯度清零；z>0 时dy/dz=1，梯度不变）；返回的dx：就是dL/dz（损失对 ReLU 输入 z 的梯度），会传递给前一层（全连接层）继续反向计算。反向传播的关键特点链式法则是核心：把复杂的复合函数求导拆解成多个简单导数的乘积，从后往前逐层计算；效率高：一次反向传播就能算出所有参数的梯度，不用重复计算；和前向传播配套：前向传播时会记录中间结果（比如 ReLU 的mask），反向传播时复用这些结果快速算梯度。三、具体简单案例指定的数值（x=2、W=3、b=1、真实值 = 5），搭建一个极简神经网络（输入→全连接层→ReLU 层→损失）第一步：先明确网络结构我们的极简网络只有 3 层：输入x → 全连接层（W=3, b=1）→ ReLU层 → 输出y → 损失L（均方误差）全连接层公式：z=x∗W+bReLU 层公式：y=max(z,0)损失函数（均方误差）：L=1/2(y−t)2（加 1/2 是为了求导时消去系数，不影响梯度方向）第二步：前向传播（正向算结果）我们从输入 x 开始，一步步算到损失 L：步骤公式数值计算结果1. 全连接层计算z=x∗W+bz=2∗3+1=7z=72. ReLU 层计算y=max(z,0)y=max(7,0)=7y=73. 损失计算L=1/2(y−t)2L=1/2(7−5)2=1/2∗4=2L=2前向传播结论：输入 x=2 经过网络后输出 y=7，和真实值 5 的损失是 2。第三步：反向传播（反向算梯度）反向传播的核心是链式法则，从损失 L 出发，反向算每一层的梯度，最终得到损失对 W、b、x 的梯度（我们的目标是更新 W 和 b）。先明确反向传播的目标我们需要算 3 个梯度：dL/dy：损失对 ReLU 输出 y 的梯度dL/dz：损失对全连接层输出 z 的梯度（ReLU 的输入）dL/dW、dL/db：损失对全连接层参数 W、b 的梯度（最终要用来更新参数）逐步骤计算梯度（纯数值）步骤 1：计算dL/dy（损失对 ReLU 输出 y 的梯度）公式：dL/dy=dyd[1/2(y−t)2]=y−t数值计算：dL/dy=7−5=2结论：dL/dy=2步骤 2：计算dL/dz（损失对全连接层 z …