当前位置: 首页 > news >正文

参数初始化方法

梯度消失与梯度爆炸

考虑一个 3 层的全连接网络。
H 1 = X × W 1 H{1}=X \times W{1} H1=X×W1 H 2 = H 1 × W 2 H{2}=H{1} \times W{2} H2=H1×W2 O u t = H 2 × W 3 Out=H{2} \times W_{3} Out=H2×W3
其中第 2 层的权重梯度如下:
Δ W 2 = ∂ L o s s ∂ W 2 = ∂ L o s s ∂ o u t ∂ o u t ∂ H 2 ∂ H 2 ∂ w 2 = ∂ L o s s ∂ o u t ∂ o u t ∂ H 2 H 1 \begin{aligned} \Delta \mathrm{W}{2} &=\frac{\partial \mathrm{Loss}}{\partial \mathrm{W}{2}}=\frac{\partial \mathrm{Loss}}{\partial \mathrm{out}} \frac{\partial \mathrm{out}}{\partial \mathrm{H}_{2}} \frac{\partial \mathrm{H}{2}}{\partial \mathrm{w}{2}} \ &=\frac{\partial \mathrm{Loss}}{\partial \mathrm{out}} \frac{\partial \mathrm{out}}{\partial \mathrm{H}_{2}} \mathrm{H}_{1} \end{aligned} ΔW2=W2Loss=outLossH2outw2H2 =outLossH2outH1
所以 Δ W 2 \Delta \mathrm{W}{2} ΔW2依赖于前一层的输出 H 1 H{1} H1。如果 H 1 H{1} H1 趋近于零,那么 Δ W 2 \Delta \mathrm{W}{2} ΔW2也接近于 0,造成梯度消失。如果 H 1 H{1} H1 趋近于无穷大,那么 Δ W 2 \Delta \mathrm{W}{2} ΔW2也接近于无穷大,造成梯度爆炸。要避免梯度爆炸或者梯度消失,就要严格控制网络层输出的数值范围。
下面构建 100 层全连接网络,先不适用非线性激活函数,每层的权重初始化为服从 N ( 0 , 1 ) N(0,1) N(0,1)的正态分布,输出数据使用随机初始化的数据。

import torch
import torch.nn as nn
from common_tools import set_seedset_seed(1)  # 设置随机种子class MLP(nn.Module):def __init__(self, neural_num, layers):super(MLP, self).__init__()self.linears = nn.ModuleList([nn.Linear(neural_num, neural_num, bias=False) for i in range(layers)])self.neural_num = neural_numdef forward(self, x):for (i, linear) in enumerate(self.linears):x = linear(x)return xdef initialize(self):for m in self.modules():# 判断这一层是否为线性层,如果为线性层则初始化权值if isinstance(m, nn.Linear):nn.init.normal_(m.weight.data)    # normal: mean=0, std=1layer_nums = 100
neural_nums = 256
batch_size = 16net = MLP(neural_nums, layer_nums)
net.initialize()inputs = torch.randn((batch_size, neural_nums))  # normal: mean=0, std=1output = net(inputs)
print(output)

输出为:

tensor([[nan, nan, nan,  ..., nan, nan, nan],[nan, nan, nan,  ..., nan, nan, nan],[nan, nan, nan,  ..., nan, nan, nan],...,[nan, nan, nan,  ..., nan, nan, nan],[nan, nan, nan,  ..., nan, nan, nan],[nan, nan, nan,  ..., nan, nan, nan]], grad_fn=<MmBackward>)

也就是数据太大(梯度爆炸)或者太小(梯度消失)了。接下来我们在forward()函数中判断每一次前向传播的输出的标准差是否为 nan,如果是 nan 则停止前向传播。

    def forward(self, x):for (i, linear) in enumerate(self.linears):x = linear(x)print("layer:{}, std:{}".format(i, x.std()))if torch.isnan(x.std()):print("output is nan in {} layers".format(i))breakreturn x

输出如下:

layer:0, std:15.959932327270508
layer:1, std:256.6237487792969
layer:2, std:4107.24560546875
.
.
.
layer:29, std:1.322983152787379e+36
layer:30, std:2.0786820453988485e+37
layer:31, std:nan
output is nan in 31 layers

可以看到每一层的标准差是越来越大的,并在在 31 层时超出了数据可以表示的范围。
下面推导为什么网络层输出的标准差越来越大。
首先给出 3 个公式:
E ( X × Y ) = E ( X ) × E ( Y ) E(X \times Y)=E(X) \times E(Y) E(X×Y)=E(X)×E(Y):两个相互独立的随机变量的乘积的期望等于它们的期望的乘积。
D ( X ) = E ( X 2 ) − [ E ( X ) ] 2 D(X)=E(X^{2}) - [E(X)]^{2} D(X)=E(X2)[E(X)]2:一个随机变量的方差等于它的平方的期望减去期望的平方
D ( X + Y ) = D ( X ) + D ( Y ) D(X+Y)=D(X)+D(Y) D(X+Y)=D(X)+D(Y):两个相互独立的随机变量之和的方差等于它们的方差的和。
可以推导出两个随机变量的乘积的方差如下:
D ( X × Y ) = E [ ( X Y ) 2 ] − [ E ( X Y ) ] 2 = D ( X ) × D ( Y ) + D ( X ) × [ E ( Y ) ] 2 + D ( Y ) × [ E ( X ) ] 2 D(X \times Y)=E[(XY)^{2}] - [E(XY)]^{2}=D(X) \times D(Y) + D(X) \times [E(Y)]^{2} + D(Y) \times [E(X)]^{2} D(X×Y)=E[(XY)2][E(XY)]2=D(X)×D(Y)+D(X)×[E(Y)]2+D(Y)×[E(X)]2
如果 E ( X ) = 0 E(X)=0 E(X)=0 E ( Y ) = 0 E(Y)=0 E(Y)=0,那么 D ( X × Y ) = D ( X ) × D ( Y ) D(X \times Y)=D(X) \times D(Y) D(X×Y)=D(X)×D(Y)
我们以输入层第一个神经元为例:
H 11 = ∑ i = 0 n X i × W 1 i \mathrm{H}_{11}=\sum{i=0}^{n} X{i} \times W{1 i} H11=i=0nXi×W1i
其中输入 X 和权值 W 都是服从 N ( 0 , 1 ) N(0,1) N(0,1)的正态分布,所以这个神经元的方差为:
D ( H 11 ) = ∑ i = 0 n D ( X i ) ∗ D ( W 1 i ) = n ( 1 ∗ 1 ) = n \begin{aligned} \mathbf{D}\left(\mathrm{H}_{11}\right) &=\sum{i=0}^{n} \boldsymbol{D}\left(X{i}\right) * \boldsymbol{D}\left(W{1 i}\right) \ &=n (1 * 1) \ &=n \end{aligned} D(H11)=i=0nD(Xi)D(W1i) =n(11) =n
标准差为: std ⁡ ( H 11 ) = D ( H 11 ) = n \operatorname{std}\left(\mathrm{H}_{11}\right)=\sqrt{\mathbf{D}\left(\mathrm{H}_{11}\right)}=\sqrt{n} std(H11)=D(H11) =n ,所以每经过一个网络层,方差就会扩大 n 倍,标准差就会扩大 n \sqrt{n} n 倍,n 为每层神经元个数,直到超出数值表示范围。对比上面的代码可以看到,每层神经元个数为 256,输出数据的标准差为 1,所以第一个网络层输出的标准差为 16 左右,第二个网络层输出的标准差为 256 左右,以此类推,直到 31 层超出数据表示范围。可以把每层神经元个数改为 400,那么每层标准差扩大 20 倍左右。从 D ( H 11 ) = ∑ i = 0 n D ( X i ) × D ( W 1 i ) D(\mathrm{H}_{11})=\sum{i=0}^{n} D(X{i}) \times D(W{1 i}) D(H11)=i=0nD(Xi)×D(W1i),可以看出,每一层网络输出的方差与神经元个数、输入数据的方差、权值方差有关,其中比较好改变的是权值的方差 D ( W ) D(W) D(W),所以 D ( W ) = 1 n D(W)= \frac{1}{n} D(W)=n1,标准差为 s t d ( W ) = 1 n std(W)=\sqrt\frac{1}{n} std(W)=n1
因此修改权值初始化代码为nn.init.normal_(m.weight.data, std=np.sqrt(1/self.neural_num)),
结果如下:

layer:0, std:0.9974957704544067
layer:1, std:1.0024365186691284
layer:2, std:1.002745509147644
.
.
.
layer:94, std:1.031973123550415
layer:95, std:1.0413124561309814
layer:96, std:1.0817031860351562

修改之后,没有出现梯度消失或者梯度爆炸的情况,每层神经元输出的方差均在 1 左右。通过恰当的权值初始化,可以保持权值在更新过程中维持在一定范围之内,不过过大,也不会过小。
上述是没有使用非线性变换的实验结果,如果在forward()中添加非线性变换tanh,每一层的输出方差还是会越来越小,会导致梯度消失。因此出现了 Xavier 初始化方法与 Kaiming 初始化方法。

Xavier 方法

Xavier 是 2010 年提出的,针对有非线性激活函数时的权值初始化方法,目标是保持数据的方差维持在 1 左右,主要针对饱和激活函数如 sigmoid 和 tanh 等。同时考虑前向传播和反向传播,需要满足两个等式: n i ∗ D ( W ) = 1 \boldsymbol{n}_{\boldsymbol{i}} * \boldsymbol{D}(\boldsymbol{W})=\mathbf{1} niD(W)=1 n i + 1 ∗ D ( W ) = 1 \boldsymbol{n}_{\boldsymbol{i+1}} * \boldsymbol{D}(\boldsymbol{W})=\mathbf{1} ni+1D(W)=1,可得: D ( W ) = 2 n i + n i + 1 D(W)=\frac{2}{n_{i}+n_{i+1}} D(W)=ni+ni+12。为了使 Xavier 方法初始化的权值服从均匀分布,假设 W W W服从均匀分布 U [ − a , a ] U[-a, a] U[a,a],那么方差 D ( W ) = ( − a − a ) 2 12 = ( 2 a ) 2 12 = a 2 3 D(W)=\frac{(-a-a)^{2}}{12}=\frac{(2 a)^{2}}{12}=\frac{a^{2}}{3} D(W)=12(aa)2=12(2a)2=3a2,令 2 n i + n i + 1 = a 2 3 \frac{2}{n_{i}+n_{i+1}}=\frac{a^{2}}{3} ni+ni+12=3a2,解得: a = 6 n i + n i + 1 \boldsymbol{a}=\frac{\sqrt{6}}{\sqrt{n_{i}+n_{i+1}}} a=ni+ni+1 6 ,所以 W W W服从分布 U [ − 6 n i + n i + 1 , 6 n i + n i + 1 ] U\left[-\frac{\sqrt{6}}{\sqrt{n_{i}+n_{i+1}}}, \frac{\sqrt{6}}{\sqrt{n_{i}+n_{i+1}}}\right] U[ni+ni+1 6 ,ni+ni+1 6 ]
所以初始化方法改为:

a = np.sqrt(6 / (self.neural_num + self.neural_num))
# 把 a 变换到 tanh,计算增益
tanh_gain = nn.init.calculate_gain('tanh')
a *= tanh_gainnn.init.uniform_(m.weight.data, -a, a)

并且每一层的激活函数都使用 tanh,输出如下:

layer:0, std:0.7571136355400085
layer:1, std:0.6924336552619934
layer:2, std:0.6677976846694946
.
.
.
layer:97, std:0.6426210403442383
layer:98, std:0.6407480835914612
layer:99, std:0.6442216038703918

可以看到每层输出的方差都维持在 0.6 左右。
PyTorch 也提供了 Xavier 初始化方法,可以直接调用:

tanh_gain = nn.init.calculate_gain('tanh')
nn.init.xavier_uniform_(m.weight.data, gain=tanh_gain)
- nonlinearity:激活函数名称
- param:激活函数的参数,如 Leaky ReLU 的 negative_slop。

下面是计算标准差经过激活函数的变化尺度的代码。

x = torch.randn(10000) 
out = torch.tanh(x)
gain = x.std() / out.std() 
print('gain:{}'.format(gain))
tanh_gain = nn.init.calculate_gain('tanh') 
print('tanh_gain in PyTorch:', tanh_gain)

输出如下:

gain:1.5982500314712524 
tanh_gain in PyTorch: 1.6666666666666667

结果表示,原有数据分布的方差经过 tanh 之后,标准差会变小 1.6倍左右。

Kaiming 方法

虽然 Xavier 方法提出了针对饱和激活函数的权值初始化方法,但是 AlexNet 出现后,大量网络开始使用非饱和的激活函数如 ReLU 等,这时 Xavier 方法不再适用。2015 年针对 ReLU 及其变种等激活函数提出了 Kaiming 初始化方法。
针对 ReLU,方差应该满足: D ( W ) = 2 n i \mathrm{D}(W)=\frac{2}{n_{i}} D(W)=ni2;针对 ReLu 的变种,方差应该满足: D ( W ) = 2 n i \mathrm{D}(W)=\frac{2}{n_{i}} D(W)=ni2,a 表示负半轴的斜率,如 PReLU 方法,标准差满足 std ⁡ ( W ) = 2 ( 1 + a 2 ) ∗ n i \operatorname{std}(W)=\sqrt{\frac{2}{\left(1+a^{2}\right) * n_{i}}} std(W)=(1+a2)ni2
代码如下:nn.init.normal(m.weight.data, std=np.sqrt(2 / self.neuralnum)),或者使用 PyTorch 提供的初始化方法:nn.init.kaiming_normal(m.weight.data),同时把激活函数改为 ReLU。

常用初始化方法

PyTorch 中提供了 10 中初始化方法

  • Xavier 均匀分布
  • Xavier 正态分布
  • Kaiming 均匀分布
  • Kaiming 正态分布
  • 均匀分布
  • 正态分布
  • 常数分布
  • 正交矩阵初始化
  • 单位矩阵初始化
  • 稀疏矩阵初始化

每种初始化方法都有它自己使用的场景,原则是保持每一层输出的方差不能太大,也不能太小。

相关文章:

参数初始化方法

梯度消失与梯度爆炸 考虑一个 3 层的全连接网络。 H 1 X W 1 H{1}X \times W{1} H1XW1&#xff0c; H 2 H 1 W 2 H{2}H{1} \times W{2} H2H1W2&#xff0c; O u t H 2 W 3 OutH{2} \times W_{3} OutH2W3​ 其中第 2 层的权重梯度如下&#xff1a; Δ W 2 ∂ L o s s …...

Go的基础运行方式和打包

目录 基础运行方式导入路径 打包技巧相关知识点 基础运行方式 // 文件名可以不是main&#xff0c;但包名和入口函数比如是main // main.go package main // 导入包的时候可以直接导入&#xff0c;也可以导入后指定包名&#xff0c; import ("fmt"godemo "githu…...

Deepin 图形化部署 Hadoop Single Node Cluster

Deepin 图形化部署 Hadoop Single Node Cluster 升级操作系统和软件 快捷键 ctrlaltt 打开控制台窗口 更新 apt 源 sudo apt update更新 系统和软件 sudo apt -y dist-upgrade升级后建议重启 开启ssh服务 打开资源管理器 进入系统盘 找到 etc 目录 在系统盘的 etc 目录上 右键…...

23款奔驰GLS400升级柏林之声音响系统,体验不一样的感觉

Burmester 环绕立体声音响系统–为每位乘员打造令人印象深刻的音质13个高性能扬声器、总功率为590瓦的9声道数字信号处理器(DSP)放大器以及放大器/扬声器系统专为车辆配置&#xff0c;打造出一流的Burmester之音。必要时还可进一步提升令人印象深刻的听觉体验。声音环绕功能能够…...

Vue的map()方法和filter()方法的使用

map() map()&#xff1a;方法返回一个新数组&#xff0c;数组中的元素为原始数组元素调用函数处理后的值 案例&#xff1a; const data res.map(item > item.id); const data res.map(item > return item.id); const data res.map(item > { name: item.name, id…...

qt创建临时文件

1、临时文件系统 在 Linux 系统中&#xff0c;创建临时文件系统很简单&#xff0c;执行如下指令即可&#xff1a; mount -t tmpfs -o size1024m tmpfs /mnt/tmp 挂载成功后&#xff0c;在 /mnt/tmp 这个挂载点下创建的所有文件都将会是临时文件, 也就是说&#xff1a;当电脑关…...

Element——table排序,上移下移功能。及按钮上一条下一条功能

需求&#xff1a;table排序&#xff0c;可操作排序上移下移功能。判断第一行上移禁用和最后一行下移禁用&#xff0c;排序根据后端返回的字段 <el-table:data"tableData"style"width: 100%"><el-table-column type"index" label"序…...

无涯教程-Android - Linear Layout函数

Android LinearLayout是一个视图组&#xff0c;该视图组将垂直或水平的所有子级对齐。 Linear Layout - 属性 以下是LinearLayout特有的重要属性- Sr.NoAttribute & 描述1 android:id 这是唯一标识布局的ID。 2 android:baselineAligned 此值必须是布尔值&#xff0c;为…...

ELK安装、部署、调试(六) logstash的安装和配置

1.介绍 Logstash是具有实时流水线能力的开源的数据收集引擎。Logstash可以动态统一不同来源的数据&#xff0c;并将数据标准化到您选择的目标输出。它提供了大量插件&#xff0c;可帮助我们解析&#xff0c;丰富&#xff0c;转换和缓冲任何类型的数据。 管道&#xff08;Logs…...

【Spring Security】UserDetails 接口介绍

文章目录 UserDetails 的作用UserDetails 接口中各个方法详解 UserDetails 的作用 UserDetails 在 Spring Security 框架中主要担任获取用户信息的接口&#xff0c;通过该接口就能拿到用户的信息和验证用户的信息&#xff0c;这些信息在下面的方法中会有讲述。 UserDetails 接…...

C# Linq源码分析之Take(四)

概要 本文主要对Take的优化方法进行源码分析&#xff0c;分析Take在配合Select&#xff0c;Where等常用的Linq扩展方法使用时候&#xff0c;如何实现优化处理。 本文涉及到Select, Where和Take和三个方法的源码分析&#xff0c;其中Select, Where, Take更详尽的源码分析&…...

Python 和 C++ 使用细节差别

1. 循环中的可迭代对象长度 1. 循环中的可迭代对象长度 C 中&#xff0c;for循环中写明a.size()&#xff0c;每次循环这个值是重新计算的&#xff1b; # include “iostream” # include <vector> using namespace std;int main() {vector<int> a(10);int cnt 0…...

在Ubuntu Linux系统上安装RabbitMQ服务并解决公网远程访问问题

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…...

葫芦娃自动预约-公众号代挂

效果 #小程序://航旅黔购/1nkYlNRVzm0Gg9x #小程序://贵旅优品/7zz6mtnSVgDfyqa #小程序://新联惠购/ibFdsuhWqIbczEd #小程序://贵盐黔品/u2TgExCUdkavrFe #小程序://空港乐购/ANkOOdqEeo71kah #小程序://遵航出山/ZkR7DQy1raoPxKD #小程序://乐旅商城/Ip5cgpJ7TLmRrWF #小程序…...

ESP32应用教程(0)— PMW3901MB光流传感器

文章目录 前言 1 传感器介绍 1.1 关键特征 1.2 关键参数 2 硬件概述 2.1 信号引脚 2.2 参考电路图 3 寄存器 3.1 寄存器列表 3.2 性能优化寄存器 4 代码说明 4.1 结构体说明 4.2 编译说明 5 波形分析 前言 本文介绍了在 ESP32 DEVKIT V1 开发板上开发 PMW3901MB…...

docker部署nginx,部署springboot项目,并实现访问

一、先部署springboot项目 1、安装docker&#xff1a; yum install docker -y 2、启动docker&#xff1a; service docker start 重启&#xff1a; service docker restart 3、查看版本&#xff1a; docker -v 4、使设置docker.service生效&#xff08;路径&#xff1a;…...

十五、模板方法模式

一、什么是模板方法模式 模板方法&#xff08;Template Method&#xff09;模式的定义如下&#xff1a;定义一个操作中的算法骨架&#xff0c;而将算法的一些步骤延迟到子类中&#xff0c;使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 模板方法模式包含以…...

jvm 什么是常量池,常量池定义 class常量池

首先需要理解下Java的class文件&#xff0c;以及class文件结构&#xff1a; 1.Class文件是一组以8个字节为基础单位的二进制流&#xff0c;各个数据项目严格按照顺序紧凑地排列在文 件之中&#xff0c;中间没有任何分隔符&#xff0c;这使得整个Class文件中存储的内容几乎全部…...

CA证书颁发机构服务器

目录 一、CA证书颁发机构是什么&#xff1f; 二、数字证书可以干什么&#xff1f; 三、PKI&#xff1a;即公钥加密体系&#xff08;public key cryptography&#xff09; 四、CA在网络中的工作流程及原理&#xff08;以网站为例&#xff09; 五、HTTPS 的工作原理 六、CA私有证…...

5. 线性层及其他层

5.1 神经网络结构 5.2 线性拉平 import torch import torchvision from torch import nn from torch.nn import ReLU from torch.nn import Sigmoid from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datase…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...