├── 2023_Fall ├── Linear Algebra.md ├── Mathematical Analysis(I).md └── Programming.md ├── 2024_Fall ├── CAQA.md ├── Computer Organization and Design.md ├── Modern Algebra.md ├── Optimization.md ├── Physics(II).md └── Xi's_thought.md ├── 2024_Spring ├── Data Structure.md ├── Mathematical Analysis(II).md ├── Mathematical Logic.md ├── Modern Chinese History by Liang Li, Jun Deng.md └── Physics(I).md ├── 2025_Spring ├── Algorithm.md ├── Combinatorics.md ├── Large_Language_Models.md ├── Machine_Learning.md └── Modern_Operating_System.md ├── LICENSE ├── README.md └── others ├── CS50(1,2).md ├── Cognitive_Psychology.md ├── Computer Networking.md ├── Concurrency.md ├── Cryptography.md ├── Deep Learning.md ├── Game Theory.md ├── Information Theory.md ├── Linear Algebra(Addition).md ├── Machine_Learning_Compilation.md ├── Natural Language Processing.md ├── Numerical Analysis(part).md ├── Operating_System.md ├── Probability.md ├── Psychology of Emotion.md ├── Python.md ├── Reinforcement Learning.md ├── Reinforcement_Learning.md ├── Transformer.jpg ├── basic operations of deep learning.md └── numpy.md /2024_Fall/CAQA.md: -------------------------------------------------------------------------------- 1 | # CAQA 2 | 3 | ## 量化设计与分析基础 4 | 5 | RISC(Reduced Instruction Set Computer,精简指令集计算机)体系结构,关注在指令级并行的利用,以及如何更好地利用缓存两个问题上。 6 | 7 | 由于硬件性能地提高,很多编程以生产效率更高的语言(java)等进行,而不是效率更高的C类进行。但是,为了保持生产效率,并且尝试缩小性能的差距,即时编译器和跟踪编译的解释器取代了传统的编译器和链接器。此外,在互联网上课以使用的“软件即服务(SaaS)”也取代了必须要在本地进行安装和运行的紧缩套装软件。 8 | 9 | Dennard sacling(登纳德缩放比例定律)在2004年左右终结。它描述的是对于给定的硅面积,增加晶体管的数量,功率密度恒定。这是因为晶体管尺寸下降,速度更快,耗电量下降。其终结的原因在于无法在保持集成电路的可靠性的情况下,进一步地减小电流和降低电压。 10 | 11 | 一位其终结,半导体行业开始采用多处理器或者多核设计。这意味着除了指令级并行(ILP)外,数据级并行(DLP)和线程级并行(TLP)都开始成为人们关注的对象。 12 | 13 | 近期终结的Moore's Law(摩尔定律)。即1-2年内,芯片上可容纳的晶体管数量翻倍。 14 | 15 | 处理器性能提升速度放缓的四个原因: 16 | 17 | - 摩尔定律的放缓和登纳德缩放比例定律的终结。 18 | 19 | - 微处理器的功耗预算需要保持不变。 20 | 21 | - 多核高效处理取代了单个大功耗的处理器。 22 | 23 | - 多重处理已经达到Amdahl定律的上限。 24 | 25 | ### 计算机的分类 26 | 27 | - 个人移动设备(手机、平板等) 28 | 29 | - 桌面计算机 30 | 31 | - 服务器(关注于可用性、可扩展性。高吞吐率) 32 | 33 | - 集群/仓库级计算机(可用性。性价比、功耗) 34 | 35 | - 物联网/嵌入式(比如智能手表、智能音箱) 36 | 37 | ### 并行结构的分类 38 | 39 | #### 应用程序 40 | 41 | - 数据级并行(DLP):许多数据项可以同时操作。 42 | 43 | - 任务级并行(TLP):创建的工作任务可以单独执行并且主要采用并行方式执行。 44 | 45 | #### 硬件的利用方式 46 | 47 | - 指令级并行 48 | 49 | - 向量体系结构、GPU、多媒体指令集等。利用数据级并行。 50 | 51 | - 线程级并行。 52 | 53 | - 请求级并行。 54 | 55 | ### 计算机体系结构的定义 56 | 57 | 指令集体系结构(ISA):相当于软件和硬件之间的界限。 58 | 59 | #### ISA的分类 60 | 61 | - 寄存器-存储器ISA.可以通过多种指令访问存储器。 62 | 63 | - 载入-存储ISA.它们只能用载入或者存储指令来访问寄存器。 64 | 65 | #### 寻址 66 | 67 | 有些体系结构要求读取对象必须是对齐的。但像RISCV中之类的就不要求。一般而言,对齐的对象访问起来会快一些。 68 | 69 | 在RISCV中,有三种寻址的模式。分别是寄存器寻址,立即数寻址,和位移量寻址。 70 | 71 | #### 操作数和指令 72 | 73 | 操作数大小都支持比如8位、16位、32位等等。常见的操作指令有数据传输指令、算术逻辑指令、控制指令和浮点指令。 74 | 75 | #### ISA的编码 76 | 77 | 就两种不同的选择:到底是固定长度还是可变长度? 78 | 79 | 在CAQA中,体系结构指的是这三方面:ISA、组成或微体系结构、硬件。 80 | 81 | ### 技术趋势 82 | 83 | - 集成电路逻辑技术。晶体管上数量一直在增加,但是速度放缓了。 84 | 85 | - 半导体DRAM。DRAM的增速也下降了。之前是3年增加到原来的3倍,但现在已经达不到了。 86 | 87 | - 半导体闪存。目前,闪存增大速率还是很快的。大约每年增加50%到60%,大概是两年翻倍的样子。 88 | 89 | - 磁盘技术。目前,磁盘技术基本密度饱和了。最后的希望是通过HAMR(热辅磁记录)的方式来增大其密度。也就是进一步优化磁盘读写头。 90 | 91 | - 网络技术。网络性能目前取决于交换机的性能和传输系统的性能。 92 | 93 | ### 性能趋势 94 | 95 | 带宽,或者说是吞吐量指的是在给定时间内完成的总工作量。 96 | 97 | 延迟,或者说是响应时间,指的是一个事件从开始到完成所需要的时间。比如一次磁盘访问需要的毫秒数等等。 98 | 99 | 带宽的改进速度超过延迟。根据经验,带宽的增加速度至少是延迟改进速度的平方。 100 | 101 | 集成电路的制造工艺一般用**特征尺寸**(feature size)来衡量。其指的是晶体管或者一根连线在x轴方向或者y轴方向上的最小尺寸。我们常说的7nm指的就是这个。 102 | 103 | ### 集成电路的功耗和能耗趋势 104 | 105 | #### 最大功耗 106 | 107 | 最大功耗对电源系统提出了要求。如果它的最大功耗超过了电源所能提供的范围,那么电压一般会发生下降,从而导致器件无法正常工作。现代处理器中,如果其发现电压供应上的问题,那么它就会减缓速度来调整电压,尽管这样会导致性能上的降低。 108 | 109 | #### 持续功耗 110 | 111 | 衡量它的指标一般被称为热设计功耗(TDP),它在对系统的散热提出的要求。冷却系统的散热,一般而言绝对不能小于TDP。但由于最大功耗一般会超过TDP,当现代处理器发现温度接近结点温度的上限是,会降低时钟频率来减小功耗。如果其不奏效,可能会启用热过载保护装置使芯片断电。 112 | 113 | #### 能耗 114 | 115 | 功耗,指的是单位时间的能耗。但是,一般而言,用能耗去衡量处理器更加好一些。因为能耗和特定的任务,以及完成该项任务所需要的时间相互关联。也就是说,能耗等于平均功耗乘上时间。 116 | 117 | 能耗用于衡量处理器是合理的,而功耗一般用来确定指标,比如散热量等等。 118 | 119 | #### 微处理器的内部 120 | 121 | 对于CMOS芯片而言,主要的能耗源就是开关晶体管,也被称为动态能耗。每个晶体管的能耗,和由该晶体管驱动的容性负载和电压平方的乘积成正比。如果我们要考虑动态功耗,那么动态功耗应该正比于容性负载、电压平方和开关频率的乘积。 122 | 123 | 因此,对于固定的一项任务而言,降低时钟频率可以降低功耗,但是不会降低能耗。 124 | 125 | 目前,有几种方式尝试在时钟频率和电源电压保持不变的情况下来提高能效。 126 | 127 | - 以逸待劳。关闭非活动模块的时钟。比如没有浮点数操作时的浮点单元。 128 | 129 | - 动态电压-频率调整。通过降低电压,减少频率,使其在空闲时间功耗小一些。 130 | 131 | - 针对典型情景进行设计。比如低功耗模式,在空闲情况下对磁盘采用低转速模式等等。 132 | 133 | - 超频。在少数几个核上用较高的频率短时运行,直到温度开始上升。 134 | 135 | 尽管动态功耗更为主要,静态功耗也是确实存在的。静态功耗与静态电流和电压的乘积成正比。也就是说,静态功耗与器件数目成正比。 136 | 137 | 如果增加晶体管的数目,那么它们就算空闲着,也会增加功效。功耗极低的系统可能会关闭非活动模块的电源(电源门控)来缓解这个问题。 138 | 139 | 如果能选用速度快,能耗低的处理器,使其他部分进入睡眠,也有助于降低整体能耗。这种策略被称为**竞相暂停(race-to-halt)**。 140 | 141 | “暗硅”:由于热限制,在任意时刻,一个芯片的大部分都不能使用。使用领域专用的一些处理器,可以想办法减少那些低能效的运算,从而提高能效。也就是说,把通用核和专用核结合使用。 142 | 143 | ### 成本趋势 144 | 145 | 学习曲线:芯片的制造成本随着时间的推移而降低。学习曲线是根据**良率**测得的。良率,指的是成功通过测试的器件占所占生产器件总数的百分比。 146 | 147 | $$ 148 | 集成电路的成本=\frac{晶片成本+晶片测试成本+封装与最终测试成本}{最终测试良率}\\ 149 | 150 | $$ 151 | 152 | 关于其中的晶片成本,我们有: 153 | 154 | $$ 155 | 晶片成本=\frac{晶元成本}{每个晶圆上的晶片数\times 晶片良率} 156 | $$ 157 | 158 | 每个晶圆上的晶片数,我们可以通过下式计算: 159 | 160 | $$ 161 | 每个晶圆上的晶片数=\frac{\pi\times(晶圆直径/2)^2}{晶片面积}-\frac{\pi\times晶圆直径}{\sqrt{2\times晶片面积}} 162 | $$ 163 | 164 | 前一项是朴素的计算。后一项是对边角料的处理。 165 | 166 | ### 可信任度 167 | 168 | 这一点在计组中有所提及。指标有**MTTF**(平均无故障时间),**FIT**(故障率),**MTTR**(平均修复时间),**MTBF**(平均故障间隔时间)=MTTF+MTTR。 169 | 170 | 我们定义,模块可用性为$\frac{MTTF}{MTTF+MTTR}$ 171 | 172 | ### 性能的测量、报告和汇总 173 | 174 | 对于用户而言,一般更加在意缩短响应时间;WSC的操作人员就更关心吞吐量。 175 | 176 | 最直接的执行时间被定义为响应时间(elapsed time),即完成一项任务的延时。CPU时间则指的是处理器执行计算的时间,不包括等待IO等时间。 177 | 178 | ### 计算机设计的量化原理 179 | 180 | - 充分利用并行。 181 | 182 | - 局部性原理。 183 | 184 | - 重点关注常见情形。 185 | 186 | - Amdahl定律。 187 | 188 | ### 处理器性能公式 189 | 190 | $CPU时间=程序的CPU时钟周期数\times 时钟周期时间$ 191 | 192 | 我们定义CPI(每时钟周期指令数)为:$\frac{程序的CPU时钟周期数}{指令数}$ 193 | 194 | 从而,CPU时间也可以表示为$指令数\times CPI\times 时钟周期时间$ 195 | 196 | ## 存储器层次结构设计 197 | 198 | 个人移动设备:寄存器、L1cache、L2cache,经过存储总线到达内存,然后之后是存储。 199 | 200 | 对于电脑,一般会多一个L3缓存。存储一般由闪存和磁盘实现。 201 | 202 | 一般情况下,低层级存储器中的数据是上一级存储器中数据的超集。 203 | 204 | 如今由于多核处理器,对内存带宽的需求很大。为了实现高带宽,目前有多种方式: 205 | 206 | - 缓存的多端口和流水线。 207 | 208 | - 利用三级缓存。每个核有两级私有缓存,一个共享的L3缓存。 209 | 210 | 缓存缺失率的原因(3C): 211 | 212 | - 强制(compulsory)缺失 213 | 214 | - 容量(capacity)缺失 215 | 216 | - 冲突(conflict)缺失 217 | 218 | 基本的降低缺失率的方法: 219 | 220 | - 增大缓存块。 221 | 222 | - 增大缓存总容量。 223 | 224 | - 提高相联度。 225 | 226 | - 采用多级缓存。 227 | 228 | - 为读缺失分配比写操作更高的优先级。因为读缺失,可能命中到写缓冲区正在写入最新值的位置。 229 | 230 | - 在索引缓存期间避免虚实地址的转换,缩短命中时间。 231 | 232 | ### 存储器技术与优化 233 | 234 | #### SRAM 235 | 236 | SRAM不需要进行刷新。SRAM通常使用6个晶体管来保存1位数据,防止在读取时对信息造成的干扰。SRAM通常充当着cache作用载体的角色。目前,其基本被集成在芯片上。 237 | 238 | #### DRAM 239 | 240 | DRAM需要进行刷新,亦即"D"一词表征的含义。DRAM仅适用一个晶体管,来存储一位数据。为了实现地址线的复用,DRAM会在两个时期各发送地址的一半。在**行选通**(row access strobe, RAS)阶段发送一半地址,**列选通**(column access strobe, CAS)阶段发送另一半。这个名字的由来是DRAM的内部结构决定的。 241 | 242 | #### SDRAM 243 | 244 | 同步DRAM(synchronous DRAM, SDRAM),允许一种“突发式传输模式”。当处于这种模式后,无需再次指定新的列地址,数据就会被连续地发送。 245 | 246 | SDRAM引入了**体**(bank,存储体)的概念。对于不同存储体的访问,是可以互相重叠的。每一个存储体都有各自的行缓冲区。当下一个访问对象的行和存储体与之前相同时,那么只需要发送列地址就可以进行访问了。 247 | 248 | 内存访问的过程是: 249 | 250 | - DRAM控制器发送一个存储体编号和一个行号。该命令会打开这一行,并且把整行数据读入一个缓冲区中。 251 | 252 | - 发送一个列地址。SDRAM根据所处的模式(单个请求还是突发请求)进行数据传输。 253 | 254 | 如果要对一个新行进行访问,那么存储体就需要进行充电。 255 | 256 | 双倍数据速率(double data rate, DDR)使得存储器在时钟周期上升沿和下降沿都可以传输数据。 257 | 258 | 目前,DRAM通常在双列直插存储模块(DIMM)这种小型电路板上进行销售。 259 | 260 | #### 图形数据RAM(GDRAM) 261 | 262 | 为满足GPU需求进行特制。 263 | 264 | - 接口更宽,有32位。 265 | 266 | - 数据管脚上的最大时钟频率更高。 267 | 268 | GDDR中的每个DRAM带宽是DDR3 DRAM的2-5倍。 269 | 270 | #### 堆叠式或嵌入式DRAM 271 | 272 | 把DRAM通过堆叠、相依的方式嵌入到同一个处理器封装内部,降低访问延迟,带宽更高。其也被称为高带宽存储器(high bandwidth memory, HBM)。 273 | 274 | #### 闪存 275 | 276 | 闪存和DRAM的体系结构区别很大,性质也很不同。 277 | 278 | - 对闪存的读取时顺序进行的,并且一次会读取一整页。 279 | 280 | - 重写闪存之前,必须把**整个块**进行擦除再写入。 281 | 282 | - 闪存是非易失性的。 283 | 284 | - 闪存限制了给每个块的写入次数。并且通过写入均衡技术来延长闪存寿命。 285 | 286 | - 高密度的NAND闪存比SDRAM便宜,但是比磁盘贵。 287 | 288 | #### 相变存储器技术 289 | 290 | 利用发热元件,使块状基底的状态在晶态和非晶态之间转换。二者的电阻特性不同,每个bit和基底上的一个二维网络有关。每一个比特都和一个交叉点对应。因此,它也被称为忆阻器(memristor). 291 | 292 | ### 存储器系统的可靠性 293 | 294 | #### 硬错误 295 | 296 | 硬错误,也可以称作永久性故障。就是硬件完全废了,要用备用行来代替它的功能。 297 | 298 | #### 软错误 299 | 300 | 软错误,或者说是瞬态故障。电路没有发生改变,但是存储单元中的内容却自顾自改变掉了。软错误一般可以通过纠错码来检测和纠正。但是对于仓储级服务器而言,要是用Chipkill来进一步降低不可恢复错误的数量。 301 | 302 | ### 优化缓存性能的高级方法 303 | 304 | #### 小而简单的L1 cache 305 | 306 | L1 cache的使命就是要足够快。因此,采用小而简单的cache可以缩短命中时间,并且降低功耗。 307 | 308 | 随着相联度增加,对该cache的访问时间和能耗都会增加。但是在近期,L1 chche选择的相联度还是稍高一些的。只是因为一般而言,访问缓存时至少需要两个时钟周期。因此,命中时间稍微长一点关系不会很大。 309 | 310 | #### 路预测 311 | 312 | 缓存中另外保存了一些位,用来预测下一次缓存访问中的路,也就是组中的哪一块。 313 | 314 | #### 缓存访问流水化及采用多体缓存 315 | 316 | 通过这种方式,可以实现在每个时钟周期内进行多次访问,从而提高缓存的带宽。每一个存储体中,会交错着进行存储。比如一个存储体中,可能存放有0,4,8,12...为tag的块。从而达到顺序交错的结果。 317 | 318 | #### 非阻塞缓存 319 | 320 | 允许数据缓存在一次缺失期间继续提供缓存命中。也就是说,发生缓存缺失时,它会尝试命中别的需要的数据,比如i-cache中的信息,从而减少了停顿带来的损失。 321 | 322 | 但是,在实现上,非阻塞缓存是有一定困难的。主要有两个问题: 323 | 324 | - 命中和缺失之间可能存在冲突。 325 | 326 | - 跟踪尚未解决的缺失。 327 | 328 | 为了解决第一个问题,主要的方法是:为命中赋予比缺失更高的优先级,并且对相互冲突的缺失进行排队。 329 | 330 | 第二个问题,主要针对的是缺失返回的顺序不一定一致。因此,一般会引入一组被称为缺失状态处理寄存器(MSHR)的寄存器。每一个寄存器中都记录了每一个缺失应当进入缓存中的哪个位置,以及缺失的标签位的取值,以及关于哪个载入或存储指令导致了这一缺失的产生等等。 331 | 332 | #### 关键字先行和提前重新执行 333 | 334 | ##### 关键字先行 335 | 336 | 在缓存缺失时,首先向存储器请求需要的字,当其到达缓存后立即发给处理器。然后慢慢载入剩余的数据。 337 | 338 | ##### 提前重新执行 339 | 340 | 向存储器请求缺失字时,依旧按照正常顺序执行。但是,只要块中需要的字到达缓存后,就立刻把它发送给处理器。 341 | 342 | #### 合并写缓冲区 343 | 344 | 对于数据进行写操作时,我们可以把所有的写操作存放在一个写缓冲区中。在这里的写操作,处理器都会认为已经执行了。并且,如果发现较近的几个写操作,目标的地址是较为相近的,那么我们可以把这些地址放到同一个写条目下。也就是说,认为一个写操作是由多个相邻的写操作构成的一个向量写操作。这样的话,可以在一定程度上减少缺失惩罚。这种技术,我们称之为写合并(write merging)。 345 | 346 | #### 编译器优化 347 | 348 | - 循环交换。 349 | 350 | - 采用分块的方式。即对于一个多层循环而言,可能采取将数组分为多个子矩阵的方式。它的好处在于,可以保证相邻的几次计算,只要不是强制缺失,相邻的数据都可以被放在缓存里。不然的话,可能会因为某一层循环需要的数据过大,把之前的放入缓存的一些仍旧需要的数据给移出去了。 351 | 352 | #### 指令和数据的硬件预取 353 | 354 | 对于指令,如果发生了缺失,处理器一般一次性提取了两个块。 355 | 356 | #### 编译器控制预取 357 | 358 | 两种预取方式:寄存器预取,和缓存预取。这些指令是由编译器插入的。 359 | 360 | 需要注意的是,这些指令可能会产生异常。如果异常发生,则认为执行了一次空指令即可。 361 | 362 | #### HBM作为额外的一级缓存 363 | 364 | HBM,即高带宽内存(High Bandwidth Memory) 365 | 366 | 对于缓存而言,一直有一个碎片化的问题(虚拟存储系统中也存在)。如果一个缓存块中,大部分数据都没有被用到,那么传输这样的数据块的时间其实是很浪费的。并且,如果一个数据块的大小过大,那么缓存中可以保存的数据块数目就会少很多,从而可能会导致更多的缓存缺失的发生。 367 | 368 | 为了解决前一个问题,一个有效的方案是增加更多的子块。(这和削减块大小区别很大吗?但是可以想到的是,一个动机是为了减少存放缓存标签的数量。) 369 | 370 | ### 虚拟存储器和虚拟机 371 | 372 | 进程的切换(process switch),或者说是上下文切换(context switch),决定了要想要使得程序可以更好地隔离开来,体系结构必须提供至少两种模式,即用户进程和操作系统进程。后者也可以被称为(kernel)进程或者管理(supervisor)进程。 373 | 374 | 变换旁路缓冲区(TLB),其中的条目类似于缓存条目。其标签,保存的是虚拟地址的一部分。数据部分,保存的是物理页地址,保护字段,有效位,使用位和脏位(dirty bit)等等。 375 | 376 | #### 虚拟机(VM)提供保护 377 | 378 | 为虚拟机提供支持的软件称为虚拟机监视器(VMM)或者管理程序(hypervisor)。虚拟机的底层硬件平台被称为宿主机(host)。 379 | 380 | VM可以提供保护,也提供了一种可以运行整个软件栈的抽象,并且使得应用程序可以在不同的环境下运行,但是却共享着同一个硬件。 381 | 382 | #### VMM的任务 383 | 384 | - 保证客户软件在VM上的运行情况应该和原始硬件没有什么差别。 385 | 386 | - 客户软件**不能**去更改实际系统资源的分配。 387 | 388 | 为了实现虚拟存储器的虚拟化,VMM区分了实际存储器(real memory)和物理存储器(physical memory)之间的概念。实际存储器可以视为是虚拟存储器和物理存储器之间的一个中间层级。还有一种说法,将二者分别命名为物理存储器和机器存储器。 389 | 390 | VMM通过维护一张影子页表(shadow page table)来维护从客户虚拟地址空间到硬件物理地址空间的映射。用户不应当尝试去修改自己的页表。只有系统级进程对页表的修改操作可以被放行。 391 | 392 | 虚拟缓存并不是所有的体系结构里都有的。因为它存在着一些问题。 393 | 394 | - 在切换进程时,虚拟地址会指向不同的物理地址。因此,切换进程后必须对缓存进行刷新。一种方案是通过进程识别符标记(PID)来作为缓存地址标记的一部分即可。 395 | 396 | - 必须要提供保护。不然就不能够起到虚拟机的隔离作用。 397 | 398 | - 虚拟缓存没有变得更普及的另一个原因,是因为OS和用户程序可能会为同一个物理地址分配了两个不同的虚拟地址。这些重复地址被称为同义地址,或者别名地址。如果虚拟缓存中有一个被修改了,而另外一个却没有同步更新,那就会出错。为了解决这个问题,需要做别名(alias)消去,也就是保证每个缓存块都拥有不同的物理地址。当然,软件也可可以通过强制的手段,共享某些地址位,也就是进行所谓的页面着色,来解决这个问题。也就是说,所有的别名地址都具有着相同的特征等等。 399 | 400 | ## 线程级并行 401 | 402 | - 多处理器模型一:运行一组紧密耦合的线程协同完成一项任务:并行处理。 403 | 404 | - 多处理器模型二:分别执行多个相对独立的进程,即请求级冰鞋。称为多道程序。 405 | 406 | 在多处理器中,分配给一个线程的计算量称为粒度大小。 407 | 408 | 多处理器我们根据存储器的组织方式分为两类: 409 | 410 | - 对称共享存储器多处理器(SMP),也称为集中式共享存储器多处理器。这也是大多数多核处理器采用的方式。其有时也被称为一致存储器访问(UMA)多处理器。每个处理器独自占有L1、L2等部分。共享层次更后的缓存。 411 | 412 | - 分布式共享存储器(DSM)。每一个处理器都有自己独占的存储器。每个处理器可以向自己的存储器发出请求,也可以向远程的存储器发出请求。但显然,自己的存储器会更快一些。 413 | 414 | 在上述行文中的共享存储器,指的是地址空间(address space)是共享的。 415 | 416 | ### 多处理器缓存一致性 417 | 418 | 一致性(coherence):定义读操作返回什么值。 419 | 420 | 连贯性(consistency,我觉得更应该被翻译成保序性):定义写入值什么时候能被返回。 421 | 422 | 存储器系统一致性的条件: 423 | 424 | - 同一个处理器,对某一个位置进行的读操作,跟在对该位置的写操作之后。倘若在这段时间里没有其他处理器对该位置进行写操作,那么一定会返回上一次写操作的值。 425 | 426 | - 不同处理器,经过足够长的时间后,对某一个位置进行的读操作,跟在对该位置的写操作之后。倘若在这段时间里没有其他处理器对该位置进行写操作,那么一定会返回上一次写操作的值。 427 | 428 | - 不同处理器,对某一位置的写操作是串行化的。 429 | 430 | #### 一致性的基本实现方案 431 | 432 | - 迁移 433 | 434 | - 复制 435 | 436 | 主要问题在于,独占缓存部分的一致性是需要想办法保证的。 437 | 438 | 两种缓存一致性协议: 439 | 440 | - 目录协议:把特定物理内存块的共享状态保存在一个位置中。称之为目录。 441 | 442 | - 监听协议:监听协议有两种实现方式,写无效协议和写入更新(写入广播协议)。目前主流的视线方式是写无效协议。 443 | 444 | 在写穿透(write through)中,实现写无效协议是相对简单的。但是对于写返回(write return)中,想要实现写无效协议是更具有一定难度的。因为当前数据并非一定在存储器中。一种常见的解决方案,是每个处理器都要保持对读写信号的监听。如果发现自己拥有所请求内容的有效脏副本,那么就提供出去。为了跟踪缓存块是否被共享,可以再次添加一个bit。当被共享时,就需要对这个bit修改状态。并且在之后,也要把它放到总线上。这样的话,其他块就会收到相应的失效信息,并且这个块被标记成了**独占(exclusive)** 状态,并且拥有这个唯一副本的核被称为这个缓存块的拥有者。 445 | 446 | #### 基本一致性协议的扩展 447 | 448 | 常见的一致性协议具有MSI三种状态(modified, shared, invalid)。MESI协议中添加了exclusive这种状态。MOESI则在MESI协议中添加了owned这种状态。表示该缓存拥有这个块的最新副本,但是在存储器中已经过时。 449 | 450 | 多处理器可能会产生的更多种缺失可能:真共享缺失和假共享缺失,前者顾名思义,而后者则是因为采用了基于无效的一致性算法导致的。 451 | 452 | #### DSM和目录式一致性 453 | 454 | 目录协议中,保存了每个可缓存块的状态。比如有哪些缓存持有该块的副本,是否需要进行更新等等。 455 | 456 | 在目录协议的简单协议下,状态可能为: 457 | 458 | - 共享。一个及以上节点缓存了这个块。存储器的值是最新的。 459 | 460 | - 未缓存。没有节点缓存了这个块。 461 | 462 | - 已修改。只有一个节点拥有这个缓存块的副本。并且,这个节点已经对这个块进行了写操作。 463 | 464 | 每个目录,都负责着本节点的存储器上,所有可缓存块的信息。 465 | 466 | 由于分布性的特点,处理器访问的地址不同,那么访存的时间也可能不同:因为分布式的特点,存储器可能在本节点,也可能不在。 467 | 468 | #### 同步 469 | 470 | 在监听协议和目录协议中,我们默认了操作的原子性,但实际上并不好说。我们需要更多的操作来维护其原子性。 471 | 472 | #### consistency 473 | 474 | 顺序一致性:每次程序执行的结果都是一样的。一种方式,是要求处理器把访存导致的所有无效信号都发射完毕,才可以宣告该处理器的访存操作完成。或者,推迟下一次访存,直到本次访存完全结束。也就是说,单个进程内的操作顺序必须和编码时的情况相同。 475 | 476 | ## 向量、 SIMD 和 GPU 477 | 478 | ### 向量体系结构 479 | 480 | 在 RV64V中,有这些组件: 481 | 482 | - 向量寄存器:每个向量寄存器都保存一个向量,比如32个64位元素。 483 | 484 | - 向量功能单元:用于计算。 485 | 486 | - 向量载入、存储单元:从存储器中载入向量,或者把向量存储到存储器中。 487 | 488 | - 标量寄存器:就是正常的那些寄存器。 489 | 490 | 动态寄存器类型设定:每一个向量寄存器需要配置它们的数据类型和宽度。 491 | 492 | 编译器可以为非跨迭代相关的代码生成向量指令,从而提高效率。 493 | 494 | 现代的向量计算机具有多条并行的流水线。它们可以在每个时钟周期生成一个或多个结果。护航指令组(convoy):一组可以一起执行的向量指令。它们之间不包含任何结构冒险。 495 | 496 | 执行一个护航指令组所需的时间单位称为钟鸣(chime)。如果向量长度为$n$,那么执行这条指令所需的时间大概就是钟鸣乘上向量长度。 497 | 498 | 钟鸣的问题在于,它忽略了向量的启动延迟等问题。向量功能单元的流水线在被填满之前会有延迟。 499 | 500 | 谓词寄存器:如果迭代过程中有分支跳转语句,那么我们需要额外的一些操作。比如说,我们可以额外引入一个谓词寄存器,每一位用来代表是否要执行分支跳转。这一方式被称为向量掩码控制。 501 | 502 | 解决向量长度不确定的问题:额外添加一个向量长度寄存器来控制所有向量运算的长度。为了避免生成向量长度大于硬件可接受的长度,我们采用一种称为条带挖掘的技术,从而把过长的向量拆开来。 503 | 504 | 处理多维数组时,可能会有步幅的问题。也就是说,正在被相邻处理的元素不一定是物理上相邻的。向量按步幅加载时,效率可能会低一些。 505 | 506 | 集中-分散:支持稀疏向量的压缩表示。 507 | 508 | ### 多媒体 SIMD 509 | 510 | 和向量体系结构相比,它的问题在于没有向量长度寄存器,没有步幅或者集中/分散数据传送指令,也没有掩码寄存器。它的好处在于易于实现,并且不需要像向量体系结构中那样,有很高的传输带宽。 511 | 512 | 屋檐性能模型:把浮点性能、存储器性能、运算密度汇总在一个二维图形里。运算密度是梅子姐存储器访问的数据可以支持的浮点运算次数。 513 | 514 | ### 图形处理器 515 | 516 | CUDA: Compute Unified Device Architecture 517 | 518 | CUDA线程被认为是所有这些并行形式的统一主题。CUDA线程被分块、分组执行,称之为线程块(thread block)。 519 | 520 | 网格(grid) 指的是在 GPU上运行的,由一组线程块(thread block)构成的代码。 521 | 522 | 线程块调度器(thread block scheduler)把线程块指定给相对应的处理器。称之为多线程 SIMD 处理器。 523 | 524 | 专用存储器(private memory):多线程 SIMD处理器中的每一条 SIMD 通道会获得片外 DRAM 上的一个专用部分。用来存储一些私有变量。而片上的存储器称为局部存储器。 525 | -------------------------------------------------------------------------------- /2024_Fall/Modern Algebra.md: -------------------------------------------------------------------------------- 1 | # Modern Algebra 2 | 3 | ## 等价关系 4 | 5 | 对于非空集合$A$上的关系$R$,若$R$具有自反性,对称性和传递性,那么$R$就是$A$上的等价关系。 6 | 7 | ## 商集 8 | 9 | 对于非空集合$A$上的关系$R$,以$R$的不相交的等价类为元素的集合,记作$A/R$ 10 | 11 | ## 划分 12 | 13 | 如果存在集合$\pi$: 14 | 15 | - $\forall x,x\in\pi\implies x\sub A$ 16 | 17 | - $\empty\not\in\pi$ 18 | 19 | - $\cup\pi=A$ 20 | 21 | - $\forall x, y\in\pi,x\cap y=\empty$ 22 | 23 | 那么我们就称集合$\pi$是一个划分,称$\pi$中的元素为$A$的划分块。 24 | 25 | 对于一个$A$上的等价关系$R$,$A/R$就是$A$的一个划分。它被称为由等价关系$R$诱导出的$A$的划分。A的划分显然也可以诱导出一个等价关系。 26 | 27 | ## 偏序关系 28 | 29 | 集合中任意两个元素都可比,那么这种比较关系称为全序关系。 30 | 31 | ## 群的定义 32 | 33 | - 封闭性 34 | 35 | - 结合性 36 | 37 | - 单位元 38 | 39 | - 逆元 40 | 41 | - 非空集合 42 | 43 | 如果一个群的运算还符合交换律,那么它就是可交换群。 44 | 45 | 单位元是唯一的。 46 | 47 | 每一个元素的逆元也是唯一的。 48 | 49 | 从而,群具有消去律。 50 | 51 | 群的等价定义:可以把单位元和逆元改为左单位元和左逆元。 52 | 53 | 群的等价定义:可以把单位元和逆元改为$\forall a,b\in G, ax=b,ya=b$在$G$中有解。 54 | 55 | 有限群的等价定义:可以把单位元和逆元改为符合左右消去律。 56 | 57 | ## 子群的定义 58 | 59 | $H\sub G$,$H$和原有运算符合群的定义。 60 | 61 | 等价定义:$HH\sub H;H^{-1}\sub H$ 62 | 63 | 子群的并不一定是子群,但子群的交一定是子群。 64 | 65 | ## 同构 66 | 67 | $$ 68 | f:G_1\to G_2\\ 69 | f(a\cdot b)=f(a)\oplus f(b) 70 | $$ 71 | 72 | 这是个双射。 73 | 74 | ## 生成群 75 | 76 | 群中包含某些元素的最小子群。这些元素构成的集合称之为生成元。我们也可以将生成元生成的群看作是所有包含这些元素的循环群的交。 77 | 78 | 如果只挑选了一个或两个元素,那么这里可以简记。 79 | 80 | ## 循环群 81 | 82 | 生成元中只有一个元素的群。要么是无限循环群,要么是有限循环群。两种结构的形状是特定的。无限循环群和整数加法群同构。 83 | 84 | 最小的非循环群阶为4. 85 | 86 | 循环群的子群也是循环群。 87 | 88 | ## 阶 89 | 90 | 元素的阶$g(a):a^{g(a)}=1$ 91 | 92 | 群的阶:群中元素的数目。 93 | 94 | $$ 95 | \text{ord}(g) = t, g^m=1\implies t|m\\ 96 | 97 | \text{ord}(g)=t\implies \text{ord}(g^s)=t/\text{gcd(t, s)},\text{ord}(g^s)=\text{ord}(g^{\text{gcd}(t, s)}) 98 | $$ 99 | 100 | ## 平面上的运动群 101 | 102 | 对于所有的非空集合$M$而言,我们称$M$上的可逆变换指$M\to M$的双射。 103 | 104 | 平面$P$的一个变换,指的是$P$的一个保距变换。平面运动的几何方式有且仅有三种:平移、旋转、翻折加平移。 105 | 106 | 我们定义变换的运算为变换的复合。那么所有的变换和这种运算构成了一个群。我们称之为$M$的对称群。$M$的对称群的子群称为$M$的变换群。 107 | 108 | 我们用$M(\R^2)$代表$\R^2$上的所有运动。所有平面上的运动和上述乘法构成了一个群。我们称之为平面$\R^2$上的运动群。对于一个平面图形$K$而言,我们称所有能够使原图形与之重合,那么记其为$S(K)$,称其为平面图形$K$的对称群。 109 | 110 | ## Cayley's Theorem 111 | 112 | 任何群都同构于一个变换群。 113 | 114 | 对于一个集合而言,每一个元素都对应一个$G$上的可逆映射$T_g:x\to gx$.因此,$G$和$G$上的一个变换子群同构。 115 | 116 | ## Permutation 117 | 118 | 一个置换,指的是一个有限集合上,自身到自身的一个双射。$n$个元素构成的集合上的所有置换构成的集合,其元素个数显然为$n!$个。 119 | 120 | 对称群,对于$n$而言,它指的就是关于$[1,n]\cap\N$上的所有置换组成的集合,记为$S_n$。它的子群,我们就称之为置换群。交错群,指的就是对称群中所有的偶置换群,记为$A_n$。 121 | 122 | ## cycle 123 | 124 | 指的是置换时构成一个首尾相接的结构。如果cycle的长度为偶数,我们称之为偶轮换。如果只有两个元素,那么我们称这个轮换为对换。 125 | 126 | 所有的置换可以唯一地分解成若干个不相交的轮换之乘积。如果轮换之间是不相交的,那么它们之间交换顺序是没有任何关系的。否则,我们要严格地从右向左进行轮换操作。 127 | 128 | 如果一个置换就是一个轮换,那么它的级就是其中元素的个数。如果它会被分解成若干个轮换,那么它的级为所轮换的长度的最小公倍数。 129 | 130 | 关于轮换,我们有这样的等式成立: 131 | 132 | $$ 133 | (k\ l)(k\ a\ ...\ b)(l\ c\ ...\ d)=(k\ a\ ...\ b\ l\ c\ ...\ d)\\ 134 | (k\ l)(k\ a\ ...\ b\ l\ c\ ...\ d)=(k\ a\ ...\ b)(l\ c\ ...\ d) 135 | $$ 136 | 137 | 如果一个置换中的偶轮换有偶数个,那么我们称这个置换为偶的。否则,就是奇的。 138 | 139 | 这是因为,所有的轮换都可以分解为若干个对换。所有偶置换最终可以转化为偶数个对换。所有的奇置换最终可以转换为奇数个对换。尽管对换分解的表示方式可能是不唯一的,但是奇偶性一定是相同的。 140 | 141 | ## coset 142 | 143 | $$ 144 | g\in G, A\sub G,A\to gA 145 | $$ 146 | 147 | 这个映射是个双射。特殊地,如果$A$是$g$的子群,那么我们称$gA$为$H$由$g$产生的左陪集。同理,$Ag$就是右陪集了。 148 | 149 | 如果$H$是$G$的有限子群,那么$H$和$gH$中的元素一样多。 150 | 151 | 如果$H\leq G$,那么关于$H$,有这些性质: 152 | 153 | - $\forall g\in G, g\in gH$ 154 | 155 | - $a,b\in G,\exist h\in H,b=ah\iff aH=bH$ 156 | 157 | - $aH\cap bH\neq\empty\implies aH=bH$ 158 | 159 | 左陪集和右陪集的数量一样多。 160 | 161 | 实际上,我们可以把满足性质二的元素看成是一个等价类。 162 | 163 | ### index 164 | 165 | $[G:H]$用来表示$G$在$H$中的index.表示有多少个与$H$不同的且大小相同的陪集。实际上,我们有$|G|=|H|[G:H]$ 166 | 167 | 如果$G$是一个有限群。$a\in G\implies ||\ \ |\ \ |G|,a^{|G|}=1$ 168 | 169 | 如果$G$是有限群,那么其中每一个元素的阶一定都是$|G|$的因子。 170 | 171 | 因此,如果$G$的阶是质数,那么它一定是一个循环群。 172 | 173 | ## Euler's Theorem 174 | 175 | 如果$a,n$互质,并且$n\geq 2$,那么$a^{\phi(n)}\equiv1\ \text{mod}\ n$ 176 | 177 | 关于$\phi(n)$的计算,我们有: 178 | 179 | $$ 180 | n=p_1^{e_1}...p_t^{e_t},\phi(n)=\prod_{i=1}^t(1-\frac{1}{p_i}) 181 | $$ 182 | 183 | 推论,费马小定理: 184 | 185 | $p$是质数,并且$a$不是$p$的倍数,那么$a^{p-1}\equiv 1\ \text{mod}\ p$ 186 | 187 | ## 正规子群和同态 188 | 189 | 如果$H,K$均为$G$的子群,并且$G$是可交换群,那么$HK$一定是个群。 190 | 191 | $$ 192 | H,K\leq G, HK\leq G\iff HK=KH\\ 193 | \forall a, b\in G,H\leq G,(aH)(bH)=abH\iff\forall c\in G,cH=Hc 194 | $$ 195 | 196 | 如果$H\leq G$我们称$H$是$G$的正规子群当且仅当下面中某一个成立: 197 | 198 | - $cHc^{-1}\sub H,\forall c\in G$ 199 | 200 | - $cHc^{-1}=H,\forall c\in G$ 201 | 202 | - $cH=Hc,\forall c\in G$ 203 | 204 | - $H$在$G$中的所有左陪集也是$G$中的一个右陪集。 205 | 206 | - $H$在$G$中的所有右陪集也是$G$中的一个左陪集。 207 | 208 | 正规子群最重要的性质,就是左陪集等于右陪集。 209 | 210 | 我们记$G/N$为$G$关于$N$的商群,其元素为所有的关于$N$的陪集,其中$N$是$G$的正规子群。 211 | 212 | $f:G\to G'$,其中$G$和$G'$是两个群,我们称$f$是一个同态映射,如果$\forall a,b\in G, f(ab)=f(a)f(b)$ 213 | 214 | 同态映射会把单位元映射为另一个集合中的单位元。并且,$f(a^{-1})=f(a)^{-1}$ 215 | 216 | 我们称同态映射的核(kernel)为所有把原集合中的元素映射为相集中的单位元的元素的集合。 217 | 218 | 我们称,$\pi:G\to G/N,\pi(a)=aN$为自然同态。它的核为$N$. 219 | 220 | 一个同态是单射,当且仅当核中只有单位元。 221 | 222 | 考虑$f:G\to G'$是一个同态。 223 | 224 | - $M\leq G\implies f(M)\leq G'$,如果$f$是满的,并且$M$是正规子群,那么$f(M)$也是$f(G)$(注意不是$G'$)正规子群。 225 | 226 | - $K\leq G'\implies f^{-1}(K)\leq G$,如果$K$是正规的,那么$f^{-1}(K)$也是正规的。 227 | 228 | ## Factor Theorem 229 | 230 | 同态映射$f:G\to G$的核$K$中包含着$N$,考虑由$N$诱导出的自然映射$\pi:G\to G/N$,那么存在一个同态$\bar f:G/N\to G',s.t.\ \bar f\circ\pi = f$,并且还具有这些性质: 231 | 232 | - $\bar f$是满的当且仅当$f$是满的。 233 | 234 | - $\bar f$是单的,当且仅当$K=N$。 235 | 236 | - $\bar f$是同构,当且仅当$f$是满的,并且$K=N$ 237 | 238 | ## 同构定理 239 | 240 | ### 第一同构定理 241 | 242 | $f:G\to G'$是以$K$为核的同态,那么$\text{img}(f)$与$G/K$同构。 243 | 244 | ### 第二同构定理 245 | 246 | 引理:$H,N\leq G$,并且$N$在$G$中是正规的,那么: 247 | 248 | - $HN=NH$ 249 | 250 | - $N$是$HN$的正规子群。 251 | 252 | - $H\cap N$是$N$的正规子群。 253 | 254 | 第二同构定理:$H,N\leq G$,$N$在$G$中是正规的,那么$H/(H\cap N)$与$HN/N$中存在同构。 255 | 256 | ### 第三同构定理 257 | 258 | $H,N$都在$G$中正规,并且$N\sub H$,则$G/H$与$(G/N)/(H/N)$同构。 259 | 260 | ## 群与商群间的一一对应定理 261 | 262 | 如果$N$是$G$的正规子群,那么$G$中所有包含$N$的子群和商群$G/N$的子群存在一一对应关系。即$N\leq H\leq G$,则$H/N\leq G/N$ 263 | 264 | 也就是说,存在这样一个一一映射$\psi:H\mapsto H/N$。并且$H_1\leq H_2\iff H_1/N\leq H_2/N$,并且此时有$[H_2:H_1]=[H_2/N:H_1/N]$ 265 | 266 | $H$是$G$的正规子群,当且仅当$H/N$是$G/N$中的正规子群。 267 | 268 | $H_1$是$H_2$的正规子群,当且仅当$H_1/N$是$H_2/N$的正规子群。并且,$H_2/H_1$与$(H_2/N)/(H_1/N)$同构。 269 | 270 | ## 有限交换群 271 | 272 | 在阶为$n$的循环群$$中,$\forall n,m\in \Z^+,m|n\implies\exists H\leq ,\text{ord}(H)=m$ 273 | 274 | 如果$G$是有限交换群,$\text{ord}(G)=n=pm,p\ \text{ is prime,}\implies \exists a\in G,a^p=1$ 275 | 276 | 如果$G$是有限交换群,$\text{ord}(G)=n,\forall m,n\in\Z^+,m|n\implies\exists H\leq G,\text{ord}(H)=m$ 277 | 278 | ## 群在集合上的作用 279 | 280 | $G$是一个群,假设它作用在集合$X$上,那么$\forall g\in G$存在一个映射$x\mapsto g\circ x\in X$,并且$h\circ(g\circ x)=(hg)\circ x$,$1\circ x=x$ 281 | 282 | 一个群在一个集合上的作用,诱导出一个从$G$到$S_X$的一个同态。 283 | 284 | 需要注意的是,函数$f_g$是一个双射。 285 | 286 | 设$a\in G$,若$\forall x\in G,ax=xa$,那么称$a$是$G$的中心元。 287 | 288 | 我们称$B(x)=\{gx:g\in G\}$为$x$的轨道。 289 | 290 | 一个元素$x$的稳定子是$G(x)=\{g\in G:gx=x\}$,它是$G$的一个子群。如果$y=ax$,那么$G(y)=aG(x)a^{-1}$ 291 | 292 | 一个元素的每一个轨道都是一个等价类。从而,一个元素轨道的数量$|B(x)|=[G:G(x)]$,因为它们都是等价类。 293 | 294 | 对于一个群的共轭而言,它的每个元素诱导出的映射,稳定子就是中心子。并且有$|G|=|C|+\sum_{i}[G:C_G(x_i)]$ 295 | 296 | 对于一个有限群而言,如果$H,K$都是$G$的子群,那么$|HK|=\frac{|H||K|}{|H\cap K|}$ 297 | 298 | 对于一个有限群$G$而言,假如其作用在有限群$X$上,并且令$f(g)=|\{x\in X:g\circ x=x\}|$,那么$G$作用在$X$上的轨道数量是$\frac{1}{|G|}\sum_{g\in G}f(g)$ 299 | 300 | 主要思路还是数两次。为了解决串珠染色问题,我们就可以通过数轨道的方式进行确认。 301 | 302 | ## 西罗定理 303 | 304 | 考虑一个素数$p$,我们称一个非平凡群是$p-group$当其中每一个元素的阶都是$p^r$.如果$|G|=p^rm,p\not|\ m$,那么对于$G$的子群$P$,如果它的阶是$p^r$,那么我们就称它为$G$的$Sylow\ p-subgroup$ 305 | 306 | 如果$G$是个有限群,那么$G$是个$p-group$当且仅当$G$的阶是$p$的幂次。 307 | 308 | $G$是一个阶为$p^rm$的群,$p$是个素数,$r\in \Z^+$,$p\not|\ m$,则: 309 | 310 | - $G$一定有至少一个$Sylow\ p-group$,并且$G$的每个$p-subgroup$都被包含于一个$Sylow\ p-subgroup$ 311 | 312 | - $n_p$是$G$中$Sylow\ p-subgroup$的数量。那么$n_p\equiv1\text{mod}\ p,n_p|m$ 313 | 314 | - 所有的$Sylow\ p-subgroup$都是共轭的。 315 | 316 | 如果一个群$G$的阶可以被素数$p$整除,那么$G$一定有一个阶为$p$的元素。 317 | -------------------------------------------------------------------------------- /2024_Fall/Optimization.md: -------------------------------------------------------------------------------- 1 | # Optimization 2 | 3 | ## Lec 2 4 | 5 | Weierstrass极值定理: 6 | 7 | $$ 8 | S\ \text{is compact},f:S\to\R\text{ is continuous on }S,f \text{ is bounded and has both}\\ 9 | \text{min and max values.} 10 | $$ 11 | 12 | 方向导数: 13 | 14 | $$ 15 | \nabla_vf(x_0)=\lim_{h\to 0}\frac{f(x_0+hv)-f(x_0)}{h} 16 | $$ 17 | 18 | 偏导数就是取单位向量。 19 | 20 | 可微: 21 | 22 | $$ 23 | \lim_{x\to x_0}\frac{||f(x)-f(x_0)-J(x-x_0)||}{||x-x_0||}=0 24 | $$ 25 | 26 | 其中,$\text{d}f(x_0)=J,\nabla f(x_0)=J^T$ 27 | 28 | 一般地,有: 29 | 30 | $$ 31 | \nabla_vf(x_0)=\nabla f(x_0)^Tv 32 | $$ 33 | 34 | 一阶必要条件: 35 | 36 | $$ 37 | f\text{ is diffenrential, }\text{for any feasible direction }v,\nabla_v f(x^*)\geq 0 38 | $$ 39 | 40 | 如果$x^*$是个内点,那么上式应为$\nabla f(x^*)=0$ 41 | 42 | Schwarz's theorem: 43 | 44 | $$ 45 | f:\Omega\subset\R^n\to\R,x\in\Omega \text{ s.t }B(x,\varepsilon)\sub\Omega,f\text{ has continuous }\frac{\partial^2f}{\partial x_ix_j}\\ 46 | \text{forall }i,j,\text{then }\frac{\partial^2f}{\partial x_ix_j}=\frac{\partial^2f}{\partial x_jx_i} 47 | $$ 48 | 49 | 二阶必要条件: 50 | 51 | $$ 52 | f\text{ is twice continuously differentiable, }\forall v\in\R^n\\ 53 | v^T\nabla^2f(x^*)v\geq 0 54 | $$ 55 | 56 | Sylvester's criterion: 57 | 58 | - $A$ 是正定的,等价于所有顺序主子式大于零。 59 | 60 | - $A$ 是半正定的,等价于所有主子式不小于零。 61 | 62 | - 如果所有顺序主子式大于零,且$\text{det}(A)\geq0$,那么$A$ 是半正定的。 63 | 64 | 二阶充分条件: 65 | 66 | $$ 67 | f:\R^n\to\R\text{ is a twice continuously differentiable function, }\\ 68 | \nabla f(x^*)=0,\nabla^2f(x^*)>0 69 | $$ 70 | 71 | ## Lec 3 72 | 73 | ### lines, rays and segments 74 | 75 | 通过不相同两点$x,y$的直线可以表示为: 76 | 77 | $$ 78 | \theta x+(1-\theta)y,\theta\in\R 79 | $$ 80 | 81 | 类似地,射线和线段就可以表示为: 82 | 83 | $$ 84 | \theta x+(1-\theta)y,\theta\geq0\\ 85 | \theta x+(1-\theta)y,\theta\in[0,1] 86 | $$ 87 | 88 | 为了简便,在之后,我们记$1-\theta$为$\bar\theta$. 89 | 90 | ### convex sets 91 | 92 | 我们称一个$\R^n$中的集合,当且仅当: 93 | 94 | $$ 95 | x\in C,y\in C,\theta\in[0,1]\implies\theta x+\bar\theta y\in C 96 | $$ 97 | 98 | 我们称这样,系数和为1的组合为$x,y$的凸组合。 99 | 100 | 空集,直线类,点,超平面,半平面,仿射空间,凸多面体$\{x|Ax\leq b\}$不等号表征各个元素比较,范数球,椭圆,半正定矩阵等都是凸的。 101 | 102 | 仿射空间$\{x|Ax=b\}$是凸多面体。因为等号可以由两个不等式组合得到。 103 | 104 | ### convexity preserving operations 105 | 106 | 两个凸集取交,还是凸集。 107 | 108 | 将凸集进行仿射变换,结果还是凸集。 109 | 110 | 仿射变换的逆变换也是保凸的。 111 | 112 | ### convex hull 113 | 114 | 考察$x_1,...,x_m\in \R^n$,我们称:$\sum_{i=1}^m\theta_ix_i$为前述点的凸组合。其中,我们规定$\theta_i\geq0,\sum_{i=1}^m\theta_i=1$ 115 | 116 | 如果前述点在一凸集中,那么这样的凸组合一定在该凸集中。这一点可以通过两个两个逐次吃下去来证明。 117 | 118 | 我们称包含集合$S$的最小凸集为$S$的凸包,记作$\text{conv}(S)$ 119 | 120 | 实际上,凸包就是$S$中的凸组合构成的集合。 121 | 122 | ### simplexes 123 | 124 | 考虑点$x_0,...,x_m\in\R^n$,我们称这些点是仿射独立的,如果$x_i-x_{i-1}$之间全都线性独立。 125 | 126 | 仿射独立的充要条件是$\sum_{i=0}^mc_i=0,\sum_{i=0}^mc_ix_i=0\implies\forall i\in[m],c_i=0$ 127 | 128 | 一个m维的单纯形,指的是给出的m+1个仿射独立点的凸包。 129 | 130 | 符合直觉的,零维单纯形是个点,一维单纯形是个线段,二维单纯形是个三角形,三维单纯形是个四面体。 131 | 132 | 我们称由标准基向量构成的单纯形为probability n-simplex,它应该在n+1维中存在。我们称由零向量和所有标准基向量构成的单纯形为unit n-simplex,它在n维中存在。 133 | 134 | 单纯形实际上可以看作由$\R^m$到$\R^n$的一个线性变换。 135 | 136 | ### convex cones 137 | 138 | 我们称一个集合是个锥,如果$x\in C\implies\theta x\in C,\theta\geq0$ 139 | 140 | 凸锥,就是凸的锥。从直觉上看,凸锥感觉像是几条锥边封闭出的一个空间。 141 | 142 | 一个集合是凸锥,当且仅当: 143 | 144 | $$ 145 | x_1,x_2\in C,\theta_1,\theta_2\geq0\implies \theta_1x_1+\theta_2x_2\in C 146 | $$ 147 | 148 | 我们称$x_1,...,x_m$的锥组合为: 149 | 150 | $$ 151 | \sum_{i=1}^m\theta_ix_i,\forall i\in[m],\theta_i\geq0 152 | $$ 153 | 154 | 我们称一个集合$S$的锥包(conic hull)为包含一个$S$的最小凸锥,记作$\text{cone}(S)$ 155 | 156 | ### projection onto convex set 157 | 158 | 我们称$x$与集合$C$之间的距离为$\text{dist}(x,C)=\inf_{z\in C}||x-z||$ 159 | 160 | 如果这样的$C$是非空的,封闭的并且是凸的,那么一定存在唯一的$\hat x$,使得$\text{dist}(x,C)=||x-\hat x||$,我们把这样的$\hat x$称作$x$在$C$上的投影,记作$P_C(x)$.显然,一个点的投影倘若等于其本身,那么它一定在$C$中。 161 | 162 | 从直觉上想,封闭的在保证存在性,凸在保证唯一性。 163 | 164 | 如果$C$是非空的,封闭的,凸的,那么$\leq 0,z\in C$,也就是说,这些向量之间的夹角一定不是锐角。 165 | 166 | 投影运算是非扩张的。也就是说,$||P_C(x)-P_C(y)||\leq||x-y||$ 167 | 168 | 如果C是非空的,封闭的,并且是凸的,那么$x_0\not\in C,\exists w\in \R^n-\{0\},s.t. \sup_{x\in C}\ <\ $ 169 | 170 | 这是因为$wx=$确立了一个超平面。从直觉上想,这在描述外点和闭凸集之间线性可分。 171 | 172 | ### supporting and separating hyperplane theorems 173 | 174 | 我们考虑$\partial C$上一点$x_0$,那么存在超平面$P=\{x:w^Tx=w^Tx_0\}$,如果其满足:$\leq,\forall x\in C$,那么我们称这样的超平面为集合$C$在$x_0$处的支撑超平面。对于非空凸集而言,这样的支撑超平面在边界处总是存在的。 175 | 176 | 凸集具有很好的性质,它的内点与其闭包的内点相同。它的边界点与其闭包的边界点也相同。 177 | 178 | 对于两个非空不相交凸集$C_1,C_2$而言,它们一定可以被一个超平面可分。也就是说,$\exist w\in \R^n-\{0\},b\in \R,w^Tx\leq b, x\in C_1;w^Tx\geq b,x\in C_2$ 179 | 180 | 具体的证明方式,可以考虑$C:\{x|x=x_1-x_2,\forall x_1\in C_1,\forall x_2\in C_2\}$由于这两个集合之间是不相交的,因此零向量一定不在这个集合中。 181 | 182 | 因此,我们只需要考虑$\leq 0,\forall x\in C$。之后可得。 183 | 184 | Farkas' lemma:$A\in\R^{m\times n},b\in\R^m$,那么这两个集合当中有且仅有一个是空的: 185 | 186 | $$ 187 | S_1=\{x\in\R^n:Ax=b,x\geq0\}\\ 188 | S_2=\{y\in R^m:A^Ty\leq 0,b^Ty>0\} 189 | $$ 190 | 191 | 第一个集合是空集,当且仅当$b$在$\text{cone}(A)$内。$A^Ty\leq 0$等价于所有所有$\text{cone}(A)$内的点$z$,有$z^Ty\leq 0$ 192 | 193 | 所有的锥包都是封闭的。 194 | 195 | ## convex functions 196 | 197 | 凸函数的定义: 198 | 199 | - $\text{dom}(f)=S$是个凸集。 200 | 201 | - $\forall x, y\in S,\theta\in[0,1],f(\theta x+\bar\theta y)\leq\theta f(x)+\bar\theta f(y)$ 202 | 203 | 也就是琴生不等式成立。 204 | 205 | 严格凸函数的定义:上述第二点改为$\theta\in(0,1),f(\theta x+\bar\theta y)<\theta f(x)+\bar\theta f(y)$ 206 | 207 | - $f凸\iff -f凹$ 208 | 209 | - $f严格凸\iff -f严格凹$ 210 | 211 | 对于一个凸函数$f$而言,其上相异两点$x,y$,下列两条中有且只有一条成立: 212 | 213 | - $f(\theta x+\bar\theta y)<\theta f(x)+\bar\theta(y),\theta\in (0,1)$ 214 | 215 | - $f(\theta x+\bar\theta y)=\theta f(x)+\bar\theta(y),\theta\in[0,1]$ 216 | 217 | 严格凸,实际上再说第二部分是不存在的,也就是说没有哪部分可以用$y=w^T x+b$的形式来表示。 218 | 219 | 也就是说,函数曲线要么在函数两点连线的下方,要么就是连线。不能和连线有别的相交点。 220 | 221 | 凸函数的零阶条件: 222 | 223 | $$ 224 | f\ is\ convex\iff\forall x\in \text{dom}(f),\forall d,g(t)=f(x+td)\ is\ convex\ \\ 225 | on\ \text{dom}(g)=\{t:x+td\in\text{dom}(f)\} 226 | $$ 227 | 228 | 这件事情实际上在描述,从任何一个超平面去截这个函数,在切面上应该是凸的。 229 | 230 | 对于一个凸函数,如果我们想把它的定义域从$S$扩展到$R^n$,那么我们只需要给所有不在$S$中的点定义为$+\infin$即可。这两个函数的凸性是相同的。 231 | 232 | 凸函数的一阶条件: 233 | 234 | 可微函数$f$定义在一个开凸集上,那么$f\ is\ convex\ \iff f(y)\geq f(x)+\nabla f(x)^T(y-x),\forall x, y\in \ \text{dom}(f)$ 235 | 236 | 这件事情在描述切线放缩法。 237 | 238 | 如果我们要求$x,y$相异,把$\geq$改为$>$,那么就变成了严格凸的充分必要条件。 239 | 240 | 因此,对于凸函数而言,如果$\nabla f(x)=0$,那么这个点一定是全局最小值。 241 | 242 | 凸函数的二阶条件: 243 | 244 | $$ 245 | f\ is\ convex\iff\nabla^2f(x)\ is\ positive\ semidefinite. 246 | $$ 247 | 248 | 但是,$\nabla^2 f(x)\ is\ positive\ semidefinite$为$f(x)$是严格凸的充分不必要条件。但是对于二次函数$x^TQx+b^Tx+c$而言($Q\ is\ a\ symmetric$),这一点是充要条件。因为$\nabla^2f(x)=2Q$ 249 | 250 | 对于凸函数而言,如果有局部最小值,那么一定有全局最小值。但是,凸函数不一定有局部最小值。 251 | 252 | 对于严格凸函数而言,全局最小值如果存在,一定只有一个点。但是,如果全局最小值只可以在一个点处取到,并不意味着这是个严格凸函数。比如绝对值函数。 253 | 254 | **sublevel sets**(下水平集):在定义域中,所以函数值小于某个值$\alpha$的自变量所构成的集合,记作$C_\alpha$ 255 | 256 | 凸函数的下水平集,和凹函数的上水平集都是凸集。但是,非凸函数的下水平集可能都是凸集。比如$\sqrt {|x|}$ 257 | 258 | epigraph:$f:S\sub \R^n\to \R,\text{epi}\ f=\{(x,y)\in \R^{n+1}:x\in S, y\ge f(x)\}$ 259 | 260 | 定理:$f\ is\ convex\iff \text{epi}\ f\ is\ a\ convex\ set$ 261 | 262 | 凸集的投影,也一定是凸集。 263 | 264 | 凸函数的一阶条件,暗示着$f(x_0)+\nabla f(x_0)^T(x-x_0)$是$\text{epi}\ f$ 的支撑超平面。 265 | 266 | 几个不等式: 267 | 268 | - Jensen's inequality:$f(\theta x+\bar\theta y)\leq\theta f(x)+\bar\theta f(y),\theta\in [0,1],f\ is\ convex, x,y\in \text{dom}(f)\\=:\theta=0,1$ 269 | 270 | - Holder's inequality:$\sum_{i=1}^n|x_iy_i|\leq||x||_p||y||_p,p\in(1,+\infin)\\ =:x(y)=0$ 271 | 272 | - Minkowski's inequality:$||x+y||_p\leq ||x||_p+||y||_p,p\in(1,+\infin)$ 273 | 274 | ### Convexity-preserving operations 275 | 276 | - 函数的锥组合,$f(x)=\sum_{i=1}^mc_if_i(x),c_i\ge 0$ 277 | 278 | - 仿射变换,$f(x)=g(Ax+b)$ 279 | 280 | - 函数的复合,$f(x)=h(g_1(x),...,g_m(x))$ 281 | 282 | - 逐点取最大值,即$f(x)=\sup_{i\in I}f_i(x)$ 283 | 284 | - 部分最小值,$f(x)=\inf_{y\in C}g(x,y)$ 285 | 286 | 函数的锥组合中,不能使用减、乘、除运算。 287 | 288 | 对于函数的复合而言,我们有: 289 | 290 | - $h\ is\ convex,\ h\ is\ increasing,\ g\ is\ convex\implies f\ is\ convex$ 291 | 292 | - $h\ is\ convex,\ h\ is\ decreasing,\ g\ is\ concave\implies f\ is\ convex$ 293 | 294 | - $h\ is\ concave,\ h\ is\ increasing,\ g\ is\ concave\implies f\ is\ concave$ 295 | 296 | - $h\ is\ concave,\ h\ is\ decreasing,\ g\ is\ convex\implies f\ is\ concave$ 297 | 298 | 求二阶导时可以观察到这一点。对于定义域延拓,相似的结果也成立。 299 | 300 | 逐点取最小值的话,结果不一定是个凹函数。我们对它不能保证任何事情。 301 | 302 | ## Linear Programming 303 | 304 | 线性规划问题,就是求一个多元线性函数在约束条件下的最值问题。所有的不等式约束条件,我们都可以通过乘上负一来改变不等号的方向。同时,所有的等式约束都可以用两个不等式约束来表示。从而,所有的约束条件都可以被表示为小于不等式。同时,我们可以把所有的变量要求是非负的。我们可以通过在不等式约束的每一个式子上加上一个松弛变量,把不等式化为等式。这样就可以把约束条件写为$Ax=b$的形式。通过对每一行的系数操作,我们也可以保证$b$是一个全非负的向量。同时,我们要求所有松弛变量都是非负的。然后,我们可以把每个变量化为$x_i^+-x_i^-$的形式。这样可以保证$x_i^+$和$x_i^-$都是非负的。 305 | 306 | 满足上面这一串要求的线性规划问题形式,我们称之为线性规划的标准形式。 307 | 308 | ### 线性规划基本定理 309 | 310 | 线性规划问题的最优解如果存在,那么一定是顶点。 311 | 312 | 我们定义,如果$x\in R^n$是一个顶点,那么至少有$n$个线性独立的约束条件在$x$处取等。 313 | 314 | 我们定义,$x\in R^n$是凸集$C$的极点,如果它不能被表示为其他点的凸组合。对于所有的多面体$\{x|Ax\leq b\}$而言,顶点一定是极点,极点一定是顶点。多面体中有极点,当且仅当$P$中不包含直线,并且$P\neq \empty$. 315 | 316 | 因此,一种朴素的求解方法,就是把每一个顶点都枚举一遍。 317 | 318 | ### 单纯形法 319 | 320 | 我们称两个顶点是邻居,当且仅当它们都对同样的$n-1$个约束取等号。 321 | 322 | 单纯形法的主要思路,是从原点开始迭代,然后通过换元的方式增大我们的函数值。但问题是,原点并不总是一定在可行域内。如果我们已经发现$Ad\leq b$,那么我们可以令$y=d-x=y^+-y^-$,这样可以保证所有变量都非负。所以,对于约束条件$Ax=b$,我们可以将其改写为$Ax+s=b$,其中显然有一个解$x=0,s=b$。这样,我们就解决了可能找不到可行解的情况。然后,我们可以检查$s=0$是否在可行域内。 323 | 324 | ### 对偶法 325 | 326 | 考虑这样的问题: 327 | 328 | $$ 329 | Q:\max(-b^Ty),s.t.\ -A^Ty\le -c, y\ge 0\\ 330 | Q:\min(-c^Tx),s.t.\ -A^Tx\ge -b,x\ge 0 331 | $$ 332 | 333 | 这两个问题是对偶问题。实际上,解决最大值的对偶问题,是通过约束的加减乘除,找到满足系数要求的最小值,作为原最大值的一个上界,之后说明可取来解决问题。由于这一点,我们有弱对偶定理: 334 | 335 | $$ 336 | x\text{ is feasible for primal, and } y\text{ is feasible for dual}\implies c^Tx\leq b^Ty 337 | $$ 338 | 339 | 推论:如果$c^Tx$是无界的,那么对偶问题一定是无解的。 340 | 341 | 强对偶定理:如果原始问题有一个有穷的最优解$x^*$,那么对偶问题一定也有个有穷的最优解$y^*$,并且一定有$c^Tx^*=b^Ty^*$ 342 | 343 | 我们之前有Farkas's lemma,说明$\{x\in\R^m|Ax=b,x>0\}$和$\{y\in\R^n|A^Ty\le 0,b^Ty>0\}$中有且只有一个是空的。 344 | 345 | 从而,我们可以得到推论:$A\in\R^{m\times n},b\in \R^m$,那么下面中一定有且仅有一个成立: 346 | 347 | - $\exists x\in\R^n,Ax\ge b,x\ge0$ 348 | 349 | - $\exist y\in\R^m,A^Ty\ge 0,b^Ty<0,y\leq 0$ 350 | 351 | Complementary slackness:$x,y$分别是原始问题和对偶问题的可行解,那么$x,y$分别是最优解当且仅当$y^T(b-Ax)=0,x^T(A^Ty-c)=0$ 352 | 353 | 也就是说,一项要么为零,要么等号可取。 354 | 355 | ## 梯度下降法 356 | 357 | 对于一个凸函数而言,一个点是全局最小值,当且仅当: 358 | 359 | $$ 360 | \forall y\in D,\nabla f(x^*)^T(y-x^*)\ge0 361 | $$ 362 | 363 | 对于梯度下降法而言,我们就是在进行这样的迭代:$x_{k+1}=x_k+t_k\vec v_k,\vec v_k\cdot\nabla f(x_k)<0$ 364 | 365 | 最后我们设定一个收敛条件即可。 366 | 367 | Rayleigh商:考虑$Q$为一个对称的半正定矩阵,$\lambda_{min},\lambda_{max}$分别为其最小和最大的特征值。那么我们有$\lambda_{min}||x||_2^2\leq x^TQx\leq\lambda_{max}||x||^2_2$ 368 | 369 | 我们定义一个函数为L-Lipshitz,当$\forall x,y\in\text{dom}\ f,||f(x)-f(y)||\leq L||x-y||$ 370 | 371 | 我们定义一个函数是$L-smooth$,当它的梯度是L-Lipschitz的时候。 372 | -------------------------------------------------------------------------------- /2024_Fall/Xi's_thought.md: -------------------------------------------------------------------------------- 1 | # 习近平新时代中国特色社会主义思想概论复习 2 | 3 | ## 新时代坚持和发展中国特色社会主义 4 | 5 | ### 中国特色社会主义进入新时代 6 | 7 | #### 社会主要矛盾变化是关系全局的历史性变化 8 | 9 | 党的十八大以来,经过科学分析,我们党及时作出我国社会主要矛盾已经转化为人民日益增长的美好生活需要和不平衡不充分的发展之间的矛盾的重大战略判断。 10 | 11 | - 需求侧:经过长期发展,人民对美好生活的向往更加强烈,需要更加广泛。 12 | 13 | - 供给侧:同时,我国社会生产力水平总体上显著提高,社会生产能力在很多方面进入世界前列。 14 | 15 | 更加突出的问题是发展不平衡不充分。 16 | 17 | 18 | 19 | ##### 如何看待新时代我国社会主要矛盾的变化? 20 | 21 | 新时代我国社会主要矛盾的变化,是关系全局的历史性变化,对党和国家工作提出了许多新要求。新时代我国社会主要矛盾的变化,是在社会主义初级阶段中发生的变化,没有改变对我国社会主义所处历史阶段的判断。我们既要看到我国社会主要矛盾的变化,也要看到我国仍处于并将长期出于社会主义初级阶段的基本国情没有变,我国是世界最大发展中国家的国际地位没有变。我们既不能落后于时代,也不能脱离实际,超越阶段。 22 | 23 | 24 | 25 | ## 以中国式现代化全面推进中华民族伟大复兴 26 | 27 | ### 中国式现代化是强国建设、民族复兴的唯一正确道路 28 | 29 | #### 中国式现代化的中国特色 30 | 31 | 中国式现代化是人口规模巨大的现代化。中国式现代化是全体人民共同富裕的现代化(本质特征),这是中国式现代化区别于西方现代化的显著标志。中国式现代化是物质文明和精神文明相协调的现代化。物质贫困不是社会主义,精神贫乏也不是社会主义。物质富足、精神富有是社会主义现代化的根本要求。中国式现代化是人与自然和谐共生的现代化(鲜明特点)。中国式现代化是走和平发展道路的现代化。 32 | 33 | #### 中国式现代化的本质要求 34 | 35 | 中国式现代化的本质要求是:坚持中国共产党领导,坚持中国特色社会主义,实现高质量发展,发展全过程人民民主,丰富人民精神世界,实现全体人民共同富裕,促进人与自然和谐共生,推动构建人类命运共同体,创造人类文明新形态。 36 | 37 | 中国式现代化是中国共产党领导的社会主义现代化,这是对中国式现代化的定性,是管总、管根本的。 38 | 39 | ##### 中国式现代化创造了人类文明新形态 40 | 41 | 中国式现代化提供了一种全新的现代化模式。中国式现代化打破了“现代化=西方化”的迷思,展现了不同于西方现代化的新图景。中国式现代化是对西方式现代化理论和实践的重大超越。中国式现代化为广大发展中国家提供了全新选择。 42 | 43 | ## 坚持党的全面领导 44 | 45 | ### 中国共产党领导是中国特色社会主义最本质的特征 46 | 47 | #### 中国共产党领导是中国特色社会主义制度的最大优势 48 | 49 | ### 健全和完善党的领导制度体系 50 | 51 | #### 党的领导制度是我国的根本领导制度 52 | 53 | ## 坚持以人民为中心 54 | 55 | ### 全面落实以人民为中心的发展思想 56 | 57 | #### 推动全体人民共同富裕取得更为明显的实质性进展 58 | 59 | 共同富裕是中国特色社会主义的本质要求,是中国式现代化的重要特征。 60 | 61 | 要从全局角度来把握共同富裕。共同富裕是全体人民共同富裕,是人民群众物质生活和精神生活都富裕。不是少数人的富裕,也不是整齐划一的平均主义,不是所有人都同时富裕,也不是所有地区同时达到一个富裕水准。要处理好先富和后富的关系,允许一部分人先富起来,同时要积极推动先富带动后富。实现全体人民共同富裕是一个长期的历史过程,不可能一蹴而就,必须保持历史耐心,进行不懈努力,根据现有条件把能做的事情尽量做起来,积小胜为大胜,不断推动全体人民共同富裕取得更为明显的实质性进展。 62 | 63 | 扎实推进共同富裕,必须坚持正确的原则和科学的思路。促进共同富裕,要鼓励勤劳创新致富,坚持基本经济制度,尽力而为量力而行、坚持循序渐进的原则。 64 | 65 | ## 全面深化改革开放 66 | 67 | ### 统筹推进各领域各方面改革开放 68 | 69 | #### 全面深化改革开放要坚持正确方法论 70 | 71 | 增强全面深化改革的系统性、整体性、协同性。加强顶层设计和摸着石头过河相结合。统筹改革发展稳定。胆子要大,步子要稳。坚持重大改革于法有据。 72 | 73 | ## 推动高质量发展 74 | 75 | ### 完整、准确、全面贯彻新发展理念 76 | 77 | #### 以新发展理念引领高质量发展 78 | 79 | 高质量发展是全面建设社会主义现代化国家的首要任务,是遵循经济规律发展的必然要求。高质量发展,是能够很好满足人民日益增长的美好生活需要的发展,是体现新发展理念的发展,是创新成为第一动力、协调成为内生特点、绿色成为普遍形态、开放成为必由之路、共享成为根本目的的发展。高质量发展关系我国社会主义现代化建设全局,具有重大战略意义。第一,高质量发展为全面建设社会主义现代化国家提供更为坚实的物质基础。第二,高质量发展是不断满足人民对美好生活需要的重要保证。第三,高质量发展是维护国家长治久安的必然要求。 80 | 81 | ### 坚持和完善社会主义基本经济制度 82 | 83 | #### 构建高水平社会主义市场经济体制 84 | 85 | 以习近平同志为核心的党中央提出使市场在资源配置中起决定性作用,更好发挥政府作用,这是我们党在理论和实践上的重大推进,是对中国特色社会主义建设规律认识的一个新突破。要加快建设高标准市场体系。要推进宏观经济治理体系和治理能力现代化。要依法规范和引导资本健康发展。 86 | 87 | ### 加快构建新发展格局 88 | 89 | #### 大力推动构建新发展格局 90 | 91 | 要着力推动实施扩大内需战略同深化供给侧结构性改革有机结合。要着力发展实体经济。要着力加快科技自立自强。要着力推动产业链供应链优化升级。 92 | 93 | ## 发展全过程人民民主 94 | 95 | ### 全过程人民民主是社会主义民主政治的本质属性 96 | 97 | #### 全过程人民民主是全链条、全方位、全覆盖的民主 98 | 99 | 全过程人民民主是全链条的民主。有民主选举、民主协商、民主决策、民主管理、民主监督五个环节。 100 | 101 | 全过程人民民主是全方位的民主,贯通国家政治生活和社会生活各层面各维度。 102 | 103 | 全过程人民民主是全覆盖的民主,涵盖国家各项事业各项工作,贯穿“五位一体”总体布局和“四个全面”战略布局的方方面面,是各方面民主的有机统一。 104 | 105 | ## 建设社会主义文化强国 106 | 107 | ### 铸就社会主义文化新辉煌 108 | 109 | #### 传承发展中华优秀传统文化 110 | 111 | 中华优秀传统文化是中华文明的智慧结晶和精华所在,是中华民族的根和魂。 112 | 113 | 中华文明具有连续性、创新性、统一性、包容性、和平性的突出特性。 114 | 115 | 我们要推动中华优秀传统文化创造性转化、创新性发展。 116 | 117 | ## 维护和塑造国家安全 118 | 119 | ### 构建统筹各领域安全的新安全格局 120 | 121 | #### 统筹发展和安全 122 | 123 | 统筹发展和安全,是党和国家的一项基础性工作,是我们党治国理政的一个重大原则。 124 | 125 | 发展和安全是两件大事。发展解决的是动力问题,是推动国家和民族赓续绵延的根本支撑;安全解决的是保障问题,是确保国家和民族行稳致远的坚强柱石。 126 | 127 | 以新安全格局保障新发展格局。 128 | 129 | ## 中国特色大国外交和推动构建人类命运共同体 130 | 131 | ### 推动构建人类命运共同体 132 | 133 | #### 构建人类命运共同体是世界各国人民前途所在 134 | 135 | 重要性:构建人类命运共同体是我们党审视当今世界发展趋势,针对当今世界面临的重大问题提出的重要理念。 136 | 137 | 内涵:人类命运共同体,顾名思义,就是每个民族、每个国家的前途命运都紧紧联系在一起,应该风雨同舟,荣辱与共,努力把我们生于斯、长于斯的这个星球建成一个和睦的大家庭,把世界各国人民对美好生活的向往变成现实。构建人类命运共同体,就是要携手世界各国人民共同建设持久和平、普遍安全、共同繁荣、开放包容、清洁美丽的世界。 138 | 139 | #### 推动构建人类命运共同体的价值基础和重要依托 140 | 141 | 推动构建人类命运共同体,要弘扬全人类共同价值,必须弘扬全人类共同价值。 142 | 143 | 全人类共同价值与西方所谓的“普世价值”是两个不同的概念,两者存在根本区别。前者反映了全人类的共同利益,体现了不同文明的价值共识,后者仅仅代表部分西方国家的利益,依靠霸权强行输出。世界上不存在高人一等的“自由民主”,不存在唯我独尊的“普世价值”。全人类共同价值是以联合国宪章为基础和行为准绳的,其理论基础是共时性的、不是独断性的,实践基础是包容性的、不是排他性的,反映了世界各国人民普遍认同的价值理念的最大公约数,从根本上符合世界人民携手共建人类命运共同体、共创人类更加美好未来的前进方向。 144 | 145 | #### 积极参与全球治理体系改革和建设 146 | 147 | 推进全球治理体系改革和建设,是完善全球治理、增进世界各国人民福祉的客观要求,也是构建人类命运共同体的内在要求。全球治理事关应对各种全球性挑战,事关给国际秩序和国际体系定规则、定方向,需要世界各国共同参与。多边主义符合各国人民利益,是维护和平、促进发展的有效途径。随着世界经济政治格局的变化和全球性挑战日益增多,加强全球治理、完善全球治理体系的呼声越来越高。要坚定维护以联合国为核心的国际体系、以国际法为基础的国际秩序。 148 | 149 | #### 高质量共建“一带一路” 150 | 151 | “一带一路”倡议根治历史、更面向未来,源于中国、更属于世界。共建“一带一路”追求的是发展,崇尚的是共赢,传递的是希望。共建“一带一路”是造福沿线各国人民的大事业。 152 | 153 | 154 | -------------------------------------------------------------------------------- /2024_Spring/Data Structure.md: -------------------------------------------------------------------------------- 1 | # Part 0 绪论 2 | 3 | 进程 4 | 5 | 抽象化的方法 6 | 7 | Router 8 | 9 | 数据结构的内容:如何存储?如何运算? 10 | 11 | ## 数据的逻辑结构 12 | 13 | **集合结构**:同类而无序。 14 | 15 | **线性结构**:线性有序。除去头尾,既有前驱,也有后继。 16 | 17 | **树形结构**:如树、堆等。除去根外,所有节点仅一个前驱,可有多个后继。 18 | 19 | **图状结构**:前驱后继数目不限。 20 | 21 | 通常有的操作为:创建、释放、更新、查找等。 22 | 23 | 存储节点、方式、附加信息。 24 | 25 | ## 关系的存储 26 | 27 | **顺序存储** 数组等 28 | 29 | **链接存储** 指针 链表等 30 | 31 | **哈希存储** 集合结构的存储 32 | 33 | **索引存储** 所有节点存储在存储区。另外设置索引区域表示不同节点之间的关系。 34 | 35 | ## 运算的实现 36 | 37 | 运算对应算法。而算法对应一个函数。 38 | 39 | ## 算法的质量 40 | 41 | 正确性、鲁棒性、易读性、高效性。 42 | 43 | 时间性能、空间性能。 44 | 45 | 最坏情况的时间复杂度。 46 | 47 | 空间需求,分为存储被处理数据的空间,以及实现操作所需的**额外**空间。 48 | 49 | 空间性能关注的是**额外**引入的空间量。 50 | 51 | 算法运算量的计算:引入标准操作。确定算法在给定条件下所需的标准操作数。 52 | 53 | 用渐进表示法表示时间复杂度:考虑问题规模很大的时候,运行时间随问题规模的变化规律。只考虑数量级。 54 | 55 | 四种描述方法: 56 | 57 | $$ 58 | 大O,大\Omega,大\Theta,小o 59 | $$ 60 | 61 | 分别表示:上界、下界、相等、严格下界。 62 | 63 | 多项式时间复杂度以及指数时间复杂度。 64 | 65 | ### 时间复杂度的计算 66 | 67 | 求和定理:若$P$由$P_1,P_2$组成,两部分的时间复杂度分别为$O(f(n)),O(g(n))$,则$P$的时间复杂度为$O(\max(f(x),g(x))$ 68 | 69 | 求积定理:比较显然。循环等计算时会用到。 70 | 71 | ## 算法的优化 72 | 73 | ## 空间复杂度 74 | 75 | # 数据结构的实现 76 | 77 | 过程化程序设计 or OOP? 78 | 79 | OOP,模板 80 | 81 | # Part I 线性表 82 | 83 | ## 线性表的定义 84 | 85 | 基类尽量都要定义虚析构函数。 86 | 87 | ## 线性表的实现 88 | 89 | 常用顺序实现或链接实现。 90 | 91 | 当插入删除次数较少的时候,倾向于顺序实现。 92 | 93 | # Part II 栈 94 | 95 | 括号配对时仅进行词法检查,不会执行语法检查。 96 | 97 | 可使用栈进行将递归程序转化为非递归程序。 98 | 99 | 使用文件流对象可以提高效率,避免多次的打开和关闭文件。 100 | 101 | main函数可以有参数。第一个参数是int, argc;第二个参数是 char**。 102 | 103 | 后缀表达式:运算符在两个运算对象之后。 104 | 105 | 中缀表达式和后缀表达式中,运算数的顺序相同。 106 | 107 | 倘若要做一个四则运算计算器,那么我可以将表达式边转换边进行计算。 108 | 109 | 此外,需要注意空格、数字可能有多位等情况。 110 | 111 | CPU内分成了多个时间片。处理任务时进程会排成一个队列。 112 | 113 | ## 队列 114 | 115 | 队头队尾标记,数组规模 116 | 117 | 判断队列中是否有剩余的空间。 118 | 119 | 链表存储时,表头作为队头。 120 | 121 | 模拟:事件驱动和时间驱动的模拟。如排队系统,就是事件驱动的模拟。 122 | 123 | # Part II 树 124 | 125 | 节点只有一个父亲,可以有很多个儿子。 126 | 127 | 一个节点的儿子数目称为这个节点的度。一棵树上节点度的最大值,称为这棵树的度。 128 | 129 | 满二叉树:除去最底层,任意一层的节点都都有两个儿子。 130 | 131 | 关于二叉树的一个不是很显然的结论:叶子结点的度数等于度数为2的节点数加1。 132 | 133 | $$ 134 | n=n_0+n_1+n_2\\ 135 | B=n-1\\ 136 | B=n_1+2n_2 137 | $$ 138 | 139 | 故得之。 140 | 141 | 二叉树的遍历方式有前序遍历,中序遍历,后序遍历三种方式。 142 | 143 | e.g.可以使用后序遍历计算斐波那契数列;用前序遍历进行快速排序。 144 | 145 | 通过前序遍历和中序遍历,可以唯一确定一棵二叉树。 146 | 147 | 顺序实现:通过位置关系决定逻辑关系。 148 | 149 | 链接实现:位置随意。通过指针来表示逻辑关系。 150 | 151 | ## 优先级队列 152 | 153 | 二叉堆 154 | 155 | 堆是一棵完全二叉树。 156 | 157 | 插入操作的复杂的最坏是对数的,最好情况下是常数。 158 | 159 | 出堆操作,倘若将最下层的元素移至最上层,则显然为了满足有序性,复杂度为对数级别。 160 | 161 | 在建堆时,最坏情况是$\Theta(N\log N)$ ,平均情况为线性的。 162 | 163 | 左堆可归并,是因为其不严格要求完全二叉树。(左偏树) 164 | 165 | 斜堆可以看做是自平衡的左偏树。 166 | 167 | 二项堆可以看做是二项树的集合。 168 | 169 | 如果要归并二项堆,直接同位相加即可。 170 | 171 | ## 二叉树 172 | 173 | 使用非递归方式先根遍历二叉树,可以使用栈。 174 | 175 | 使用非递归方式中根遍历二叉树,在入栈过程时,需要暂存根节点内容。增加一个计数器,统计根出栈的次数。只有出栈次数达到2,才是真正的出栈。 176 | 177 | 若欲后根遍历,当出栈次数达到3,方为真正的出栈。 178 | 179 | ### 表达式树 180 | 181 | 使用后序遍历的方式,可以计算出表达式树的值。 182 | 183 | ### Huffman树 184 | 185 | Huffman树需要存储父亲节点。是故,我们应当选择三叉链表进行存储。通常采用归并的方法进行建树。 186 | 187 | ## 森林 188 | 189 | 如何把森林转化为二叉树? 190 | 191 | 首先,把每一颗树转化为二叉树。然后自根节点向右,把树分开来。把树转化为二叉树,可以通过儿子兄弟表示法进行化归。把新二叉树的右儿子表示原先的兄弟,而左儿子表示原先最左边的儿子。 192 | 193 | # 集合 194 | 195 | ## 静态查找表 196 | 197 | ## 动态查找表 198 | 199 | ## 平衡树 200 | 201 | 红黑树:如果删除的节点是红色的,那么我们直接删除就可以了。如果只有一个儿子的节点,那么它一定是黑节点,我们只需要把其儿子修改为黑色,在提上来就可以了。如果是黑色的叶节点,那么我们需要比较复杂的调整。 202 | 203 | 如果一个子树上少了一个黑节点,那么我们应当想办法调整这一点。如果被调整节点的兄弟是红色的,那么我们可以对父节点进行旋转,但是被调整节点路径上还是少一个黑节点。 204 | 205 | 自底向上的调整可能一路回溯到根节点。 206 | 207 | 自顶向下的删除:把正在调整的节点调整为红色或者只有一个红节点。 208 | 209 | 置换排序:在小内存限制下的外排序算法。首先,读入内存所允许的数据量,将其按规定排序。将“最小”的元素输出。然后,输入一个新的元素。如果,这个元素在小内存中是“最小“的,那么将其放在队尾,说明不能输出,等待下一个文件。重新执行输出操作。 210 | 211 | # 图 212 | 213 | 节点的度数,定义为有多少条边与这个节点相连。类似的,我们可以定义出入度和出度。 214 | 215 | 树的度,指的是所有节点中度数的最大值。树中节点的度,指的是出度。 216 | 217 | 我们定义完全图的概念。无向完全图,指的是每两个节点间均有边相连。有向完全图,则是每两个节点之间都有可以互相通行的两条边。 218 | 219 | 我们定义子图的概念,也就是挑选了部分的节点和部分的边组成的一张图。 220 | 221 | 简单路径:除了起点和终点可能相同外,其余路径均不相同,则称其为简单路径。 222 | 223 | 环:一条简单路径。且起点和终点相同,路径长度至少为1。 224 | 225 | 连通分量:指的是非连通图中的极大连通子图。 226 | 227 | 有向图中,如果任意两点之间都是连通的,那么我们称其为强连通图。 228 | 229 | 强连通分量,指的是极大的连通子图。 230 | 231 | 弱连通图,指的是一张非强连通图,在忽略掉边的有向性的情况下,其为一张连通图,则称其为一张弱连通图。 232 | 233 | 生成树:连通图的极小连通子图。包含了图的所有n个节点,然仅含有n-1条边。 234 | 235 | 邻接矩阵、邻接表、逆邻接表。如果为了寻找前驱和后继都比较方便,我们可以创建邻接表和逆邻接表。但是这样可能有损于一致性。有一种方法,是使用十字链表来进行操作。每一个节点存在两个指针,一个指针用来指向邻接表中的对象,另外一个指针中存储指向逆邻接表的指针。 236 | 237 | 邻接多重表:解决无向图中边存储两次的问题。把一个节点写在两个链表中。 238 | 239 | 有向图的强连通分量的查找方法:从一个节点进行深度优先遍历。随后,对之进行编号。按照后序方式进行编号。随后,我们可以得到一组深度优先的森林。此后,我们将所有的边进行反向。从编号最大的序号开始进行遍历。得到的每一个连通块即为强连通分量。 240 | 241 | 拓扑排序:对于有向无环图,可以有多种拓扑排序。 242 | 243 | 关键路径:假定带边权图上每条边的权值代表了要花费的天数,存在一个源点和汇点,每一个点可以被访问当且仅当其所有前趋节点都被访问。为了保证访问时间最短,我们需要保证某些点在可以被访问后马上被访问。这样的路径就是关键路径。求解算法,就是正序跑一遍,再逆序跑一遍,观察最迟和最早发生时间是否相同。 244 | 245 | 生成树:图的一个子图。其包含图中所有的点,并且其边构成一棵树。 246 | 247 | 最小生成树:在带权图中,挑选的边权和最小的生成树。kruskal算法是选边的算法。而prim算法是选点的算法。 248 | -------------------------------------------------------------------------------- /2024_Spring/Modern Chinese History by Liang Li, Jun Deng.md: -------------------------------------------------------------------------------- 1 | # 第一章 2 | 3 | 1842年8月29日,英国和中国签订了中国近代史上第一个不平等条约《南京条约》。 4 | 5 | 中法签订《黄埔条约》,中美签订《望厦条约》。 6 | 7 | 从1840年鸦片战争到1949年中华人民共和国成立之前的近代中国,是半殖民地半封建社会。 8 | 9 | 鸦片战争前的中国社会是封建社会。鸦片战争以后,独立的中国逐步变成半殖民地的中国,封建的中国逐步变成半封建的中国。 10 | 11 | 近代中国半殖民地半封建社会的矛盾,呈现出错综复杂的情况。占支配地位的主要矛盾,是帝国主义和中华民族的矛盾,封建主义和人民大众的矛盾。帝国主义和中华民族的矛盾是最主要的矛盾。 12 | 13 | 近代以来中华民族面临的两大历史任务是争得民族独立和人民解放,以及实现国家富强和人民幸福。 14 | 15 | 通过一系列不平等条约,俄国共侵占中国领土150多万平方公里,为最多的列强。 16 | 17 | 帝国主义侵略中国的最终目的,是要瓜分中国,灭亡中国。 18 | 19 | 帝国主义列强并没有能够实现瓜分中国的图谋。帝国主义列强之间的矛盾和互相制约,是一个重要的原因。但是最根本的原因是中华民族进行的不屈不挠的反侵略斗争。 20 | 21 | 历次的反侵略战争都是以中国失败,中国政府被迫签订丧权辱国的条约而告结束的。中国内部主要有两个原因,社会制度的腐败和经济技术的落后。前者为更根本的原因。 22 | 23 | 林则徐是近代中国睁眼看世界的第一人。魏源在《海国图志》中提出了“师夷长技以制夷”的思想。 24 | 25 | # 第二章 26 | 27 | 《天朝田亩制度》是最能体现太平天国社会理想和太平天国运动特色的纲领性文件。它实际是一个以解决土地问题为中心的社会改革方案。 28 | 29 | 《资政新篇》是太平天国后期颁布的社会发展方案,是一个具有资本主义色彩的方案。 30 | 31 | 1856年9月的天京事变成为太平天国由盛转衰的分水岭。 32 | 33 | 洋务派兴办洋务事业,首先是为了镇压农民起义,同时也借此加强海防、边防,并趁机发展本集团的实力。 34 | 35 | 洋务运动的指导思想是“中学为体,西学为用”。 36 | 37 | 洋务事业归纳起来有三方面:兴办近代企业、建立新式海陆军、创办新式学堂,派遣留学生。 38 | 39 | 戊戌维新运动的背景:甲午战争的惨败,造成了新的民族危机,激发了新的民族觉醒。 40 | 41 | 戊戌维新运动的代表人物有康有为、梁启超、谭嗣同、严复等。谭嗣同写了《仁学》,严复翻译了赫胥黎的《天演论》。 42 | 43 | 戊戌维新运动中维新派与守旧派的论战,实质上是资产阶级思想与封建主义思想在中国的第一次正面交锋。 44 | 45 | 戊戌维新运动是一次爱国救亡运动,是一场资产阶级性质的政治改良运动,更是一场思想启蒙运动。 46 | 47 | # 第三章 48 | 49 | 1904年至1905年,日俄战争发生在中国东北,清政府却宣称局外中立。 50 | 51 | 预备立宪并没能挽救清王朝,反而激化了社会矛盾,加重了危机。主要原因在于,清政府改革的根本目的是延续其反动统治。 52 | 53 | 1894年11月,孙中山在檀香山组建了第一个革命团体兴中会,立誓“驱除鞑虏,恢复中国,创立合众政府”。 54 | 55 | 1905年8月29日,孙中山等人在日本东京成立中国同盟会,这是近代中国第一个领导资产阶级革命的全国性政党。 56 | 57 | 同盟会的政治纲领是“驱除鞑虏,恢复中华,创立民国,平均地权”。孙中山将其概括为民族主义,民权主义,民生主义,后被称为三民主义。民族主义包括“驱除鞑虏,恢复中华“两项内容。民权主义的内容是”创立民国“,即政治革命。民生主义指的是”平均地权“,即社会革命。 58 | 59 | 1911年5月,清政府宣布“铁路干线收归国有”,借“国有”名义把铁路利权出卖给帝国主义,激起保路风潮。其中以四川最烈。 60 | 61 | 1912年3月,临时参议院颁布《中华民国临时约法》,是中国历史上第一部具有资产阶级共和国宪法性质的法典。 62 | 63 | # 第四章 64 | 65 | 李大钊率先在中国举起马克思主义旗帜。他先后发表《法俄革命之比较观》,《庶民的胜利》,《Bolshevism的胜利》。 66 | 67 | 中国早期信仰马克思主义的人物,主要有三种类型:首先是新文化运动的精神领袖,主要代表人物是李大钊、陈独秀;其次是五四爱国运动的左翼骨干,主要代表为毛泽东等;最后是一部分原中国同盟会会员,辛亥革命时期的活动家,其代表为董必武等。 68 | 69 | 早期马克思主义思想运动的特点:第一,重视对马克思主义基本理论的学习,明确地同第二国际的社会民主主义划清界限;第二,注意从中国的实际出发,学习、运用马克思主义;第三,开始提出知识分子应当同劳动群众相结合的思想。 70 | 71 | 中国共产党早期组织的活动:第一,研究和宣传马克思主义,研究中国实际问题;第二,到工人中去进行宣传和组织工作;第三,进行关于建党问题的讨论和实际组织工作。 72 | 73 | 中国共产党的先驱们创建了中国共产党,形成了坚持真理、坚守理想,践行初心、担当使命,不怕牺牲、英勇斗争,对党忠诚、不负人民的伟大建党精神。 74 | 75 | 1923年6月在广州举行的中共三大,决定共产党员以个人身份加入国民党,以实现国共合作。 76 | 77 | 1924年1月,中国国民党一大由孙中山主持在广州举行,对三民主义作出新的解释,即“新三民主义”。新三民主义的政纲同中国共产党在民主革命阶段的纲领基本一致,因而有了国共合作的基础。 78 | 79 | 1925年5月,以五卅惨案为起点,掀起了全国范围的大革命高潮。 80 | 81 | 1927年4月12日,蒋介石在上海发动反共政变。7月15日,汪精卫在武汉召开“分共”会议,屠杀搜捕共产党员和革命群众。国共合作全面破裂,大革命最终失败。 82 | 83 | ## 自行整理问题:第一次国共合作的原因,经过,和经验教训 84 | 85 | 原因:二七惨案后,中国工人运动转入低潮。中国共产党从中看到,此时的中国革命力量远不如帝国主义和封建势力强大。所以二七惨案后,中国共产党决定采取更为积极的步骤,联合孙中山领导的中国国民党;此时的孙中山因依靠军阀打军阀屡遭挫折,陷于苦闷。他看到中国共产党领导的工人运动所产生的影响,认识到中国共产党是一支新兴的,生机勃勃的革命力量,愿意和中国共产党合作。1923年1月,共产国际执委会作出《关于中国共产党与国民党的关系问题的决议》,对国共合作起了推动作用。 86 | 87 | 经过:国民党一大事实上确认了联俄,联共,扶助农工的三大革命政策,标志着第一次国共合作正式形成。1925年5月,以五卅惨案为起点,掀起了全国范围的大革命高潮。在这样的有利形势下,国共两党合作进行了广东战争,统一并巩固了广东革命根据地,1925年7月1日,国民政府在广州建立。1926年7月,北伐战争开始。革命势力发展到长江流域和黄河流域的大部分地区。中国离殇上空前广大的人民解放运动得以形成。1925年3月12日,孙中山在北京病逝。1926年3月,蒋介石制造中山舰事件,同年5月在国民党二届二中全会上提出“整理党务案”,实行反共步骤。1927年4月12日,蒋介石在上海发动反共政变。7月15日,汪精卫在武汉召开“分共”会议,屠杀搜捕共产党员和革命群众。国共合作全面破裂,大革命最终失败。 88 | 89 | 教训:从客观方面讲,是由于反革命力量强大,资产阶级发生严重动摇,蒋介石集团、汪精卫集团先后叛变革命。从主观方面说,是由于这时中国共产党还处在幼年时期,缺乏复杂环境的政治经验,缺乏对中国社会和中国革命基本问题的深刻认识,还不善于将马克思列宁主义基本原理同中国革命基本问题的具体实际结合起来;是由于党内以陈独秀为代表的右倾思想发展为右倾机会主义错误并在党内机关中占了统治地位,党和人民不能组织有效抵抗,致使大革命在强大的敌人突然袭击下遭到惨重失败。 90 | 91 | # 第五章 92 | 93 | 张学良1928年12月29日宣布“遵守三民主义,服从国民政府,改易旗帜”,国民党在全国范围内建立了自己的统治。 94 | 95 | 1927年8月7日,中共中央在汉口秘密召开紧急会议(八七会议),会议确定了土地革命和武装起义的方针。毛泽东在发言中突出强调,“以后要非常注意军事。须知政权是由枪杆子中取得的。” 96 | 97 | 毛泽东写了《中国的红色政权为什么能够存在?》《井冈山的斗争》两篇文章,提出了工农武装割据的思想。 98 | 99 | 毛泽东和邓子恢等一起指定了土地革命中的阶级路线和土地分配方法:坚定地依靠贫农、雇农,联合中农,限制富农,保护中小工商业者,消灭地主阶级;以乡为单位,按人口平分土地,在原耕地的基础上,实行抽多补少、抽肥补瘦。 100 | 101 | 王明等人的“左”倾教条主义错误,对中国革命造成了极其严重的危害。其最大的恶果,就是使红军在第五次反“围剿”作战中遭到失败,不得不退出南方根据地,实行战略转移——长征。 102 | 103 | # 第六章 104 | 105 | 1931年9月18日,九一八事变,日本变中国为其独占殖民地的侵略战争由此开始。至1932年2月,中国东北全境沦陷。 106 | 107 | 1937年8月25日,中共中央革命军事委员会发布命令,宣布红军改名为国民革命军第八路军。之后,南方八省的红军游击队(除琼崖红军游击队)改编为过敏革命军陆军新编第四军。 108 | 109 | 1937年9月22日,国民党中央通讯社发表中共中央的宣言;23日,蒋介石发表实际上承认共产党合法地位的谈话,以国共两党第二次合作为基础的抗日民族统一战线正式形成。 110 | 111 | 战略防御阶段,1938年3月,李宗仁等部在台儿庄战役中取得大捷。 112 | 113 | 统一战线中的独立自主原则;坚持抗战、团结、进步,反对妥协、分裂、倒退;巩固抗日民族统一战线的策略总方针。 114 | 115 | 毛泽东总结中国共产党成立以来的历史经验,指出统一战线、武装斗争、党的建设,是中国共产党在中国革命中战胜敌人的三个主要法宝。 116 | 117 | 中共七大,将以毛泽东为主要代表的中国共产党人把马克思列宁主义基本原理统中国具体实际相结合所创造的理论成果正式命名为毛泽东思想,将其确立为党的指导思想并且写入党章。 118 | 119 | 抗日战争胜利的原因:第一,以爱国主义为核心的民族精神是中国人民抗日战争胜利的决定因素;第二,中国共产党的中流砥柱作用是中国人民抗日战争胜利的关键;第三,全民族抗战是中国人民抗日战争胜利的重要法宝;第四,中国人民抗日战争的胜利,同世界所有爱好和平和正义的国家和人民、国际组织以及各种反法西斯力量的同情和支持也是分不开的。 120 | 121 | 抗日战争胜利的意义:彻底粉碎了日本军国主义殖民奴役中国的图谋,有力捍卫了国家主权和领土完整,彻底洗刷了近代以来抗击外来侵略屡战屡败的耻辱;促进了中华民族的大团结,形成了伟大的抗战精神;对世界各国夺去反法西斯战争的胜利,维护世界和平产生了巨大影响;坚定了中国人民追求民族独立、自由、解放的意志,开启了古老中国凤凰涅槃,浴火重生的历史新征程,为中国共产党团结带领全国人民继续奋斗,赢得新民主主义革命胜利,奠定了重要基础。 122 | 123 | ## 自行整理问题:持久战的战略总方针,敌后战场的开辟和发展,游击战争的战略地位和作用,统一战线的相关内容。 124 | 125 | 持久战的战略总方针:1938年5月至6月间,毛泽东发表了《论持久战》的讲演,总结全民族抗战10个月来的经验,批驳了“亡国论”“速胜论”等错误观点,系统地阐明了持久战方针。毛泽东指出,中日战争是半殖民地半封建的中国和帝国主义的日本之间在20世纪30年代进行的一个决死的战争。毛泽东强调,“兵民是胜利之本”。毛泽东科学预见了抗日战争的发展进程,即抗日战争将经过战略防御、战略相持、战略反攻三阶段。战略相持阶段是最关键阶段。《论持久战》系统阐明了抗日战争的发展规律和坚持抗战、争取抗战胜利必须实行的战略总方针,是中国共产党领导抗日战争的纲领性文献,对全国抗战的战略指导产生了积极影响。 126 | 127 | 敌后战场的开辟和发展:为贯彻执行全面抗战路线,中国共产党作出了开辟敌后战场的战略决策。一开始,八路军主要是直接在战役上配合国民党军队作战。1937年11月太原失守后,八路军在敌后实施战略展开,发动独立自主的敌后游击战争,开辟多个抗日根据地。在华北,以国民党为主体的正规战争结束,以共产党为主的游击战争上升到主要地位。新四军则挺进长江南北,创建华中抗日根据地。中国共产党把工作重点放在敌后农村,就是在新的抗日民族解放战争条件下,继续走农村包围城市,武装夺取政权的道路。 128 | 129 | 游击战争的战略地位和作用:在全民族抗战中,游击战被提到战略地位,具有全局性意义。在战略防御阶段,从全局看,国民党正面战场的正规战是主要的,敌后游击战是辅助的。但是,游击战迫使日军调兵保守占领区,减轻了正面战场压力,使战争转入相持阶段起了关键性作用。在战略相持阶段,敌后游击战争成为主要的抗日作战方式。为实行战略反攻准备条件的任务主要是由人民军队的游击战完成的。在全民族抗战过程中,中国共产党发挥了中流砥柱作用,领导全功人民,指挥革命抗日武装力量,为坚持抗战,夺取抗战最后胜利作出了彪炳史册的贡献。 130 | 131 | 统一战线相关:抗战开始,中共中央就提出必须在统一战线中坚持独立自主原则,力争中共对抗日战争的领导权,使自己成为团结全民族抗战的中坚力量。1939年7月,中共明确提出坚持抗战、团结、进步,反对妥协、分裂、倒退,反对汪精卫集团的叛国投降活动,继续争取同蒋介石集团合作抗日。1941年1月发生皖南事变,但中国共产党以抗日大局为重,在军事上严守自卫,在政治上坚决反击。为了抗日民族统一战线的坚持、扩大和巩固,中共总结反“摩擦”斗争的经验,制定了“发展进步势力,争取中间势力,孤立顽固势力”的策略总方针。中共对顽固派贯彻又联合有斗争的政策。在同顽固派作斗争时,坚持有理、有利、有节的原则。 132 | 133 | # 第七章 134 | 135 | 《中国土地法大纲》是一个彻底反封建的土地革命纲领。它指引着在封建制度压迫下的亿万农民群众,将自己的力量汇入民主革命的洪流。 136 | 137 | 1949年6月30日,毛泽东发表《论人民民主专政》一文,明确指出,人民民主专政需要工人阶级的领导。人民民主专政的基础是工人阶级、农民阶级和城市小资产阶级的联盟,而主要是工人和农民的联盟。进行中国的人民革命和发展中国的经济,需要团结民族资产阶级,但它不能充当革命的领导者,也不应当在国家政权中占主要的地位。 138 | 139 | # 第八章 140 | 141 | 1950年10月8日,毛泽东发布命令,组建以彭德怀为司令员兼政治委员的中国人民志愿军。 142 | 143 | 1953年开始实施”一五“计划,重点是重工业。 144 | 145 | 中国队资产阶级实现和平赎买政策。 146 | 147 | 1956年,毛泽东报告了《论十大关系》。前五条主要讨论经济问题,后五条主要讨论政治关系。 148 | 149 | 1956年,中共八大在北京举行。周恩来作关于发展国民经济第二个五年计划建议的报告。1957年2月,毛泽东在最高国务会议上发表《如何处理人民内部矛盾》(后改为《关于正确处理人民内部矛盾的问题》)的讲话。这一文章中的论断科学揭示了社会主义社会发展的动力,也为后来的社会主义改革奠定了理论基础。 150 | -------------------------------------------------------------------------------- /2024_Spring/Physics(I).md: -------------------------------------------------------------------------------- 1 | # 0、绪论 2 | 3 | 实验和观测的区别:能否控制 4 | 5 | # 1、质点运动学 6 | 7 | 运动是绝对的。对物体运动的描述是相对的。 8 | 9 | **参考系**:用来描述物体运动而选作参考的物体或相对静止的物体系。 10 | 11 | 常见的有太阳参考系、地心参考系、地面参考系、实验室参考系、质心参考系。 12 | 13 | 质心参考系是常见的零动量系。 14 | 15 | **坐标系**:参考系的数学抽象。常见的有直角坐标系、球坐标系、柱坐标系、自然坐标系等。 16 | 17 | **质点**:大小形状可忽略。各部分运动相同时,可以如此抽象。 18 | 19 | **位置坐标与位置矢量** 20 | 21 | **运动方程与轨迹**:位矢满足的方程。 22 | 23 | **位移**:位移显然是个矢量。满足矢量的叠加性。 24 | 25 | **路程**:标量。 26 | 27 | 自然坐标系: 28 | 29 | $$ 30 | \vec v=v\vec e_t\\ 31 | \vec a={d\vec v\over dt}={dv\over dt}\vec e_t+v{d\vec e_t\over dt} 32 | $$ 33 | 34 | 当$dt\to 0$时,$\Delta\vec e_t=\vec e_t(t+\Delta t)-\vec e_t(t)$ 35 | 36 | $\Delta\vec e_t=\Delta\theta\vec e_n$ 37 | 38 | ${d\vec e_t\over dt}=\lim_{\Delta t\to0}{\Delta\theta\over\Delta t}\vec e_n={d\theta\over dt}\vec e_n$ 39 | 40 | 故,在自然坐标系中,我们有 41 | 42 | $$ 43 | \vec a={dv\over dt}\vec e_t+v{d\theta\over dt}\vec e_n 44 | $$ 45 | 46 | 又因为 47 | 48 | $$ 49 | {d\theta\over dt}={d\theta\over ds}\cdot{ds\over dt}={d\theta\over ds}v 50 | $$ 51 | 52 | 即为 53 | 54 | $$ 55 | \vec a={dv\over dt}\vec e_t+v^2{d\theta\over ds} 56 | $$ 57 | 58 | 我们定义$d\theta\over ds$为曲率。而曲率半径,则为曲率之倒数。 59 | 60 | 曲率半径,可看作轨道附近之内切圆的半径。 61 | 62 | 又因为 63 | 64 | $$ 65 | \vec a =a_t\vec e_t+a_n\vec e_n 66 | $$ 67 | 68 | 故此,法向加速度的表达式可以写作$v^2\over\rho$ 69 | 70 | 圆周运动时,角速度$\omega={d\theta\over dt}$,其为矢量。其方向根据圆周运动方向进行右手定则得之,垂直于此运动平面。 71 | 72 | 定义$\beta={d\omega\over dt}$,称之为角加速度。在圆周运动中,$a_t=R\beta$,$a_n=R\omega^2$ 73 | 74 | 定义$\beta$之正方向为$\omega$之正方向。这是符合直觉的。 75 | 76 | 显然在同一坐标系下,无论我如何分解加速度,其值是相同的。 77 | 78 | 在平面直角坐标系中,有$\rho=|{(1+y'^2)^{3\over 2}\over y''}|$ 79 | 80 | 在极坐标系中,我们显然有: 81 | 82 | $$ 83 | \vec v = {dv\over dt}\vec e_t+{d\theta\over dt}\vec e_n 84 | $$ 85 | 86 | 运动学上一般就两种类型问题。求导或者积分。 87 | 88 | 先求总加速度,再求切向加速度,平方求法向加速度,更简便。 89 | 90 | 几何约束在运动学中计算的作用。 91 | 92 | ## 相对运动 93 | 94 | 运动描述是具有相对性的。假设两个参考系相对做平动。 95 | 96 | $S'$相对$S$的位置矢量是$\vec R$ 97 | 98 | 则,$\vec r=\vec r'+\vec R$ 99 | 100 | 这个公式中蕴含着一些假设:空间两点距离的测量与物体运动无关。时间间隔与不同的参考系无关。也就是说,认为时空是**绝对的**。 101 | 102 | $\vec v=\vec v'+\vec u,\vec a=\vec a'+{d\vec u\over dt}$ 103 | 104 | 这就是伽利略变换。在各个分量下,也可以这样。 105 | 106 | 速度叠加公式不适用于光速。 107 | 108 | # 2、质点动力学 109 | 110 | 一,惯性定律。但是,它的前提条件是在惯性参考系中。物理界上,实际上还没有找到严格的惯性参考系。 111 | 112 | 第二定律。 113 | 114 | $\vec F={d\vec p\over dt}$ 115 | 116 | 第二定律具有瞬时性和矢量性。 117 | 118 | 牛三认为力是超距的。也就是说,认为力的传播速度是无限的。实际上力是有限速度的,大家认为是以光速传播的。如果力速度有限,在同一时刻,作用力和反作用力不相等。 119 | 120 | 牛顿力学仅对惯性系、低速、宏观、实物(非场)物体适用。 121 | 122 | 质子的寿命远长于中子。 123 | 124 | 一个质子:2个top和一个down。 125 | 126 | 一个中子:2个down和一个top。 127 | 128 | 夸克总是三个三个存在。但是轻子可以单独存在。带电轻子易于观察到,但不带电的,如中微子等,则不容易被观察到。 129 | 130 | 第二代、第三代费米子衰变很快。 131 | 132 | 万有引力、电磁力、强力、弱力。 133 | 134 | 玻色子(弱子),胶子(强子),万有引力(引力子?) 135 | 136 | 质量分为惯性质量和引力质量。 137 | 138 | 目前的引力常数,就是包含了**惯性质量和引力质量之比**,使得我们在正常计算中,只需把它当作1就可以了。 139 | 140 | 如果质点在均匀球体之外,那么其受到的万有引力等价于球的质量集中在球心时产生的万有引力。 141 | 142 | 如果质点在均匀球壳之内,那么其受到的万有引力为0。 143 | 144 | $\vec G=\vec F_引 +\vec F_离$ 145 | 146 | $\vec F_离=-\vec F_向$ 147 | 148 | $p\approx F_引-F_向\cos\varphi$ 149 | 150 | 弹性力-胡克定律。这种力实际上也是一种电磁力。这种力称为线性恢复力。 151 | 152 | 发生形变,故而产生形变。形变导致物体内部分子间产生电磁斥力,从而产生出弹性力。同理,若绳子之类的物体被伸长,物体内部分子之间会产生电磁引力,从而产生出弹性力。 153 | 154 | 考虑绳子牵引一个物块作匀加速运动,倘若绳子有质量,那么绳子内,各处的弹力不一定相等。 155 | 156 | 应变:${l-l_0\over l_0}$ 157 | 158 | 应力一开始会正比增长。但在弹性极限之前,已经有一部分,应力不与应变成正比。这个极限称为正比极限。当超过弹性极限后,此时产生的形变就是范性形变。此时,应力随应变的增长速度减缓。当应变进一步增长,就会来到断裂点。 159 | 160 | 考虑摩擦力,滑动摩擦系数和物体相对运动速度有关。这个系数先减小,之后增大。 161 | 162 | 滑动摩擦系数与光滑程度、温度都有关。当温度足够高时,摩擦系数会突然降为0。 163 | 164 | 流体阻力。当速度较小时,$f=cv$;速度再快$f=bv^2$;速度再高$f=kv^3$ 165 | 166 | 流体阻力与速度、流体种类、运动物体的形状等有关。 167 | 168 | 分子之间的力:剩余电磁力。 169 | 170 | 洛伦兹力: 171 | 172 | $\vec F=q(\vec E +\vec v\times \vec B)$ 173 | 174 | 熵力:长链分子被拉伸时,熵会减小;当外界影响撤去后,熵会趋向于增加,产生恢复力。 175 | 176 | 牛顿力学解题步骤: 177 | 178 | 1、找物体 179 | 180 | 2、考察力和性质 181 | 182 | 3、画参考系 183 | 184 | 4、隔离法 185 | 186 | 5、运动方程 187 | 188 | 6、几何关系 189 | 190 | 7、必要近似 191 | 192 | 变量替换的方法,简化微分方程,从而易于求解。 193 | 194 | 支持力的方向显然方向是一定的。如果支持力计算出了负值,那么说明二者脱离了。 195 | 196 | 牛顿定律只在惯性参考系成立。 197 | 198 | 严格意义上没有什么惯性系。我们常用地面参考系和地心参考系、太阳参考系来近似之。 199 | 200 | 一切相对惯性系做匀速直线运动的参考系,也是惯性系。 201 | 202 | 力学相对性原理:牛顿定律在任何惯性参考系中具有相同的形式。也可以表述为,一切惯性系,不可于其中做力学实验,来判断其相对于其他惯性参考系的速度。 203 | 204 | $S$为惯性系,$S'$为非惯性系,$S'$相对于$S$之加速度为$\vec a_0$ 205 | 206 | 则在这两个平动参考系中,$\vec a=\vec a_0+\vec a'$ 207 | 208 | 故,牛顿第二定律在非惯性系中不成立。 209 | 210 | 非惯性系中引入惯性力$\vec F=-m\vec a$ 211 | 212 | 在匀速转动参考系中,存在离心惯性力。$\vec T=m\vec a,T=m\omega r^2$方向始终背离圆心。 213 | 214 | 在匀速转动参考系中,存在科里奥利力。$f=-2m\vec\omega\times\vec v$,垂直于速度方向。 215 | 216 | # 4、动能定理和机械能守恒定律 217 | 218 | 功的计算表达式是一个路径积分。在直角坐标系中将其分解,就可以转化为定积分。 219 | 220 | 摩擦力做功与路径有关。 221 | 222 | 动能定理仅在惯性系中成立,因为这是由牛顿第二定律推导而来的。倘若非要在非惯性系中用,需要加上惯性力等假想力。 223 | 224 | 由质点到质点组,再到连续物体。 225 | 226 | 质点系中,有内力和外力。 227 | 228 | 在质点系中内力冲量总为0,一对内力的功通常不为0。一对力,指分别作用在两个物体上的大小相等,方向相反的力。可以是作用力与反作用力的关系,也可以不是。 229 | 230 | 一对滑动摩擦力所做的功恒小于零。 231 | 232 | 一对力所做的功,与参考系无关。 233 | 234 | 在没有相对位移或相对位于于一对力垂直,其功必为0。 235 | 236 | 如果质点所受的力仅与位置有关,那么质点受力的空间分布称为力场。 237 | 238 | 如果力的作用线在质点运动过程中始终通过一个固定点的力,我们称这个点为力心,并且把这种力称为有心力。 239 | 240 | 有心力做功,与路径无关!我们把做功与路径无关,仅与初末位置有关的力,称为保守力。保守力沿着闭合路径,积分总为0。 241 | 242 | 回旋力,摩擦力是常见的非保守力。 243 | 244 | 如果环路积分为0,称为无旋的;反之则有旋。 245 | 246 | 如果曲面积分得通量为0,称为无源的;反之则有源。 247 | 248 | 势能。保守力场对应一个势能。势能可以随便加一个常量,因为我们要用的一半是差值。我们规定无穷远处,引力势能为0。 249 | 250 | 势能零点可以随意选取。 251 | 252 | $$ 253 | E_p(\vec r)=\int_p^{p_0}\vec F(\vec r)d\vec r\\ 254 | dA=\vec F\cdot d\vec r=F_xdx+F_ydy+F_zdz 255 | $$ 256 | 257 | 因为$dA=dE_p$ 258 | 259 | 所以$F_x=-{\partial E_p\over \partial x}$ 260 | 261 | 其余同理。故 262 | 263 | $$ 264 | \vec F=-\nabla E_p 265 | $$ 266 | 267 | 质点系的势能属于质点系这个系统称为相互作用势能。 268 | 269 | 质点系的势能为:$V=\sum_j\sum_{i>j}E_{pji}$ 270 | 271 | 外力、内力对系统做功之和为系统动能总增量。 272 | 273 | 内力的总共,可以看做保守力做功之和和非保守力做功之和。保守力做的总功,不会影响系统的总功。 274 | 275 | 若外力和非保守力做功为0,并且在惯性参考系下,则系统的总机械能保持不变。 276 | 277 | 在一个惯性系中机械能守恒,在另一惯性系中机械能不一定守恒。比如匀速上升的电梯。 278 | 279 | # 5、动量与角动量 280 | 281 | 动量:$\vec p=m\vec v$ 282 | 283 | 力矩:$\vec r \times \vec F$ 284 | 285 | 角动量:$\vec L=\vec r\times\vec p$ 286 | 287 | 内力对质点组的时间积累始终为0。 288 | 289 | 平动,是冲量改变动量;转动,是角冲量改变角动量。 290 | 291 | 变力的冲量$\vec I=\int_{t_1}^{t_2}\vec F(t)dt$ 292 | 293 | $d\vec p=d\vec I=\vec F$ 294 | 295 | 匀速圆周运动,运动一圈冲量为0。 296 | 297 | 动量定理符合矢量性,可以从分量考虑。 298 | 299 | 质点系是一个零动量系。系统不受外力或所受合外力为零时,系统总动量守恒。当外力远小于内力时,可以近似认为系统总动量守恒。 300 | 301 | 定义质点系的质心为:$\vec r_c={m_1\vec r_1+m_2\vec r_2\over m_1+m_2}$ 302 | 303 | 质心的动量等效于整个系统的动量。 304 | 305 | 对于更多物体,$\vec r_c={\sum_{i=1}^n m_1\vec r_i\over\sum_{i=1}^nm_i}$ 306 | 307 | 对于连续的物体,我们也可以把整个物体切割成很多块的小“质元”。 308 | 309 | 碰撞的分类:弹性碰撞和非弹性碰撞。完全非弹性碰撞,物体合为一体。 310 | 311 | 弹性碰撞:动能守恒,动量守恒。 312 | 313 | 对于非弹性碰撞,我们定义$e={v_2-v_1\over v_{10}-v_{20}}$ 314 | 315 | 称之为恢复系数。恢复系数与物体材质等有关。 316 | 317 | 恢复系数为1,说明弹性;恢复系数为0,说明完全非弹性碰撞。恢复系数大于1,说明机械能增加,可能过程中的一些化学能转化为机械能。 318 | 319 | 接下来,我们考虑变质量物体的运动。把运动物体和增加或减少的质量共同看做一个质点系。 320 | 321 | 在只计算重力的过程中,$F=-m_1g=m_1{dv\over dt}+u{dm_1\over dt}$ 322 | 323 | 两侧积分:$v={u\ln{m_{10}\over m_1}}-gt$ 324 | 325 | 一个是初始质量,一个是喷气后的质量。齐奥尔科夫斯基公式。目前常采取多级发射方式。 326 | 327 | 为什么要引入角动量?因为动量不可以描述转动的情况。 328 | 329 | $\vec L=\vec r\times\vec p$ 330 | 331 | 大小上等于$rmv\sin\theta$ 332 | 333 | 可以用分量的形式表达。 334 | 335 | ${d\vec L\over dt}=\vec r\times \vec F$ 336 | 337 | 我们记$\vec M=\vec r\times\vec F$ 338 | 339 | 此即为力矩,我们称$\vec Mdt$为冲量矩。类似地,积分可以得到角动量的改变量。 340 | 341 | 在$\vec M$为0的情况下,则$d\vec L\over dt$不变,角动量是一个常矢量。 342 | 343 | 对于钢制杆的摆问题,角动量守恒。 344 | 345 | 两种常见的力矩为0的情况:第一种,合外力为0;第二种,合外力是一个有心力。此刻,角动量是一个常量,轨道在同一个平面内。 346 | 347 | 开普勒第二定律:${dS\over dt}={L_0\over2ms}$ 348 | 349 | 倘若绕固定轴进行转动,在固定轴方向上的力矩为0,那么显然在固定轴方向上的角动量是一个常量。 350 | 351 | 离心势能:$L^2\over2mr^2$ 352 | 353 | 等效势能记作$V_{eff}={L^2\over 2mr^2}-{GMm\over r}$ 354 | 355 | 内力矩之和亦总为0。对于质点系而言,内力不会改变系统的角动量。 356 | 357 | 一个系统的动量守恒和角动量守恒之间并没有必然的联系。 358 | 359 | r是选取点指向力的作用线的矢量。通过内力可以实现角动量的转移。 360 | 361 | # 6、刚体运动基础 362 | 363 | 刚体是一种理想模型。在任何情况下,形状和体积都不改变。刚体上各质元之间的相对位置保持不变。 364 | 365 | 我们称完全描述运动所需的独立坐标系为自由度。 366 | 367 | 对于刚体,我们只需确认其中的三个点,就可以确定位置,即自由度为9。但是,倘若三个点之间的间距相等时,我们只需要两个点,也就是自由度只需要6。 368 | 369 | 刚体的运动分为平动和转动。转动可以分为定轴转动和定点转动。 370 | 371 | 定轴转动:每一个质元都在做圆周运动,各质元运动的圆心在同一条直线上。 372 | 373 | 对于刚体的角动量,可以写为$J\vec\omega$ 374 | 375 | 刚体的转动动量是${1\over 2}J\omega^2$ 376 | 377 | 定点运动:自由度为3。指的是只有一点固定不动的运动。 378 | 379 | 对于定轴转动,我们只需要研究明白某一垂直于转轴的平面(转动平面)上的运动。在转动平面内,取转心O和参考轴x。如果角加速度方向与角速度平行。$a_t=r\alpha$ 380 | 381 | 对于定轴转动,只有垂直转轴的外力才产生沿转轴方向的力矩。平行于转轴的外力形成的力矩被转轴产生的力矩抵消。 382 | 383 | $M=\sum_i r_iF_i\sin\theta_i$ 384 | 385 | 类似地,我们可以计算出定轴转动过程中的角动量。$\vec L=\sum_i(\vec R_i\times\Delta m_i\vec v_i)$ 386 | 387 | 由于定轴转动过程中角速度相同,所以$L=(\sum_i\Delta m_ir_i^2)\omega$ 388 | 389 | 我们记$J=\sum_i\Delta m_ir_i^2$称为刚体对轴的转动惯量。 390 | 391 | 如果在转动过程中J不变,那么$M={dL\over dt}={dJ\omega\over dt}=J{d\omega\over dt}=J\alpha$ 392 | 393 | 对称刚体绕对称轴的转动,刚体只有沿转轴方向的角动量。对于非对称的刚体,还有垂直转轴方向的角动量。$\int_{t_0}^tMdt$称为角冲量。 394 | 395 | 刚体对转轴的力矩为0时,其对转轴的角动量保持不变。 396 | 397 | 角动量守恒有这么几种情况: 398 | 399 | 1. $J,\omega$都不变 400 | 401 | 2. $J,\omega$都变化,但守恒 402 | 403 | 3. 刚体组 404 | 405 | 刚体的转动惯量:$J=\sum_i\Delta m_ir_i^2$ 406 | 407 | 均匀圆环的转动惯量,显然为$mR^2$ 408 | 409 | 均匀圆盘的转动惯量${1\over 2}mR^2$ 410 | 411 | 平行轴定理:刚体对任一转轴的转动惯量等于通过质心的平行转轴的转动惯量加上刚体质量乘上两平行轴间距离的平方。 412 | 413 | 薄板的垂直轴定理:三条轴垂直,$J_z=J_x+J_y$ 414 | 415 | # 第八章 416 | 417 | 行波:随时间的变化,波的几何形状进行了平移。 418 | 419 | 相速率:波构型的传播速率。相当于波速。 420 | 421 | 波动方程:$\frac{\partial^2 y}{\partial t^2}=\frac{f}{\eta}\frac{\partial^2 y}{\partial x^2}$ 422 | 423 | 其中,$f$为水平方向上的力。$\eta$为弦的线密度。 424 | 425 | 并且,关于波速,有$\frac{f}{\eta}=v^2$ 426 | 427 | 从智障一点的角度去想,$v=\frac{dx}{dt}$,那么显然有上面那玩意。 428 | 429 | 对于弦,位于平衡位置时,动能和势能极大。位于振幅极大值时,动能和势能极小。 430 | 431 | 能量密度,代表单位体积质元具有的能量。能流密度,代表单位时间内通过$x$处单位面积的平均能量。 432 | 433 | 能流密度为$I=\frac{1}{2}\rho\omega^2v^2A^2$ 434 | 435 | 驻波:合成波的空间部分和时间部分分离了。振动最大处,称为波腹。振动最小处,称为波节。 436 | 437 | 惠更斯原理:在每一时刻,波前上的每个点都会成为下一时刻的波源。 438 | 439 | 在固定端发生波的反射,存在半波损失。在自由端发生波的反射,会按照原相位反射。 440 | 441 | 对于两端固定的波,任意次谐波和基波都存在。如果一端固定,一端自由,只存在奇次谐波。 442 | 443 | 对于波的干涉,我们称$\gamma=\frac{|\omega_1-\omega_2|}{2\pi}$为拍频。这表征了波干涉下的振动强度的频率变化。 444 | 445 | 对于波$y=A\cos(wt-kx)$,其相速度为$\frac{\omega}{k}$,群速度为$\frac{d\omega}{dk}$ 446 | 447 | 多普勒效应:$f'=\frac{v-v_r}{v-v_s}f$ 448 | 449 | # 第九第十章 450 | 451 | 温标:按照一定规则标定的温度数值。 452 | 453 | 理想气体:严格遵循克拉伯龙方程,内能只和温度有关的气体。温度不太低,压强不太高的气体上近似成立。 454 | 455 | 理想气体温标:即以开尔文为单位的那一套温标。 456 | 457 | 热力学第零定律:热平衡具有传递性。 458 | 459 | 强度量和广延量:是否具有可加性。 460 | 461 | 气体的随机碰撞:温度定义为和分子平均动能成正比的函数。 462 | 463 | $\frac{1}{2}m\bar v^2=\frac{3}{2}kT$ 464 | 465 | 在非相对论情况下,气体压强为$p=\frac{2}{3}n\bar\epsilon_t,\bar\epsilon_t=\frac{1}{2}m\bar v^2$ 466 | 467 | 能均分定理:每一个运动自由度运动的平均能量均相同。$\bar\epsilon=(t+r+2s)\frac{1}{2}kT$,$t$为平动自由度,$r$为转动自由度,$s$为振动自由度。 468 | 469 | 比如,对于双原子分子,$t=3,r=2,s=1$,故等容热容为$\frac{7}{2}R$ 470 | 471 | 概率密度函数:$f(x)=\frac{h(x)}{\int h(x)dx}$ 472 | 473 | Maxwell速度分布函数:$F_M(\vec v)=(\frac{m}{2\pi kT})^{\frac{3}{2}}e^{-\frac{mv^2}{2kT}}$ 474 | 475 | Maxwell速率分布函数:$f_M(v)=4\pi(\frac{m}{2\pi kT})^{\frac{3}{2}}e^{-\frac{mv^2}{2kT}}v^2$ 476 | 477 | 速率分布函数极大值对应的速率称为最概然速率。 478 | 479 | 大气密度分布:$n(z)=n_0e^{-mgz\over kT}$ 480 | 481 | 玻尔兹曼密度分布:$n(\vec r)=n(\vec r=0)e^{-\epsilon_p(\vec r)\over kT}$ 482 | 483 | 玻尔兹曼能量分布律:$dN=n_0(\frac{m}{2\pi kT})e^{-\epsilon(v_x,v_y,v_z,x,y,z)\over kT}dxdydzdv_xdv_ydv_z$ 484 | 485 | 对于固体的定容摩尔热容,有杜龙-珀替定律,对于温度较高的单质固体材料,热容为$3R$,双原子$6R$,三原子$9R$ 486 | 487 | 准静态过程:过程的每一时刻都可以近似看作平衡态。 488 | 489 | 热力学第一定律:内能改变量等于热量和做功之和。 490 | 491 | 等压热容为等容热容加上$nR$,因为做功。等温热容为无穷大。 492 | 493 | 在绝热过程中,令$\gamma=\frac{C_p}{C_v}$,则$pV^\gamma$为一个常数。由克拉伯龙方程,我们可以进行一定的变形。 494 | 495 | 多方过程:热容保持不变的情况下的过程。记多方过程中的热容为$C_n$,等容过程下的热容为$C_v$,等压过程下的热容为$C_p$那么令$n=\frac{C_p-C_n}{C_v-C_n}$,那么$pV^n\equiv constant$ 496 | 497 | 定义焓为$H=E+pV$,焓也是一个状态函数。体系焓的变化,表征在等压过程中,系统从外界吸收的热量的多少,即$Q_p=H_2-H_1$ 498 | 499 | 真实情况下,焓不仅仅是温度的函数。 500 | 501 | 可逆过程:体系可完全恢复到初态,并且不消耗能量。 502 | 503 | 对外界做功的热力学循环体系,称为热机;外界对之做功的热力学体系,称为热泵。 504 | 505 | 热机效率$\eta=\frac{\Delta W}{\Delta Q}$,即有效做功和吸热量的比值。 506 | 507 | 卡诺循环:等温膨胀,绝热膨胀,等温压缩,绝热压缩。卡诺热机效率为$\eta=1-\frac{T_2}{T_1}$ 508 | 509 | 奥托循环:等容吸气,绝热膨胀,等容放气,绝热压缩。$\eta=1-\frac{V_1^{\gamma-1}}{V_2^{\gamma-1}}$ 510 | 511 | 如果倒开卡诺机,那么我们就得到了卡诺制冷机。性能系数(COP)表征输入单位功可去除的热量。即$COP=\frac{Q}W$ 512 | 513 | 热力学第二定律两种表述: 514 | 515 | 开尔文表述:不可能从单一热源吸收热量,将其完全转化为有用的功而不产生其他影响。 516 | 517 | 克劳修斯表述:不可能吧热量从低温物体传到高温物体,而不引起其他变化。 518 | -------------------------------------------------------------------------------- /2025_Spring/Algorithm.md: -------------------------------------------------------------------------------- 1 | # Algorithm 2 | 3 | ## Introduction 4 | 5 | Turing machine is a Triple $(\Gamma,Q,\delta)$ 6 | 7 | Church-Turing Thesis: an effective method iff it's computable by a Turing machine. 8 | 9 | Halt Problem 10 | 11 | - Divide and Conquer 12 | 13 | - Graphs 14 | 15 | - Greedy 16 | 17 | - Dynamic Programming 18 | 19 | - Max Flow 20 | 21 | - NP-hardness 22 | 23 | - Advanced Problems 24 | 25 | NP and P 26 | 27 | NP-complete problem 28 | 29 | Approximation Algorithms 30 | 31 | Online Algorithm: how to evaluate:$\forall \text{ input }A(\sigma)\leq \Gamma\cdot OPT(\sigma)$ 32 | 33 | Ski-rental 34 | 35 | ## Divide and Conquer and Running Time Analysis 36 | 37 | ### Integer Multiplication 38 | 39 | Divide a multiplication problem into two smaller problems! 40 | 41 | #### Karatsuba Algorithm 42 | 43 | $$ 44 | 45 | (a*10^\frac{n}{2}+b)(c*10^\frac n2+d)=ac*10^n+(ad+bc)*10^\frac n2+bd\\ 46 | 47 | =ac*10^n+((a+b)(c+d)-ac-bd)*10^\frac n2+bd 48 | $$ 49 | 50 | Try to down the calculation! 51 | 52 | #### Better algorithms 53 | 54 | Toom-Cook: $O(n^{1.465})$,break it into 5 $\frac n3$-size problems 55 | 56 | ### Matrix Problems 57 | 58 | #### Srassen's magical idea 59 | 60 | 61 | -------------------------------------------------------------------------------- /2025_Spring/Combinatorics.md: -------------------------------------------------------------------------------- 1 | # Combinatorics 2 | 3 | ## Lec 1 4 | 5 | 多项式:$P(x)=a_0+a_1x+...+a_nx^n$ 6 | 7 | 我们不知道它是几次多项式。 8 | 9 | 如果$P\in\N[x],x\in\Z$,那么我们需要询问多少个 $x$,才可以确定每一个系数? 10 | 11 | 2次。 12 | 13 | 如果允许 $x\in\R$,那么一次就可以了。但是算不算得出来是个问题。 14 | 15 | 但如果 $P\in\Z[x],x\in\Z$,那么就不可以在有限步中知道答案了。 16 | 17 | 比如说,$P+(x-x_0)...(x-x_k)$ 18 | 19 | 对称差 $A\Delta B$ 具有交换律和结合律。 20 | 21 | 实际上,对于更广泛的对称差,我们可以定义为 $\{x||\{i\in[k]:x\in A_i\}|为奇数\}$ 22 | 23 | $A^B$ 可以定义为 $B\to A$ 的所有映射的集合。而映射也可以看成是一个划分的形式。 24 | 25 | 我们可以自然地定义 $\dbinom{[n]}{k}$ 为在 $[n]$ 中挑选 $k$ 个的种类数,其和 $\dbinom nk$ 等价。 26 | 27 | 在组合中,定义 $0^0 = 1$ 更合适。 28 | 29 | 比如笛卡尔积中,假如 $A=\{1\}$, 则 $A^2=A\times A=\{(1,1)\},A^1=\{(1)\}\neq A,A^0=\{()\}\neq \empty$ 30 | -------------------------------------------------------------------------------- /2025_Spring/Large_Language_Models.md: -------------------------------------------------------------------------------- 1 | # CS2916 LLMs 2 | 3 | ## Lec1 4 | 5 | ### 引言 6 | 7 | - Generative Pretraining(vectors) 8 | 9 | - Prompting Engineering 10 | 11 | 数据标注 $\to$ 数据合成 12 | 13 | ### NLP 基础 14 | 15 | Challenges: 16 | 17 | - 多义性(ambigious) 18 | 19 | - 递归性(recursive) 20 | 21 | - 结构复杂性(complex) 22 | 23 | Tasks: 24 | 25 | - Text to Label 26 | 27 | - Text-Span to Label(A union of text and a span) 28 | 29 | - Text-Text to Label 30 | 31 | - Text to Labels 32 | 33 | - Text to Text 34 | 35 | - Text to Tree 36 | 37 | - **Word Prediction** 38 | 39 | Feature $\to$ Architecture $\to$ Objective $\to$ Prompt 40 | 41 | ## Lec 2 42 | 43 | Fine-tuning 44 | 45 | Prompting 46 | 47 | ML is to find a mapping! 48 | 49 | Three Concepts of ML: 50 | 51 | - Model 52 | 53 | - Learning Policy 54 | 55 | - Optimization(SGD is often used in LLMs) 56 | 57 | self-supervised training 58 | 59 | GD vs SGD 60 | 61 | training set, validation set, test set 62 | 63 | SGD and batch GD 64 | 65 | Optimization and Normalization(decay, SGD, early stopping) 66 | 67 | Some h-paras: 68 | 69 | - gradient_accumulation 70 | 71 | - weight_decay 72 | 73 | - warmup_ratio 74 | 75 | MLPs 76 | 77 | LLMs automatically extract features! 78 | 79 | ### NN and DL 80 | 81 | The Bitter Lesson 82 | 83 | Activation Functions 84 | 85 | ReLU, tanh, Sigmoid 86 | 87 | gradient vanish 88 | 89 | h-paras, learning paras, status values 90 | 91 | inductive bias 92 | 93 | No-Free-Lunch-Law 94 | 95 | ## Lec 3 96 | 97 | RNN: difficult to be parallelled, and the long-distance dependencies are difficult to be catched. 98 | 99 | Gradient boom: use gradient clipping to ensure the gradient is in a proper range. 100 | 101 | LSTM 102 | 103 | BERT 104 | 105 | ResNet 106 | 107 | Highway Network 108 | 109 | CNN kernel, step, padding, 110 | 111 | Narrow CNN, Equal CNN and Wide CNN. 112 | 113 | Multi-kernel CNN 114 | 115 | Pooling, max pooling may be the most common one. 116 | 117 | Pooling is a **great** way to reduce dimensions. 118 | 119 | LM 120 | 121 | We use $\prod_{i=1}^nP(\omega_i|w_1,w_2,...)$ to judge whether a model performs well or not. 122 | 123 | ## Lec 4 124 | 125 | ### NMT 126 | 127 | encoder-decoder model 128 | 129 | When decoding, the output token will be re-input in the model. 130 | 131 | seq2seq: input tokens as a sequence, and the outputs are in a sequence too. 132 | 133 | Attention and RNN 134 | 135 | LSTM: Consider the situation that a key word is in the middle of the setence. 136 | 137 | gradient vanishing and gradient exploding: the problem of long-term dependency 138 | 139 | A easy way is to use a max-pooling to the all $h$ in the models. 140 | 141 | Attention Mechanism: the key point is that it build a direct connection between the input and the output. 142 | 143 | RNN with attention: $s_i=f(s_{i-1},y_{i-1},c_i)$, where $c_i = \sum_{j=1}^N\alpha_{ij}h_j$, $y_{i-1}$ is the last output token, and $s_{i-1}$ is the last value. 144 | 145 | Self-attention: attention embedded in encoder-encoder, which can be seen LSTM with a better output way: use a weight matrix to measure the significance of the all tokens. Multi-head self-attention. 146 | 147 | Further more, we don't use RNN, and add positional embedding code. 148 | 149 | ### Transformer 150 | 151 | QKV 152 | 153 | $$ 154 | \text{Attention}(Q,K,V)=\text{softmax}(\frac{QK^T}{\sqrt {d_k}})V 155 | $$ 156 | 157 | In transformer, we will let $\text{head\ numbers} \times \text{head\ dimension} = \text{input dimension}$, which is helpful for calculation: since we'll use many layers of Transformer, we want lwt the input and the output have the same dimension, which does coding a favor. 158 | 159 | Position Encoding: use cos and sin. However, as for as I know, RoPE is much more common today. 160 | 161 | ### Decoder-Only LLMs 162 | 163 | When decoder, is self-regressive. 164 | 165 | GPT-3 166 | 167 | SFT(supervised fine-tuning), RLHF(reinforce learning) 168 | 169 | Use human data to build a reward model. PPO 170 | 171 | language generation 172 | 173 | in-context learning 174 | 175 | world knowledge 176 | 177 | SFT: answer the question;generlization; code generation; CoT. 178 | -------------------------------------------------------------------------------- /2025_Spring/Machine_Learning.md: -------------------------------------------------------------------------------- 1 | # Machine Learning 2 | 3 | ## Lec1 机器学习简介 4 | 5 | 什么是 AI? 6 | 7 | #### 数据科学 8 | 9 | 已知联合概率分布 $p(x_1,x_2)$,设法找到条件分布 $p(x_2|x_1)$ 10 | 11 | LM: $p(x)=\prod_{i=1}^T p_\theta(x|x_0,...,x_T)$ 12 | 13 | 从 LM 到 LLM 14 | 15 | 有价值的是数据产生的服务。 16 | 17 | #### 机器学习的定义 18 | 19 | 智能的本质在于学习。 20 | 21 | ANI, AGI, ASI 22 | 23 | 机器学习研究的是学习算法。由三元组 明确定义。 T 为某些任务, E 为经验, P 为性能。 24 | 25 | 什么时候机器学习具有优势? 26 | 27 | 两种机器学习的类型:预测和决策。 28 | 29 | 预测: 30 | 31 | - 监督学习,根据数据预测所需的输出。 32 | 33 | - 无监督学习,生成数据实例。 34 | 35 | 决策:强化学习,在动态环境中采取行动。 36 | 37 | 2012 AI 的崛起 38 | 39 | #### 机器学习的应用 40 | 41 | 预测任务,生成任务,决策任务。 42 | 43 | #### 机器学习基本思想 44 | 45 | 监督学习,无监督学习,强化学习 46 | 47 | 监督学习: 48 | 49 | 给定带标签的训练数据集 $D=\{(x_i,y_i)\}_{i\in[n]}$, $x_i$ 是特征数据, $y_i$ 是对应的标签。学习的是对应的映射 $y_i\simeq f_\theta(x_i)$, 我们把 $\{f_\theta(·)\}$ 称为假设空间。学习的过程,也就是对参数的更新。 50 | 51 | 学习的想法:预测的结果尽量接近。即 $\min_\theta\frac 1N\sum_{i=1}^N\mathcal{L}(y_i,f_\theta(x_i))$ 52 | 53 | 比较常见的还是均方误差 $\frac12(y_i-f_\theta(x_i))^2$, $1/2$ 还是为了梯度更好计算。并且容忍小误差,惩罚更大的误差。损失函数选择平方的原因,还是为了惩罚更远的错误。 54 | 55 | 梯度学习方法 56 | 57 | 使用不同的模型,实际上就是在修改不同的假设空间。 58 | 59 | #### 模型选择 60 | 61 | ##### 欠拟合和过拟合 62 | 63 | under-fitting, over-fitting 64 | 65 | 泛化 66 | 67 | ##### 正则化 68 | 69 | 添加对参数的惩罚项。即 $\min_\theta\frac 1N\sum_{i=1}^N\mathcal{L}(y_i,f_\theta(x_i))+\lambda\Omega(\theta)$ 70 | 71 | Proposed Model 最好能力较强。因为能力差是没法解决的。但正则化(regularization)可以帮助解决问题。 72 | 73 | 比较经典的正则化方式: 74 | 75 | - L2 正则化(岭回归 Ridge): $\Omega(\theta)=\sum_m\theta_m^2$ 76 | 77 | - L1正则化(拉索回归 LASSO): $\Omega(\theta)=\sum_m|\theta_m|$,倾向于会让一些参数降为 0 。 78 | 79 | 80 | -------------------------------------------------------------------------------- /2025_Spring/Modern_Operating_System.md: -------------------------------------------------------------------------------- 1 | # 现代操作系统 2 | 3 | ## 第一章 引论 4 | 5 | 内核态和用户态:操作系统运行在内核态,对所有硬件有完全访问权。 6 | 7 | 操作系统有两个功能: 8 | 9 | - 提供抽象 10 | 11 | - 管理硬件(主要是多路复用,包括时间和空间) 12 | 13 | 大多数总线都是共享总线架构。因此,需要通过仲裁器决定谁使用总线。 14 | 15 | PCIe 总线取代了之前的 PCI 总线。PCIe 采用串行总线架构,而 PCI 采用并行总线架构。 16 | 17 | 这里所谓的串行,指的是单个数据是串行传输的;并行指的是单个数据通过多个数据通路发送,这对精确性等要求高,时延长。PCIe 的时延更短。 18 | 19 | ### 操作系统的基本概念 20 | 21 | **进程**(process):本质上是一个程序。进程有对应的**地址空间**(address space, 亦被称为 core image)。进程中包括一个程序计数器,寄存器等等。 22 | 23 | 和进程相关的所有信息,都会存在操作系统的一张表中,即**进程表**(process table)中。 24 | 25 | 进程间通信:interprocess communication. 26 | 27 | 工作目录(working directory): 每个进程有一个工作目录。若没有给出绝对地址,那么会在该目录下寻找。 28 | 29 | 文件描述符(file descriptor): 打开文件后检查其权限。如果权限许可,那么返回一个小整数。这个整数称为文件描述符。 30 | 31 | 管道(pipe): 一种虚文件。连接两个进程。 32 | 33 | rwx 位 34 | 35 | 进程标识符(Process IDentifier, PID). fork() 父进程返回值为子进程 PID, 子进程返回值为 0. 36 | 37 | mount 调用可以把目录挂载到别的位置下面。 38 | 39 | ## 第二章 进程与线程 40 | 41 | ### 进程 42 | 43 | 守护进程(daemon): 在后台停留的进程。当请求到达时唤醒并进行处理。 44 | 45 | 进程创建:系统初始化,系统调用 fork() 等。 46 | 47 | 父进程和子进程具有不同的地址空间。有时也会共享。此时为 copy on write. 48 | 49 | 进程退出:可能是自愿退出(无论是正常退出还是出错退出);也可能是非自愿退出(严重错误,或者被其他进程杀死)。 50 | 51 | UNIX 中,每一个进程都和它所有的子进程组成一个进程组。 init 进程会在系统初始化时被拉起。所有进程都可以看做是 init 进程的后裔进程。 52 | 53 | 在 Windows 中,进程的继承关系就可以被转移。父进程通过**句柄**与子进程交互。但其一旦把句柄转给另一个进程,继承关系就被转移。 54 | 55 | 进程的状态: 56 | 57 | - 运行态 58 | 59 | - 就绪态(可以运行,但是 CPU 被占用) 60 | 61 | - 阻塞态 62 | 63 | 调度程序需要对不同状态的进程的处理进行转移。 64 | 65 | 进程表:每个进程占用一个进程表项。保证该进程可以直接从阻塞态和就绪态转移到运行态。 66 | 67 | interrupt vector 68 | 69 | 多道程序设计: CPU 利用率 $= 1-p^n$ 70 | 71 | ### 线程 72 | 73 | 传统中,一个进程包含一个地址空间和一个控制线程。在一个地址空间下,准并行地执行多个控制线程。 74 | 75 | 线程的好处: 76 | 77 | - 利于通信 78 | 79 | - 易于创建和摧毁 80 | 81 | - 如果多个线程并非 CPU 密集型任务,那么就可以提高效率 82 | 83 | 线程之间也会不断切换,从而看上去在并行执行。比如 PC, 寄存器, 堆栈, 状态都会由线程来保存。 84 | 85 | 每个进程也应该存有一份线程表。 86 | 87 | 两种线程实现方式:在用户空间中和在内核中实现。 88 | 89 | 如果线程在用户空间中实现,那么内核只需要像单线程进程那样就可以了。 90 | 91 | 如果线程在内核中实现,那么线程的创建与摧毁也需要进行系统调用。需要与线程有关的调用都不得不进行系统调用。 92 | 93 | 还有一种方式是尝试进行混合的实现。 94 | 95 | 多个用户级线程对应一个内核线程。具体多少都由程序员。 96 | 97 | ### 进程间通信(IPC) 98 | 99 | 竞争条件(race condition) 100 | 101 | 临界区(critical region, critical section) 102 | 103 | 需要阻止对共享内存的同时读写:互斥(mutual exclusion) 104 | 105 | - 中断屏蔽 106 | 107 | - 自旋锁:自旋过程中 CPu 的空转称为忙等待(busy waiting). 这种策略只适合于等待时间较短的情况。不然性能浪费严重。 108 | 109 | - Peterson 算法 110 | 111 | - TSL(test and set lock)执行 TSL 后的 CPU 会锁住内存总线,并且禁止其他 CPU 在本指令结束之前访问内存。 112 | 113 | - XCHG 114 | 115 | 信号量、互斥量、条件变量 116 | 117 | 屏障(barrier):可以用于进行一组线程的同步。直到所有要求的线程都达到了屏障,才会一起被释放。 118 | 119 | 无锁化:读-复制-更新(Read-Copy-Update, RCU).在一定的宽限期后,旧数据才不再可能被读到。 120 | 121 | ### 调度 122 | 123 | - 计算密集型任务 124 | 125 | - I/O密集型任务 126 | 127 | 三种不同的环境: 128 | 129 | - 批处理 130 | 131 | - 交互式 132 | 133 | - 实时 134 | 135 | 不同的环境的要求不同。比如,批处理环境追求更高的 CPU 利用率。交互式环境要求最小的响应时间。实时环境要求来到的请求尽量满足截止时间。 136 | 137 | #### 批处理环境 138 | 139 | - first-come, first-served 140 | 141 | - shortest job first 142 | 143 | - shortest remaining time next 144 | 145 | #### 交互环境 146 | 147 | - round robing(轮转调度,但上下文切换也需要时间) 148 | 149 | - 优先级调度 150 | 151 | - CTSS(Compatible Time Sharing System, 多级队列,每次运行后下移优先级,但是分配的时间片长度翻倍) 152 | 153 | - 最短进程优先 154 | 155 | - 保证调度(尽量保证一定的性能) 156 | 157 | - lottery scheduling(彩票调度,摇奖,可以给更重要的进程更高的优先级) 158 | 159 | - 公平调度,每个用户分配到的 CPU 时间相同 160 | 161 | #### 实时环境 162 | 163 | - hard real time(硬实时,必须达到 DDL) 164 | 165 | - soft real time(软实时,允许偶尔错失 DDL) 166 | 167 | 进程进行了 fork 之后,需要注意 wait. 防止产生 zombie(死了没人收尸)。父进程死了,还活着就是 orphan; 死了就是 zombie. 168 | 169 | ## 第三章 内存管理 170 | 171 | 把物理地址直接暴露给进程是非常危险的。因此,需要地址空间这种存储器抽象。 172 | 173 | 每个进程都有一份自己的地址空间。实现方式是动态重定位,也就是把每个进程的地址空间映射到不同的实际物理内存。 174 | 175 | Problem: 每个进程拥有不同的地址空间,是非常消耗内存的行为。 176 | 177 | 两种解决方法: 178 | 179 | - 交换(swapping): 进程切换时把当前地址空间中的内容存回磁盘。 180 | 181 | - Virtual Memory 182 | 183 | 交换时,不必存储那些没有用到的内存! 184 | 185 | 如何跟踪分配内存的使用情况? 186 | 187 | - 位图(给一定大小的数据块打上 0-1标记) 188 | 189 | - 空闲区链表(利用各种适配算法去分配内存) 190 | 191 | ### 虚拟内存 192 | 193 | 每个程序拥有自己的地址空间。该空间被分割成多个块,称为页(page)。一页上的地址范围是连续的。 194 | 195 | 程序产生的地址都是虚拟地址,并且构成了一个虚拟地址空间!虚拟地址不会送内存总线上,而是送到内存管理单元(Memory Management Unit, MMU)上。 196 | 197 | 页在物理内存中的对应被称为页框(page frame). 198 | 199 | 为了有效判断一个 page 是否在内存中,会采用一个 present/absent bit 来记录页面是否在内存中。如果 MMU 发现其不在内存中,那么就会产生 page fault. 需要将其换入内存。 200 | 201 | 一般而言,采取页号作为页表的内存。 202 | 203 | 页表:每一个页表项由多个部分组成:页框号,脏位(dirty bit), present/absent bit, 保护位,访问位,允许高速缓存位。 204 | 205 | 我们不希望这个过程由很大的开销。需要加速分页的过程。 206 | 207 | 一种方式是转换检测缓冲区(Translation Lookaside Buffer, TLB, 快表)。其通常在 MMU 中,拥有更少的表项。实际上就可以看作是页表的一份缓存。 208 | 209 | 我们称页在内存中,而不在 TLB 中的情况为软失效(soft miss); 页不在内存中的情况为硬失效(hard miss). 无论哪一种,我们都需要进行页表遍历。 210 | 211 | - 次要缺页错误(页在内存中,但是页表中没有记录) 212 | 213 | - 严重缺页错误(页不在内存中) 214 | 215 | - 段错误(访问非法地址) 216 | 217 | 针对大内存的页表,我们也有两种处理方式: 218 | 219 | - 多级页表 220 | 221 | - 倒排页表(由页框去对应页表项,而不是页本身去对应页表项) 222 | 223 | 处理缺页中断时,我们如何进行页面置换? 224 | 225 | - 最优置换,淘汰之后最远会被用到的页。这是理想情况,不能实现。 226 | 227 | - NRU(Not Recently Used):随机淘汰一个在最近一段时间未使用的页表。 228 | 229 | - FIFO(无需赘述,但效果不好) 230 | 231 | - Second Chance, 在 FIFO 的基础上,如果一张页加入内存后第一次出队,那么把这张页重新入队,并且重新进行出队操作。对每一页而言,直到第二次出队,才被真正换出。 232 | 233 | - Clock, 实际上和 Second Chance 没有太大的区别。 234 | 235 | - LRU(Least Recently Used) 236 | 237 | - NFU(Not Frequently Used),每一个页拥有一个计数器。每次时钟中断进行一次扫描,检查它们是否被访问。如果是,则计数器加一。换出访问最不频繁的页。 238 | 239 | - 老化(Aging) 算法,在 NFU 的基础上,改为计数器右移一位,然后最高位设为 1. 其他一致。 240 | 241 | - 工作集页面置换,称进程需要的所有页面为工作集。设法在进程运行之前,其工作集已在内存中,即预先调页(prepaging).发生缺页中断时,淘汰不在工作集中的一页。 242 | 243 | - WSClock(工作集时钟).类似于工作集页面置换和 Clock 的结合。 244 | 245 | ### 分页系统的设计问题 246 | 247 | 我们称一个程序每执行几条指令就发生一次缺页中断的情况为颠簸。 248 | 249 | 缺页中断时,选择本进程的页进行淘汰,还是在全局上进行考虑?即:进行局部(local)页面置换,还是全局(global)页面置换。 250 | 251 | 全局的置换,通常效果会更好一些。并且,我们也给每一个进程规定一个最小的页框数,保证有这些内容在内存中。目前的一种方式是 PFF(page fault frequency, 缺页中断率)算法。控制分配给每一个进程的页框数。 252 | 253 | 负载控制:当 PFF 过高时,可以考虑把一些进程交换到磁盘中,并且释放其所有页面。 254 | 255 | 页面大小也需要进行一定的考虑。 256 | 257 | 指令空间可以考虑和地址空间分离。 258 | 259 | 部分内存中的页面也可以进行共享。 260 | 261 | 使用动态链接库 262 | 263 | 内存映射文件 264 | 265 | 如果发生缺页中断,那么我们可以进行一次上下文切换,进行别的工作,直到传输完成。 266 | 267 | 内存分段(segment).每个段的地址都是从 0 开始。这样可以为不同段一起设置不同的保护权限,并且有助于数据共享。 268 | 269 | ## 第四章 文件系统 270 | 271 | ### 文件 272 | 273 | 对于所有操作系统中,都有着普通文件(regular file) 和目录(directory) 两种文件。目录是一种管理文件结构的系统文件。 274 | 275 | UNIX: Everything is a file. 276 | 277 | 普通文件分为 ASCII 文件和二进制文件两种。 278 | 279 | 二进制可执行文件头会有一个 magic number(魔数),用来表征这个文件是一个可执行的二进制文件。 280 | 281 | 早期的操作系统只能进行顺序访问(sequential access).但是随着发展,有了随机访问文件(random access file). 282 | 283 | 文件也拥有着一定的属性(attribute). 284 | 285 | 文件操作需要系统调用来协助处理。比如 `create, delete, open, close, read, write, append, seek, get attributes, set attributes, rename`等等。 286 | 287 | 根目录:所有的目录可以构成一棵树。这棵树的根就是根目录。路径名一般会用两种方式来指明文件名。即绝对路径名(absolute path name) 和相对路径名(relative path name). 相对路径名是从工作目录(working directory) 开始的。 288 | 289 | '.' 表示当前目录, ".." 表示父目录。 290 | 291 | 目录的操作也包含多种系统调用。如 `create, delete, opendir, closedir, readdir, rename, link, unlink` 等等。unlink 就是删除一个目录项。如果一个文件只在该目录中,那么这个文件就会被删除。 292 | 293 | link 产生的是一种硬链接。 294 | 295 | 还有一种方式称为符号链接,即软链接。也就是创造一个文件,其中包含了一个绝对路径。 296 | 297 | ### 文件系统的实现 298 | 299 | 文件系统存放在磁盘上。每个分区中存在一个独立的文件系统。磁盘中的 0 号扇区被称为主引导记录(Master Boot Record, MBR), 其用来引导计算机。 MBR 的结尾是分区表,用来表示每个分区的起始位置和结束位置。 300 | 301 | 计算机引导时,BIOS 会读入并且执行 MBR. MBR 会确定活动分区,并且读入活动分区第一个块(引导块,boot block)并且进行执行。活动分区,也就是计算机的系统分区。 302 | 303 | 文件系统中,也有的是从超级块(super block)开始。超级块中包含文件系统中的一些关键参数,比如魔数是什么,文件系统中的块数量有多少,等等。 304 | 305 | #### 文件的实现方案 306 | 307 | - 连续分配?好处是实现简单,读性能好。但是删除文件后,磁盘空间会非常零碎。 308 | 309 | - 链表分配?这样可以充分的利用磁盘空间,但是问题是随机访问速度慢,指针占掉了很多空间。 310 | 311 | - 采用一张表!也是进行链表,但是不是在磁盘上构造,而是在内存中抽象地构造一张。内存中这样的表被称为文件分配表(FAT). 312 | 313 | - index-node(i 节点),列出了一个文件的文件属性和所有磁盘块的地址。它的好处在于只有在需要使用这个文件的时候才需要读入内存。 314 | 315 | #### 目录的实现方案 316 | 317 | 两种方案: 318 | 319 | - 简单实现,直接包含一个固定的文件名和文件实行。 320 | 321 | - 文件名后只引用对应的 i-node. 322 | 323 | 如果采用共享文件的情况,那么可能会有多个目录指向同一个文件。这样的联系被称为链接,文件结构就变成了一个有向无环图(DAG). 324 | 325 | 日志结构的文件系统(Log-structured File System, LFS),采用了一种完全不同的文件系统。 326 | 327 | 日志文件系统(重新启动后,可以通过查看日志,获取崩溃前计划完成的任务并且完成之) 328 | 329 | 虚拟文件系统(Virtual File System,VFS):把所有的文件系统统合在一个文件系统下。VFS 对所有的用户进程都有一套统一的上层接口,即 POSIX 接口。 330 | 331 | #### 文件系统的管理和优化 332 | 333 | 所有的文件系统基本都把文件按照块来进行存储。选择块的大小是一件很重要的事。 334 | 335 | 记录空闲块的方式:块状链表来存储空闲块 or 采取位图。 336 | 337 | 磁盘强制配额:不允许某些文件拥有太多的磁盘空间、 338 | 339 | 文件系统也需要考虑备份,即容灾能力。物理转储和逻辑转储。 340 | 341 | 文件系统的一致性 342 | 343 | 为了提升性能,有这样的几种方式: 344 | 345 | - 块高速缓存(block cache) 或 缓冲区高速缓存(buffer cache)。逻辑上都是磁盘的一部分,但实际上存在内存中。 346 | 347 | - 块提前读 348 | 349 | - 减少磁盘臂运动:把可能顺序访问的块放在一个柱面上等等。 350 | 351 | ## 第五章 输入/输出 352 | 353 | I/O 设备可以分为两种:块设备(block device, 如硬盘,U盘等等)和字符设备(character device,键盘,鼠标等等). 354 | 355 | I/O 设备一般也由机械部件和电子部件两部分组成。电子部件被称作为设备控制器(device controller)或者适配器(adapter).机械部件则是设备的本身。设备控制器和设备之间的接口通常是一个很低的接口。每个设备控制器被分配为一个 I/O端口号。用来和 CPU 进行通信。 356 | 357 | 现在也许更多的都是采用直接存储器存取(Direct Memory Access, DMA)的方式。CPU 通过总线和内存,IO 设备相连。 DMA 可以独立于 CPU 去访问内存总线。 358 | 359 | DMA 的作用是把 IO设备的数据传输到存储器中。 360 | 361 | 1. CPU 通知 DMA 该把数据传输到哪里。 362 | 363 | 2. DMA 控制器在总线上发起一个读请求到磁盘控制器,发起 DMA 传送。 364 | 365 | 3. 磁盘控制器将数据写入内存。 366 | 367 | 4. 写操作完成后,其发给 DMA 一个应答信号。 368 | 369 | DMA 控制器也可通过每次一字和块模式两种模式来进行操作。 370 | 371 | DMA 一字模式下, CPU 由于总线被占用,如果想使用总线,则必须进行等待。这种机制被称为周期窃取(cycle stealing). 块模式下,则会进行大量的传输。被称为突发模式(burst mode). 372 | 373 | I/O 软件需要有设备的独立性。这一点需要考虑统一命名(uniform naming). 374 | 375 | 精确中断的性质: 376 | 377 | - PC 保存在一个已知的位置。 378 | 379 | - 所有 PC 前的指令被执行完毕。 380 | 381 | - 所以 PC 后的指令未执行。 382 | 383 | - PC 指向的指令的执行状态已知。 384 | 385 | 同步问题?错误处理?缓冲问题? 386 | 387 | - 程序控制的I/O 388 | 389 | - 中断驱动的I/O 390 | 391 | - 使用 DMA 的I/O 392 | 393 | I/O 软件通常由四个层次组成: 394 | 395 | 1. 中断处理程序 396 | 397 | 2. 设备驱动程序 398 | 399 | 3. 与设备无关的I/O软件(这里用于向用户层提供一个设备驱动程序的统一接口,并且提供缓冲,错误报告,分配和释放专用设备,提供和设备无关的块大小等等) 400 | 401 | 4. 用户级的 I/O 软件 402 | 403 | 假脱机(spooling)技术:使得某一个进程开始独占该 I/O 设备。或者是通过守护进程(daemon)去管理假脱机目录(spooling directory)下的文件。通过这种方式,类似于给 IO 设备提供了更多的一层抽象。避免了不必要的长时占用。 404 | 405 | ### 盘 406 | 407 | 如磁盘,光盘,固态硬盘等等。 408 | 409 | RAID(Redundant Array of Independent Disk) 410 | 411 | 磁盘的扇区由前导码,数据, ECC(纠错码)三部分组成。 412 | 413 | 考虑到如果扇区如果编号在相邻位置,那么当前一个块复制完毕后,由于检验纠错码需要时间,我们必须要等机械臂旋转一圈之后才能复制下一个块。为了解决这个问题,我们采用单交错或者双交错的方式,用这种编号方式来提高效率。 414 | 415 | 读写磁盘块的时间: 416 | 417 | - seek time 418 | 419 | - rotation delay 420 | 421 | - actual data transfer time 422 | 423 | FCFS(First-Come, First-Served) 这种方式很平凡,但不易优化。 424 | 425 | 一种调度算法是最短寻道优先(SSF, Shortest Seek First),总是处理和当前磁头距离最近的请求。 426 | 427 | 为了保证每个请求早晚都可以解决,我们有电梯算法(Elevaroe algorithm).即磁头按一个方向移动(up, down),直到该方向上的请求全部处理完成。 428 | 429 | 如果扇道中有一个扇区出错了,那么一般而言,该扇道上的备用扇区就会替换为该扇区。 430 | 431 | #### 稳定存储器 432 | 433 | 由一对全同的磁盘组成。它们总能读出相同结果。 434 | 435 | - 稳定写:先写在驱动器 1 上。然后检查 1 上的结果。如果通过校验,那么修改驱动器 2.否则重复 n 次。如果超过 n 次,则启用备用块。 436 | 437 | - 稳定读:先堵在驱动器 1 上。检查 ECC. 如果错误,再读 n 次。如果 ECC 总是不正确,那么读 2 的数据。 438 | 439 | - 崩溃恢复(crash recovery): 检查两盘上的对应位置。如果都是好块并且相同,那么什么都不做。如果一好一坏,则用好的覆写坏的。如果都是好块但是不同,那么把 1 上的数据覆写 2. 440 | 441 | ### 时钟 442 | 443 | 时钟硬件一般用晶体振荡器去做。计数器会随着时钟每一次脉冲而减少。 444 | 445 | 时钟软件则是进行除了根据已知的时间间隔产生中断外的大多数任务。 446 | 447 | 还有所谓的软定时器。避免中断,并且是在内核态的情况下。 448 | 449 | ### 用户界面 450 | 451 | 键盘,文本窗口,X窗口系统(X Window System) , GUI 等等。 452 | 453 | ### 瘦客户机(thin client) 454 | 455 | 即以 PC 为中心的计算转移为了以 web 为中心的计算。 456 | 457 | ### 电源管理 458 | 459 | Windows 系统有一个进行电源管理的精巧机制,称为 ACPI(Advanced Configuration and Power Interface, 高级配置与电源接口)。通过 ACPI, 操作系统可以向仍和符合标准的驱动程序发出命令,并且令其报告情况,甚至也可以令其削减功率水平。 460 | 461 | ## 第六章 死锁 462 | 463 | 有些资源是不可抢占的! 464 | 465 | 1. 请求资源 466 | 467 | 2. 使用资源 468 | 469 | 3. 释放资源 470 | 471 | 这是需要资源的一个常规顺序。 472 | 473 | 死锁的定义:一组进程中的每个进程都在等待其他进程才能完成的事件! 474 | 475 | 死锁发生的四个条件: 476 | 477 | - 互斥 478 | 479 | - 占有和等待 480 | 481 | - 不可抢占 482 | 483 | - 环路等待 484 | 485 | ### 鸵鸟算法 486 | 487 | 我更愿意称这种算法为苏联算法。 488 | 489 | 假装什么问题都没有就好了。说不定 bug 之后就不触发了。 490 | 491 | ### 死锁检测和死锁恢复 492 | 493 | 在这里,我们允许死锁的发生。但是死锁一旦发生,我们就会马上想办法去恢复。 494 | 495 | 我们可以通过构建一张资源分配图,然后检查这张图上是否有环来解决这个问题。 496 | 497 | 如果每种类型我们具有多个资源,这时的死锁检测可以采取矩阵方式检查。 498 | 499 | 死锁恢复主要有三种方式: 500 | 501 | - 抢占。临时将某个资源的所有权进行转移。 502 | 503 | - 回滚。回到上一个正常的检查点。并且把某个资源的所有权转移。 504 | 505 | - 杀死进程。 506 | 507 | ### 死锁避免 508 | 509 | 通过资源轨迹图,我们可以直观地看到哪些地方是不安全的。 510 | 511 | 对于一个状态,如果存在一种资源的调度方案,使得每个进程都能够正常执行,那么我们就称这个状态为安全状态。反之,则为不安全状态。 512 | 513 | 银行家算法:判断某个进程申请资源后,是否会处于不安全状态。如果不安全,则不允许给出资源。 514 | 515 | ### 死锁预防 516 | 517 | 考虑破坏四个条件。前三个条件都是比较难以破坏的,因此我们只得考虑第四个条件。比如说,我们可以考虑给资源进行编号,必须从小到大地获得锁的顺序。 518 | 519 | 其他的一些问题:通信死锁,活锁等等。 520 | 521 | ## 第七章 虚拟化和云 522 | 523 | 虚拟机监控程序(hypervisor, VMM)需要解决三个问题: 524 | 525 | - 安全性(Safety) 526 | 527 | - 保真性(Fidelity) 528 | 529 | - 高效性(Efficiency) 530 | 531 | 目前的 VMM 可以粗略分为两种类型。 532 | 533 | - Type 1 hypervisor, 唯一一个运行在最高特权级的程序。支持多个虚拟机。 534 | 535 | - Type 2 hypervisor, 运行在宿主操作系统(host operating system)上。向上支持其他客户操作系统(guest operating system)。 536 | 537 | ### 高效虚拟化技术 538 | 539 | 先考虑第一类 VMM. 操作系统自以为处在内核态(我们把这种状态称为虚拟内核态, virtual kernel mode),并且访问特权指令时,会被 VMM 捕获,并且才和硬件做交互。如果在不支持虚拟化的操作系统上,那么会在宿主操作系统执行和模拟之前进行二进制改写,保证正确性。 540 | 541 | 虚拟化和半虚拟化的区别:半虚拟化时,要求对原操作系统进行改写,移除掉那些敏感操作,而是像虚拟化调用那样执行 hypervisor call. 我们把这时的 VMM 称作 Microkernel(微内核)。 542 | 543 | ### 内存虚拟化 544 | 545 | 显然,我们应该给每个客户操作系统准备一张页表,这被称为影子页表(shadow page table)。这一项工作是由 VMM 去完成的。为了减少开销,硬件上有一种名为嵌套页表(nested page table) 的支持。也就是直接能查到宿主机的物理地址,而无需 VMM 的参与。 546 | 547 | ### 云 548 | 549 | 云的五条特征: 550 | 551 | - 按需自主服务。 552 | 553 | - 普适的网络访问。 554 | 555 | - 资源池,即资源分配对用户是透明的。 556 | 557 | - 快速可伸缩。 558 | 559 | - 服务可计量。 560 | 561 | ### x86 的虚拟化 562 | 563 | - 564 | 565 | 566 | 把虚拟化引入 x86 过程中的三个挑战:兼容性,性能和隔离。 567 | 568 | x 86 的体系结构是不可虚拟化的! 569 | 570 | 在把 x86 虚拟化的过程中, VMM 中内含有决策算法,判断该操作应该采是直接执行,还是进行更多的二进制翻译等等。比如,当虚拟机处于内核态,或者可以关中断和执行I/O指令以及运行在实模式下时,必须采用二进制翻译。 571 | 572 | VMware 由三部分组成: VMX,即用户态的程序;VMM驱动程序;包含复用 CPU 和内存等软件所需的 VMM. 573 | 574 | 实际上, VMware 和宿主操作系统是同权的!都是系统级别的程序。两个独立的系统级上下文的切换被称为系统切换(world switch). 575 | 576 | ESX Server 是一种第一类虚拟化的解决方案。 577 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Linzhang Li 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notes 2 | Seven Streams' notes. 3 | 4 | Please **don't** use the preview of github. 5 | 6 | Please **download** them if you'd like to read them. 7 | 8 | I'll be glad if my notes can help you! 9 | 10 | If you find any mistakes, please tell 7Streams! 11 | -------------------------------------------------------------------------------- /others/CS50(1,2).md: -------------------------------------------------------------------------------- 1 | # Lecture 1 2 | 3 | 输入$\to$算法$\to$输出 4 | 5 | 进制 6 | 7 | 标准化 8 | 9 | 计算机中区分字符和数字的方法? 10 | 11 | ASCII$\to$Unicode 12 | 13 | 约定:标准化 14 | 15 | 伪代码 16 | 17 | 边界情况 18 | 19 | Script 20 | 21 | 抽象化:不必过度在意底层的实现,将其抽象为一个模块。 22 | 23 | # Lecture 2 24 | 25 | 终端 26 | 27 | Linux 28 | 29 | ./hello 30 | 31 | .代表当前文件夹。/hello 代表运行hello。 32 | 33 | rm 用于删除文件, 34 | 35 | ls 用于展示当前文件夹所有文件。 36 | 37 | make:自动的编译。 38 | 39 | cp:copy文件。 40 | 41 | dir:创建目录。 42 | 43 | mv:移动或重命名。 44 | 45 | c:printf函数。%称为格式码,用于告诉计算机此处应该有一个怎样的数据。%i:整型;%f:浮点数;%lli:长长整型等。 46 | 47 | ..代表父文件夹。 48 | 49 | 语法糖 50 | -------------------------------------------------------------------------------- /others/Cognitive_Psychology.md: -------------------------------------------------------------------------------- 1 | # cognitive psychology 2 | 3 | ## Lec 1 4 | 5 | ### 部分实验 6 | 7 | #### 扑克魔术 8 | 9 | 开始和结束刺激更容易被记忆(并且最后的很长) 10 | 11 | 认知心理学:人类思维的信息加工过程及其神经基础的实证科学。 12 | 13 | 刺激->感知觉->短时记忆->长时记忆 14 | 15 | 认知心理学的方法:实验设计 16 | 17 | #### 视觉错觉 18 | 19 | 人的视觉系统是一套高度智能化的系统->自动分析 20 | 21 | 人脑是多模态的 22 | 23 | #### 乱序阅读 24 | 25 | 人类阅读的目标是获得句子的意义 26 | 27 | 对于实验总体而言,这类情况可以分为两种: 28 | 29 | - 人类意识不能控制的“错觉” 30 | 31 | - 人类可以靠意识控制的“错觉” 32 | 33 | ### 人类的知性 34 | 35 | 终极的科学问题? 36 | 37 | 行为主义心理学:刺激和反应 38 | 39 | 首因效应和近因效应 40 | 41 | 有意义的内容记忆起来显然简单。 42 | 43 | 人类的短期记忆:大概容量在 5-9 个组块。短期记忆的单位不是 byte 那样,而是按照信息单元 (chunk) 进行处理的。 44 | 45 | 认知流畅度也会对司法裁决产生影响?! 46 | 47 | Q: 短时记忆中内容提取,这是并行的还是串行的? 48 | 49 | 根据目前的实验来看,串行和并行都有。 50 | 51 | ### 人脑及其功能分区 52 | 53 | #### 神经元 54 | 55 | 人的认知:大规模的神经元交互。 56 | 57 | 脑岛 58 | 59 | 人脑:体积大、沟回多。并且,人的前额大得多。人脑出生后明显增长。并且成人的到依旧具有可塑性。 60 | 61 | 胼胝体 62 | 63 | ## Lec 2 64 | 65 | 人的部分脑区受伤了,可能会产生犯罪冲动? 66 | 67 | 脑电图 68 | 69 | 脑磁图(电场产生磁场) 70 | 71 | 事件相关电位 72 | 73 | 自由意志? 74 | 75 | 李贝特实验 76 | 77 | 用供血量的增加来观察兴奋的脑区(血氧密度不同) 78 | 79 | 人脑的耗能也会自发地进行震荡 80 | 81 | 认知脑和社会脑 82 | 83 | ### 感知觉 84 | 85 | 视觉最敏锐的地方——中央凹在脑中占有了很大的对应位置。 86 | 87 | ### 格式塔组织原则 88 | 89 | - 接近原则 90 | 91 | - 相似原则 92 | 93 | - 良好连续原则 94 | 95 | - 闭合与良好构型原则 96 | 97 | 模板匹配模型 98 | 99 | 人类的特征分析 100 | 101 | 词优效应 102 | 103 | ## Lec 3 104 | 105 | 事实和观点需要我们来区分。 106 | 107 | ### 注意 108 | 109 | 刺激驱动注意、目标导向注意 110 | 111 | 听觉注意:双耳分听任务 112 | 113 | 过滤器理论->衰减理论(信息选择,是衰减无关信息,而不是完全阻断) 114 | 115 | 衰减理论(知觉系统)和后期选择理论(反应系统) 116 | 117 | 通过双耳实验,支持了衰减理论 118 | 119 | 人可以把中央凹的焦点对应在某个地方,但是同时也注视着非中央凹区的其他部分。 120 | 121 | 注意的转移发生在眼动之前。 122 | 123 | 人需要整合特征来识别物体时,必须要搜索。如果有独特特征,我们可以直接转移注意 124 | 125 | 捆绑问题 126 | 127 | 右侧顶叶负责注意空间位置和整体特征 128 | 129 | 左侧顶叶负责注意物体的局部方面 130 | 131 | 中枢注意 132 | 133 | 人的想象能力->物体的合成 134 | 135 | 顶叶->空间成分 136 | 137 | 颞叶->视觉成分 138 | 139 | ## Lec 4 140 | 141 | ### 记忆 142 | 143 | #### 知识的表征 144 | 145 | ##### 记忆的内容 146 | 147 | 我们记忆的对象,其实是意义 148 | 149 | 对意义的记忆,一般比较好;但是细节很快就会忘却。 150 | 151 | 命题是意义的最小知识单元。 152 | 153 | 命题网络 154 | 155 | 概念语义网络 156 | 157 | 图式 158 | 159 | 对于已有概念的借鉴 160 | 161 | 刻板印象 162 | 163 | 抽象理论和实例理论 164 | 165 | 生物类别和人造类别 166 | 167 | #### 记忆的编码 168 | 169 | 长时记忆 170 | 171 | 学单词:左侧前额叶 172 | 173 | 学图片:右侧前额叶 174 | 175 | ## Lec 5 176 | 177 | 短时记忆:单个刺激使突触强化 178 | 179 | 长时记忆:反复刺激使激酶转移到细胞核中,导致基因表达和新突触的生长。 180 | 181 | 长时记忆 ACT 理论 182 | 183 | 基线水平激活 184 | 185 | 刺激激活 186 | 187 | 长时程增强效应 188 | 189 | 闪光灯记忆(非常重要的事件) 190 | 191 | 长时记忆的影响因素 192 | 193 | - 意义 194 | 195 | - 加工深度 196 | 197 | - 学习、练习程度 198 | 199 | - 精细加工 200 | 201 | - 激起程度 202 | 203 | 记忆材料的量和加工水平有关,但和是否想学习无关。 204 | 205 | 艾宾浩斯遗忘曲线 206 | 207 | 时间(消退理论) 208 | 209 | 干扰 210 | 211 | 冗余防止干扰 212 | 213 | 扩散激活:自动提取相关知识 214 | 215 | 记忆的推断 216 | 217 | 心境、状态一致效应 218 | 219 | ## Lec 6 220 | 221 | 海马体参与形成长时记忆 222 | 223 | 长时记忆的提取、保持和长时记忆的形成需要的部位不同 224 | 225 | 外显记忆和内隐记忆 226 | 227 | 程序性记忆 228 | 229 | ### 问题解决 230 | 231 | 启发式算子空间选择 232 | 233 | 满意原则 234 | 235 | 地板效应——天花板效应 236 | 237 | 差异降低法 238 | 239 | 问题表征的方式-> 功能固着 240 | 241 | ## Lec 7 242 | 243 | 手段-目的分析 244 | 245 | 定势效应,心向效应,思维定向化 246 | 247 | 酝酿效应 248 | 249 | 顿悟问题 250 | 251 | 斯特鲁普效应 252 | 253 | 认知-关联-自主三阶段 254 | 255 | 学习的幂定律 256 | 257 | 程序化 258 | 259 | 有目的练习 260 | 261 | 技能的正迁移 262 | 263 | 有效演绎:肯定前件和否定后件 264 | 265 | ## Lec 8 266 | 267 | 推理、判断、决策 268 | 269 | 关系类型:合取、析取、关系 270 | 271 | 形成假设、假设检验 272 | 273 | 证实偏向 274 | 275 | 先验概率、条件概率、后验概率 276 | 277 | 赌徒谬误 278 | 279 | 锚定效应 280 | 281 | 识别启发式 282 | 283 | 主观效应 284 | 285 | ## Lec 9 286 | 287 | 社会认知心理学 288 | 289 | empathy 和 sympathy 290 | 291 | theory of mind 292 | 293 | ## Lec 10 294 | 295 | 大部分人(右利手和约一半左利手)语言功能主要在左脑发展 296 | 297 | 语言学:生成性和规则性 298 | 299 | - 单元的语义性和任意性 300 | 301 | - 时间和空间的转移性 302 | 303 | - 分立性和生成性 304 | 305 | 世界上大部分语言结构中,主语在宾语前面。 SOV 是最流行的。 306 | 307 | 思维依赖语言?语言依赖思维?还是二者独立? 308 | 309 | - 感觉运动阶段 310 | 311 | - 前运算阶段 312 | 313 | - 具体运算阶段 314 | 315 | - 形式运算阶段 316 | 317 | 晶态智力、液态智力、空间智力(?) 318 | -------------------------------------------------------------------------------- /others/Concurrency.md: -------------------------------------------------------------------------------- 1 | # 第二章 线程管理 2 | 3 | ## 线程,启动! 4 | 5 | ```cpp 6 | void DoSomething() {}; 7 | std::thread my_thread(DoSomething); 8 | ``` 9 | 10 | 这样就创建了一个线程。一般使用的是void函数。这样,当函数执行结束后,线程也跟着结束了。 11 | 12 | 如果一个类重载了函数运算符,那么它的实例也可以作为thread的构造参数。 13 | 14 | 把函数对象传入线程构造函数之时,我们不可以使用临时变量。假设我们创建了一个名为A的类,其已重载了函数运算符,如果我们写 15 | 16 | ```cpp 17 | std::thread my_thread(A()); 18 | ``` 19 | 20 | 天才的C++就会认为这是一个函数声明。 21 | 22 | 为了避免出现这个问题,也许把调用构造函数时的小括号换成大括号是个不错的方法。 23 | 24 | 如果主线程终止后,新线程依旧在瞎搞,就会出现UB。是故,我们应当使用join方法或者detach方法。 25 | 26 | 如果我们打算等待新线程结束后再退出主线程,那么我们可以写: 27 | 28 | ```cpp 29 | my_thread.join(); 30 | ``` 31 | 32 | 需要注意的是,如果线程运行时抛出异常,并且抛出异常的时机在调用join方法之前,那么就会跳过join。最好在异常处理的语句中也加上join方法的调用。 33 | 34 | 如果使用detach方法,那么线程就会在后台开始运行,其与主线程之间不再有交互的可能,其他的线程亦不可访问之。并且,被detach的线程不可再join。 35 | 36 | 分离线程常被称为守护线程。其运行时间长,可能进行很多操作。 37 | 38 | ## 传参 39 | 40 | ```cpp 41 | void f(int x, const int &y); 42 | std::thread my_thread(f, 114514, 1919810); 43 | ``` 44 | 45 | 即使函数参数采用了引用传递的方式,其也会被拷贝至新线程的内存空间中。因此,倘若不是const引用,编译器运行时,发现我们试图引用一个右值,就会报错。 46 | 47 | ```cpp 48 | void f(int x, int & y) { 49 | cout << ++y << endl; 50 | } 51 | int main() { 52 | int data = 1919810; 53 | thread my_thread(f, 114514, data); 54 | my_thread.join(); 55 | return 0; 56 | }//CE 57 | 58 | void f(int x, int & y) { 59 | cout << ++y << endl; 60 | } 61 | int main() { 62 | int data = 1919810; 63 | thread my_thread(f, 114514, ref(data)); 64 | my_thread.join(); 65 | return 0; 66 | }//Correct 67 | ``` 68 | 69 | 需要传入引用! 70 | 71 | ```cpp 72 | class A { 73 | public: 74 | void Test() { 75 | cout << "OK"; 76 | }; 77 | }; 78 | int main() { 79 | A x; 80 | thread my_thread(&A::Test, &x); 81 | my_thread.join(); 82 | return 0; 83 | } 84 | ``` 85 | 86 | 使用引用的方式,我们可以调用成员函数。 87 | 88 | ## 转移所有权 89 | 90 | 线程属于资源占有的类型,它不可以进行复制操作。但是可以进行移动操作。 91 | 92 | ```cpp 93 | void f(); 94 | std::thread thread_1(f); 95 | std::thread thread_2 = std::move(thread_1); 96 | ``` 97 | 98 | 这样,我们就转移了线程的所有权。thread_1已经和它所控制的线程不再有任何联系了。如果在转移时,thread_2拥有某个线程的控制权,那么thread_2的原线程会被终止。 99 | 100 | ## 确定线程数量 101 | 102 | ```cpp 103 | std::thread::hardware_concurrency()//可以返回并发线程的数量。 104 | ``` 105 | 106 | ## 线程标识 107 | 108 | ```cpp 109 | std::thread::id//是一种类型。可以存储线程的id。 110 | std::this_thread::get_id()//可以返回当前线程的id。为上述提到的类型。 111 | ``` 112 | 113 | # 第三章 共享数据 114 | 115 | ## 条件竞争 116 | 117 | 我们引入了不变量的概念,比如BPT中的左儿子和右儿子节点等。当进行查询操作时,这些内容没有被修改,所以不变量没有改变,顺序没有任何关系。如果不变量被修改时,其他线程又恰好访问了这一部分数据,那么就会出现UB。我们把这样的数据竞争称为条件竞争。调试过程中,一般调不出来这些问题。因为这样的条件竞争显然是时间敏感的,必须非常凑巧。 118 | 119 | ## 互斥量 120 | 121 | ```cpp 122 | mutex my_mutex; 123 | vector test; 124 | void MyPushBack(int x) { 125 | lock_guard my_guard(my_mutex); 126 | test.push_back(x); 127 | return; 128 | } 129 | int MyUnder(int x) { 130 | lock_guard my_guard(my_mutex); 131 | return test[x]; 132 | } 133 | ``` 134 | 135 | 使用这样的代码,可以保证两种函数不会同时对数据进行访问。lock_guard类可以自动给对象上锁,并且在析构的时候自动解锁。 136 | 137 | 在进行编程的时候,尽量不要把受保护的内容引用或指针传递到互斥量作用域之外。 138 | 139 | 我们需要想办法找到一个锁的合适的颗粒度。如果颗粒度过大,可能BPT的并发两行就写完了,没有意义。如果颗粒度过小,数据的保护效果可能不是很好。 140 | 141 | 死锁的出现:互相持有一个不同的互斥量,但是相互又想要请求对方的互斥量锁。 142 | 143 | ```cpp 144 | mutex mymutex1, mymutex2; 145 | void Test() { 146 | lock(mymutex1, mymutex2); 147 | lock_guard my_guard1(mymutex1, adopt_lock); 148 | lock_guard my_guard2(mymutex2, adopt_lock); 149 | } 150 | ``` 151 | 152 | 此为一种解决方案。也就是说,在申请锁的时候,一下子申请两个锁。随后将其分配给lock_guard的实例,转移互斥量的控制权。 153 | 154 | 为了避免死锁,一般有这么几种方式:避免嵌套锁、使用自己的代码,保持获取锁的固定顺序、使用层次锁结构。 155 | 156 | 使用herarchical_mutex可以创建不同层的锁实例。一个线程持有高层次锁的时候,可以进一步申请低层次锁。但是持有低层次锁时,无法申请高层次锁。 157 | 158 | 在初始化时,我们需要将最初的所有线程的初始值设置为最大值,以便于获取任意层次的锁。 159 | 160 | unique_lock是一种类似于lock_guard的类型。但是,它更加灵活,可以自行调用lock和unlock函数。在作用域结束后一样会被析构。使用defer_lock而非adopt_lock,就可以只记录互斥量的信息,但不会上锁。unique_lock也是只可移动,不可复制。 161 | 162 | ## 保护共享数据的方式 163 | 164 | 为了避免多个线程对同一部分数据进行初始化操作。我们可以引入once_flag和call_once。once_flag用来标记只能执行一次。call_once能够保证只有一个线程可以执行这部分函数。 165 | 166 | ```cpp 167 | void f(){}; 168 | once_flag flag; 169 | call_once(flag,f); 170 | ``` 171 | 172 | 我们也可以保护那些不常用的数据。 173 | 174 | 如果使用recursive_mutex,那么我们就允许一个线程多次对同一个互斥量上锁。并且需要多次解锁。 175 | 176 | # 第四章 同步操作 177 | 178 | ## 等待事件或条件 179 | 180 | 一种方式,是采用 181 | 182 | ```cpp 183 | mutex x; 184 | void test(){ 185 | unique_lock test(x); 186 | test.unlock(); 187 | this_thread::sleep_for(chrono::milliseconds(100)); 188 | test.lock(); 189 | } 190 | ``` 191 | 192 | 这样操作,允许其他线程在该线程休眠期间,获取mutex的锁。 193 | 194 | notify_one函数和wait函数通常会同时使用。这两者都是条件变量的成员函数。notify_one函数是在一个线程的操作基本完成之后,通知其他的线程。其他的线程如果已经调用了wait函数,那么就会重新开始检查,是否满足条件。如果满足条件,就会继续运行。wait函数在条件不满足时,会解锁mutex,保证其他线程可以获取这个互斥量,并且继续等待。否则,则获取这个互斥量。需要注意,在使用notify_one的时候,需要保证当前线程已经获得了所需的mutex。 195 | 196 | ## future 197 | 198 | ```cpp 199 | int f() { 200 | return 114514; 201 | } 202 | int main() { 203 | future test = async(f); 204 | this_thread::sleep_for(chrono::seconds(1)); 205 | cout << test.get() << endl; 206 | return 0; 207 | } 208 | ``` 209 | 210 | 采用这种方式,可以异步处理一定的对象。通过get函数,我们可以返回future事件的处理结果。当然,也可以传参。 211 | 212 | ```cpp 213 | auto f1 = async(launch::deferred, f); 214 | auto f2 = async(lauch::async, f); 215 | ``` 216 | 217 | f1会在调用get函数或者wait函数的时候才会执行。其被延迟了。f2则会立刻开启了一个新线程开始工作。 218 | 219 | packaged_task是一个全新的模版类型,其参数是一个函数的类型签名,(包含函数的类型,形参表)。它会返回一个future类型,并且,它的主要作用在于可以在不同的线程之间达到通信的效果,从而传递数据。不过需要注意的是,一个packaged_task只能执行一次! 220 | 221 | promise也是一种类型,其模版参数的使用方法和future相同。 222 | 223 | ```cpp 224 | void doWork(std::promise& p) { 225 | // 模拟耗时操作 226 | std::this_thread::sleep_for(std::chrono::seconds(2)); 227 | 228 | int result = 42; 229 | 230 | // 设置值给 promise 231 | p.set_value(result); 232 | } 233 | 234 | int main() { 235 | std::promise myPromise; 236 | std::future result = myPromise.get_future(); // 获取与 promise 关联的 future 237 | 238 | std::thread worker(doWork, std::ref(myPromise)); // 启动线程执行任务 239 | 240 | // 获取任务的返回值 241 | int value = result.get(); 242 | std::cout << "任务的结果:" << value << std::endl; 243 | 244 | worker.join(); 245 | 246 | return 0; 247 | } 248 | ``` 249 | 250 | 使用这种方法,我们可以把线程与promise相连接。通过get_future函数,我们可以获得产生的future类型,并且捕捉相关的异常信息。在async过程中,如果出现了异常,在使用get函数的过程中就可以再次抛出这个异常。对于promise,我们可以调用promise类的set_ecxeption函数,从而显式地给promise对象存储一个异常。 251 | 252 | 但是,future类是只移动的。我们希望可以使用shared_future实例来进行。shared_future返回的结果是不同步的,我们需要使用互斥量来对访问进行保护。为了减少数据竞争的出现,由于shared_future实例是可拷贝的,所以我们可以将其进行拷贝到线程之中,再次进行操作。 253 | 254 | shared_future类型可以使用move函数,将future类型的所有权转移。 255 | 256 | ## 限时等待 257 | 258 | 我们可以对线程的等待做出一定的限制。如果等待时间过长,我们就认为其超时了。一般而言,我们具有两种方式进行超时判断。第一种,是时间段,使线程等待比如30ms之类的时间。第二种,是时间点,比如规定在某个时间超时。 259 | 260 | mutex和recursive_mutex都不支持超时操作。但是,time_mutex和recursive_timed_mutex都是支持超时操作的。这两种类型都具有try_lock_for()和try_lock_until()函数,可以在一个时间段内持续尝试获取锁,或者在指定的时间点前获取互斥锁。这两个函数的返回值均为bool类型。成功获取锁时,会返回true,失败时,则会返回false。 261 | 262 | # 263 | -------------------------------------------------------------------------------- /others/Cryptography.md: -------------------------------------------------------------------------------- 1 | # 第一章 密码学和数据安全导论 2 | 3 | 密码分析学和密码使用学的区别 4 | 5 | 密码使用学的三个主要分支:对称算法、非对称算法、密码协议。 6 | 7 | ## 1、对称密码学(单密钥) 8 | 9 | 明文、密文、密钥。所有可能的密钥组成的集合称为密钥空间。 10 | 11 | 替换密码:**不安全** 12 | 13 | 穷举法 14 | 15 | 字母频率分析 16 | 17 | 好的密码应该隐藏被加密文本的统计属性! 18 | 19 | ## 2、密码分析 20 | 21 | 主要分为三种:古典密码分析、旁道攻击、社会工程攻击。 22 | 23 | ### Kerckhoffs原理 24 | 25 | 安全的密码体系必须保证除密钥外,加密算法和解密算法等的公开不会影响加密的安全性。 26 | 27 | ### 密钥长度 28 | 29 | 只有当穷举是最好的破解方法是,讨论密钥长度才有意义。 30 | 31 | ## 3、模运算与古典密码 32 | 33 | 扩展概念的模运算 34 | 35 | 在每一个剩余类中,所有成员行为等价 36 | 37 | ### 整数环 38 | 39 | 整数环包括从0到k的整数。定义: 40 | 41 | $$ 42 | a+b\leftrightarrow (a+b)mod(k+1) \\ 43 | c\times d\leftrightarrow (c\times d)mod(k+1) 44 | $$ 45 | 46 | 如果环对加法和乘法封闭,那么这个环就是封闭的。 47 | 48 | 加法和乘法满足结合律。 49 | 50 | 存在加法和乘法的恒等变换。 51 | 52 | 存在加法逆元。 53 | 54 | 对于一个元素而言,存在它的乘法逆元,当且仅当其与模数互质。 55 | 56 | rmk:整数环是不是一个线性空间? 57 | 58 | ### 移位密码 59 | 60 | ### 仿射密码 61 | 62 | 加密和解密过程可以这样理解: 63 | 64 | $$ 65 | e_k(x)=y\equiv (ax+b)mod26\\ 66 | d_k(y)=x\equiv a^{-1}(y-b)mod26 67 | 68 | 69 | 70 | $$ 71 | 72 | 这种条件下要求存在乘法逆元,故$gcd(a,26)=1$。 73 | 74 | 尽管仿射加密比移位加密好一些,但没有好到哪里去。 75 | 76 | # 第二章 序列密码(流密码) 77 | 78 | ## 1、序列密码简介 79 | 80 | 序列密码单独对每个**明文**位进行加密。加密和解密使用同一种方法。即:与给定的密钥取异或。 81 | 82 | 因此,密钥序列的安全性是序列密码的核心问题。 83 | 84 | ## 2、随机数 85 | 86 | 真随机数生成器(TRNG):基于物理过程。输出具有不可复制性。 87 | 88 | 伪随机数生成器(PRNG):通过一个种子,运算得到一个随机数。根据得到的结果修改种子。为了保证随机,这类函数要保证结果足够均匀。 89 | 90 | 加密安全的伪随机数生成器(CSPRNG):要求结果具有不可预知性。不能通过前一次随机数的发生结果判断下一次的发生结果。通常可以使用真随机种子来执行。 91 | 92 | 无条件安全:无论多少计算资源,也无法破译,那么称为无条件安全。 93 | 94 | 一次一密(OTP):通过真随机数生成器得到密钥序列。只有合法的通信者才知道密钥。密钥序列中,每一位只使用一次。那么,称其为一次一密。 95 | 96 | 一次一密具有无条件安全性。 97 | 98 | 但是,OTP很少使用。一方面,一般的PC没有TRNG。并且,为了加密和解密,需要等同大小的密钥,并且双方还需要进行交换。 99 | 100 | 一般而言,我们使用伪随机数生成器。 101 | 102 | 一般而言,密码只能做到计算安全。 103 | 104 | 如果使用PRNG构建密码流,那么当文件所有密文和部分明文泄露时,密钥就很容易被攻破。因此,才出现了CSPRNG。 105 | 106 | ## 3、基于移位寄存器的序列密码 107 | 108 | ### LFSR 109 | 110 | 简单而言,它使用了一个寄存器。在每一个tick内,寄存器内容右移1位,同时得到一份输出值。与此同时,根据上一个tick寄存器中各个位的状态,挑选其中的部分,对它们进行异或操作,得到左端最高位的输入。异或操作的对象是保密的。密钥就是挑选了哪些位数进行异或。 111 | 112 | 但是,由于LFSR是线性的,只要能够对应密钥序列长度两倍之多的明文和密文,通过求解线性方程组,就可以破解密钥。 113 | 114 | ### Trivium 115 | 116 | 这种算法使用了三个寄存器。可以认为它们中的内容以类似环的方式排布。只有当密钥和初始向量都知道的情况下,这种加密才会被攻破。 117 | 118 | # 第三章 数据加密标准(DES)与替换算法 119 | 120 | ## 1、DES 121 | 122 | ### 混淆与扩散 123 | 124 | 根据香农的理论,强加密算法都基于以下两种操作:Confusion和Diffusion。Confusion是为了模糊明文与密文的关系。而Diffusion则是为了抹除明文的统计属性。 125 | 126 | ### 算法概述 127 | 128 | DES是一种对称密码。它是一种分组密码。DES算法对每个块中的数据都会进行16轮加密。 129 | 130 | 密钥长度为64位,其中8位为校验位,故密码实际长度为56位。 131 | 132 | 第一步:IP置换 133 | 134 | 分块。每个块中有64位。使用IP表将64位进行互相交换。 135 | 136 | 随后,将64bit的数据分为左侧32位和右侧32位。左32位使用Feistel网络处理。右32位使用f函数处理。然后,交换左侧和右侧。 137 | 138 | f函数的过程:先将8组4bit扩展为8组6bit。这一步中使用了扩展函数E。将扩展后的48为与密钥进行异或操作。将8组6bit送入8个S-盒中,重新得到8组4bit。这一步是非线性的。因为$S(a\oplus b)\not=S(a)\oplus S(b)$ 139 | 140 | Feistel结构:左32位等于上次右32位。右32位等于上次f函数结果与上次左32位取异或。 141 | 142 | ## 2、DES的替换算法 143 | 144 | AES、3DES、DESX、PRESENT 145 | 146 | # 第四章 高级加密标准(AES) 147 | 148 | ## 1、AES——Rijndael算法 149 | 150 | Rijndael算法中没有Feistel网络。 151 | 152 | 明文首先会经过一次密钥加法。 153 | 154 | 明文会经过n次的:字节代换(S-盒)、扩散(行移位和列混淆)、密钥加法。 155 | 156 | ### 伽罗瓦域(有限域) 157 | 158 | #### 群 159 | 160 | 群的概念:封闭性,操作满足结合律,存在全等操作,存在逆元。 161 | 162 | 如果一个群的群操作满足交换律,那么这个群就是阿贝尔群。 163 | 164 | #### 域 165 | 166 | 一个域中的所有元素构成一个加法群。中性元为0。 167 | 168 | 一个域中除0外所有元素构成一个乘法群。中性元为1。 169 | 170 | 域中的所有元素满足乘法分配律。 171 | 172 | #### 域的阶 173 | 174 | 域中元素的个数。 175 | 176 | 当且仅当m是一个素数的正整数幂时,阶为m的域才存在。 177 | 178 | #### 素数域 179 | 180 | 阶为素数的域。加法和乘法意为带模加法与乘法。 181 | 182 | 这个域中的元素为0,1,2,...,n-1 183 | 184 | GF(2)={0,1} 185 | 186 | #### 扩展域 187 | 188 | GF($2^8$)显然不是一个素数域。我们称这是一个扩展域。 189 | 190 | 对于这个域中的元素,我们可以用这样的方式来表示: 191 | 192 | $$ 193 | A=a_72^7+...+a_12^1+a_0,a_i\in \{ 0,1\} 194 | $$ 195 | 196 | 很显然,这就是二进制的表示方式。 197 | 198 | 在扩展域中,我们这样定义加法: 199 | 200 | $$ 201 | A+B=\sum_{i=0}^7((a_i\oplus b_i)*2^i 202 | $$ 203 | 204 | 从程序员的角度看,这不过就是异或罢了。 205 | 206 | 在扩展域中,我们这样定义乘法: 207 | 208 | $$ 209 | P=\sum_{i=0}^7p_i*2^i,要求P是一个不可约多项式\\ 210 | A\times B=(\sum_{i=0}^7a_i2^i)(\sum_{i=0}^7b_i2^i)modP 211 | $$ 212 | 213 | P必须是不可约的。 214 | 215 | ### AES的具体过程 216 | 217 | 在字节代换层,即通过S-盒进行了一次混淆。S-盒是一个双射,所以是可逆的。但是,S-盒是一个非线性操作。 218 | 219 | 在扩散层,首先进行ShiftRow。在这一步中,状态矩阵的每一行移动了不同的量。这一步是线性的。 220 | 221 | 随后,进行MixColumn。在这一步中,实际上进行了在GF(2^8)中的一次乘法。 222 | 223 | 在密钥加密层,就是将明文与密钥进行了一次异或操作。 224 | 225 | Rmk:S盒是一个重要的操作。它破坏了加密时的线性性,增大了密码线性分析法的难度。 226 | 227 | # 第五章 分组密码的更多内容 228 | 229 | ## 1、电子密码本模式(ECB) 230 | 231 | 这种情况下,相同的明文都会映射到相同的密文。导致安全性的缺失。 232 | 233 | ## 2、密码分组链接模式(CBC) 234 | 235 | 所有分组的加密都链接在一起。同时,每一段的密钥初始向量进行了随机化。 236 | 237 | Rmk:每一个区块的加密情况与上一个区块有关。 238 | 239 | ## 3、输出反馈模式(OFB) 240 | 241 | 每进行一次加密,就会对密钥进行一次改变。并且这个改变与明文无关。 242 | 243 | ## 4、密码反馈模式(CFB) 244 | 245 | 每进行一次加密,就会根据密文对密钥进行一次改变。 246 | 247 | ## 5、计数器模式(CTR) 248 | 249 | 选择一个合适的初始值,计数器将其递增,并得到不同的密钥,将这些密钥作用于加密。 250 | 251 | 计数器模式可以进行并行操作,这是OFB和CFB所不具有的。 252 | 253 | ## 6、伽罗瓦计数器模式(GCM) 254 | 255 | 相较于CTR增加了验证操作。保证数据的正确性。 256 | 257 | ## 7、双重加密和中间人攻击 258 | 259 | 当进行两次加密时,一种相对高效地攻击方法是中间人攻击。即,先从左侧尝试蛮力攻击,再从右侧进行蛮力攻击。这样,只要找到匹配的中间值即可。复杂度为破解一侧加密的复杂度的2倍。 260 | 261 | # 第六章 公钥密码学简介 262 | 263 | ## 1、引入 264 | 265 | 单向函数的定义:正向计算是容易的,反向计算在计算上不可行。 266 | 267 | 具有实用性的三类公钥算法:整数分解方案,离散对数方案,椭圆曲线方案。 268 | 269 | ## 2、基本数论知识 270 | 271 | 辗转相除法 272 | 273 | 扩展辗转相除法:可以计算模操作的逆元。 274 | 275 | 欧拉函数,记$\Phi(m)为Z_m中与m$互素的整数个数。 276 | 277 | 若$m=p_1^{e_1}p_2^{e_2}...p_n^{e_n}$ 278 | 279 | 则$\Phi(m)=\prod_{i=1}^n(p_i^{e_i}-p_i^{e_i-1})$ 280 | 281 | 费马小定理:a为整数,p为素数 282 | 283 | $$ 284 | a^p\equiv a(mod\ p)\\ 285 | 286 | $$ 287 | 288 | 欧拉定理 289 | 290 | 当gcd(a,m)=1时 291 | 292 | $$ 293 | a^{\Phi (m)} \equiv 1(mod\ m) 294 | $$ 295 | 296 | # 第七章 RSA密码体制 297 | 298 | ## 1、加密与解密 299 | 300 | ### RSA密钥的生成 301 | 302 | 选择两个大素数p,q,令n=p*q 303 | 304 | 那么,$\Phi(n)=(p-1)(q-1)$ 305 | 306 | 再选择一个数$e\in Z_{\Phi(n)}$ 307 | 308 | 满足$gcd(e,\Phi(n))=1$ 309 | 310 | 计算一个私钥d,$d\cdot e \equiv 1mod(\Phi(n))$ 311 | 312 | ### RSA的加密 313 | 314 | 使用短公开指数或是中国剩余定理 315 | 316 | ## 2、大素数 317 | 318 | ### 费马素性测试 319 | 320 | 即利用费马小定理,找是否存在与1同余的数。 321 | 322 | 错误率较高。 323 | 324 | ### Miller-Rabin素性测试 325 | 326 | ## 3、攻击 327 | 328 | 协议攻击 329 | 330 | 数学分析攻击 331 | 332 | 旁道攻击:从物理角度攻击。比如电流活跃情况。 333 | 334 | # 第八章 基于离散对数问题的公钥密码体制 335 | 336 | ## 1、Diffie-Hellman密钥交换 337 | 338 | 联合密钥 339 | 340 | 双方共同选定一个大素数和一个整数。并将它们公开。随后,双方用对方的公钥和自己的私钥进行加密,可以得到一个共同的密钥。 341 | 342 | ## 2、数学知识 343 | 344 | 群中,一个元素是k阶的,指a^k=1,1是单位元。 345 | 346 | 一个群中,阶数最大的元素称为原根。 347 | 348 | 如果群中存在一个元素的阶数与群的阶数相同,那么这个群是循环群。拥有最大阶的元素称为原根。群中每个元素都可以写作原根的幂。 349 | 350 | 对于一个素数p,$Z_p^{*}$是一个阿贝尔 有限 循环 群。 351 | 352 | 如果一个群是有限群,那么$a^{|G|}=1$,并且任何一个元素的阶数都可以整除群的阶数。 353 | 354 | 对于一个有限 循环 群G,其中有$\Phi (|G|)$个原根。如果G的阶数是素数,那么,G中任何不为1的数都是原根。 355 | 356 | 对于一个循环群G,G中每个阶数为s的元素,都是拥有s个元素的循环子群的原根。 357 | 358 | 任何一个子群的阶数都可以整除整个群的阶数。 359 | 360 | G是一个n阶的有限循环群,$\alpha$为原根,那么,对整除n的每个整数k,G都存在一个唯一阶数为k的循环子群。 361 | 362 | ## 3、离散对数问题 363 | 364 | $$ 365 | \alpha^x\equiv \beta\ mod\ p\\ 366 | x =log_{\alpha}\beta\ mod \ p 367 | $$ 368 | 369 | 计算指数很简单,但反向计算是困难的。 370 | 371 | ## 4、Elgamal加密方案 372 | 373 | 首先,双方选定大素数和原根,获得公共密钥。 374 | 375 | 然后,运用公共密钥作为乘法掩码,加密信息。 376 | 377 | 最后,收信方利用公共密钥解密。 378 | 379 | # 第九章 椭圆曲线密码体制 380 | 381 | ## 1、椭圆曲线 382 | 383 | 椭圆曲线$Z_p$定义为: 384 | 385 | $$ 386 | y^2\equiv x^3+ax+b\ mod\ p\\ 387 | 4a^3+27b^2\not \equiv 0\ mod \ p 388 | $$ 389 | 390 | 以及一个无穷大的虚数点。 391 | 392 | 椭圆曲线上,不同点的加法,定义为坐标之和 393 | 394 | 相同点的加法,定义为该点处的切线与椭圆曲线交点关于x轴的对称。 395 | 396 | ## 2、椭圆曲线构建离散对数问题 397 | 398 | 在椭圆曲线上选定一个起点,我们用快速幂的思路,令其自我相加很多次。然后再随意加上几次,得到一个终点。破解者为了破解密码,不得不穷举。 399 | 400 | # 第十章 数字签名 401 | 402 | 数字签名是用Hash函数对填充后的信息生成的值再加盐,再次hash之后的摘要与自身私钥作用的结果。对方可以使用公钥验签。这一过程的安全性主要还是由上述三种方法保证。 403 | 404 | # 第十一章 哈希函数 405 | 406 | ## 1、哈希函数的安全性要求 407 | 408 | 单向性、弱抗冲突性、计算抗冲突性 409 | 410 | ## 2、常见的哈希函数 411 | 412 | ### MD4 413 | 414 | ### SHA-1 415 | 416 | # 第十二章 消息验证码 417 | 418 | ## 1、MAC 419 | 420 | 根据对称密钥和信息得到。比非对称密钥来得快速。 421 | 422 | 这样是为了避免发生信息的篡改。 423 | 424 | 但是,它不具有不可否认性。 425 | 426 | ## 2、几种常见的方式 427 | 428 | HMAC、分组MAC(使用密码链方式加密,CBC)、伽罗瓦计数器MAC 429 | 430 | # 第十三章 密钥建立 431 | 432 | ## 1、密钥刷新与密钥衍生 433 | 434 | 利用已有的密钥和一个衍生值,通过一个单向函数计算得到新的密钥。 435 | 436 | ## 2、使用密钥分配中心的密钥建立 437 | 438 | 密钥分配中心与每个用户都共享一个密钥。从而保证用户间密钥传递的安全性。 439 | 440 | 通过指明密钥的生存周期,和发信人的ID,可以提高其安全性,避免重演攻击等情况。 441 | 442 | ## 3、证书 443 | 444 | CA体系 445 | 446 | 证书的吊销 447 | -------------------------------------------------------------------------------- /others/Deep Learning.md: -------------------------------------------------------------------------------- 1 | # 第三章中的ideas 2 | 3 | 随机梯度下降:抽取一个小批量计算梯度,并更新参数。 4 | 5 | 均方差损失函数和最大似然估计之间的联系:如果噪声符合正态分布,即误差$\epsilon$符合${1\over \sqrt{2\pi}\sigma}\exp(-{\epsilon^2\over 2\sigma^2})$ 6 | 7 | 取对数之后就比较明显了。 8 | 9 | 交叉熵的概念:$\sum -p(j)\log q(j)$ $p(j)$是真实分布,而$q(j)$是预测结果概率。我们用这个函数,可以衡量其准确度。 10 | 11 | Softmax函数用于将所有概率归一化。Softmax一定是最合理的方式吗? 12 | 13 | # 第四章中的ideas 14 | 15 | 目前常用的激活函数有Sigmoid,tanh,ReLU。但是目前Sigmoid基本不被使用。因为Sigmoid的导数不够大,尤其是远离0时。层数过多时会引起梯度消失。与Sigmoid不同的是,tanh函数是奇函数。导数也存在类似问题。所以现在多用ReLU。 16 | 17 | 如果网络中没有激活函数层,那么就相当于矩阵相乘而已。堆叠稠密层没有价值。 18 | 19 | 过拟合的问题,目前主要有两种解决方法。第一种,是引入正则化损失。目的是为了避免某个参数过大,导致某个节点的影响力过高。第二种,是使用暂退法。在反向传播时,故意停止某几个节点的反向传播。这样的目的是为了提高泛化的准确性。因为一部分节点“不存在”,不会影响最终的结果。 20 | 21 | 正则化损失使用L2范数,在线性回归中就是岭回归;而使用L1范数,则就是套索回归。 22 | 23 | 前向传播,实际上就是计算的过程。反向传播,则是按照微积分的链式法则进行计算。求梯度的过程是从后向前的,故名之。 24 | 25 | 梯度爆炸的问题,则是由于网络初始化数值不恰当,导致梯度过大,结果不收敛。 26 | 27 | 对称性导致神经网络表达性下降的问题:如果某层中(只是举例!)两个神经元计算得到的梯度始终相等,那么这两个神经元的实际作用就相当于一个神经元。我们要用暂退法,正则化来打破这种对称性。 28 | 29 | 我们可以通过参数初始化的方式,来缓解上述的几个问题。 30 | 31 | 对于非高难度问题,随机参数初始化即可。或者我们可以使用Xavier初始化。 32 | 33 | 训练数据对结果的影响:协变量的偏移,标签的偏移和概念的偏移。因此,我们必须要有所动作,想办法减小这种偏移的影响。 34 | 35 | # 第六章中的ideas 36 | 37 | 图像中的不变性:对于物体的识别,应该具有**平移不变性**。同时,在神经网络的前面几层中,应该也具有**局部性**。显然,离得很远的图像之间应当关联较小。 38 | 39 | 准确地说,卷积运算应该称为互相关。有时也可以喊它特征映射,因为它如同提取出了特征一般。感受野,指的是在前向传播期间可能影响传播的所有元素。 40 | 41 | padding和stride,前者为了保持信息量,后者则为了减少冗余。 42 | 43 | 卷积核通常会设置成奇数,这是为了保证图像两侧处理时的对称性。 44 | 45 | 通过增加输出通道的方法,可以认为是提取出了不同的特征,进而把这些特征从不同的通道中进行了处理。 46 | 47 | 1*1卷积层:利用不同的核函数,把不同的特征类型提取到不同的通道中。 48 | 49 | 池化层的作用:将不同通道的特征提取到同一个神经元中,从而提高图像的识别力。 50 | 51 | 一种思路是最大池化,用最大的特征值代表全部。另一种思路是使用平均池化,将特征值取平均,从而达到普遍的识别。这样的主要优点是减少卷积层对位置的敏感性。 52 | 53 | VGG块: 一堆3*3的卷积层,最后放一个步幅为2的3 *3最大池化层,就是模块化。 54 | 55 | NiN块:将全连接层换为两个1*1的卷积层来代替全连接层。在使用时交替使用NiN块以及步幅为2的最大池化层。在最后时使用全局平均池化。 56 | 57 | GoogLeNet:含并行连接的网络。Inception块:在同一个块中,有多条通路,从而抽取更多的信息。在不同的通路中,使用了不同尺寸的卷积核。从另一个方面去想,这也是在提取不同大小的信息。 58 | 59 | 批量规范化:对于一个小输入,我们将中间层的输入输出进行标准化。因为在不同的层之间,它们的数据量级可能有较为显著的区别。表达式为$\gamma\circ {x-\hat\mu\over\sigma}+\beta$。$\gamma,\beta$也是需要学习的参数。为了保证不发生除零错误,我们需要给$\sigma$始终加上一个常量。虽然引入了噪声,但是泛化效果更好。(看上去有点玄学。但现实情况里也确实一直有噪声,也能理解) 60 | 61 | 批量规范化,在全连接层中的实现,一般放在激活函数之前。卷积层也放在相似的位置上,但是每个层应当拥有自己的拉伸参数和偏移参数。在torch中,我们可以在放置全连接层、卷积层的时候在参数中进行设置(batchnorm)。在预测时,我们用总体的均值和方差来参与计算。 62 | 63 | “将现代深度学习的实践比作炼金术” 64 | 65 | 楽。现在AI的工作是不是很大程度上在依靠着直觉? 66 | 67 | 我喜欢依靠直觉,但我不一定有直觉XD 68 | 69 | 残差层:我们可以把优化模型的过程,看做寻找最优函数的过程。但是,这个最优函数并**不一定**可以被我们的架构取到。所以,我们希望造出一个更好的架构,让它中距离最优函数的“距离”更近些。如果我们能够严格保证我们创新的架构与原先的架构模拟的内容存在严格的包含关系,那么我们就可以认为新的架构确实离目标函数更近些。因此,产生了残差块。残差块的目的是,使得模拟的函数从原先的$f(x)$转变为$f(x)-x$,(因为在输出时还会加上$x$) 70 | 71 | 稠密块:首先由一串卷积层构成。在每经过一次卷积层后,将输出的结果与输入连接,然后再进入下一层的运算。思想是为了如Taylor展开般,更好地去模拟一个函数。因此,在最后的输出中,通道数会显著增加。因此,要在之后添加一个过渡层,其由1*1卷积层和平均池化层构成,从而降低模型复杂度。 72 | 73 | # 第八章中的ideas 74 | 75 | 我们应当如何处理文本?显然,要把大象放进冰箱,我们要先打开冰箱门,将文本作为字符串加载到内存中。然后,我们将字符串拆分为词元,比如单词和字符。然后,建立一个词表,把词元映射到数字。最后,将文本转换为数字索引序列。 76 | 77 | 对于语言模型,我们的目的实际上是为了估计$P(x_1,...,x_T)$这一联合概率。那么,对于语言模型的生成问题,我们实际上就是想要找到一个合适的单词,使得$P(x_t|x_{t-1},...,x_1)$有一个较为可观的值。 78 | 79 | 一种直观的想法,就是统计某一个单词在数据库中出现的总次数,然后分别统计其前一个字母为某一值的总次数。但是,这种方法的精确度很低,因为对于一些不常见的单词组合,不一定找得出合适数量的估计。 80 | 81 | 一种方法是采用拉普拉斯平滑的方式。它的假设是所有词都会等可能出现。 82 | 83 | $$ 84 | \hat P(x)={n(x)+\epsilon\over n + m\epsilon} 85 | $$ 86 | 87 | $n$为总单词数,$m$为出现的不同单词有多少个,$\epsilon$是一个规定的超参数。 88 | 89 | 如果我们把文本中的词汇做出一些统计后,我们可以看到出现次数最多的词是诸如the、and这类没营养的词。是故,我们想过滤掉这些词,我们把这些词汇称为停用词(stop words)。在过滤掉最前面最高词频的一些词汇后,剩余词汇的出现频率基本满足齐普夫定律。即,第$i$高词频的词出现次数有$n_i\propto {1\over i^\alpha}$ 90 | 91 | 拉普拉斯平滑的颓势于此尽见。从直觉上去想,我们过分高估了尾部单词的出现频率。 92 | 93 | 除了一元语法词,单词序列基本上也遵循齐普夫定律。 94 | 95 | 我们如果打算使用神经网络来训练语言模型,那么我们应当对数据进行一定的预处理。我们会把长序列划分为一个个小的子序列。一般有两种采样的方式:随机采样和顺序采样。 96 | 97 | 我们为什么需要循环神经网络?这是因为如果单词的数量增加,如果我们考虑条件概率,那么我们需要存储的参数数量显然会以指数级别增加。这是不可接受的。因此,我们将过去对现在的影响抽象为一个隐状态。 98 | 99 | 并且,隐状态之间的转移方程可以抽象为$h_t=f(x_t,h_{t-1})$。我们将每个单词出现的概率近似表示为$P(x_t|x_{t-1},...,x_1)\approx P(x_t|h_{t-1})$ 100 | 101 | 隐状态可以用这个方式计算:$H_t=\phi(XW_1+H_{t-1}W_2+b_1)$ 102 | 103 | $H_t$表征了从$x_1$到$x_t$之间的所有变量的影响。最终的输出,我们可以记作$O_t=H_tW_3+b_2$ 104 | 105 | 独热编码:将无关变量之间由于编码产生的”连续“分离开来。 106 | 107 | 梯度裁剪:解决梯度爆炸的问题。即,对于得到的梯度,我们每次反向移动的梯度量为$\min(1,\frac{\theta}{||\vec g||})\vec g$ 108 | 109 | 但是,考虑到循环神经网络中,最后的梯度与每个时刻的值都有关。如果我们对梯度进行完全计算,这在时空上是不可接受的。一般而言,我们只会计算最后几次影响下的梯度,使用这种定长梯度的方法来解决这一问题。还有一种处理方式是随机选取一个长度,选择这些对象影响下的梯度。目前,选取定长的这种做法较为主流。 110 | 111 | # 第九章中的ideas 112 | 113 | GRU:门控循环单元。是RNN下的一种特殊变体。实际上,我们新增了两种结构,更新门和重置门。在具体实现上,我们在RNN基础上,每次计算出的结构与重置矩阵进行一次元素积,重置矩阵中的取值在0~1之间。值越趋于0,就越会被重置。我们将结果进行偏置等操作后,输出的结果为$Z\circ H_t+(1-Z)\circ H_{t-1}$也就是说,将当前的结果视作两次操作的混合,或者可以把这看做是更新的程度。我们把重置门操作后的情况,称为候选隐状态。将更新门操作后的情况,称为隐状态。 114 | 115 | LSTM:长短期循环单元。在这种结构下,我们需要三种门,输入门,遗忘门,输出门。三种门的运算都符合RNN的基本操作,即基于之前的隐状态,进行矩阵乘法以及偏置加法。候选记忆元的计算与前三者无异。其思想与GRU非常接近。区别在于,其将$1-Z$转化为了$I$(输入门)进行运算。之后,在类似于GRU的操作过后,我们使用激活函数进行处理,然后将其与输出门进行元素乘法。因此,我们可以认为LSTM和GRU的区别在于,把三次处理的参数之间的相关性去除,从而提供更高的准确度。这样做可以缓解梯度爆炸和梯度消失的问题。(?) 116 | 117 | 深度循环神经网络:堆叠多个“并行线”的RNN,RNN中的每个单元不仅依赖于时序上的上一单元,还依赖于层数上的上一个相同位置的单元。 118 | 119 | 双向循环神经网络:考虑到,完形填空的过程中,我们应该填的词语,不仅和上文有关,也和下文有着很大的关系。所以,产生了双向循环神经网络。 120 | 121 | 在这个过程中,我们引入了隐马尔可夫模型。每一个时刻的隐藏变量仅依赖于前一个时刻。每一个时刻的输出仅依赖于当前时刻的隐藏变量。在这个过程中,我们可以使用动态规划的办法来辅助计算。在这里,动态规划的主要思想,就是从连加连乘中拆分出一个一个时刻隐变量的求和,和剩余部分之连乘。之后,只要进行递归就可以了。 122 | 123 | 语言真是一种不好使用的工具...... 124 | 125 | 利用隐马尔可夫模型中的递推,我们就可以建立起双向循环神经网络。 126 | 127 | 机器翻译:机器翻译是语言**序列转换模型**的关键性问题。解决的是如何将序列从一种语言自动翻译成另外一种语言。在神经网络之前,一般使用的是统计学方法进行。这一部分称为统计机器翻译。也就是说,根据大量的语料库,进行统计,选用最高概率的对象进行翻译。 128 | 129 | 神经网络机器翻译,则是另外一种不同的方法。 130 | 131 | 首先是老规矩。我们将数据集按照词元进行划分,从而得到词表。我们定义,如果一个词元出现的次数少于2次,定义为相同的未知词元。这是为了缓解词表大小过大的问题。 132 | 133 | 同时,为了让语句成为相同的长度,我们会用特定的填充词元,来保证每一个序列的长度是相同的。我们在序列的开始,会统一地添加上一个开始标记,在序列的末尾,统一地添加上一个终止标记。 134 | 135 | 编码器-解码器架构:编码器的作用,是把任意长度的序列,映射到一个固定长度的序列。解码器的作用,则是将编码器处理后输出的定长序列,重新映射到一个长度可变的序列。编码器-解码器架构,就是把编码器和解码器捆绑在一起,共同组织起一个架构。 136 | 137 | 序列到序列学习:首先,我们通过编码器,按顺序将输入内容处理并进行编码。在这一过程中,我们引入一个嵌入层,也就是一个矩阵,用来将词元转化为一个特征向量。在翻译的过程中,我们将编码出的内容进行解码,每翻译一个词,就更新目前的隐状态。$h_t=f(x_t,h_{t-1})$然后,我们需要一个函数,来表示编码,即$c=q(h_1,...,h_T)$,此用于表示所谓的上下文变量,一个定长的编码。 138 | 139 | 之后,我们应当考虑输出的问题。我们可以考察第$t$个输出的对象产生的概率。即:$P(y_t'|y_1,...,y_{t'-1},c)$ 140 | 141 | 为了解决这一点,考虑到RNN的特性,所以我们也跟着定义在输出过程中的隐状态,我们定义为$s_{t'}=g(y_{t'-1},c,s_{t'-1})$,然后运用长短期循环单元中的输出门或者简单的softmax来处理输出。 142 | 143 | 我们如何来评价一个序列预测的好坏?2002年中提出了BLEU的方法。即: 144 | 145 | $$ 146 | e^{\min(0,1-{\frac{len_{label}}{len_{pred}}})}\prod_{n=1}^kp_n^{1/2^n} 147 | $$ 148 | 149 | len表示在标签或预测对象中的词元数。k则是匹配的最长的$n$元词法。也就是,配上的最长长度。$p_i$表示匹配上的$n$元语法与预测所得序列中的$n$元词法数量。为何要用指数的方式进行处理?因为显然,长度越长,与难度之间的关系并不是线性的,难度显著提高。 150 | 151 | 那么,怎么样进行输出呢?第一种方法就是最朴素的策略,贪心搜索。在每一个时间步处,都选择当前位置上,具有最高**条件概率**出现的词元。但是,这并不一定是一个最优的序列,也就是说,$\prod_{t'=1}^{T'}P(y_{t'}|y_1,...,y_{t'-1},c)$不一定是最大值。如果我们一定要找到最优的序列,那么可以想到的一种方法就是运用穷举进行查找。但这样的复杂度是不可接受的。 152 | 153 | 一种折中的方式,就是进行束搜索。也就是说,在每一个时间步处,选择k个条件概率乘积最高的词元,并且进一步向下搜索。保证在每个时间步处,都选择k个这样的“最优词元”进行向下的搜索。 154 | 155 | # 第十章中的idea 156 | 157 | Attention is all you need! 158 | 159 | 注意力提示:分为自主性的,和非自主性的注意力提示。 160 | 161 | 自主性提示的含义,可以理解为外界的提示。非自主性提示,指的是key和value之间的映射关系。所有的提示通过attention pooling,从而得到一个好的输出值。非自主性,可以粗略地理解为对一个值的选择倾向。自主性提示区分开了注意力机制和一般的神经网络层。 162 | 163 | Nadaraya-Watson核回归:如果我们最终仅用所有输出的平均值进行输出,那么我们显然就忽略了输入的内容与训练集中的输入内容之间的联系。因此,我们可以考虑根据输入的位置对输出进行加权,即: 164 | 165 | $$ 166 | f(x)=\sum_{i=1}^n{K(x-x_i)\over \sum_{j=1}^nK(x-x_j)}y_i 167 | $$ 168 | 169 | 其中,$K$是核函数。比如说,我们可以选用高斯核函数。也就是说,我们考虑注意力汇聚的情况,对每一个输出的结果根据输入之间的差距进行加权处理。 170 | 171 | 如果我们的数据量真的很多,那么我们应当可以通过这个非参数化的注意力汇聚模型,得到一个让人满意的输出。 172 | 173 | 为了进一步提高它的能力,我们可以引入参数,从而更好地调整权值的关系。我们可以令: 174 | 175 | $$ 176 | f(x)=\sum_{i=1}^n\text{softmax}(-\frac{1}{2}((x-x_i)\omega)^2)y_i 177 | $$ 178 | 179 | 注意力评分函数: 180 | 181 | 我们可以如此表示注意力汇聚函数$f$: 182 | 183 | $$ 184 | f(q,(k_1,v_1),...,(k_m,v_m))=\sum_{i=1}^m\alpha(q,k_i)v_i 185 | $$ 186 | 187 | 其中,$\alpha$表示: 188 | 189 | $$ 190 | \alpha(q,k_i)=\text{softmax}(a(q,k_i)) 191 | $$ 192 | 193 | $a$是注意力评分函数。它可以将查询-键值向量对映射成一个标量。 194 | 195 | 考虑到,我们在操作词元的过程中,填充了一些无意义的词元。一种可以想到的优化,是指定一个合适的有效序列长度,过滤掉所有超出指定范围位置的词元。 196 | 197 | 一种注意力评分函数是加性注意力: 198 | 199 | $$ 200 | a(q,k)=w_v^T\tanh(W_q q+W_kk) 201 | $$ 202 | 203 | $w_v,W_q,W_k$均为可学习参数。在这里,我们不应当启用偏置。从直觉上看较为合理。 204 | 205 | 另外一种注意力评分函数是缩放点积注意力: 206 | 207 | $$ 208 | a(q,k_i)=q^Tk_i/\sqrt d 209 | $$ 210 | 211 | 其中,$d$为向量长度。 212 | 213 | Bahdanau注意力:之前的机器翻译中,上下文变量$c$的值始终是不变的。如果随着翻译的进行,上下文变量的值发生改变,那么会发生什么事情呢? 214 | 215 | RMK:**愚以为,目前机器学习的一个比较常见的优化过程,就是把运算过程中的一些不变量,改为变量,从而使机器进行学习这些参数。比如从GRU到LSTM的过程,把原来统一由更新门进行的工作,分给了多个不同的组件进行工作。是故,此为以时间换能力的一种做法。此依赖于算力的更新迭代。** 216 | 217 | Bahdanau注意力模型,采用这样的方式,来更新翻译过程中的上下文变量: 218 | 219 | $$ 220 | c_{t'}=\sum_{t=1}^T\alpha(s_{t'-1}, h_t)h_t 221 | $$ 222 | 223 | 其中,$\alpha$为加性注意力函数。$s_{t'-1}$是查询。 224 | 225 | 多头注意力:并行地堆了不同的注意力汇聚模型。让人想到GoogLeNet中的设计。 226 | 227 | 自注意力和位置编码:如果查询、键、值来自于同一组输入,那么我们称这种注意力为自注意力。自注意力机制和CNN相比,感受野更大,从而易于获取更多信息。但是,它需要大数据(因为不像CNN那样捕捉到了平移不变性等),并且在长序列训练时复杂度较高。但是,它容易捕捉到长程的信息,并且最长路径短。和RNN相比。它具有并行的优势。自注意力输出为: 228 | 229 | $$ 230 | y_i=f(x_i,(x_1,x_1),...,(x_n,x_n)) 231 | $$ 232 | 233 | $x_i$是query,$x_i$同时也作为key和value。 234 | 235 | 考虑到,在机器翻译过程中,使用自注意力方式,不像RNN那样,可以保持原有的位置信息。所以,在编码时,我们给每个词元添加**位置编码**。假定$X\in \R^{n\times d}$,表示有$n$个词元,$d$维的嵌入表示。那么,位置编码的矩阵大小亦为此。并且,有: 236 | 237 | $$ 238 | p_{i,2j}=\sin(\frac{i}{10000^{2j/d}})\\ 239 | p_{i,2j+1}=\cos(\frac{i}{10000^{2j/d}}) 240 | $$ 241 | 242 | 我们称之为$P$。将之加于$X$上。 243 | 244 | 这两个式子在做什么?我们观察下,可以发现,同一列的元素,位于相同的一个正弦波段上。并且,同一列上,从上到下,大小之间有着明显的区别。这样做的合理性在哪里?比如,我们可以观察二进制下0到7: 245 | 246 | $$ 247 | 000\\ 248 | 001\\ 249 | 010\\ 250 | 011\\ 251 | 100\\ 252 | 101\\ 253 | 110\\ 254 | 111 255 | $$ 256 | 257 | 可以看到,位数越高,0-1之间振荡的频率越小。因此,这种位置编码的一个想法,就是要模拟这种趋势。采用浮点数存储,比二进制方法节省空间。并且,这样的位置编码还可以捕获相对位置信息。这是一个线性代数的计算,在这里就不记录了。![](C:\Users\Lincher\Desktop\notes\other%20lectures\Transformer.jpg) 258 | 259 | Transformer模型。直接上图吧。图中的“加”表示这里是残差神经网络的类似方法,即加上原有的自变量。规范化,指的是将输出矩阵除以一特定值,避免梯度爆炸。逐位前馈网络,指的是全连接层、ReLU层和全连接层的组合。掩蔽多头注意力和普通的多头注意力有什么区别?一个主要的想法是,在输出的序列中,前面的内容不应当改变对后面内容的注意力。(rmk:对吗?) 260 | 261 | # 第十二章 计算机视觉 262 | 263 | ## 图像增广 264 | 265 | 所谓图像增广,指的是对数据图片进行一定变换,从而降低一些属性(比如位置)对结果的影响。 266 | 267 | 这一操作是为了提高模型的泛化性。 268 | 269 | 它的思路就是为了减少模型对不该关注的对象的无意义关注。比如说,把一只猫旋转90度,它还是一只猫。或者,我们将一只猫的图片,截取一部分,作为人类,我们依旧可以认出来这是猫的一部分。光线的明暗,猫的毛色,都不应该成为我们无法辨认出这只动物是猫的理由。 270 | 271 | ## 微调 272 | 273 | 运用场景:我们要分辨椅子的种类。但是椅子的种类比较少,尽管每种椅子的照片样本是很多的。 274 | 275 | 微调,就是为了解决在这种情况下模型分类能力较差的问题。首先,我们把原来的模型照抄过来,把参数原封不动地拷贝一遍,除了输出层。在输出层上,我们进行随机的初始化。这样做的一个直觉就是,在更大的数据集上,模型可能学习到了一些关于图形的纹理特征等通用信息,但是,只不过在输出层上可能要进行较大幅度的重新组合。 276 | 277 | 所以,我们仅使用一个全新的输出层,此前的对象保持不变。 278 | 279 | 由于输出层是全新的,所以,我们需要提高输出层的学习率。 280 | 281 | ## 目标检测和边界框 282 | 283 | 我们使用矩形边界框来“框”住对象。 284 | 285 | ## 锚框 286 | 287 | 如果需要人手工去标注边界框的数据,那未免过分愚蠢了些。因此,我们需要目标检测算法,来帮助我们进行查询,查找这些区域中,是否包含着我们的目标,并且对边界框进行进一步的调整。 288 | 289 | 所谓锚框,指的是以每个像素为中心,生成多个缩放比和宽高比不同的边界框,称之为锚框。 290 | 291 | 假定输入图片的高度为h,定义生成图片宽高比为r,缩放比为s,则锚框宽度为$hs\sqrt r$,高度为$hs/\sqrt r$ 292 | 293 | 生成不同的锚框,可以有不同的缩放比。为了降低取样数量,我们一般会挑选一个缩放比,在这个缩放比下多次改变宽高比采样;再挑选一个宽高比,在这个宽高比下多次改变缩放比进行采样。 294 | 295 | 我们使用交并比的概念,来判断锚框的覆盖效果。 296 | 297 | 我们定义杰卡德系数为:$\frac{|A\cap B|}{|A\cup B|}$,即交并比。 298 | 299 | 以下是一种把真实边界框分配给锚框的算法。 300 | 301 | 假设我们有$n_a$个锚框,有$n_b$个边界框。定义一个$n_a*n_b$的矩阵,第i行第j列的元素表示$A_i$与$B_j$的交并比。 302 | 303 | 首先,我们找到矩阵中最大的元素$x_{ij}$,把真实边界框$B_j$分配给$A_i$。然后,我们丢弃掉第$i$行和第$j$列中的所有元素。 304 | 305 | 我们重复这一操作,直到矩阵已经为空。对于多于的锚框,我们记进行遍历。如果这些锚框和某些真实边界框的交并比达到一个阈值,我们就把这个边界框分配给这个锚框。 306 | 307 | hmm。感觉很平凡的一种方法。 308 | 309 | 在这样分配了真实边界框后,我们就可以给每一个锚框进行类别上的标记了。我们标记锚框的类别,和被分配到的真实边界框类别相同。我们从中心坐标、高度、宽度这几个方面来标记锚框和真实边界框之间的偏移量。比较常见的有这种方法: 310 | 311 | $$ 312 | (\frac{\frac{x_b-x_a}{\omega_a}-\mu_x}{\sigma_x}, 313 | \frac{\frac{y_b-y_a}{\omega_a}-\mu_y}{\sigma_y}, 314 | \frac{\log\frac{\omega_b}{\omega_a}-\mu_\omega}{\sigma_\omega}, 315 | \frac{\log\frac{h_b}{h_a}-\mu_h}{\sigma_h} 316 | ) 317 | $$ 318 | 319 | $\mu$和$\sigma$均为一些特定的常数。 320 | 321 | 如果一个锚框没有被分配仍和的真实边界框,那么我们将锚框的类别标记为背景。我们将所有的背景类别的锚框称为负类锚框。剩余的,我们称其为正类锚框。我们不关心负类锚框的偏移量。 322 | 323 | 如果锚框的数量过多,可能会输出许多较为相似的预测边界框,其围绕着相同的目标。为了解决这一重复计算的问题,我们可以采用非极大值抑制的方法(当初只分配一个最像的会好吗?还是因为样本不够,预测不够准确?) 324 | 325 | 首先,我们选取置信度最高的预测边界框,也就是该边界框类别的确定程度。我们将所有非背景类的边界框按置信度降序排列,生成列表。从L的开头开始选取,遍历一遍,取出和该预测边界框交并比过大的所有边界框。重复这一过程,直到结束。 326 | 327 | ## 多尺度目标检测 328 | 329 | 对于一张图片而言,就算按照锚框的取样策略,以整张图片上的每一个像素为中心,想要按照锚框采样策略将锚框全部采样一遍,数量上还是太多了。所以,我们首先可以采用均匀分布的方式,均匀地选择一些中心点。并且,考虑到小的物体对象更难以捕获,我们可以多采样一些小的锚框,少采样一些大的锚框。 330 | 331 | 可以通过这样的方式进行实现。我们称卷积层输出的二维数组为特征图。 332 | 333 | 假定特征图的尺寸为$h\times w$,那么我们就均匀地在原图上选取$h\times w$个点,进行锚框的生成操作。假设我们总共有$c$张这样的特征图。 334 | 335 | ## 单发多框检测(SSD) 336 | 337 | SSD算法以一个基础网络块,和多个多尺度特征块叠加而成。每一个块都会根据多尺度目标检测的方式进行类别的预测和边界框的检测。 338 | 339 | 类别预测层:假设总共有$q$类物体,那么我们应当分出$q+1$个类别。在类别预测层中,使用了一个保持了输入的高和宽的卷积层,即padding为1的3*3卷积层。假设在每个位置上,我们会生成$a$个锚框。这样,可以保证输出的结果和该层中的锚框存在一一对应关系。因为有$q+1$个类别,所以我们应当最终产生$a(q+1)$个通道。并且,通道上的固定位置,即表示了对应采样点的结果。 340 | 341 | 边界框预测层:与类别预测层相同,但是输出结果应当表征锚框的偏移量,所以输出通道数是$4a$ 342 | 343 | 高宽减半块:由两个padding为1的3*3卷积层和步幅为2的2 *2最大池化层构成。 344 | 345 | 基础网络块:为了提取特征。在示例中,采用了三个高宽减半块,并且每通过一次高宽减半块,就翻倍输出的通道数量。 346 | 347 | ## R-CNN 348 | 349 | 首先,在不同尺度下选取多个提议区域,可以具有不同形状和大小。然后,通过一个预训练之卷积网络,提取特征。用其他模型对提取出的特征分类。用线性回归模型来预测区域内特征对应的边界框偏移量。 350 | 351 | Fast R-CNN:调换了卷积网络和选取提议区域之间的顺序。先对整张图片进行特征提取,然后再选取提议区域。然后,使用RoI将提议区域中的特征转化为形状相同的区域。从而便于在连接后输出。然后,通过一个全连接层变换形状,之后进行类别预测和边界框预测。 352 | 353 | Faster R-CNN:将提议区域的选取方式从选择性选取转换为区域提议网络。区域提议网络由一个卷积层、选取锚框、类别分类和边界框偏移量预测、非极大值抑制等过程构成。 354 | 355 | Mask R-CNN:基于Faster R-CNN,但是把RoI换为了兴趣区域对齐层。这里运用了双线性插值法来保留空间信息。兴趣区域对齐层会额外连接一个全卷积层,从而进行掩码预测。 356 | 357 | 双线性插值法:单线性插值是平凡的。如果我们已知空间中一个矩形的四个顶点处函数值,那么我们可以在$x$方向分别进行一次单线性插值。将所得到的插值点在$y$方向上进行一次线性插值,这就是双线性插值。 358 | 359 | 选取提议区域的一种方法:选择性搜索。首先,把图片分为很多小块。然后,计算相邻两个块之间的相似程度。如果足够相似,则合并之,最终得到可能具有某种特征的物体。 360 | 361 | ## 转置卷积 362 | 363 | 转置卷积操作上有点类似于对卷积进行反向操作,然其并非卷积的逆操作。具体地说,就是在原特征图上的每个位置,和卷积核进行乘法运算,然后将其映射到后一张输出的特征图上的,大小与转置卷积核相同的对应范围内。这样做,可以起到类似重建特征图尺寸的效果。 364 | -------------------------------------------------------------------------------- /others/Game Theory.md: -------------------------------------------------------------------------------- 1 | # 第一课 2 | 3 | 囚徒困境 4 | 5 | 收益 6 | 7 | 严格优势策略(选择它的收益严格大于相同情况下选择其他的收益) 8 | 9 | 严格劣势策略 10 | 11 | 帕累托最优:经济效率的最高化 12 | 13 | 换位思考分析 14 | 15 | # 第二课 16 | 17 | 博弈的组成部分: 18 | 19 | **博弈者** 20 | 21 | **策略** 22 | 23 | 计法如下: 24 | 25 | $$ 26 | s_i表示第i位博弈者策略。\\ 27 | S_i表示第i位博弈者的策略集合。\\ 28 | s表示一次博弈中的策略组合。\\ 29 | s-i表示除了i外其他博弈者的策略组合。 30 | $$ 31 | 32 | **收益** 33 | 34 | $$ 35 | U_i(s)表示在s这个策略组合下,第i位博弈者收益。 36 | $$ 37 | 38 | 假定:所有博弈者都知道其他博弈者的策略和收益。(完全状态博弈) 39 | 40 | 弱优势策略(选择它的收益不小于相同情况下选择其他的收益) 41 | 42 | 弱劣势策略 43 | 44 | 公共知识、共同知识 45 | 46 | 剔除劣势策略 47 | 48 | # 第三课 49 | 50 | 迭代剔除劣势策略(不断推测,剔除劣势策略) 51 | 52 | 中值选民定理 53 | 54 | 建模的过程中,可以先建立简单模型,再根据实际情况增加约束条件。 55 | 56 | 最佳对策:当博弈另一方作出某种选择时,博弈方的最佳策略。 57 | 58 | 画图法 59 | 60 | # 第四课 61 | 62 | 通过分析,不要选择在任何“信念”下都是劣势的策略。 63 | 64 | $$ 65 | \hat S_i 是在S-i情况下的最佳策略。\\ 66 | iff \:\ U_i(\hat S_i,S-i)\geq U_i(S_i,S-i) 67 | $$ 68 | 69 | 此外,当我们有信念P时,最佳策略可以定义为期望收益最高的策略。 70 | 71 | $$ 72 | E(\hat S_i,p)\geq E(S_i,p) 73 | $$ 74 | 75 | 合伙人博弈 76 | 77 | “外部性” 78 | 79 | 纳什均衡:在其他人选择固定下,每个人都做出了最佳回应。 80 | 81 | # 第五课 82 | 83 | “不反悔”原理 84 | 85 | 最佳对策不一定是唯一的。 86 | 87 | 严格劣势策略显然不会成为纳什均衡的一部分。 88 | 89 | 投资博弈 90 | 91 | 博弈的结果会不断趋向于纳什均衡。 92 | 93 | 协同博弈 94 | 95 | 协同博弈通过沟通可以改善。囚徒困境不可以。“信心”“领导力” 96 | 97 | # 第六课 98 | 99 | 策略互补博弈 100 | 101 | 需求曲线 102 | 103 | 古诺博弈:产量的竞争 104 | 105 | # 第七课 106 | 107 | 伯川德竞争:价格的竞争 108 | 109 | 选民投票模型:中间派 110 | 111 | # 第八课 112 | 113 | 选票投票模型:候选人倾向不可以过于极端。同一倾向的候选人增多会降低这一倾向胜出的概率。 114 | 115 | 居住模型:**很可能**种族隔离。当处于此均衡时,不存在有利变动。但是,当恰好两种种族混合居住时,是个更好的均衡。混居:弱纳什均衡。因为两个城镇情况相似。而种族隔离时,是个严格纳什均衡。这也就是说,混居时是一个**不稳定**的纳什均衡。如果这个弱纳什均衡被打破,有可能会导向种族隔离那个纳什均衡。 在这个博弈中,存在一个临界点。存在一个非常神奇的均衡:所有人都选择同一个城镇。然后,就会因超出容量而随机选择。 116 | 117 | 1、细节对结论的影响。 118 | 119 | 2、随机分配的作用。可能会比自 主选择效果来得更好。 120 | 121 | 3、现象的产生不一定是每个人偏好该现象的结果。也有可能是像居住模型中的情况。 122 | 123 | # 第九课 124 | 125 | 混合策略:$P_I(S_i)$参与者$I$赋予策略$S_i$的概率。 混合策略的收益即是各策略收益的加权和。 126 | 127 | 如果一个混合策略是最佳策略,那么选择的每一个纯策略必须也是最佳策略。 128 | 129 | 一个混合策略纳什均衡:当且仅当一位成员的最佳对策是混合策略,另一位也是混合策略。 130 | 131 | # 第十课 132 | 133 | recap:混合策略中每一个纯策略的收益必然严格相等。 134 | 135 | 随机化 136 | 137 | 如果其不相等,那么显然不如使用纯策略。改变A的混合策略概率,会影响B的决策。 138 | 139 | # 第十一课 140 | 141 | 进化论与博弈论。 142 | 143 | 动物行为学中:策略是天生的。 144 | 145 | 简化的进化论模型:只考虑种内竞争,考虑一个对称的博弈。 146 | 147 | 进一步简化模型,只考虑无性繁殖,不考虑突变。 148 | 149 | S是进化稳定的,(S,S)是纳什均衡。 150 | 151 | 但是一个策略是进化稳定的,不意味这是 最优策略。 152 | 153 | 在一个双参与人的对称博弈中,$\hat S$是进化稳定纯策略,iff 154 | 155 | $$ 156 | (1-\epsilon)u(\hat S,\hat S)+\epsilon u(\hat S, S')>(1-\epsilon)u(S',\hat S)+\epsilon u(S',S') 157 | $$ 158 | 159 | $\hat S$是ES,if 160 | 161 | $$ 162 | (\hat S,\hat S)是纳什均衡。u(\hat S,\hat S)> u(S',\hat S),\forall S'\\ 163 | 即(\hat S,\hat S)是严格纳什均衡。 164 | $$ 165 | 166 | 这是进化稳定纯策略的两种等价定义。 167 | 168 | # 第十二课 169 | 170 | 不对称纯策略纳什均衡 171 | 172 | 在这种情况下,我们不能得到一个纯策略的纳什均衡。但是,可以有一个混合策略的纳什均衡。 173 | 174 | SLF策略:sneak little fu**ers策略 175 | 176 | 如果没有非进化稳定的策略? 177 | 178 | # 第十三课 179 | 180 | 借贷模型 181 | 182 | 有顺序博弈:贯序博弈。关键在于一方博弈者可以知道另一方博弈者的决策。 183 | 184 | 树形图 185 | 186 | 需要作出预测,**逆向归纳法**。 187 | 188 | 道德风险 189 | 190 | 一种规避风险的方法是减少投资规模。用法律等强制规则来约束双方。 191 | 192 | 一种方法是把单回合博弈变为重复博弈。 193 | 194 | 激励设计 195 | 196 | 计件、分成:两种传统的激励方式 197 | 198 | 担保,担保是承诺策略中的一种。 199 | 200 | 减少可选策略来改变其他人的举动。承诺策略需要使其他人知道。 201 | 202 | # 第十四课 203 | 204 | 古诺模型:产量竞争 205 | 206 | 贯序博弈的古诺模型:斯塔克伯格模型 207 | 208 | 第一个博弈方会倾向于比古诺模型中的均衡多做。这个博弈被称为**策略代换**。因为第二方在知道了第一方的策略后,会调整自己的策略,使自己的利益最大化。最终的结果,会导致总产量上升。 209 | 210 | 第一个博弈方的总利润会上升,第二方的博弈方的总利润会减少。 211 | 212 | 如何让第一个博弈方的行为变得具有较高的可信度?这个时候我们就需要**承诺**。也就是说,需要**沉没成本**。 213 | 214 | 在贯序博弈中,关键的是信息到达的时机。 215 | 216 | 因此,如果一个博弈方知道在作出决定后,另一个博弈方在作出决定时已经知道其作出的决定,那么他可以选择更加有利于己方的策略。 217 | 218 | 先行得利模式 219 | 220 | 先行策略一般会有更大的利益。 221 | 222 | # 第十五课 223 | 224 | 先行优势和次行优势。 225 | 226 | 策梅洛理论:考虑完全信息博弈。当一名博弈者可以做决定时,完全知道博弈者的策略。并且结果只有胜、负、和。 227 | 228 | 要么:参与人一可以必胜;参与人一可以不负;参与人二可以必胜。这种博弈只有这三种类型。 229 | 230 | 国际象棋也是个完全信息博弈。所以,国际象棋一定是有解的。 231 | 232 | 完全信息博弈,指的是在每个节点上的决策者,都知道自己位于整个博弈节点的博弈。 233 | 234 | 不可置信的威胁 235 | 236 | # 第十六课 237 | 238 | 非可信威胁 239 | 240 | 表现出“疯子”的策略 241 | 242 | 连锁店博弈 243 | 244 | 决斗博弈 245 | 246 | 优势理论和逆向归纳法 247 | 248 | # 第十七课 249 | 250 | 独裁者博弈 251 | 252 | 两期议价博弈 折损的概念 253 | 254 | # 第十八课 255 | 256 | 信息集合的概念:一系列一方博弈者无法识别的节点。在信息集合中的同层节点,显然应当有相同数量的策略选择。 257 | 258 | 开始考虑非完美信息博弈。 259 | 260 | 子博弈的纳什均衡 261 | 262 | # 第十九课 263 | 264 | 战略效应: 265 | 266 | e.g.:是否引入一种能够减低成本的新设备?我们要考虑竞争者对引入设备所作的战略性变化。 267 | 268 | # 第二十课 269 | 270 | 不要仅仅像一个会计一样去计算,要考虑策略对收益、参与者的影响。 271 | 272 | 战争博弈、贿赂博弈、全薪拍卖 273 | 274 | 沉没成本(sunk cost),尊严和信誉 275 | 276 | # 第二十一课 277 | 278 | 连任失败效应 279 | 280 | 短期背叛的诱惑和较为长期的合作收益 281 | 282 | 重新谈判 283 | 284 | # 第二十三课 285 | 286 | 非对称信息 287 | 288 | 信息披露的过程,不传达信息这种行为本身也是一种信息。 289 | 290 | 信息能否被核实也具有重要性。 291 | 292 | 分离均衡 学位通胀 293 | 294 | # 第二十四课 295 | 296 | 公共价值型拍卖:赢家的诅咒。 297 | -------------------------------------------------------------------------------- /others/Information Theory.md: -------------------------------------------------------------------------------- 1 | # Lec 2 2 | 3 | ## 熵 4 | 5 | 记号约定:$X$是离散随机分布。$\mathcal{X}$为字母表。 6 | 7 | 我们用如下的方法定义熵: 8 | 9 | $$ 10 | H(X)=-\sum_{x\in X}p(x)\log p(x) 11 | $$ 12 | 13 | 显然当$p(x)=0$时,不会提供任何信息。 14 | 15 | 一般此时$\log$的底数都取2。底数为2,称为bits。底数为e,称为nats。 16 | 17 | $$ 18 | 0\leq H(X)\leq\log|\mathcal{X}| 19 | $$ 20 | 21 | 第一个等号成立时,为不可能事件或者必然事件。 22 | 23 | 第二个等号成立时,为均一分布。 24 | 25 | 概率论的链式法则和贝叶斯规则: 26 | 27 | $$ 28 | p(x_1,...,x_n)=p(x_n)p(x_{n-1}|x_n)...p(x_1|x_2,...,x_n)\\ 29 | p(x)p(y|x)=p(y)p(x|y) 30 | $$ 31 | 32 | ## 联合熵 33 | 34 | 对于多个随机变量的分布。 35 | 36 | 定义为: 37 | 38 | $$ 39 | H(X,Y)=-\sum_{x\in\mathcal{X}}\sum_{y\in\mathcal{Y}}p(x,y)\log p(x,y) 40 | $$ 41 | 42 | 显然有: 43 | 44 | $H(X,X)=H(X)$ 45 | 46 | $H(X,Y)=H(Y,X)$ 47 | 48 | ## 条件熵 49 | 50 | $X=x$已知,$p(Y=y|X=x)$也是一个概率密度函数。 51 | 52 | $$ 53 | H(Y|X)=\sum_{x\in\mathcal{X}}p(x)H(Y|X=x)\\ 54 | =-\sum_{x\in\mathcal{X}}p(x)\sum_{y\in\mathcal{Y}}p(y|x)\log p(y|x)\\ 55 | =-\sum_{x\in\mathcal{X}}p(x,y)\sum_{y\in\mathcal{Y}}\log p(y|x)\\ 56 | =-E\log p(Y|X) 57 | $$ 58 | 59 | 从直觉的角度而言,条件熵已经有一定的限定了,所以有 60 | 61 | $$ 62 | H(Y|X)\leq H(Y)\\ 63 | H(X|Y)\not=H(Y|X)\\ 64 | H(X|Y)+H(Y)=H(Y|X)+H(X)=H(X,Y) 65 | $$ 66 | 67 | 第三个等式是符合直觉的。 68 | 69 | ## 零熵 70 | 71 | 如果一个随机变量$X$相对另一个随机变量$Y$的条件熵为0,则$X$是$Y$的一个函数。这是符合直觉的。说明$X$的取值一直和$Y$有关。 72 | 73 | # Lec 3 74 | 75 | ## 相对熵(K-L距离) 76 | 77 | $$ 78 | D(p||q)=\sum_{x\in \mathcal{X}}p(x)\log {p(x)\over q(x)}\\ 79 | =E_p\log {p(X)\over q(X)} 80 | $$ 81 | 82 | 相对熵永远是非负的。 83 | 84 | $$ 85 | D(p||q)=E_p\log p(X)-E_p\log q(X) 86 | $$ 87 | 88 | 容易观察到,相对熵并不是一种度量。首先,相对熵显然就不具有对称性。 89 | 90 | $$ 91 | D(p||q)=0\iff p=q 92 | $$ 93 | 94 | Pinsker不等式 95 | 96 | $$ 97 | D(p||q)\geq{1\over 2\ln 2}V^2(p,q) 98 | $$ 99 | 100 | ## 互信息 101 | 102 | $$ 103 | I(X;Y)=\sum_x\sum_yp(x,y)\log {p(x,y)\over p(x)p(y)}\\ 104 | =D(p(x,y)||p(x)p(y))\\ 105 | =E_{p(x,y)}\log{p(X,Y)\over p(X)p(Y)} 106 | $$ 107 | 108 | 互信息符合对称性。$I(X,X)=H(X)$。这两部分都是符合直觉的。 109 | 110 | 可以用这样非正式的集合方法表示信息之间的关系: 111 | 112 | $$ 113 | H(X,Y)=H(X)\cup H(Y)\\ 114 | I(X;Y)=H(X)\cap H(Y)\\ 115 | H(X|Y)=H(X)/I(X;Y)\\ 116 | H(Y|X)=H(Y)/I(X;Y) 117 | $$ 118 | 119 | 这样的相对关系,是非常符合直觉的。 120 | 121 | $$ 122 | \log{p(X,Y)\over p(X)p(Y)}=-\log p(X)-\log p(Y)+\log p(X,Y) 123 | $$ 124 | 125 | 从而可以证明 126 | 127 | $$ 128 | I(X;Y)=H(X)+H(Y)-H(X,Y) 129 | $$ 130 | 131 | 互信息可以在一定程度上刻画出变量之间的相关性。 132 | 133 | ## 熵的链式法则 134 | 135 | $$ 136 | H(X_1,X_2,...,X_n)=H(X_1)+H(X_2|X_1)+...+H(X_n|X_{n-1},...,X_1) 137 | $$ 138 | 139 | ## 条件互信息 140 | 141 | $$ 142 | I(X;Y|Z)=H(X,Z)-H(X|Y,Z) 143 | $$ 144 | 145 | $$ 146 | I(X_1,...,X_n;Y)=\sum_{i=1}^nI(X_i;Y) 147 | $$ 148 | 149 | ## 条件相对熵 150 | 151 | $$ 152 | D(p(y|x)||q(y|x))=E_{p(x,y)}\log {p(Y|X)\over q(Y|X)} 153 | $$ 154 | 155 | $$ 156 | D(p(x,y)||q(x,y))=D(p(x)||q(x))+D(p(y|x)||q(y|x)) 157 | $$ 158 | 159 | # Lec 4 160 | 161 | ## 熵的独立界 162 | 163 | $$ 164 | H(X_1,...,X_n)\leq \sum_{i=1}^nH(X_i) 165 | $$ 166 | 167 | 这一点是符合直觉的。等号成立当且仅当均为独立变量。 168 | 169 | ## 马尔科夫链 170 | 171 | 假设$X\to Y\to Z$构成一个马尔科夫链,则 172 | 173 | $$ 174 | p(x,y,z)=p(x)p(y|x)p(z|y) 175 | $$ 176 | 177 | 马尔科夫过程应当是具有可逆性的。 178 | 179 | $$ 180 | I(X;Z|Y)=0\\ 181 | I(X;Y|Z)=E_{p(X,Y,Z)}\log{p(X,Y|Z)\over p(X|Z)p(Y|Z)} 182 | $$ 183 | 184 | ### 数据处理不等式 185 | 186 | $$ 187 | I(X;Y)\geq I(Y;Z) 188 | $$ 189 | 190 | 在如上马尔科夫链的假设上。 191 | 192 | 此外,我们可以定义: 193 | 194 | $$ 195 | I(X;Y;Z)=I(X;Y)-I(X;Y|Z) 196 | $$ 197 | 198 | ## Fano不等式 199 | 200 | 我们打算去估计随机变量$X$的分布$p(x)$ 201 | 202 | 我们观察到了与$X$相关的变量$Y$,概率分布为$p(y|x)$ 203 | 204 | $$ 205 | P_e=Pr(\hat X=X)\\ 206 | H(P_e)+P_e\log|\mathcal{X}|\geq H(X|\hat X)\geq H(X|Y) 207 | $$ 208 | 209 | 我们定义误差的随机变量: 210 | 211 | $$ 212 | E=0,\hat X=X;E=1,\hat X\not=X 213 | $$ 214 | 215 | 故,当$\hat X=X$之时,$P_e=0$,故在计算过程中可以略去这一项。 216 | 217 | 是故,我们有: 218 | 219 | $$ 220 | H(P_e)+P_e\log(|\mathcal{X}-1|)\geq H(X|\hat X) 221 | $$ 222 | 223 | # Lec 5 224 | 225 | 给出一系列随机变量$X_1,X_2,...$,我们称这个系列收敛于随机变量$X$,当以下三种条件其一符合时: 226 | 227 | $$ 228 | \exist n,\forall \epsilon>0,Pr\{|X_n-X|>\epsilon\}\to0\\ 229 | \exist n,E(X_n-X)^2\to0\\ 230 | Pr\{\lim_{n\to\infin}X_n=X\}=1 231 | $$ 232 | 233 | 对于上述记号,当$A$是一个集合时,定义为: 234 | 235 | $$ 236 | Pr\{X=A\}=\sum_{a\in A}Pr\{X=a\} 237 | $$ 238 | 239 | 大数定律:n个独立的随机变量$X_1,...X_n$符合$p(x) $ 240 | 241 | 强大数定律:$Pr\{\lim_{n\to\infin}\bar X_n=E(X)\}=1$ 242 | 243 | 弱大数定律:$\bar X_n\to E(X)$ 244 | 245 | ## AEP(渐进均分性) 246 | 247 | 令$X_1,...,X_n$为$i.i.d$的随机变量,其分布均符合$p(x)$,则: 248 | 249 | $$ 250 | -{1\over n}\log(p(X_1,...,X_n))=-{1\over n}\sum_{i=1}^n\log p(X_i)\to H(X) 251 | $$ 252 | 253 | 注意到上式的底数为2。取指数后,并取出随机变量的事件,我们就可以得到一些符合下面这个关系的事件: 254 | 255 | $$ 256 | 2^{-n(H(X)-\epsilon)}\leq p(x_1,...,x_n)\leq2^{-n(H(X)+\epsilon)} 257 | $$ 258 | 259 | 我们把这样的事件组成一个集合,称作典型集,记作$A_\epsilon^{(n)}$。典型集中的事件总数约为$2^{nH}$ 260 | 261 | 典型集中事件发生的概率之和趋于1。 262 | 263 | 我们定义高概率集为最小的,满足$Pr(X=B_\delta^{(n)})\geq 1-\delta$的集合。 264 | 265 | ## 数据压缩 266 | 267 | 对数据首先进行编码,之后再进行解码。 268 | 269 | 定义$P_e=P(X^n\neq \hat X^n)$ 270 | 271 | # Lec 6 272 | 273 | ## 随机过程 274 | 275 | 如果n个随机变量之间存在相互联系呢?那么我们之后将引入熵率。 276 | 277 | 在随机过程中,各变量的观测是有顺序的。 278 | 279 | eg:赌徒的破产,马尔科夫过程。即: 280 | 281 | $$ 282 | X_{i+1}=X_i\underline+1 283 | $$ 284 | 285 | ### 稳态过程 286 | 287 | $$ 288 | Pr\{X_1=x_1,...,X_n=x_n\}=Pr\{X_{1+l}=x_1,...,X_{n+l}=x_n\} 289 | $$ 290 | 291 | 也就是说,系统在时间上具有不变性。 292 | 293 | 故 294 | 295 | $$ 296 | p(X_1)=p(X_2)=...=p(X_n)\\ 297 | p(X_1,X_3)=p(X_2,X_4) 298 | $$ 299 | 300 | ## 马尔科夫过程 301 | 302 | $$ 303 | P(X_{n+1}=x_{n+1}|X_n=x_n,...,X_1=x_1)=Pr(X_{n+1}=x_{n+1}|X_n=x_n) 304 | $$ 305 | 306 | 马尔科夫链具有时间不变性。 307 | 308 | 当$p(X_{n+1})=p(X_n)$时,马尔科夫过程是一个稳态。 309 | 310 | $$ 311 | p(x_{n+1})=\sum_{x_n}p(x_n)P_{x_nx_{n+1}}=x^TP=x^T 312 | $$ 313 | 314 | ## 熵率 315 | 316 | 对于一个有时序的随机过程,熵率可以这样定义: 317 | 318 | $$ 319 | H(\mathcal{X})=\lim_{n\to\infin}{1\over n}H(X_1,...,X_n) 320 | $$ 321 | 322 | 由链式法则, 323 | 324 | $$ 325 | H(X_n,...,X_1)=\sum_{i=1}^nH(X_i|X_{i-1},...,X_1) 326 | $$ 327 | 328 | 我们可以令右侧这个累加式中,每一项为$a_n$,随后验证其收敛性。 329 | 330 | 注意到,右侧这一条件熵每一项是递减的。并且,熵始终大于0。 331 | 332 | 定义:$H'(\mathcal{X})=\lim_{n\to\infin}H(X_n|X_{n-1},...,X_1)$ 333 | 334 | 因此,熵率在数值上等于$H'(\mathcal{X})$ 335 | 336 | 考虑马尔科夫过程的熵率。由于马尔科夫链具有无后效性,所有其熵率就是$H(X_2|X_1)$ 337 | 338 | ## 热力学第二定律 339 | 340 | 我们可以把孤立系统看做是一个马尔科夫过程。 341 | 342 | ## 马尔科夫过程的函数 343 | 344 | $X_1,...,X_n$是一个马尔科夫过程。 345 | 346 | $Y_1,...,Y_n,Y_i=\phi(X_2)$ 347 | 348 | 首先,我们可以找到条件熵的下界,也就是$H(\mathcal{Y})$ 349 | 350 | 然后,我们可以找到$H(\mathcal{Y})$一个下界,也就是$H(Y_n|Y_{n-1},...,Y_1,X_1)$ 351 | 352 | 两边同取极限即可。 353 | 354 | # Lec 7 355 | 356 | 定义:编码的非奇异性。也就是编码和事件之间存在一个双射。 357 | 358 | 定义:前缀码,每一个编码都不是其他编码的前缀。 359 | 360 | 对一组前缀码,存在Kraft不等式: 361 | 362 | $$ 363 | \sum_{i=1}^mD^{-i}\leq 1 364 | $$ 365 | 366 | $D$是字母表的大小。$i$是每一个编码的长度。如果等号不成立,那么编码是有冗余的;如果等号成立,那么我们称其为完备码;若该等式不成立,那么相应的编码并不是唯一可解编码。 367 | 368 | 我们为什么需要前缀码?这是因为当传输信息时,我们不再需要按照固定长度(比如8个bit)来解码,而是可以直接从前往后,根据编码树解码。根据前缀码的性质,这样的解释是唯一的。Kraft不等式就在描述这样一件事情。 369 | 370 | 关于最优码,我们总是希望编码的平均长度越短越好。 371 | 372 | ## 香农编码 373 | 374 | 假设一个事件出现的概率为$p(i)$,我们令其对应事件的编码码长为$\lceil-\log p(i)\rceil$。从小到大进行编码。它也是前缀码,但不是最优码。只有当概率分布满足一定条件时,方可有紧致性。 375 | 376 | # Lec 8 377 | 378 | ## Huffman编码 379 | 380 | 每次取出D个出现概率最低的编码,在当前位合并为一个编码,从而使期望编码最少。我们依次这样操作下去。直到当前位置只有两个节点为止。 381 | 382 | 为了Huffman编码最长编码情况出现的比较小,我们应当加入一些假符号,使其概率值为0,从而使总符号数为$1+k(D-1)$ 383 | 384 | 我们称一个分布是D-adic的,如果每一个事件出现的概率均为$D^{-n},n\in N$ 385 | 386 | 如果一个码字,没有兄弟姐妹,也就是说,其为父节点之唯一子节点,那么显然,我们可以删除最后一位。 387 | 388 | ## Shannon-Fano-Elias编码 389 | 390 | 事件无需按照发生概率的大小进行分布。我们定义一个累积概率函数,为该符号此前出现的所有发生事件的概率之和。然后,我们再在此基础上加上当前事件发生概率之一半。将此函数值表达为$D$进制之小数,把小数点后的后$\lceil p(x)\rceil+1$位作为其编码。 391 | 392 | 用数值来表示事件的idea。 393 | 394 | # Lec 9 395 | 396 | ## 随机变量的生成 397 | 398 | 用二叉树来作为算法的表示树。每一个节点要么为叶子节点,要么就有两个儿子节点。 399 | 400 | 所有的事件都位于叶子节点处。在每一个节点处,向左儿子移动和向右儿子的概率是相等的。当每一个事件与叶子节点之间形成双射之时,树的期望深度与该随机变量的信息熵相等。如若不然,则树的期望深度不会小于信息熵的大小。 401 | 402 | 如果一个事件发生的概率并非$1\over 2$的正整数次幂,那么我们可以将其发生的概率改写为二进制,随后分解进行表示。 403 | 404 | ## 通用信源编码 405 | 406 | 在实际生活中,我们常常会不知道不同符号的概率分布,那么我们就没有办法按照概率来编码。 407 | 408 | 是故,在这个过程中,我们想要完成的事情,就是最小化我们估计的某一事件概率和该事件实际概率之间的差距。也就是最小化最大冗余。 409 | 410 | 冗余可以转化为信道的容量进行计算。 411 | 412 | ## 算术编码 413 | 414 | 算术编码依旧不能脱出需要已知概率的桎梏。它承袭了Shannon-Fanos-Elias编码的思想。首先,其将$[0,1)$按照概率之分布,划分为对应之区间。倘若某一数字在某符号对应之区间中,则说明这一位便是它了。此后,再将每一区间按概率层层划分,依此法进行划分,从而解码得到结果。 415 | 416 | ## LZ算法 417 | 418 | 此为一种无损压缩之方式。它使用了一个滑动窗口进行编码,在这个滑动窗口中,包含两部分内容。第一部分是已编码部分,称为查找缓冲区。第二部分是未编码部分,称为先行缓冲区。然后,在查找缓冲区中检索,是否有先行缓冲区中的第一个字符。然后,我们用一个三元组来表示之。三元组中的内容,包含偏移量(从查找缓冲区的哪里复制?)、长度(需要复制多少个字符?)、后继(下一个字符是什么?)。倘若没有搜索到,那么记录为$<0,0,C(...)>$,…代表的就是下一个字符。 419 | 420 | 显然,需要滑动窗口的大小是相同的,这样才可以保证其正确性。 421 | 422 | # Lec 10 423 | 424 | 我们可以用状态转移矩阵来模拟在传输过程中数据遇到的噪声。 425 | 426 | ## 离散无记忆信道(DMC) 427 | 428 | 我们希望发送出的信息$W$与接收方解码后得到的信息$\hat W$尽可能相近。 429 | 430 | DMC,之前通信过的内容不会影响状态转移矩阵。 431 | 432 | 我们定义信道容量为$C=\max_{p(x)}I(X;Y)$ 433 | 434 | $X$为发送的信息,$Y$为接收方收到的信息。 435 | 436 | $C\geq0,C\leq \log\mathcal{X},C\leq\log\mathcal{Y}$ 437 | 438 | 一般情况下,写不出信道容量的显式表达式。 439 | 440 | # Lec 11 441 | 442 | 信息集:可能发送的信息的集合。 443 | 444 | 对于每一个信息,我们可以用它们的序号来表示之。 445 | 446 | 无记忆性和反馈: 447 | 448 | 信道的第n次扩展:已经传输过n次信息后的情况。假设收到的信息为$y_k$ 449 | 450 | ,发出的信息为$x_k$,我们称信道为无记忆性的,当: 451 | 452 | $p(y_k|x_k,y_{k-1})=p(y_k|x_k)$ 453 | 454 | 我们称一个信道是无反馈的,当: 455 | 456 | $p(x_k|x_{k-1},y_{k-1})=p(x_k|x_{k-1})$ 457 | 458 | 从直观上去想,就是发送的内容与对方接收到的内容无关。 459 | 460 | 如果无记忆且无反馈,那么 461 | 462 | $p(y_n|x_n)=\Pi_{i=1}^np(y_i|x_i)$ 463 | 464 | $H(Y_n|X_n)=\sum_{i=1}^nH(Y_i|X_i)$ 465 | 466 | ## DMC 467 | 468 | 信息集与序号之间建立起了一个双射,从而得到了一个码本。 469 | 470 | 我们假设信息集中有$M$个元素。那么,我们定义码率为$\log M\over n$,$n$为码长。 471 | 472 | 定义:条件错误概率: 473 | 474 | $\lambda_i=Pr(g(Y^n)\neq i|X^n =x^n(i))=\sum_{y^n}p(y^n|x^n(i))I(g(y^n)\neq i)$ 475 | 476 | 其中,$I$是示性函数。其表示发送信息i时,发生错误的概率。 477 | 478 | 最大错误概率,就是条件错误概率之最大值。 479 | 480 | 平均错误概率,则为取平均。 481 | 482 | 我们称一个码率是可取的,指存在一个序列,使得在这种编码条件下,最大错误概率趋于零。 483 | 484 | 联合典型性与联合AEP 485 | 486 | 信道编码定理:对于一个信道容量$C$,待传的信息率为$R$,只要$RH$ 524 | 525 | 在信息传输过程中,有$R0$的集合。 546 | 547 | 高斯分布的微分熵为${1\over 2}\log (2\pi e\sigma^2)$ 548 | 549 | 一个连续性随机变量携带了无穷的信息(考虑0~1的均匀分布,将对象写成二进制,则每一位的信息熵为1,总体信息熵为无穷)。微分熵并不能用来衡量信息的多少。 550 | 551 | $h(aX)=h(X)+\log|a|\\ h(AX)=h(X)+\log|\det A|$ 552 | 553 | 为了将连续型的随机变量与离散型的随机变量挂钩,我们可以规定落在某一个区间内的对象,都取同一个函数值。这个函数值通过积分中值定理,保证该区间内积分值不变,从而维护总概率为1。我们记这时的离散随机变量为$X^\Delta$ 554 | 555 | $p(X^\Delta=x_i)=\int_{i\Delta}^{(i+1)\Delta}f(x)dx=f(x_i)\Delta$ 556 | 557 | 所以 558 | 559 | $H(X^\Delta)=-\sum\Delta f(x_i)\log f(x_i)-\log\Delta$ 560 | 561 | 我们也可以定义连续型随机变量的AEP和典型集。 562 | 563 | 联合微分熵$-\int f(x^n)\log f(x^n)dx^n$ 564 | 565 | 条件微分熵$-\int f(x,y)\log f(x|y)dxdy$ 566 | 567 | 协方差矩阵 568 | 569 | 我们定义两个随机变量的协方差为$cov(X;Y)=E(X-EX)E(Y-EY)=E(XY)-(EX)(EY)$ 570 | 571 | 对于一组随机变量组成的向量$X=[x_1,...,X_n]^T$我们定义其协方差矩阵为$E(X-EX)(X-EX)^T$ 572 | 573 | 我们定义关联矩阵为$EXX^T$,$EXX^T=E(X-EX)(X-EX)^T+(EX)(EX^T)$ 574 | 575 | 协方差矩阵是对称的。 576 | 577 | 对于多元正态分布$N$,有 578 | 579 | $f(x)={1\over (\sqrt{2\pi})^n|K|^{1\over 2}}e^{-{1\over2}(x-\mu)^TK^{-1}(x-\mu)}$ 580 | 581 | 这是非常复杂的一坨公式...$K$是协方差矩阵。 582 | 583 | 其微分熵和一元高斯分布时非常相近。为${1\over 2}\log (2\pi e)^n|K|$ 584 | 585 | 对于两个连续型随机变量,我们定义其相对熵$D(f||g)$为$\int f\log{f\over g}$ 586 | 587 | 对于互信息,$I(X;Y)=\int f(x,y)\log{f(x,y)\over f(x)f(y)}dxdy$ 588 | 589 | 互信息依旧是非负的。微分熵可以有负值。 590 | 591 | # Lec 14 592 | 593 | 最大熵原理: 594 | 595 | $h(X)\leq{1\over2}\log(2\pi e\sigma^2)$ 596 | 597 | 当$X$符合正态分布时,熵最大。 598 | 599 | 平衡信息不等式: 600 | 601 | $h(X,Y)\leq h(X)+h(Y)\\ h(X,Y,Z)\leq {1\over2}h(X,Y)+{1\over2}h(Y,Z)+{1\over2}h(Z,X)$ 602 | 603 | 等。动机是为了保证式子两边的变量总权重是一样的。这里可以是离散的,可以是连续的。 604 | 605 | Han's不等式: 606 | 607 | 考察指标集$\{1,...,n\}$中之一集合$S$。我们记$X(S)$为下标在$S$中的$x_i$之集合。 608 | 609 | 记$h^{(n)}_k={1\over C^k_n}\sum_{|S|=k}{h(X(S))\over k}$ 610 | 611 | $g_k^{(n)}={1\over C^k_n}\sum_{|S|=k}{h(X(S)|X(S^C))\over k}$ 612 | 613 | 显然有$h_k^{(n)}=g_k^{(n)}$ 614 | 615 | 通过平衡信息不等式,$h_k^{(n)}$随k增大而增大。 616 | 617 | 由联合熵和条件熵的性质,$g_k^{(n)}$随k增大而减少。 618 | 619 | Fisher信息:$I(X)=\int_{-\infin}^{+\infin}f(x)[{{\partial\over\partial x}f(x)\over f(x)}]^2dx$ 620 | 621 | 也是针对连续变量提出的。 622 | 623 | # Lec 15 624 | 625 | 连续信道。最具代表性的一种:高斯信道。 626 | 627 | 如果是时间离散信道,我们认为输出是输入和噪声的和(废话)。噪声符合标准正态分布。 628 | 629 | 最主要的限制一般是能量限制。 630 | 631 | 对于码字的长度,我们一般限制为: 632 | 633 | $$ 634 | {1\over n}\sum_{i=1}^n x_i^2\leq P 635 | $$ 636 | 637 | 高斯信道的信道容量为$C=\max_{f(x)\leq EX^2\leq P}\leq I(X;Y)$ 638 | 639 | 记噪声的方差为$N$,则 640 | 641 | $C={1\over 2}\log(1+{P\over N})$ 642 | 643 | 我们可以认为,每一个码字附近可以看做一个超球体。因为噪声符合标准正态分布,所以有很高的概率,接收端的信息在发出内容的球体附近。 644 | 645 | 我们希望,我们的小球之间彼此并不相交。 646 | 647 | 高斯信道的定义:我们认为所有事件在一个事件集内。事件和编码存在一一映射。满足上述的性质,存在解码函数。如果接收方接收的信息落在了唯一球体中,那么OK。否则,则认为出错。 648 | 649 | 平行高斯信道:多个高斯信道,并且它们的噪声是不同的。我们希望知道,在这种情况下的信道容量是多大。 650 | 651 | $C=\max_{f(x_1,x_2,...,x_k)\leq E\sum x_i^2\leq P}I(X_1,...,X_k;Y_1...,Y_k)$ 652 | 653 | # Pre by Stargazer 654 | 655 | 考虑一个二元序列,两个符号出现的概率分别为5%、95%。在这种情况下进行Huffman编码,就是没有压缩。 656 | 657 | 考虑算术编码。 658 | 659 | Byte Pair Encoding 660 | 661 | 把一些出现频率高的视作同一个词元,从而进行压缩。 662 | -------------------------------------------------------------------------------- /others/Linear Algebra(Addition).md: -------------------------------------------------------------------------------- 1 | # 向量空间拾遗 2 | 3 | ## 组(list)和长度(length)的定义 4 | 5 | 设$n$是**非负整数**。我们称$n$个有顺序的元素是一个长度为$n$的组,表示为$(x_1,...,x_n)$。两个组相等当且仅当长度和其中的元素均相等。 6 | 7 | 特殊地,我们称长度为2的组是有序对(pair),长度为3的组是有序三元组(triple)。所有的组一定是有限长度的,因为$n$是非负整数。长度为0的组也是可以的。 8 | 9 | 组中的元素**可以重复**,是**有序的**。 10 | 11 | ## $F^n$的定义 12 | 13 | $F^n$是F中元素组成的长度为n的组的集合。我们称这个组中的第j个元素为这个组的第j个坐标。 14 | 15 | ## 域的性质 16 | 17 | 对域定义的两种运算满足交换律和结合律。存在乘法单位元和加法单位元。存在加法逆元,对于非0元素存在乘法逆元,满足数乘的分配律。 18 | 19 | ## $F^S$的定义 20 | 21 | 令$S$是一个集合,我们用$F^S$表示S到F的所有函数的集合。 22 | 23 | 也就是说,每一个F中的n元组,我们可以将其视为一个$[n]\to F$的函数。 24 | 25 | ## 子空间的和 26 | 27 | 我们首先需要定义子集的和。子集的和,定义为在每一个子集中挑选出一个元素,将其相加所能得到的所有的和所构成的集合。 28 | 29 | 子空间的和依旧是子空间。并且,它们的和是包含这些子空间的**最小子空间**。 30 | 31 | ## 直和 32 | 33 | $$ 34 | 若U_1+...+U_m中的每一个元素可以唯一表示为\\ 35 | u_1+...+u_m,其中u_j\in U_j,那么称这样的子空间和为直和。\\ 36 | 记作U_1\oplus ...\oplus U_m 37 | $$ 38 | 39 | 子空间之间的和是直和,当且仅当0表示为$u_1+...+u_m$时,每一个$u_j$都等于0。 40 | 41 | 两个子空间之间的和是直和,当且仅当两个子空间的交集中只有0。 42 | 43 | # 有限维向量空间拾遗 44 | 45 | 多项式是一个向量空间。 46 | 47 | 多项式$p$的次数:系数不为0的最高项的次数,记作$deg(p)$规定恒等于0的多项式次数为$-\infin$。 48 | 49 | 我们用$P_m(F)$表示系数在$F$中并且次数不超过$m$的所有多项式构成的集合。$P(F)$表示系数在$F$中的所有多项式构成的集合。 50 | 51 | 对于有限维的向量空间$V$而言,对于$\forall$子空间$U$,$\exist$子空间$W,s.t.V=U\oplus W$ 52 | 53 | $$ 54 | \dim(U_1+U_2)=\dim U_1+\dim U_2 -\dim(U_1\cap U_2) 55 | $$ 56 | 57 | # 线性映射拾遗 58 | 59 | 定义:$L(V,W)$表示$V$到$W$的所有线性映射的集合。这是一个线性空间。 60 | 61 | 零空间(核)的定义,指的是$T\in L(V,W),V$中被$T$映射为$0$的向量子集。remark:考虑矩阵时,把矩阵看做是线性映射。 62 | 63 | 零空间是V的子空间。 64 | 65 | 像是W的子空间。 66 | 67 | 当齐次线性方程组中,变量数多于方程时,齐次线性方程组一定有非零解。 68 | 69 | remark:我们可以把它考虑成一个矩阵,并且列数多于行数。那么零空间的维数一定不为0。 70 | 71 | 一个线性映射是可逆的,当且仅当它是双射。它的逆是唯一的。 72 | 73 | 同构,指的就是可逆的线性映射。如果两个向量空间之间存在一个同构,那么这两个向量空间是同构的。$F$上的两个有限维向量空间同构,当且仅当其维数相同。 74 | 75 | 我们定义,向量空间到自身的线性映射称为**算子**。 76 | 77 | $L(V)$表示$V$上全体算子所组成的集合。 78 | 79 | 假设$V$是有限维,$T\in L(V)$。若$T$是单射(满射),则$T$是可逆的。 80 | 81 | 我们定义,向量空间$V_1,V_2,...,V_m$的积$V_1\times V_2\times ...\times V_m=\{(v_1,...,v_m):v_i\in V_i\}$ 82 | 83 | 向量空间的积也是个向量空间。 84 | 85 | 向量空间积的维数显然等于各向量空间的维数之和。 86 | 87 | 定义$\tau(u_1,...,u_m)=u_1+...+u_m$则$U_1+...+U_m$是直和当且仅当$\tau$为单射。 88 | 89 | 设$V$是有限维的,$U_1,...,U_m$均为$V$的子空间。则$U_1+...+U_m$是直和当且仅当$\dim(U_1+...+U_m)=\sum_{i=1}^m\dim U_i$ 90 | 91 | 我们定义$v+U=\{v+u:u\in U\},U\subset V,v\in V$ 92 | 93 | 我们称$V$的形如$v+U$的子集为$V$的仿射子集。仿射子集$v+U$平行于$U$。remark:这里的平行需要注意维数的问题。 94 | 95 | 设$U\subset V$,商空间$V/U$指$V$所有的平行于$U$的仿射子集的集合。即$V/U=\{ v+U : v\in V\}$ 96 | 97 | 平行于$U$的两个仿射子集要么相等,要么不相交。 98 | 99 | 商空间上的加法和标量乘法比较特殊。 100 | 101 | $$ 102 | (v+U)+(w+U)=(v+w)+U\\ 103 | \lambda(v+U)=(\lambda v)+U 104 | $$ 105 | 106 | 商空间也是个向量空间。 107 | 108 | 设$U$是$V$的子空间,商映射$\pi:\pi(v)=v+U$ 109 | 110 | $\dim V/U=\dim V-\dim U$ 111 | 112 | $T\in L(V,W)$,定义$\tilde T:V/ null(T)\to W,\tilde T(v+null(T))=T(v)$ 113 | 114 | 我们定义$V$上的线性泛函是$V\to F$的线性映射。 115 | 116 | $V$上的所有线性泛函构成的向量空间称为$V$的对偶空间,记作$V'$。 117 | 118 | 若$V$是有限维的,对偶空间的维数与原空间维数相同。 119 | 120 | 对偶基是对偶空间的一组基。 121 | 122 | 若$T\in L(V,W)$,$T$的对偶映射是$T'\in L(W',V')$,若$\phi\in W',T'(\phi)=\phi\circ T$ 123 | 124 | $(ST)'=T'S'$,对偶映射的其他运算是平凡的。 125 | 126 | 零化子的定义:$U\subset V,U^0=\{\phi\in V':\forall u\in U,\phi(u)=0\}$ 127 | 128 | $null(T')=(range\ T)^0$ 129 | 130 | $U^0$是$V$的子空间。并且,$\dim U+\dim U^0=\dim V$ 131 | 132 | $T$满射,等价于$T'$单射。 133 | 134 | $\dim range (T')=\dim range(T)$ 135 | 136 | $M(T')=(M(T))^T$ 137 | 138 | 转置和对偶之间有很大的相关性,行秩等于列秩。 139 | 140 | # 多项式 141 | 142 | $p,s\in P(F),s\not=0,\exist !q,r\in P(F),s.t.\\ p=sq+r,\deg r < \deg s$ 143 | 144 | 多项式$s\in P(F)$是$p\in P(F)$的因式$iff\ \exist q\in P(F),s.t.p=sq$ 145 | 146 | 多项式的每个零点对应一个一次因式。 147 | 148 | 多项式零点个数不超过多项式次数。 149 | 150 | 实系数多项式的非实零点**成对**出现。 151 | 152 | # 本征值、本征向量、不变子空间 153 | 154 | ## 不变子空间 155 | 156 | $$ 157 | T\in L(V),U\subset V,iff\forall u\in U,Tu\in U 158 | $$ 159 | 160 | 则称$U$在$T$下不变。 161 | 162 | 接下来,考虑一维(不包括$Z$)的不变子空间。就有$Tv=\lambda v$ 163 | 164 | 这里,我们就得到了特征值(本征值)。$v$就是特征向量。 165 | 166 | 当$U$是$V$下的不变子空间时,我们做出如下定义: 167 | 168 | 限制算子:$T|_U\in L(U),T|_U(u)=Tu,u\in U$ 169 | 170 | 商算子:$T/U\in L(V/U),(T/U)(v+U)=Tv+U,v\in V$ 171 | 172 | 我们定义$T^m\in L(v),m\in N,T^0=I,T^m=TTT...T,T^{-m}=(T^{-1})^m$ 173 | 174 | $T\in L(V),p\in P(F),z\in F,p(z)=a_0+a_1z+...+a_mz^m.\\ p(T)=a_0I+a_1T+...+a_mT^m$ 175 | 176 | $pq(T)=p(T)q(T)=qp(T)=q(T)p(T)$ 177 | 178 | 所以,算子的任意两个多项式是交换的。 179 | 180 | 复向量空间上,每个算子一定有特征值。这是代数学基本定理确定的。 181 | 182 | 对于复向量空间上的每个算子,存在一组基,使得算子对应的矩阵是上三角矩阵。 183 | 184 | 设$T\in L(V),v_1,...,v_n$是$V$的基,则以下条件等价: 185 | 186 | $$ 187 | T对应矩阵为上三角矩阵\\ 188 | \forall j\in[n],span(v_1,...,v_j)在T下不变\\ 189 | $$ 190 | 191 | 如果$T\in L(V)$关于$V$的某个基有上三角矩阵,则矩阵可逆当且仅当对角线上元素都不为零。在这种上三角矩阵中,特征值就是对角线上的元素。也就是,0不是它的特征值。 192 | 193 | 特征空间的定义已经知道了。若$V$是有限维,$T\in L(V)$,互异的特征值$\lambda_1,\lambda_2,...,\lambda_m$对应的特征空间的和是直和。 194 | 195 | $T\in L(V)$可对角化,当$T$关于$V$的某个基有对角矩阵。也就是说,它的特征向量构成一组基。 196 | 197 | # 内积空间 198 | 199 | 范数的定义:$||x||=\sqrt{}$ 200 | 201 | 内积的抽象定义: 202 | 203 | $$ 204 | u,v\in V,(u,v)\to F\\ 205 | \geq0\\ 206 | =0\iff v = 0\\ 207 | =+\\ 208 | <\lambda u,v>=\lambda\\ 209 | =\overline {} 210 | $$ 211 | 212 | 欧几里得内积: 213 | 214 | $$ 215 | <(w_1,...,w_n),(z_1,...,z_n)>=w_1\bar {z_1}+...+w_n\bar {z_n} 216 | $$ 217 | 218 | 内积空间,就是带有内积的向量空间。 219 | 220 | 故,$||v||=0\iff v=0\\ \forall \lambda\in F,||\lambda v||=|\lambda|||v||$ 221 | 222 | 两个向量正交,iff$=0$ 223 | 224 | $||\leq||u||||v||$ 225 | 226 | $||u+v||\leq||u||+||v||$ 227 | 228 | $||u+v||^2+||u-v||^2=2(||u||^2+||v||^2)$ 229 | 230 | 标准正交的向量组 231 | 232 | 向量可以写成标准正交基的线性组合 233 | 234 | $\dim(V)<\infin,T\in L(V),T$关于$V$的某个标准正交基有上三角矩阵。 235 | 236 | 里斯表示定理:$\dim(V)<\infin,\phi\in L(V,F),\exist!u\in V,s.t.\forall v\in V,\phi(v)=$ 237 | 238 | 证明方式:正交分解 239 | 240 | $if\ U\subset V,\dim(U)<\infin,V=U\oplus U^\perp$ 241 | 242 | $if\ U\subset V,\dim(U)<\infin,U=(U^\perp)^\perp$ 243 | 244 | 定义正交投影$P_U$ 245 | 246 | $$ 247 | U\subset V,\dim(U)<\infin,P_U\in L(V)\\ 248 | v\in V,v=u+w,u\in U,w\in U^\perp,P_Uv=u 249 | $$ 250 | 251 | 到子空间距离最小的问题 252 | 253 | # 内积空间上的算子 254 | 255 | 伴随的定义:$T\in L(V,W),T^*:W\to V,\forall v\in V,\forall w\in W \\ =$ 256 | 257 | 伴随定义的合理性来源于里斯表示定理。当$w$给定时,$$是一个线性泛函。所以,$\exist!u\in V,s.t.=,u=T^*w$ 258 | 259 | $T\in L(V,W),T^*\in L(W,V)$ 260 | 261 | $(S+T)^*=S^*+T^*$ 262 | 263 | $(\lambda T)^*=\bar\lambda T^*$ 264 | 265 | $(T^*)^*=T$ 266 | 267 | $I^*=I$ 268 | 269 | $(ST)^*=T^*S^*$ 270 | 271 | $$ 272 | null(T^*)=(range T)^\perp\\ 273 | range(T^*)=(nullT)^\perp\\ 274 | nullT=(range(T^*))^\perp\\ 275 | rangeT=(null(T^*))^\perp 276 | $$ 277 | 278 | 共轭转置的定义是符合直觉的。 279 | 280 | $T\in L(V,W),T^*\in L(W,V)$,在基相同的前提下,二者的矩阵互为共轭转置。 281 | 282 | 定义了伴随的概念,我们可以定义**自伴性(厄米特性)**:$T=T^*$ 283 | 284 | 也就是说,自伴算子对应的每个矩阵的特征值都是实数。 285 | 286 | $$ 287 | F=C,iff\ T\in L(V),T:V\to0,\forall v\in V,=0\\ 288 | F=C,iff\ T\in L(V),T\ is\ self-adjoint,\forall v\in V,\in R 289 | $$ 290 | 291 | $$ 292 | if\ T=T^*,\forall v,=0,then\ T=0 293 | $$ 294 | 295 | 我们在这里可以定义**正规的(normal)**:$T\in L(V),iff\ TT^*=T^*T$ 296 | 297 | $T\ is\ normal\iff\forall v,||Tv||=||T^*v||$ 298 | 299 | 如果$T$是正规的,那么$T$和$T^*$有相同的特征向量。 300 | 301 | 正规算子的线性独立的特征向量相互正交。 302 | 303 | 复谱定理:下述三条等价 304 | 305 | $$ 306 | F=C,T\in L(V)\\ 307 | 1)T\ is\ normal.\\ 308 | 2)V\ has\ a\ basis\ consisted\ of\ orthonormal\ eigenvectors.\\ 309 | 3)T\ has\ a\ diagonal\ matrix\ with\ an\ orthonormal\ basis. 310 | $$ 311 | 312 | 实谱定理 313 | 314 | 二次式可逆性: 315 | 316 | $$ 317 | T\in L(V)\ is\ self-adjoint,b,c\in R,b^2<4c\\ 318 | T^2+bT+cI\ is\ invertible.\\ 319 | Because\ (T^2+bT+cI)v\not=0,that\ implies\ it's\ injective. 320 | $$ 321 | 322 | $T\in L(V)\ is\ self-adjoint,U\subset V$,$U$在$T$下不变,那么$U^\perp$在$T$下亦不变;$T|_U\in L(U),T|_{U^\perp}\in L(U^\perp)$均是自伴的。 323 | 324 | 下述三条等价: 325 | 326 | $$ 327 | F=R,T\in L(V)\\ 328 | 1)T\ is\ self-adjoint.\\ 329 | 2)V\ has\ a\ basis\ consisted\ of\ orthonormal\ eigenvectors.\\ 330 | 3)T\ has\ a\ diagonal\ matrix\ with\ an\ orthonormal\ basis. 331 | $$ 332 | 333 | $$ 334 | T\in L(V)是正的\iff T\ is\ self-adjoint,\forall v\in V,\geq0 335 | $$ 336 | 337 | $$ 338 | if\ U\subset V,P_U\ is\ a\ positive\ operator.\\ 339 | if\ T\in L(V)\ is\ self-adjoint,b ^2-4c<0,then\\ 340 | T^2+bT+cI\ is\ positive. 341 | $$ 342 | 343 | 我们可以定义算子的平方根:$R$是$T$的平方根$\iff R^2=T$ 344 | 345 | 正算子有多种刻画的方式。若$T\in L(V)$,则下列条件等价。 346 | 347 | $$ 348 | T\ is\ a\ positive\ operator.\\ 349 | T\ is\ self-adjoint\ and\ all\ the\ eigenvalues\ of\ M\geq0\\ 350 | T\ has\ a\ positive\ square\ root.\\ 351 | T\ has\ a\ self-adjoint\ square\ root.\\ 352 | \exist R\in L(V),s.t.T=R^*R 353 | $$ 354 | 355 | 每个正算子只有唯一的正平方根。 356 | 357 | $S\in L(V)$是等距同构$\iff \forall v\in V,||Sv||=||v||$ 358 | 359 | 在实内积空间上的等距同构,我们称之为**正交算子**,复内积空间上的等距同构,我们习惯性称之为**酉算子**。 360 | 361 | $S\in L(V)$,则以下条件是等价的。 362 | 363 | $$ 364 | S是等距同构。\\ 365 | \forall u,v\in V,=\\ 366 | if\ e_1,...,e_n\ are\ orthonormal\\ 367 | Se_1,...,Se_n\ are\ orthonormal\ too.\\ 368 | S^*S=I\\ 369 | SS^*=I\\ 370 | S^*是等距同构。 371 | S\ is\ invertible,S^{-1}=S^* 372 | $$ 373 | 374 | 考虑复内积空间上的等距同构的描述。 375 | 376 | $$ 377 | S是等距同构\iff V\ has\ an\ orthornormal\ basis\ consisted\\ 378 | of\ all\ the\ eigenvectors,and\ each\ eigenvalue\ equals\ to\ \underline + 1 379 | $$ 380 | 381 | **极分解** 382 | 383 | $$ 384 | T\in L(V),\exist S\in L(V)为等距同构,s.t.\ T=S\sqrt{T^*T} 385 | $$ 386 | 387 | $$ 388 | T\in L(V),T's\ singular\ values\ are\ the\ eigenvalues\ of\ \sqrt{T^*T} 389 | $$ 390 | 391 | $$ 392 | T\in L(V)\ has\ singular\ values\ s_1,...,s_n,\\ 393 | V\ has\ two\ orthronormal\ bases\ e_1,...,e_n\ and\ f_1,...,f_n,s.t.\\ 394 | \forall v\in V,Tv=s_1f_1+...+s_nf_n 395 | $$ 396 | 397 | 或者,奇异值可以这样描述 398 | 399 | $$ 400 | T\in L(V),T's\ singular\ values\ are\ the\ non-minus\ square\\ 401 | roots\ of\ T^*T's\ eigenvalues,with\ \dim(E(\lambda,T^*T))\ times\ repetations. 402 | $$ 403 | 404 | # 复向量空间上的算子 405 | 406 | 显然有: 407 | 408 | $$ 409 | T\in L(V),\{0\}=null\ T^0\subset\ null\ T^1\subset\ ...\\ 410 | if\ \exist m\in N^+,null\ T^m=null\ T^{m+1},then\\ 411 | null\ T^m=null\ T^{m+1}=null\ T^{m+2}=... 412 | $$ 413 | 414 | $$ 415 | T\in L(V),n=\dim(V),null\ T^n=null\ T^{n+1}=null\ T^{n+2}=... 416 | $$ 417 | 418 | 零空间是会停止增长的。 419 | 420 | 因为,在每一个严格包含的关系处,空间的维数至少会增加1。 421 | 422 | $$ 423 | V=null\ T^{\dim V}\oplus range\ T^{\dim V} 424 | $$ 425 | 426 | 在这里,我们需要引入广义特征向量的概念。 427 | 428 | $T\in L(V),\lambda$是$T$的特征值,$v\in V$称为$T$相应于$\lambda$的**广义特征向量**,$v\not=0,\exist j\in N^+,s.t.(T-\lambda I)^jv=0$ 429 | 430 | 我们相应地,也可以定义广义特征空间,$G(\lambda,T)$。 431 | 432 | $T\in L(V),\lambda \in F$,$T$相应于$\lambda$的广义特征空间定义为$T$相应于$\lambda$的所有广义特征向量的集合,包括$0$。 433 | 434 | 对于广义特征空间,我们有这样的表示方式: 435 | 436 | $$ 437 | T\in L(V),\lambda\in F,G(\lambda,T)=null(T-\lambda I)^{\dim V} 438 | $$ 439 | 440 | 广义特征向量具有这样的特点。 441 | 442 | $$ 443 | T\in L(V),\lambda_1,...,\lambda_m\ are\ distinct\ eigenvalues,\\ 444 | v_1,...,V_m\ are\ generalized\ eignvectors,then\\ 445 | they\ are\ linearly\ independent. 446 | $$ 447 | 448 | 考虑到我们现在一直在研究幂算子,我们可以引入幂零(nilpotent)这个概念。 449 | 450 | 一个算子是**幂零**的$\iff\exist j\in N^+,T^j=0$ 451 | 452 | $N\in L(V)$是幂零的,则$N^{\dim V}=0$ 453 | 454 | 如果$N$是幂零的,那么$V$中存在一组基,使得它的矩阵不仅是上三角的,而且对角线上所有元素均为0。 455 | 456 | 在定义了广义特征向量之后,我们就可以考虑对算子进行分解了。 457 | 458 | $T\in L(V),p\in P(F)$,则$null\ p(T),range\ p(T)$在$T$下不变。 459 | 460 | $V$是复向量空间,$T\in L(V)$,$\lambda_1,...,\lambda_m$为不同特征值,则: 461 | 462 | $$ 463 | V=G(\lambda_1,.T)\oplus...\oplus G(\lambda_m,T)\\ 464 | G(\lambda_j,T)在T下不变\\ 465 | (T-\lambda_jI)|_{G(\lambda_j,T)}均是幂零的。 466 | 467 | $$ 468 | 469 | 所以,当$V$是复向量空间,$T\in L(V)$,V有一个由广义特征向量所组成的基。 470 | 471 | $T\in L(V),T$的特征值$\lambda$的重数定义为相应的广义特征空间$G(\lambda,T)$的维数,即$\dim null(T-\lambda I)^{\dim V}$ 472 | 473 | 由于上述中,广义特征空间的直和构成整个空间,所以重数之和显然等于$\dim V$ 474 | 475 | 此处的重数,与代数重数值相同。但是,几何重数指的是特征空间的维数。 476 | 477 | 若$V$是复向量空间,$T\in L(V),\lambda_1,...,\lambda_m$是$T$的所有不同的特征值,重数分别为$d_1,...,d_m$,那么存在一个基,使得$T$关于这组基有分块对角矩阵。并且,每一个块状矩阵都是$d_j\times d_j$的上三角矩阵。 478 | 479 | $N\in L(V)$是幂零的,那么$(I+N)$有平方根。 480 | 481 | $V$是复向量空间,$T\in L(V)$若是可逆的,那么$T$有平方根。 482 | 483 | 我们这样定义$T\in L(V)$的特征多项式。设$T$的特征值为$\lambda_1,...,\lambda_m$,重数分别为$d_1,...,d_m$,则其特征多项式称为$(z-\lambda_1)^{d_1}...(z-\lambda_m)^{d_m}$ 484 | 485 | 设$V$是复向量空间,$T\in L(V)$,$q$是$T$的特征多项式,那么$q(T)=0$ 486 | 487 | 特征多项式的次数恰为$\dim V$,特征多项式的零点恰好是$T$的特征值。 488 | 489 | 考虑到归一化的重要性,我们可以引入首一多项式的概念。即,最高次数的项的系数为1的多项式。 490 | 491 | $T\in L(V),\exist!p,p(T)=0,p$是次数最小的首一多项式。我们把这样的$p$称为$T$的极小多项式。 492 | 493 | 又因为$q(T)=0$,所以$q$是$T$的极小多项式的多项式倍。$T$极小多项式的零点恰好是$T$的特征值。 494 | 495 | 在定义了这些内容之后,我们可以来讨论若尔当型。 496 | 497 | $$ 498 | N\in L(V)是幂零的,\exist v_1,...,v_n\in V,m_1,...,m_n\in N,s.t.\\ 499 | N^{m_1}v_1,...,N^0v_1,...,N^{m_n}v_n,...,N^0v_n是V的基\\ 500 | N^{m_1+1}v_1=...=N^{m_n+1}v_n=0 501 | $$ 502 | 503 | $$ 504 | T\in L(V),V的基称为T的若尔当基if\ T关于这组基有分块对角矩阵\\ 505 | \begin{bmatrix} 506 | A_1&&0\\ 507 | &...&\\ 508 | 0&&A_p 509 | \end{bmatrix}\\ 510 | A_i=\begin{bmatrix} 511 | \lambda_i&1&&0\\ 512 | &...&...&\\ 513 | &&...&1\\\ 514 | 0&&&\lambda_j 515 | \end{bmatrix} 516 | $$ 517 | 518 | 也就是说,通过线性变换,每一个向量映成其前一个向量复合上一定长度的自身。 519 | 520 | # 实向量空间上的算子 521 | 522 | 考虑$V$是一个实向量空间,我们定义其**复化**为$V\times V$,其元素是有序对$(u,v)$,$u,v\in V$我们不妨将其写作$u+iv$ 523 | 524 | $V\subset V_C$,$V_C$显然是复向量空间。 525 | 526 | 如果$v_1,...,v_n$为$V$作为实向量空间的一组基,那么它们也是$V_C$作为复向量空间上的一组基。$V$和$V_C$维数相等。 527 | 528 | 根据空间的复化,我们类似地,也可以定义算子的复化。$V$是实向量空间,$T\in L(V)$,$T$的复化定义为$T_C(u+iv)=Tu+iTv,T_C\in L(V_C)$ 529 | 530 | $T_C$的矩阵显然等于$T$的矩阵,二者选取的基相同。 531 | 532 | 每一个算子都有一维或者二维的不变子空间。 533 | 534 | $T_C$的极小多项式等于$T$的极小多项式。 535 | 536 | $T_C$的实特征值和$T$的实特征值相同。如果$\lambda\in C$是$T_C$的特征值,那么$\bar\lambda$也是$T_C$的特征值,且重数相同。也就是成对出现。因此,奇数维实向量空间上的算子一定有特征值。同时,$T$的复化$T_C$的特征多项式的系数也都是实数。 537 | 538 | $V$是实向量空间,$T\in L(V)$,则$T$的特征多项式的系数均为实数,次数为$\dim V$,$T$的特征值为特征多项式的所有实零点。 539 | 540 | 在实内积空间上,我们有这样对二维实内积空间正规算子的描述。 541 | 542 | $$ 543 | T正规但不自伴。\\ 544 | T关于V的每个标准正交基的矩阵都有\begin{bmatrix} 545 | a&-b\\ 546 | b&a 547 | \end{bmatrix}的形式,b\not=0\\ 548 | T关于V的某个标准正交基矩阵有\begin{bmatrix} 549 | a&-b\\ 550 | b&a 551 | \end{bmatrix}的形式,b>0 552 | $$ 553 | 554 | 这三个条件是等价的。 555 | 556 | 倘若$V$是内积空间,$T\in L(V)$是正规的,$U\subset V$是$T$下的不变子空间,那么 557 | 558 | $$ 559 | U^\perp在T下不变\\ 560 | U在T^*下不变\\ 561 | (T|_U)^*=(T^*)|_U\\ 562 | T|_U\in L(U)和T|_{U^\perp}\in L(U^\perp)都是正规算子。 563 | $$ 564 | 565 | 实内积空间上,正规算子可以这样刻画: 566 | 567 | $$ 568 | V的某个标准正交基使得T关于这个基有分块对角矩阵\\ 569 | 每个块要么是1\times 1矩阵,要么是形如\begin{bmatrix} 570 | a&-b\\ 571 | b&a 572 | \end{bmatrix}的2\times2矩阵,b>0 573 | $$ 574 | 575 | 实内积空间上,等距同构可以这样刻画: 576 | 577 | $$ 578 | V的某个标准正交基使得T关于这个基有分块对角矩阵\\ 579 | 每个块要么是由1或-1构成的1\times 1矩阵,\\要么是形如\begin{bmatrix} 580 | \cos\theta&-\sin\theta\\ 581 | \sin\theta&\cos\theta 582 | \end{bmatrix}的2\times2矩阵,\theta\in(0,\pi) 583 | $$ 584 | 585 | # 迹与行列式 586 | 587 | 算子的迹为按重数重复的全部特征值之和。其等于特征多项式中$z^{\dim V -1}$系数的相反数。 588 | 589 | 方阵的迹定义为对角线的元素之和。$trace(AB)=trace(BA)$ 590 | 591 | 算子的迹与基的选取无关,其迹与矩阵的迹相同。 592 | 593 | 迹具有可加性。 594 | 595 | 算子的行列式是按照重数重复的全体特征值之积。 596 | 597 | 行列式等于特征多项式中的常数项乘上$(-1)^{\dim V}$ 598 | 599 | $T$的特征多项式等于$\det(zI-T)$ 600 | 601 | 行列式具有可乘性。 602 | 603 | $|\det T|=\det\sqrt{T^*T}$ 604 | -------------------------------------------------------------------------------- /others/Machine_Learning_Compilation.md: -------------------------------------------------------------------------------- 1 | # Machine Learning Compilation 2 | 3 | ## Lec 1 4 | 5 | ### Why MLC? 6 | 7 | For applications, we need a broad coverage. 8 | 9 | At now, we may need run our model on many different systems. 10 | 11 | #### Machine Learning Deployment Problem 12 | 13 | The problem is the gap between intelligent applications and deployment environments. 14 | 15 | The environments are much more diverse now. We must consider the hardware, OS and so on. 16 | 17 | To solve the problem, we start to consider MLC. 18 | 19 | ### What's MLC? 20 | 21 | MLC is the procession that transform the development form(pytorch e.g.) to the deployment form(API interface ...). 22 | 23 | ### MLC Goal 24 | 25 | - Integration and Dependency Minimization 26 | 27 | - Leverage Hadrware Native Acceleration 28 | 29 | - Optimization in General 30 | 31 | ### Some remarks 32 | 33 | MLC may not involve code generation. 34 | 35 | Deployment form may also need training. 36 | 37 | ### Reason to study MLC 38 | 39 | - Build ML Demplyment Solution 40 | 41 | - In-depth Understanding of Existing Frameworks 42 | 43 | - Builld Software Stack for Emerging Hardware 44 | 45 | - Have fun 46 | 47 | ### Key Elements in MLC 48 | 49 | Tensor and Tensor functions 50 | 51 | **Kernel Fusion**(算子融合) to reuduce the calculation time. 52 | 53 | Abstraction and Implementation 54 | 55 | Higher abstracion is implemented by lower abstracion 56 | 57 | The implementation of a higher abstraction can be seen as a lower abstraction, which leads to more chance to optimize. 58 | 59 | ## Lec 2 Tensor Program Abstraction 60 | 61 | ### Primitive Tensor Function 62 | 63 | Primitive tensor functions can be seen as the single units of computational operation. 64 | 65 | e.g. torch.add is a primitive tensor function. 66 | 67 | Problem: How to implement a primitive tensor function? 68 | 69 | #### some feasible approches 70 | 71 | - remap to library calls(e.g. cuda) 72 | 73 | - fine grained program transformation 74 | 75 | ### Tensor Program Abstraction 76 | 77 | #### Key Elements of a Tensor Program 78 | 79 | - **buffers** to holds data 80 | 81 | - **Loop nests** to compute 82 | 83 | - **Computations** 84 | 85 | #### Why TPA? 86 | 87 | Carefully design -> better performance. 88 | 89 | - Loop Splitting 90 | 91 | - Loop Reordering 92 | 93 | - Thread Binding 94 | 95 | primitive tensor functions usually don't allocate memory to save time. 96 | 97 | ## Lec 3 98 | 99 | In numpy, `a @ b` = `np.matmul(a, b)` 100 | 101 | low-level numpy: 102 | 103 | - use a loop instead of array functions when necessarey 104 | 105 | - explicitly allocate arrays via numpy.empty and pass them around 106 | 107 | `np.testing.assert_allclose(A: np.ndarray, B:np.ndarray, rtol: float32)` is used to check whether the values of two ndarray are the same. 108 | 109 | In matmul, spatial axis will appear in the output as an axis, while reduce axis will disappear. These information sometimes can help do optimization. 110 | 111 | TensorIR 112 | 113 | ## Lec 4 114 | 115 | The view of computational graph 116 | 117 | `call_tir` : used for purify functions 118 | 119 | destination pass: destination will be seen as a para provided for functions. 120 | 121 | pure function and side effectful 122 | 123 | `dataflow()`: used to indicate the codes of a computational graph 124 | 125 | ## Lec 5 126 | 127 | Problem:Sometimes we can't determine which factor is proper. 128 | 129 | Solution:Use a stochastic method. 130 | 131 | Idea: Only focus on the most important part. 132 | 133 | ## Lec 6 134 | 135 | tensor expression 136 | 137 | how to optimize models from pytorch 138 | 139 | torchfx module 140 | 141 | ## Lec 7 142 | 143 | Some global memory may be used by several threads. A solution is to read these data once, and transport them in shared memory.(cooperative fetching) 144 | 145 | ## Lec 8 146 | 147 | specialized hardware 148 | 149 | - special store 150 | 151 | - special operator(tensor intrinsic) 152 | 153 | - some copy 154 | 155 | tensorization 156 | 157 | # 158 | -------------------------------------------------------------------------------- /others/Natural Language Processing.md: -------------------------------------------------------------------------------- 1 | # Lec 1 2 | 3 | 由于词的数量过大,所以独热编码是不合适的。我们将词表征为一个实值多维向量,用来表征词与词之间的联系性。这被称为单词嵌入。 4 | 5 | word2vec算法。对于每一个中心词,去预测哪些词语更有可能出现在上下文中。这一点是通过词向量的点积实现的。每个词有两个词向量,一个是作为中心词的,一个是作为非中心词的词向量。将中心词的向量与所有词作点积,并进行softmax,得到结果。在高维空间中,词会在不同的维度上相互靠近。 6 | 7 | # Lec 2 Word Vectors, Word Senses, and Neural Network Classifiers 8 | 9 | 在词向量的基础上,我们需要考察如何得到好的词向量。所以要进行梯度下降优化。首先,将词向量初始化为接近0的随机向量。 10 | 11 | 简单的梯度下降算法显然是不合适的。因为量太大了。所以SGD常常被使用到。 12 | 13 | 神经网络在一定条件下是**反直觉的**。 14 | 15 | 在随机梯度下降的过程中,梯度更新的矩阵对象是很稀疏的。 16 | 17 | note:大多数词向量在torch等中都表示为行向量。 18 | 19 | 为什么给一个单词对应两种不同情况下的单词向量?因为如果只有一个向量,文本窗中出现了两次这个单词,就会引入二次项,不利于优化的计算。 20 | 21 | ## skip-gram model with negative sampling 22 | 23 | 问题:在计算朴素的softmax函数时,必须要遍历词表,计算之。 24 | 25 | 这里,简单地解决方法就是把softmax换成sigmoid。并且,将损失函数的计算改为随机取样K个词。 26 | 27 | $$ 28 | J=-\log\sigma(u_o^Tv_c)-\sum_{k\in K}\log\sigma(-u_k^Tv_c) 29 | $$ 30 | 31 | 这个损失函数在直觉上,就是用一种粗略的方法去模拟softmax进行的工作。也就是说,我们希望正确的事情,点积比较大。错误的比较小,从而等价于softmax后的结果。 32 | 33 | ## Co-occurrence vectors 34 | 35 | 共现向量是巨大而又稀疏的。 36 | 37 | **SVD**,并且删除那些作用较小的一些奇异值,从而降低维度。也就是类似于截断SVD(也许就是?)的方法。 38 | 39 | 同类类比过程中,向量值大小方向相近。 40 | 41 | 考察词语的共现比率。 42 | 43 | 我们如何能够得到它们的共现比率,并且使之具有线性化特征? 44 | 45 | 目标:拟合$w_i\cdot w_j=\log P(i|j)$ 46 | 47 | 也就是说,我们通过点积这种运算来拟合了共现概率。 48 | 49 | Note:看到有其他采用互信息的方法进行构建的词向量(PMI),看上去更加合理。即考察: 50 | 51 | $$ 52 | \frac{P(x,y)}{P(x)P(y)} 53 | $$ 54 | 55 | ## word vector evaluation 56 | 57 | 两种,内部的和外部的评估。 58 | 59 | 内部评估,比如考虑单词类比这种类型。 60 | 61 | ## word senses and word sense ambiguity 62 | 63 | # Lec3: Gradients by hand and algorithmically 64 | 65 | 例子:命名实体识别(NER) 66 | 67 | ## Matrix Calculas 68 | 69 | Jacobian矩阵。 70 | 71 | $$ 72 | f(x)=[f_1(x_1,...,x_n),...,f_m(x_1,...,x_n)]\\ 73 | (\frac{\partial f}{\partial x})_{i j}=\frac{\partial f_i}{\partial x_j} 74 | $$ 75 | 76 | 在反向传播的过程中,根据链式法则,有很多东西,我们不必**重复计算**。 77 | 78 | 因为根据Jacobian矩阵的定义,如果我们只有一个输出,考虑对$W$进行优化,那么我们得到的Jacobian矩阵应该是一个$(1,mn)$形状的矩阵。不利于我们进行优化。所以,我们要对Jacobian矩阵进行变形。 79 | 80 | ## Backpropagation 81 | 82 | 玉川有一个不成熟的想法。在取ReLu为激活函数的时候,那些数值基本都没有更新。我们能不能改善这一点,加快模型的更新速度? 83 | 84 | 反向传播和正向传播应当有相同的时间复杂度。 85 | 86 | 自动微分:利用的就是反向传播算法。对每一个节点进行拓扑排序,之后可以得到结果。显然,我们需要先进行正向传播,才可以进行反向传播。 87 | 88 | 梯度下降不是万能的。 89 | 90 | # Lec 4 91 | 92 | ## linguistic structure 93 | 94 | 词性,和限定词(determiners) 95 | 96 | phrase structure grammars:最小单位由词变为了短语。 97 | 98 | phrase的构建 99 | 100 | constituency grammars:上下文无关的语法。就是那种短语结构的方式。句子不会影响短语本身。 101 | 102 | dependency grammars:依存于句子结构之上的语法。 103 | 104 | 在近二十年,dependency grammars更加被使用。简单地说,他的思路就是要考察,每一个词语,有多大程度上去修饰了某一个对象。使用通用依赖关系中,我们认为介词依存于之后的中心名词,然后再次构成短语。 105 | 106 | 问题在于,短语之间的依存关系可能具有一定的歧义。 107 | 108 | 同时,自然语言中还有一个常见的语义歧义是作用范围的模糊。 109 | 110 | 依赖关系应当构成**一棵树**。 111 | 112 | 依赖关系箭头绘制是,由被依赖对象(head)指向依赖词(dependent)。 113 | 114 | Treebanks:语法库。个人的理解,就是一个标的还不错的数据集。 115 | 116 | 依赖关系怎么判断: 117 | 118 | - 依赖词和被依赖词本身 119 | 120 | - 距离 121 | 122 | - 一般依赖关系不会跨越动词或者标点 123 | 124 | - 被依赖对象的配价(即考虑词性本身的特点。比如你不会在cat后面添加一个the之类的) 125 | 126 | 在解析过程中,我们会添加一个root标记,使得只有一个词从属于root。然后,我们不希望在处理过程中产生回环。 127 | 128 | 如果在投影弧都在句子上方,并且没有产生交叉,那么我们就称,这杨的一个句子解析是一个投影解析。 129 | 130 | ## trainstion-based dependency parser 131 | 132 | parser由$\sigma$堆栈,右侧为顶;$\beta$队列,左侧为顶;依赖弧集合$A$,和一系列shift和reduce动作构成。 133 | 134 | 首先: 135 | 136 | $$ 137 | \sigma=\text{root},\beta=w_1,...,w_n,A=\empty\\ 138 | 139 | $$ 140 | 141 | 然后,我们有三种动作可以选择: 142 | 143 | 1. shift:$\sigma.\text{push}(\beta.\text{pop()})$ 144 | 145 | 2. Left-Arc-reduce:$A.\text{insert}(r(\sigma.\text{top}, \sigma.\text{second})),\\ \text{res}=\sigma.\text{top}\\\sigma.\text{pop}(),\sigma.\text{pop}()\\ \sigma.\text{push}(\text{res})$ 146 | 147 | 3. Right-Arc-reduce:$A.\text{insert}(r(\sigma.\text{second}, \sigma.\text{top})),\sigma.\text{pop}()$ 148 | 149 | 直到$\beta=\empty$ 150 | 151 | 其中,二元组前者为head,后者为dependent。 152 | 153 | 我们要保证经过reduce操作后,head依旧在stack中。 154 | 155 | # Lec 5 156 | 157 | 句法依存分析下特征的问题:稀疏和不完整性,并且计算代价高昂。 158 | 159 | 单词嵌入。 160 | 161 | 词性标签和依赖标签。 162 | 163 | 深度学习分类器是非线性的分类器。 164 | 165 | 这些是为什么要采用深度学习作词法依赖解析器的原因。 166 | 167 | 对于单词,在输入之前,我们要用独热编码,找到词及其词性的特征向量作为输入。 168 | 169 | 另一种词法依赖解析器是基于图的词法依赖解析器。也就是考虑每一对词之间,它们之间存在某一项解析关系的概率。问题在于,复杂度是二次项级别的,比较慢。 170 | 171 | 最经典的正则化显然是L2,现在暂退的使用也很多,可能是目前最好的方法。暂退的好处在于,可能L2会对不同的参数产生不同的约束强度,从而降低对某些特征的识别。 172 | 173 | 暂退可以避免特征联合效应。 174 | 175 | 使用向量,矩阵,张量,而不是循环。 176 | 177 | 单纯的线性层叠加,可以视作是一个线性变换。 178 | 179 | $$ 180 | \text{tanh}(x)=2\text{logistic}(2x)-1\\ 181 | \text{hardtanh}(x)=x,x\in [-1, 1];-1,x<-1;1, x>1 182 | $$ 183 | 184 | ReLU应该是目前激活函数中的首选。 185 | 186 | 参数初始化:在**几乎所有**情况下,必须要用小的随机值去初始化参数。因为如果是全零矩阵,那么就是对称的情况,学不到很特殊的内容。但偏置设置为0是无伤大雅的,可能是更好地方案。 187 | 188 | Xavier初始化:该层的初始化方差为$\frac{2}{n_{in}+n_{out}}$ 189 | 190 | 一般而言,使用SGD结果还可以。但是,需要考虑学习率。如果使用Adam,它是自适应的,效果可能更不错。 191 | 192 | 在训练过程中,尽量对训练集进行shuffle,避免使模型陷入一种周期律的幻想当中。 193 | 194 | ## Language Modeling 195 | 196 | 预测下一个单词是什么。 197 | 198 | n-gram Language Models 199 | 200 | 非常简单。思想就是收集每一个不同大小的词块出现的概率。 201 | 202 | 我们首先进行马尔科夫假设,即假定下一个词的概率仅和之前的n-1个词语有关。 203 | 204 | 这样的问题在于,我们很多时候在数据集中找到这样的对象。所以并不是很好。一种方式是给每一个词语在该条件下添加一个增量$\delta$.而且,可能前n-1个词语的序列亦未曾出现,我们就要考虑缩短我们依赖的单词数。 205 | 206 | RNN的好处在于,模型可以学习到序列性的信息,并且可以充分运用已有的文本。 207 | 208 | # Lec 6 209 | 210 | "Teacher forcing" 211 | 212 | 我们的损失计算,在每一步长中,我们只预测一个单词,并对这个单词进行惩罚。但是,如果模型选择的输出不够好,我们选择采用**语料库**中的输入继续训练。 213 | 214 | 在朴素循环神经网络中,我们不能在反向传播中即修改$W_h$ 215 | 216 | 为了能从零开始生成一个句子,我们可以添加一个开始标记,将其作为第一个输入,投喂给RNN。 217 | 218 | 模型好坏的评判:困惑度(perplexity) 219 | 220 | $$ 221 | \prod_{t=1}^T(\frac{1}{P_{LM}(x^{(t+1)}|x^{(t)},...,x^{(1)})})^{\frac{1}{T}} 222 | $$ 223 | 224 | 等价于指数形式下的交叉熵损失。 225 | 226 | RNN可用于预测下一个词的词性,可以**识别句子的情绪**。 227 | 228 | 我们考虑一个矩阵,如果它的所有特征值都小于一,我们取其特征向量为一组基,求梯度后需要对特征值取次方,所以可能使得梯度消失。 229 | 230 | 类似的,也会有梯度爆炸的问题。所以,我们可以给梯度更新设定一个上限值。 231 | 232 | LSTM不能完全解决梯度消失和爆炸的问题。但总体好得多。 233 | 234 | 实际上,现在LSTM也开始被Transformer取代了。 235 | 236 | 残差神经网络,也是为了解决长距离梯度消失的问题导致的。 237 | 238 | DenseNet,HighwayNet 239 | 240 | # Lec 7 241 | 242 | ## Pre-Neural Machine Translation 243 | 244 | 在1990~2010之间,基本是采用统计学方法。即根据大量的平行语料,计算条件概率。 245 | 246 | 如何根据平行语料去计算条件概率?我们要引入一个**对齐变量**,从而确保每一个单词(短语)二元组之间有着合理的对应关系。对齐关系可是多对多的。 247 | 248 | 机器需要学习这些对齐关系。对齐变量也是个潜在的变量。 249 | 250 | 翻译过程的选择公式: 251 | 252 | $$ 253 | \text{argmax}_yP(x|y)P(y) 254 | $$ 255 | 256 | 其中,y是我们翻译的结果,x是待翻译的对象。这是根据贝叶斯公式导出的,等价于$P(y|x)\cdot1$ 257 | 258 | 上式中,前一个条件变量由一个翻译模型控制,后一个由我们构造的一个目标语言模型控制。 259 | 260 | 在翻译过程中,我们将句子拆成一个个部件,如积木一般。然后将其都尝试一下,看看组成句子的概率是不是够高。然后,挑选较高的几组选择。 261 | 262 | 这样的模型很复杂,并且包含了很多人类智慧。 263 | 264 | ## Neural Machine Translation 265 | 266 | seq2seq模型 267 | 268 | 包含两个RNN。一个将源句子进行编码。剩下一个则是根据中间状态,将其解码为目标语言。 269 | 270 | 在解码过程中,我们也要用teacher forcing方式进行训练。 271 | 272 | s2s可以做很多事情。比如概括,比如对话,比如语法解析、比如代码生成等等等 。 273 | 274 | s2s会从零开始,搭建一个句子。 它是一种条件语言模型。 275 | 276 | 多层RNN(stacked RNN) 277 | 278 | 对于编码器,2~4层为佳;对于解码器,4层更好。 279 | 280 | 如果想要更多的层数,我们需要跳过层(残差层之类)和稠密层来保证深度较高的情况下的效果。 281 | 282 | 解码的算法:第一种,贪心法。但显然不是很好。我猜可能采用束搜索之类的方法?(诶嘿,猜对了) 283 | 284 | 束搜索的停止:时间步达到上限,或者已经有一定个完成的假设答案。 285 | 286 | 显然,如果序列更长,它的得分大概是会下降的。处理这个问题的方式,是将得分对长度进行归一化。 287 | 288 | 神经网络的训练更快,更流利,对文本的运用更好,对短语相似性的利用更好。作为一个整体的神经网络系统,对这样端对端系统进行优化可能是较好的。 289 | 290 | 但问题是解释性差,不容易被控制。 291 | 292 | 使用BLEU来对机器翻译进行评分。对句子进行人工翻译,根据机器翻译和人工翻译之间的相似性评分。比如n-gram准确性,对过短的翻译给惩罚。但显然,一个句子可以有多种翻译方式,BLEU并不是非常准确。 293 | 294 | 无人称指代时,系统会带有偏见。这样当时数据集本身所导致的。 295 | 296 | ## attention 297 | 298 | s2s中的问题:必须将原有句子转化为一个隐状态。 299 | 300 | 解决方法:每一级RNN和当前编码器状态得到一个注意力得分,明白大概要把注意力放在哪里。 301 | 302 | # Lec8 Self-Attention and Transformers 303 | 304 | ## Self-Attention 305 | 306 | issue:线性交互距离可能过长。 307 | 308 | GPU尽管可以并行计算,但在多层RNN中,有一些严格的拓扑序,影响了并行性。计算时间复杂度为$O(n)$ 309 | 310 | attention考察把每个单词的表示视作是一个询问。 所以,它可以解决长线性交互距离,和并行性计算的问题。 311 | 312 | 具体细节:将一个单词嵌入,然后和询问矩阵相乘得到询问向量,和键值矩阵相乘得到键值向量,和值矩阵相乘得到值。 313 | 314 | 然后,计算询问和所有键值之间的相似性。 315 | 316 | 一种方式,是和所有点积,然后求softmax 317 | 318 | 但是,这样忽略了位置的信息。所以,我们可以为每一个句中编号添加一个位置向量,用来进行指示。只需要在第一次输入时修饰这些嵌入向量以位置向量即可。 319 | 320 | 位置向量是一个d维的向量。对于位置向量,表示方式是$p_{2n}=\cos(i/10000^{n/d}),p_{2n-1}=\sin(i/10000^{n/d})$ 321 | 322 | 但是这样效果不是很好。 323 | 324 | 目前一种更可行的方式,可能是考虑一个$d\times n$的矩阵,用它来转换信息。其中,n是最长的句子。也就是说,不能有超过n的句子。(但这个问题应该不是很难解决?) 325 | 326 | 为了提高准确性,可以通过MLP和self-attention的结合。 327 | 328 | 在解码器过程中进行self-attention,我们需要保证我们不会**预知未来**。需要给那些未来的单词添加掩码。对那些未来的点积,强制计算为-INF。 329 | 330 | ## Transformers 331 | 332 | 最重要的一个差别之一:使用多头注意力层。multi-head self-attention. 333 | 334 | 首先,令$X$为序列嵌入向量的合并。 335 | 336 | $XQ(XK)^T$实际上就是在计算得分。 337 | 338 | 我们假设有$h$个注意力头,令$Q_i,K_i,V_i\in\R^{d\times\frac{d}{h}},i\in\{1,...,h\}$ 339 | 340 | 对于每一部分,我们单独地应用self-attention。输出为$\text{softmax}(XQ_iK_i^TX^T)*XV_i$ 341 | 342 | 让每一部分的输出进行列连结,再乘上一个矩阵$Y\in\R^{d\times d}$,得到最后的总输出。它的想法是让每一个头关注一部分,然后共同作用得到一个结果。 343 | 344 | scaled dot product:如果向量维数d比较多,那么点积可能会比较大,通过softmax之后,导致梯度会比较小,降低学习的效率。所以,将原有的输出改为 345 | 346 | $$ 347 | \text{softmax}(XQ_iK_i^TX^T/\sqrt {d/h})*XV_i 348 | $$ 349 | 350 | 在Transformers架构中,经过多头注意力后,会有一个残差层,然后会进行层归一化。层归一化,指的是计算层间所有值的平均值$\mu$,计算标准偏差$\sigma$,记输入为$x$,额外三个常数$\epsilon,\gamma,\beta$,那么输出为$\frac{x-\mu}{\sqrt\sigma +\epsilon}*\gamma+\beta$ 351 | 352 | # Lec9 Pretraining 353 | 354 | 过去,将未见过的单词全部映射到UNK这个token上。 355 | 356 | byte-pair压缩算法:可以以每一个字母为单位,作为初始值。每一次,合并语料中出现的,相邻概率最高的两个token将会被合并,直到词表规模达到我们想要的情况。会尝试选择数量最少的子词来表示一个单词。 357 | 358 | ## language modeling 359 | 360 | 通过之间说的方式进行预训练一个基本的预测模型。之后,在我们自己的问题和任务上进行微调(finetune)。留下Transformer,去掉最后一个线性层,重新训练之。 361 | 362 | 目前这种方式的优势原理还没有很好的解释。目前的说法还是非常直觉化的。 363 | 364 | Encoder不可以直接用于语言建模。因为这会提前暴露下文。使用屏蔽的方法,去构建上下文表示,屏蔽大部分随机的单词。 365 | 366 | ## BERT 367 | 368 | Masked LM 4 BERT:随机预测约15%的token。选择大部分进行mask操作,部分不变,部分随机替换为其他单词。 369 | 370 | ## finetune 371 | 372 | 第一种,是全盘接受网络的参数。 373 | 374 | 第二种,是对参数进行轻量级的优化。 375 | 376 | 一种方式是进行前缀微调,prefix-tuning,也就是在网络前加入一些新的前缀可学习参数。 377 | 378 | 一种方式可进行low-rank adaptation,即控制学习的内容是一个低秩的矩阵。 379 | 380 | ## encoder-decoder 381 | 382 | Input中进行一定的mask,在输出的时候尝试输出结果。 383 | 384 | ## decoder 385 | 386 | decoder只能看到当前的情况,不可以看到之后的信息。 387 | 388 | # Lec10 389 | 390 | zero-shot and few-shot 391 | 392 | chain-of-thought 393 | 394 | COT比少量样本的作用大得多。 395 | 396 | 指令微调 397 | 398 | RLHF 399 | 400 | # Lec11 Neural Language Generation 401 | 402 | NLU&NLG 403 | 404 | 不同NLG任务的自由度不同。非开放式生成(机器翻译之属),开放式生成(故事生成等)。 405 | 406 | 非开放式生成,一般采用encoder-decoder架构。encoder可以是一个双向LSTM,decoder可以是一个autoregressive LSTM。 407 | 408 | 开放式生成可能不太适合用这种方式去解决。开放式生成存在一定的自放大效应,即对一些token不断重复之后,导致错误结果的连续出现。从另一个方面想,这说明模型学习了这种重复。一种解决方式是禁止n-grams的短暂阻塞。更好的方式,是在函数训练阶段即降低这种情况的得分。 409 | 410 | 利用束搜索,来始终挑选概率最高的字符串作为输出并不是一个非常好的方式。因为如人类那般,生成的文本会有比较大的概率波动。一种方式是在decoder中引入一定的随机性。 411 | 412 | 策略是使用top-k sampling,选择概率最高的一部分。 413 | 414 | 更好的方式:top-p samping, 相当于根据分布,动态地调整k的值,可以设定一个概率的阈值下界。 415 | 416 | 需要注意的是,基于n-gram方式进行计算重叠度量并不是一种好的方法。 417 | 418 | # Lec12 Question Answering 419 | 420 | # Lec13 Coreference Resolution 421 | 422 |   Coreference Resolution,指的是识别出段落中所有的指代。 423 | 424 | split antecedents:比如they的指代关系。 425 | 426 | 发现指代、分配指代。 427 | 428 | Coreference:共指,两个指代指向同一个实体。 429 | 430 | Anaphora:回指,一个指代依赖于之前出现过的指代,二者指代对象相同。 431 | 432 | Bridging Anaphora:一个指代依赖于之前出现过的指代,但是该指代的对象并非前一指代的对象,而是前一指代对象的某一部分或延伸附属等。 433 | 434 | 解决方法: 435 | 436 | 1、规则解析(Hobbs' naive algorithm) 437 | 438 | 基于现实知识的改进 439 | 440 | 2、指代对 441 | 442 | 3、神经网络(end-to-end) 443 | 444 | 4、BERT 445 | 446 | # Lec14 Connections Between NLP and Linguistics 447 | 448 | ## Language Structure 449 | 450 | grammaticality 451 | 452 | e.g:英语中的SVO order 453 | 454 | syntactic rules and lexicion 455 | 456 | new word with similiar structure(phonotactics) 457 | 458 | 英语中的doer-patient结构 459 | 460 | Multilinguality 461 | 462 | # Lec15 Knowledges 463 | 464 | 模型会产生错误的合理回答。 465 | 466 | 原因可能是模型未见过,或少见;也有可能是因为对语气过于敏感。 467 | 468 | 传统知识图:主体、客体、关系。 469 | 470 | entity linking 把问题中的实体连接到对应的真正实体。,也就是进行entity embedding 471 | 472 | 实体嵌入的方法有指示图嵌入(knowledge graph embedding) 473 | 474 | 词-实体共现(word-entity co-occurrence) 475 | 476 | Transformer 477 | 478 | KGLM:Local LG 局部的知识图。 479 | 480 | kNN-LM:Nearest Neighbor Language Models 481 | 482 | WKLM 483 | 484 | How to evaluate knowledge in LM 485 | 486 | # Lec16 Multimodality 487 | 488 | 多类型的输入 489 | 490 | McGurk effect("ba" and "fa") 491 | 492 | 不同数据来源的信息。 493 | 494 | Bag of visual words 495 | 496 | skip-gram 497 | 498 | GAN 499 | 500 | 特征化图片 501 | 502 | Multimodal foundation models 503 | 504 | # Lec17 Model Analysis and Explanation 505 | 506 | 模型推理不同逻辑下的问题: 507 | 508 | 1、词法分析重叠(如主动、被动间的推理关系会出错) 509 | 510 | 2、子序列(如短语修饰的名词后跟动词) 511 | 512 | 3、组成(如假设关系中的前提条件) 513 | 514 | 带有引诱物的测试集 515 | 516 | # Lec18 The future of NLP and DL 517 | 518 | 人类语言在一定程度上具有合成性。 519 | -------------------------------------------------------------------------------- /others/Operating_System.md: -------------------------------------------------------------------------------- 1 | # 操作系统 2 | 3 | ## Lec 1 4 | 5 | ### 为什么学操作系统? 6 | 7 | 学任何东西的原因:**重走从无到有的发现历程** by JYY 8 | 9 | 概念的产生的动机,基本方法,弯路... 10 | 11 | 应用、创新、革命 12 | 13 | 操作系统的动机:更快更好地服务更多应用 14 | 15 | 操作系统的基本方法: "Building Abstractions" 16 | 17 | ### 学习操作系统能得到什么? 18 | 19 | - 了解一些原理,比如窗口如何创建、 Ctrl+C 为什么有的时候不能退出程序等等。 20 | 21 | - 能够实现平常用的一些东西。 22 | 23 | ### 什么是操作系统 24 | 25 | 操作系统是**管理软/硬件资源、为程序提供服务**的程序。 26 | 27 | 计算机硬件: 28 | 29 | - 极简的公理系统(时钟,导线,逻辑门等等) 30 | 31 | - 可以支持非常复杂的电路设计 32 | 33 | 在本课程中,可以认为操作系统是硬件和软件的中间层。 34 | 35 | 计算机硬件的发展需求操作系统 36 | 37 | 1950-1960: 磁芯内存 38 | 39 | 1950s - 1960s 的操作系统:库函数和管理程序排队运行的调度代码。操作系统的概念大概从这里形成。因为这个时候计算机还很贵,需要人工给小卡片来输入... 40 | 41 | 1960s - 1970s 的操作系统:能载入多个程序到内存并且调度它们的管理程序。防止程序之间互相干扰。 42 | 43 | 本节课的主要概念在 70 年代就形成了。 44 | 45 | ## Lec 2 应用视角的操作系统 46 | 47 | - 什么是程序? 48 | 49 | - 如何在操作系统上构造程序? 50 | 51 | - 编译器的原理是什么? 52 | 53 | 处理器是状态机 54 | 55 | problem: 程序为什么可以停下来?计算机为什么可以关机? 56 | 57 | 给操作系统发送 syscall 58 | 59 | 所有的程序也都是状态机 60 | 61 | 操作系统上的应用程序 62 | 63 | 提问 64 | 65 | `strace` 用于追踪程序的进行 66 | 67 | 操作系统的职责就是管理和提供舒适的 API 68 | 69 | C 语言也是一种状态机 70 | 71 | 递归和非递归 72 | 73 | Problem: 怎么用状态表示递归函数? 74 | 75 | 那么,我们到底该如何定义状态? 76 | 77 | 状态:栈帧(含 PC )+全局变量 78 | 79 | 函数调用:放入一个栈帧 80 | 81 | 函数返回:弹出一个栈帧 82 | 83 | 编译器优化 84 | 85 | 不改变语义:系统调用的操作完全相同 86 | 87 | 外部调用是不可优化的 88 | 89 | systemcall 真的不可优化? 90 | 91 | ## Lec 3 硬件视角的操作系统 92 | 93 | CPU reset 94 | 95 | Firmware:配置计算机系统 96 | 97 | Firmware 的作用: 98 | 99 | - 进行计算机系统配置,比如 CPU 电压,接口的开关等等... 100 | 101 | - 加载操作系统 102 | 103 | 早期时,是 BIOS(Basic I/O System) 104 | 105 | Firmware 通常都是只读的 106 | 107 | UEFI 108 | 109 | 在 40 年前, Firmware 会读取前 512 Byte 到 0x7c00, 只要这 512 Byte 最后是 0x55 和 0xAA 110 | 111 | 再扣除掉 64 Byte 的分区表,共有 446 字节可以供程序员进行修改。 112 | 113 | ## Lec 4 数学视角的操作系统 114 | 115 | “严格性” 116 | 117 | 程序是一种数学严格的对象 118 | 119 | Everything is a state machine! 120 | 121 | 严格性给我们带来的 insights 122 | 123 | - 写一些 `assert` 124 | 125 | - 容易阅读 126 | 127 | - 容易验证 128 | 129 | 用数学方法理解操作系统? 130 | 131 | 操作系统就是状态机的管理者 132 | 133 | - 进程 134 | 135 | - 系统调用 136 | 137 | - 上下文切换 138 | 139 | - 调度 140 | 141 | 计算机系统中的不确定性 142 | 143 | - 调度:选择哪个状态机? 144 | 145 | - I/O: 系统外的输入不确定 146 | 147 | 状态图 148 | 149 | ## Lec 5 多处理器编程 150 | 151 | ### 多线程编程模型 152 | 153 | 独立的“栈帧”和共享的“内存”。 154 | 155 | 状态迁移:挑选一个线程走一步。 156 | 157 | 简易化的模型: 158 | 159 | - `spawn(fn)`:用于创建一个入口函数是 `fn` 的线程,并且开始执行。行为是 `sys_spawn(fn, tid)` 160 | 161 | - `join()`: `while(done != T) sys_sched()` 用于等待所有运行线程的返回。 162 | 163 | OS 会自动把线程放在不同的处理器上。从而 CPU 使用率可以超过 100% 164 | 165 | 线程具有独立的栈区。栈区大小有上限,但是我们可以调整。 166 | 167 | ### 并发编程的放弃点:状态迁移原子性的假设 168 | 169 | 共享内存使得原子性假设不再成立。 170 | 171 | 几乎所有尝试在共享内存上实现原子性的实现都是错的。直到 Dekker's Algorithm, 其可以保证两个线程的互斥。 172 | 173 | ### 并发编程的放弃点:程序顺序执行的假设 174 | 175 | 编译器可能也会进行一定的优化 176 | 177 | ### 并发编程的放弃点:全局指令顺序的假设 178 | 179 | 处理器也可以看做是一种编译器 180 | 181 | 不同处理器可能看到不同的共享内存 182 | 183 | ## Lec 6 并发控制:互斥(1) 184 | 185 | 并发编程困难的原因:推翻了顺序执行的基本假设 186 | 187 | ### 互斥 188 | 189 | 这样可以把指定的多次状态迁移转化为一次大的状态迁移,再次回到人类擅长的领域。 190 | 191 | Gustafson's law: $T_p < T_{\infin}+\frac{T_1}{p}$ 192 | 193 | 计算上,我们可以进行并行。因为经典物理中也是有局部性原理的! 194 | 195 | 如何实现互斥? 196 | 197 | ### 关中断 198 | 199 | 在一段时间上禁止中断,就实现了互斥的效果 200 | 201 | 处理器也有一些不可屏蔽中断(Non-Maskable Interrupts, NMI) ,比如电源坏了等等。 202 | 203 | 普通的应用程序不具有关中断的权利。 204 | 205 | 中断是在每个处理器上独享的。因此需要更多的方式。 206 | 207 | ### Peterson's Algorithm 208 | 209 | 实现假设: 210 | 211 | - 任何时候都可以执行一条 load/store 指令 212 | 213 | - 读写本身是原子的 214 | 215 | 若想进入临界区,则: 216 | 217 | 1. store 本线程的 flag 218 | 219 | 2. store 临界区的权限设定为对方线程所有 220 | 221 | 然后,进入观察模式: 222 | 223 | 1. load 对方线程 flag 224 | 225 | 2. load 临界区权限是谁 226 | 227 | 如果对方线程 flag 为 0, 或者临界区权限是自己,那么进入临界区。 228 | 229 | 出临界区时,则:store 本线程 flag 为 0. 230 | 231 | Tree of Thoughts 232 | 233 | 但是在现在多处理器的内存模型中,实际的 Peterson 算法就不再正确了! 234 | 235 | 在现在想要实现,那么就需要加上 barrier 236 | 237 | 并且,这个模型针对的是两个线程。 238 | 239 | ### 多处理器上的互斥实现 240 | 241 | “闭着眼睛贴”和“睁着眼睛看” 242 | 243 | 软件不够,硬件来凑! 244 | 245 | **原子指令** 246 | 247 | **自旋锁** 248 | 249 | 原子交换 250 | 251 | 如果持锁线程发生中断,自旋锁又会发生什么? 252 | 253 | ## Lec 7 并发控制:互斥(2) 254 | 255 | - safety: 在处理器上正确。并且如果一个线程持有锁,其他线程不可返回。 256 | - liveness: 多个线程执行 `lock` 时,至少有一个可以返回。 257 | 258 | ### 操作系统内核的自旋锁 259 | 260 | 问题在于,任何一个 CPU 都可以发生中断。如果在持锁期发生中断,可能就死锁了。 261 | 262 | 实现的方式:关中断+自旋锁 263 | 264 | 在关中断过程中不可以随意打开中断,也不能随意关闭中断。因此,需要额外去保存中断状态。 265 | 266 | Problem: 在哪里保存中断状态? 267 | 268 | ### Read-Copy-Update 269 | 270 | 自旋锁的问题:并发量过大时,性能下降严重。 271 | 272 | 许多对象具有 read-mostly 的特点。 273 | 274 | 每次在更新的时候,创建一个新的变量。在访问时,通过一个指针来访问。当修改完成后,把指针修改为指向新变量。 275 | 276 | 当所有的 CPU 进行一次线程的切换后,那么就可以把旧变量回收掉了。 277 | 278 | ### 应用程序与互斥锁 279 | 280 | 自旋的后果: 281 | 282 | - 自选会导致空转 283 | 284 | - 应用程序不可以关中断 285 | 286 | 解决的方式:既然只能空转,不然切换到其他线程做别的事情。 `syscall` 287 | 288 | #### futex: fast userspace mutexes 289 | 290 | - fash path:自旋成功,那么进入临界区。 291 | 292 | - slow path:自旋失败,给系统发出信号,假装自旋一下。 293 | 294 | ## Lec 8 调试理论 295 | 296 | 有时我们的代码正确了,但是编译器可能帮我们优化错了! 297 | 298 | 有的时候需要添加 **compiler barrier** 299 | 300 | 并发 bug 的触发也需要运气,有的时候甚至还需要特定的硬件( 301 | 302 | 初学者最好用保证正确的实现() 303 | 304 | ### bug 和 debug 305 | 306 | 1. 机器永远是对的 307 | 308 | 2. 未测代码永远是错的 309 | 310 | 需求 $\to$ 设计 $\to$ 代码(Fault/bug) $\to$ 执行(Error) $\to$ 失败(Failure) 311 | 312 | 如果我们能判断任意状态的正确性,那么给定一个 failure, 我们可以二分查到第一个 error,这里就是 fault 的产生。 313 | 314 | 但问题我们怎么判断?? 315 | 316 | 调试的过程,就是观察状态机执行的某个方面。 317 | 318 | 两种基本工具: print 和 gdb 319 | 320 | 一切都可以调试! 321 | 322 | 操作系统怎么“看到”内部的问题? 323 | 324 | `strace` : 追踪系统调用 325 | 326 | `perf`:状态机采样 327 | 328 | 大部分工具也存在日志可以查询! 329 | 330 | gdb cheat sheet 331 | 332 | - 还是要写好的代码:需求和设计;不言自明;不言自证。 333 | 334 | - 并且应该要做好测试工作 335 | 336 | - 多写 assert 337 | 338 | ## Lec 9 并发控制:同步(1) 339 | 340 | 同步的作用:使得多个随时间变化的量在变化过程中保持一定的关系。 341 | 342 | 即系统到达某个互相已知的状态。 343 | 344 | 第一种方式:自旋等待同步条件成立。 345 | 346 | ### 生产者-消费者问题 347 | 348 | - Prodecer(生产数据):如果缓存区有空位,就放入;否则等待。 349 | 350 | - Consumer(消费数据):如果缓冲区有数据,取走;否则等待。 351 | 352 | 当条件成立时,不可以放弃互斥锁,直接进行操作。实际上,也就是进行了 double check. 353 | 354 | 使用自旋是很通用简单的方式,但效率很难说。 355 | 356 | **条件变量** 357 | 358 | `cond_wait(&cv, &lk)`: 目前在等待条件变量 `cv` ,如果不成立,就放弃锁 `lk`. 线程进入睡眠状态。 359 | 360 | ```cpp 361 | mutex_lock(&mutex); 362 | while(!cond) { 363 | wait(&cv, &mutex); 364 | } 365 | assert(cond); 366 | ... 367 | cv_broad(&cv); 368 | mutex_unlock(&mutex); 369 | ``` 370 | 371 | ### 并行编程 372 | 373 | 只要计算任务可以构成一个有向无环图,并且我们有一个调度者分配任务的效率足够高,算法就可以并行计算。 374 | 375 | ## Lec 10 并发控制:同步(2) 376 | 377 | ### 信号量 378 | 379 | 用互斥锁来实现?每创造一个锁,就获得它。 380 | 381 | acquire-release 382 | 383 | 信号量: mutex + happens-before + 允许多个持有。 384 | 385 | ```cpp 386 | void Acquire(sem_t *sem) { 387 | atomic { 388 | wait_until(sem->count > 0) { 389 | sem->count--; 390 | } 391 | } 392 | } 393 | void Release(sem_t *sem) { 394 | atomic { 395 | sem->count++; 396 | } 397 | } 398 | ``` 399 | 400 | 比如: `join()` 401 | 402 | 信号量的好处在于不用 `notify_all()` ,但问题在于有的时候难以实现。 403 | 404 | ### 三种手段的对比 405 | 406 | 信号量: mutex 的自然推广,比较干净。 407 | 408 | 条件变量:万能,但是不干净。 409 | 410 | 条件变量是神( 411 | 412 | lock ordering 413 | 414 | 可以用信号量实现条件变量。 415 | 416 | ## Lec 11 真实世界的并发编程 417 | 418 | web 1.0: 静态刷新 419 | 420 | web 2.0: 允许后台刷新 421 | 422 | web 网页如果发出了多个请求,就会有并发问题了。 423 | 424 | 异步——回调函数 425 | 426 | Solution: event-based concuerrency 427 | 428 | 允许创建计算节点(fetch, timer...), 但是禁止计算节点之间并行,只是以事件为单位进行调度。 429 | 430 | callback hell 431 | 432 | 高性能计算 433 | 434 | 物理世界的空间局部性 435 | 436 | ```cpp 437 | #pragma omp parallel num_threads(nthread) 438 | #pragma omp for schedule(static) 439 | ``` 440 | 441 | 高性能计算中散热可能更麻烦了( 442 | 443 | 数据中心中的并发 444 | 445 | 长期的维护工作和高吞吐的请求 446 | 447 | 协程:和线程类似。但是它会一直执行,直到 `yield()` 才可以放弃 CPU. 448 | 449 | Goroutine: 线程和协程的混合。只要发现有很长延迟的操作,如 `sleep` 等等时,把这些操作异步掉,即进行 `yield()`. 450 | 451 | go 中的类管道 452 | 453 | SIMD 454 | 455 | SIMT 456 | 457 | ## Lec 12 并发 bugs 458 | 459 | ### 死锁(deadlock) 460 | 461 | #### AA-Deadlock 462 | 463 | ```cpp 464 | lock(&lk); 465 | ... 466 | lock(&lk); 467 | ``` 468 | 469 | 通过一定的 `assert` 可以排查。 470 | 471 | #### ABBA-Deadlock 472 | 473 | 死锁产生的必要条件 474 | 475 | - Mutual-exclusion 476 | 477 | - Wait-for 478 | 479 | - No-preemption 480 | 481 | - Circular-chain 482 | 483 | 最简单的方式是防止 circular-chain 的发生。 484 | 485 | Lock ordering: 给锁编号。严格按照大小顺序获得锁。 486 | 487 | ### 数据竞争(data race) 488 | 489 | 不同线程访问同一个内存,并且至少有一个是写。 490 | 491 | 这是 UB. 492 | 493 | 上错锁 or 没上锁是最可能得原因。 494 | 495 | ### 原子性和顺序违反 496 | 497 | 代码中被其他操作插入;事件没有按照预定顺序发生。 498 | 499 | ## Lec 13 应对并发 bugs 500 | 501 | 软件危机: 502 | 503 | - 无法写出所有规约 504 | 505 | - 特性的交互组合是指数增长的 506 | 507 | ### 死锁的应对 508 | 509 | lock ordering 510 | 511 | 运行时检查死锁,数据竞争等等。 512 | 513 | 可以为每一个线程取得特定锁和释放特定锁时记录日志,构建图。检查是否有环。 514 | 515 | 对于连续的同一内存,并且没有 happen before 的保证,那么一定会有竞争。 516 | 517 | `-fsanitize=thread` 518 | 519 | AddressSanitizer(asan): 非法内存访问 520 | 521 | ThreadSanitizer(tsan): 数据竞争 522 | 523 | ... 524 | 525 | ### 防御性编程 526 | 527 | 不进行完整的检查,但是实现简单、有用的检查。如 `assert` 528 | 529 | Buffer overrun 530 | 531 | canary: 用一些额外的内存检查访存越界。 532 | 533 | 烫烫烫,屯屯屯,葺葺葺 534 | 535 | ## Lec 14 操作系统上的进程 536 | 537 | 1. CPU Reset 538 | 539 | 2. Firmware 运行 540 | 541 | 3. 加载操作系统 542 | 543 | 4. 操作系统加载第一个进程 544 | 545 | 操作系统初始化阶段会开始加载第一个进程。 546 | 547 | ### fork 548 | 549 | 创建当前进程的一个完整克隆,父进程得到返回值为子进程的进程号,子进程得到的函数返回值是 0. 550 | 551 | 如果失败,调用返回值是 -1 552 | 553 | Fork Bomb: `:(){:|:&};:`, 即: 554 | 555 | ```shell 556 | :(){ 557 | : | : & 558 | };: 559 | ``` 560 | 561 | 由于 fork 之间存在父子关系,所以我们自然构造出了进程树。 562 | 563 | ### execve 564 | 565 | 重置状态机。把当前进程重置成一个可执行文件描述状态机的初始状态。它是唯一一种能够用来执行程序的系统调用。 566 | 567 | 创建新状态机的方式: fork + execve 568 | 569 | ### _exit 570 | 571 | 立即摧毁状态机,但允许有一个返回值。 572 | 573 | 调用 c 语言库中的 `exit(n)` 都是 normal exit. syscall 的 `_exit()` 就不一定了。 574 | 575 | ## Lec 15 进程的地址空间 576 | 577 | RTFM: 进程地址空间以及权限。 578 | 579 | 地址空间就是带有访问权限的内存段。 580 | 581 | Memory Map: 在状态机状态上增加,删除,或修改一段内存(mmap, munmap 等) 582 | 583 | ### 入侵进程地址空间 584 | 585 | e.g gdb, perf... 586 | 587 | 允许一个进程访问指定其他进程的内存? 588 | 589 | Game Genie: 直接添加了一个 Look-up Table(LUT) 590 | 591 | 地址空间中,到底哪一部分才是我们需要修改的内容? 592 | 593 | 按键精灵 `ydotool` 594 | 595 | 大语言模型 + 按键精灵 596 | 597 | 变速齿轮:劫持关于时间的 `syscall` 598 | 599 | 代码注入 600 | 601 | ## Lec 16 系统调用和 UNIX Shell 602 | 603 | UNIX: Everything is a file. 文件描述符就是指向文件的指针! 604 | 605 | Windows 中的 handle(句柄) 606 | 607 | 管道:一个特殊的文件(stream).它有一个读口和一个写口。读口支持 `read`, 写口支持 `write`. 608 | 609 | 命名 pipe 和 匿名 pipe 610 | 611 | 匿名管道创建时会返回读口和写口给对应进程。这一点当 fork 的时候就会派上用场。这可以实现父子进程之间的通信。 612 | 613 | 管道是进程间的一种同步机制。写并非是单纯的写,直到另一端读出数据后才结束。 614 | 615 | ### Shell 616 | 617 | Command-line interface 618 | 619 | UNIX Shell 实际上就是一种编程语言。 620 | 621 | man sh 622 | 623 | 重定向也是先建立管道,再应用 sudo 等等。 624 | 625 | ## Lec 17 C 标准库设计与实现 626 | 627 | C 语言可以看做是系统调用的一层浅封装! 628 | 629 | `musl libc` 630 | 631 | libc 基础功能是实现基础计算的一些封装。 632 | 633 | 系统调用和环境的抽象。 634 | 635 | 动态内存管理 636 | 637 | 在系统中,不太考虑最坏的情况。 638 | 639 | malloc 管理的对象:有小有大。小对象生存周期可长可短。在实现中,一般管理好小对象即可。 640 | 641 | Fast path, Slow path 642 | 643 | ## Lec 18 Linux 操作系统 644 | 645 | Minix 646 | 647 | Linux Kernel 实际也是加载了一个 init 进程。 648 | 649 | update-initramfs: 加载必要的驱动等等,挂载文件系统。 650 | 651 | 抽象是逐层构建起来的。 652 | 653 | systemd 开始配置文件系统。 654 | 655 | ## Lec 19 可执行文件和加载 656 | 657 | ### 可执行文件 658 | 659 | 操作系统中的对象,是一个字节序列,描述了状态机初始状态。 660 | 661 | elf: 不是人类友好的状态机描述。是 Linux 的主要可执行文件格式。 662 | 663 | a.out 功能太少 664 | 665 | 代码、符号、重定位 666 | 667 | 预编译 668 | 669 | ELF: 把多段字节复制到地址空间中,并且赋予对应的一些权限。然后,把 PC 跳转到指定位置。 670 | 671 | ## Lec 20 动态链接和加载 672 | 673 | 实现运行库和应用程序的分离 674 | 675 | 库依赖也是一种代码克隆 676 | 677 | "Dependency hell" 678 | 679 | 如果只有静态链接,那么每次更新都很麻烦( 680 | 681 | 两种实现方式: 682 | 683 | - 加载时完成重定位。问题是没省内存,且解析量大。 684 | 685 | - 编译器生成位置无关代码,调用时要查表。 686 | 687 | 进程地址空间通过分页机制维护出表面连续的假象 688 | 689 | global offset table(GOT):给每一个需要动态链接的符号留下了一个地址的位置。 690 | 691 | 函数调用该怎么处理? 692 | 693 | - 每次调用都查表? 694 | 695 | - 直接把地址写进代码?(可能跳不过去) 696 | 697 | PLT(Procedure Linkage Table):检查是不是在动态链接下生成,小跳大跳解决。 698 | 699 | ## Lec 21 系统调用,中断,上下文切换 700 | 701 | OS = 对象 + API 702 | 703 | `LD_PRELOAD` 704 | 705 | ### 系统调用指令 706 | 707 | syscall: 跳转,并且获得无限的权力 708 | 709 | ### 中断 710 | 711 | 操作系统具有开关中断的权限。 712 | 713 | 中断:封存状态机,然后执行操作系统代码。 714 | 715 | 保存寄存器现场->调度->恢复寄存器现场 716 | 717 | ## Lec 22 进程 718 | 719 | 通过一个地址转化,把 VPN(virtual address) 转换为 PFN(Physical Address). 720 | 721 | virtual page number + offset -> physical page number + offset 722 | 723 | 地址映射实现: 724 | 725 | 内存: Radix Tree(32-bit: 1024 叉树;64-bit: 512 叉树 原因:正好 4kB) 726 | 727 | 处理器: CR3 728 | 729 | Translation-Lookaside Buffer(TLB): 处理器部分 730 | 731 | Inverted Page Table 732 | 733 | 所有进程共享的 hash table, 以虚拟地址和进程号进行 hash 734 | 735 | Demand Paging 736 | 737 | ```cpp 738 | fork(); 739 | if(...) { 740 | execve(); 741 | } 742 | ``` 743 | 744 | 这样很浪费! 745 | 746 | fork() 后直接把父子进程的地址空间标记成只读。如果任一进程决定使用它,那么就复制一份。 747 | 748 | copy on write 749 | 750 | ### UNIX 751 | 752 | Robert Morris 753 | 754 | ## Lec 23 处理器调度 755 | 756 | 操作系统在中断后,可以选择任何进程执行。 757 | 758 | trampoline: 用于状态准备的一小段跳转代码。 759 | 760 | 资源调度? 761 | 762 | 建模,预测,决策 763 | 764 | niceness 765 | 766 | UNIX niceness: 越 nice, 就越同意让其他人获得 CPU 资源。这是很古早的机制了。如果 nice 值相同,会使用公平分享的方式, Round-Robin. 767 | 768 | 动态优先级(MLFQ): 设计了一个带有优先级的队列。如果愿意让出 CPU, 比如 vim 等(在IO),可以变得 nicer 等等。 769 | 770 | 目前的 linux 是 Complete Fair Scheduling,为每个进程运行的时间进行准确记录。 771 | 772 | problem: 互斥怎么办? 773 | 774 | 目前的解决方式:不解决 775 | 776 | signum 777 | 778 | SINGKILL 779 | 780 | ## Lec 25 持久数据存储 781 | 782 | DRAM: 电容 783 | 784 | 持久存储器可以看成是一个巨大的数组,并且允许按照 block 读写。 785 | 786 | 磁带 787 | 788 | 磁鼓 789 | 790 | 磁盘 791 | 792 | 软盘: 读写性能太差了! 793 | 794 | USB, SSD 795 | 796 | ## Lec 26 输入输出设备 797 | 798 | 一根线,一条指令 799 | 800 | IO设备就是一个能和 CPU 交换数据的接口和控制器的集合 801 | 802 | 串口(UART) 803 | 804 | 古早的键盘控制器 805 | 806 | ATA 807 | 808 | SD 卡 809 | 810 | 总线:是一个特殊的 IO 设备。它把设备进行了虚拟化,执行对应的注册和转发。从而 CPU 只要连一根总线即可。目前的是 PCI 总线。 811 | 812 | 中断控制器:收集各个设备的中断,并且选择一个发送给 CPU 813 | 814 | DMA(Direct Memory Access): 只能执行 memcpy 的处理器。 815 | 816 | GPU 817 | 818 | PPU 819 | 820 | ## Lec 27 文件和设备驱动 821 | 822 | ### 文件和文件描述符 823 | 824 | 文件就是有名字的一个对象。 825 | 826 | 文件描述符就是指向操作系统对象的指针。 827 | 828 | 访问文件: syscall 829 | 830 | “虚拟磁盘” 831 | 832 | SIGBUS 833 | 834 | offset 835 | 836 | 文件描述符在 fork 后的行为? 837 | 838 | ioctl 839 | 840 | ## Lec 28 文件系统 841 | 842 | top $\to$ down 的分类 843 | 844 | Windows 中,一个驱动器建立一棵树。 UNIX 和 Linux 则认为万物皆文件。 845 | 846 | UNIX 设计的是目录树进行拼接。 847 | 848 | mount: 把一个目录解析为另一个文件系统的根。 849 | 850 | 回环设备 851 | 852 | mkdir 853 | 854 | rm -rf * 855 | 856 | rmdir 857 | 858 | getdents 返回 count 个目录项 859 | 860 | 硬链接:允许一个文件被多个目录引用 861 | 862 | 软链接:符号链接 863 | 864 | 磁盘上的数据结构 865 | 866 | bread, bwrite 867 | 868 | 链表存储数据 869 | 870 | FAT 871 | 872 | ## Lec 29 873 | 874 | 持久数据 875 | 876 | RAID 877 | 878 | consistency 879 | 880 | 崩溃的一致性 881 | 882 | FSCK 883 | 884 | 日志 885 | 886 | # 887 | -------------------------------------------------------------------------------- /others/Probability.md: -------------------------------------------------------------------------------- 1 | # Lec 1 2 | 3 | 样本空间(sample space):某次实验(experiment)中可能出现的所有结果的集合。 4 | 5 | 事件(event):是样本空间的一个子集。 6 | 7 | **直觉不一定可靠。** 概率论中可能出现不少反直觉的内容。 8 | 9 | 概率的朴素定义: 10 | 11 | $$ 12 | P(A)={\frac{|\text{favorable outcomes}|}{|\text{possible outcomes}|}} 13 | $$ 14 | 15 | 这样做的要求是:每个结果是等可能发生的,并且样本空间大小**有限**。 16 | 17 | 计数: 18 | 19 | 假设进行了$r$次独立实验,每次的结果为$n_i$,那么总共的结果数应当有$\prod_{i=1}^rn_i$ 20 | 21 | 抽样(sampling):是否可重?是否考虑顺序? 22 | 23 | # Lec 2 24 | 25 | 插板法 26 | 27 | story proof 28 | 29 | $$ 30 | \tbinom{n}{k}=\tbinom{n}{n-k}\\ 31 | n\tbinom{n-1}{k-1}=k\tbinom{n}{k}\\ 32 | \tbinom{m+n}{k}=\sum_{j=0}^k\tbinom{m}{j}\tbinom{n}{k-j} 33 | $$ 34 | 35 | 第二个公式:“先选成员,再选谁女装”和“先选谁女装,再选剩下的成员” 36 | 37 | 第三个等式称为Vander恒等式。 38 | 39 | 概率空间(probability space)包含两部分:$S,P$,$S$是样本空间,$P$是一个函数,其定义为$S$,输入为事件$A\sub S$,$P(A)\in[0,1]$ 40 | 41 | $P$应当有$P(\empty)=0,P(S)=1,P(\cup_{n=1}^\infin A_n)=\sum_{n=1}^\infin P(A_n),A_i\cup A_j=\empty,i\neq j$ 42 | 43 | # Lec 3 44 | 45 | 抽屉原理:物体多于抽屉数,必有一个抽屉中有不止一个物体。 46 | 47 | 生日问题 48 | 49 | 一些简单的结论: 50 | 51 | $$ 52 | P(A^C)=1-P(A)\\ 53 | A\sub B\implies P(A)\leq P(B)\\ 54 | P(A\cup B)=P(A)+P(B)-P(A\cap B)\\ 55 | P(A\cup B\cup C)=P(A)+P(B)+P(C)-\\ P(A\cap B)-P(A\cap C)-P(B\cap C) 56 | +P(A\cap B\cap C) 57 | $$ 58 | 59 | 更多的交时亦是如此。正负轮替着出现。 60 | -------------------------------------------------------------------------------- /others/Psychology of Emotion.md: -------------------------------------------------------------------------------- 1 | # 情绪的主观体验及评价 2 | 3 | ## 基本情绪 4 | 5 | Ekman的六种基本情绪:快乐、愤怒、悲伤、惊奇、厌恶、恐惧。 6 | 7 | 恐惧这种情绪比其他情绪都更具有**感染力**。 8 | 9 | 一些基本情绪激活的脑区是**相互重叠**的。 10 | 11 | 厌恶可分为身体厌恶和道德厌恶。前者即**物理**上的厌恶。 12 | 13 | 基本情绪的评价方式就是采用量表进行测量。就是看上去很唐的自我数值评价。 14 | 15 | ## 复合情绪 16 | 17 | 复合情绪可分为依恋性社会情绪、自我意识情绪、自我预期情绪等。 18 | 19 | 爱与依恋被分为激情爱和陪伴爱。前者可能更是我们认知上的爱情。后者可发生在各种人际关系之间,可以是亲人、夫妻、朋友。它属于依恋性社会情绪。 20 | 21 | 自豪与羞耻是两种自我意识情绪。在自我意识情绪理论中,自豪分成了真实自豪和自大自豪,区别在于自豪归因是否为**个体可控**原因。**社会比较**在自豪感产生过程中影响较大。 22 | 23 | 敌意也是一种复合情绪。由情感、认知、行为三部分构成。情感部分包括憎恨、烦恼、生气、蔑视等。敌意是愤怒、厌恶、轻蔑的结合,而愤怒占了最主要的部分。 24 | 25 | 道德情绪也是一种自我意识情绪。 26 | 27 | ## 情绪状态 28 | 29 | 情绪状态可分为心境、激情、应激三种类型。 30 | 31 | 心境的特点是微弱且持久。作为其他心理活动的背景板。 32 | 33 | 激情是短时间且剧烈的情绪体验。由强烈欲望和明显刺激诱发。 34 | 35 | 应激?如其名。应激意外情况下诱发。 36 | 37 | ## 情绪的基本维度 38 | 39 | 愉悦度、唤醒度、支配度、趋向动机。支配度指的是对外界的影响倾向。趋向动机指的是趋向于情绪诱因。 40 | 41 | # 情绪记忆 42 | 43 | ## 记忆绩效 44 | 45 | 负性情绪可以提高记忆的准确性。但是,对于具体的记忆内容而言,正性情绪和负性情绪对其的影响与内容相关。 46 | 47 | 情绪唤醒可能通过注意,从而影响情绪记忆。 48 | 49 | 情绪记忆具有情绪依存性。如果记忆是带有情绪色彩的,那么在情绪相同时,回忆效果会提高。 50 | 51 | 情绪记忆具有心境一致性。类似情绪依存性。只不过将情绪换成了心境。 52 | 53 | # 情绪注意 54 | 55 | 人们更容易关注到负性情绪刺激。这与人类进化的过程是相一致的。 56 | 57 | 人类对情绪性项目的搜索比对中性项目的搜索要更快。情绪性项目对人类的干扰也比中性项目的干扰更强。 58 | -------------------------------------------------------------------------------- /others/Python.md: -------------------------------------------------------------------------------- 1 | # list 2 | 3 | list$\iff$ vector 4 | 5 | 支持下标访问。 6 | 7 | append(x) $\iff$ push_back(x) 8 | 9 | del(i) $\iff$ erase(it) 10 | 11 | pop(i) $\iff$ erase(it) 12 | 13 | pop() $\iff$ pop_back() 14 | 15 | 其中,pop方法有返回值。返回值为被删除的元素。 16 | 17 | remove(x) $\iff$ erase(find(x)) 18 | 19 | insert(i, x) $\iff$ insert(it, x) 20 | 21 | sort:永久排序。 22 | 23 | sorted:暂时性排序。 24 | 25 | reverse:永久反向。 26 | 27 | len() $\iff$ size() 28 | 29 | ```python 30 | items = [1, 2, 3, 4, 5] 31 | for item in items: 32 | print(item) 33 | ``` 34 | 35 | 遍历。 36 | 37 | ```python 38 | numbers = list(range(1,6)) 39 | print(numbers) 40 | ``` 41 | 42 | 这样会输出1,2,3,4,5。以1为begin,6为end。 43 | 44 | ```python 45 | even_numbers = list(range(2,11,2)) 46 | print(even_numbers) 47 | ``` 48 | 49 | 类似地。步长为2,仅此而已。 50 | 51 | 对于数值列表,我们有min,max,sum这些函数。 52 | 53 | 具有和numpy一样的切片规则:从begin到end。 54 | 55 | 在python中,直接进行列表拷贝,不会产生一个新的副本,实际上是对原有列表的一个引用。如果要复制x这个列表,可使用x[:]表示之。 56 | 57 | 元组:使用圆括号的列表。并且长度不可变。 58 | 59 | 在列表中,我们可以使用 60 | 61 | ```python 62 | a = [1, 2, 3] 63 | print(5 in a) 64 | print(6 not in a) 65 | ``` 66 | 67 | 这样的方式可以达到vector中count的效果。 68 | 69 | 列表作为if语句的条件,那么为空的情况下,返回false,否则返回true。 70 | 71 | # 条件判断 72 | 73 | python中具有elif关键字。可以与if连用,也可以和else连用,形成if-elif-else结构。 74 | 75 | # Dictionary 76 | 77 | 在python中,我们使用大括号来表示字典。可以使用类似于cpp中map的方式,即通过下标进行新增键值对。同样的,我们可以通过下标中填入键,从而实现对值的访问。要想删除键值对,我们只需要使用del函数,比如del test['to_delete']即可。to_delete为键值。 78 | 79 | ```python 80 | map = {} 81 | map[0] = 0 82 | map[1] = 1 83 | map[2] = 2 84 | for key, value in map.items(): 85 | ``` 86 | 87 | 使用这样的方式,可以实现对字典的遍历。 88 | 89 | ```python 90 | map = {} 91 | map['a'] = 0 92 | map['b'] = 1 93 | map['c'] = 2 94 | for key in map.keys(): 95 | ``` 96 | 97 | 这样是对键的遍历。 98 | 99 | 需要注意的是,dictionary不同于map,在遍历输出的过程中顺序是不保证的。所以,我们可以使用这样的句子来保证输出的顺序性。字典的键值类型可以是不同的。 100 | 101 | ```python 102 | map = {} 103 | map['a'] = 0 104 | map['b'] = 1 105 | map['c'] = 2 106 | for key in sorted(map).keys(): 107 | ``` 108 | 109 | 类似的,使用values方式,可以实现对值的遍历。 110 | 111 | 在python中,也具有set类型。set可以认为是不可重复的list。 112 | 113 | 在字典中,我们也可以将列表和字典存储在其中。 114 | 115 | # 函数 116 | 117 | python中的函数,除非传入常量,不然都是传址进行操作的。 118 | 119 | ```python 120 | def A(*paras): 121 | ... 122 | ``` 123 | 124 | 使用这样的单星号方式,可以传入不定长的参数。 125 | 126 | ```python 127 | def A(**paras): 128 | ... 129 | ``` 130 | 131 | 使用这样的双星号方式,可以传入不定长的关键字参数。 132 | 133 | ```python 134 | from A import * 135 | ``` 136 | 137 | 使用这样的方式,可以从模块中导入所有的函数。 138 | 139 | # 类 140 | 141 | ```python 142 | def __init(self, A, B): 143 | ... 144 | ``` 145 | 146 | 这是一个默认的方法。可以类比于Cpp中的构造函数。创建实例的时候会自动地进行调用。self类似于Cpp中的this指针,实现了对本身的调用。 147 | 148 | 在定义的过程中,有一点和Cpp中不同。假定类中有一个名为name的成员变量,在Cpp中,我们只需要简单地写name就可以实现对这个成员的使用。但是在Python中,则不可如是。应当使用self.name实现对自身成员变量的调用。 149 | 150 | 在定义成员函数的过程中,一般都会把第一个参数设置为self,从而实现对自身的引用。 151 | 152 | Python中的类依旧可以实现继承。可以使用这样的代码: 153 | 154 | ```python 155 | super().__init__(paras) 156 | ``` 157 | 158 | 这一点和Cpp中还是比较类似的。实现了委托构造。 159 | 160 | 子类中依旧可以实现对父类函数的重载。但是,不需要父类声明为虚函数。非常方便。 161 | 162 | # Python的IO 163 | 164 | Python中实现对文件的读入,采用如下的代码。 165 | 166 | ```python 167 | with open('test.txt') as file: 168 | content = file.read() 169 | print(content) 170 | ``` 171 | 172 | read函数在到达文件末尾后,会返回一个空行。是故,会多打印一行空白。 173 | 174 | 但是,我们可以使用rstrip函数,从而实现对空行的跳过。比如,我们可以改写为 175 | 176 | ```python 177 | print(content.rstrip()) 178 | ``` 179 | 180 | windows系统中,我们使用的是反斜杠来表示相对路径中的层次关系。其他系统中,则是使用/。 181 | 182 | 如果我们想要逐行进行读取,那么我们可以使用这样的代码。 183 | 184 | ```python 185 | with open('test.txt') as file: 186 | for line in file: 187 | print(line) 188 | ``` 189 | 190 | 同样的,在每次读取时都会多产生一行空白。这是因为换行符的存在。 191 | 192 | ```python 193 | with open('test.txt') as file: 194 | lines = file.readlines() 195 | for line in lines: 196 | print(line) 197 | ``` 198 | 199 | 使用这种方式,我们就是把所有的文本全部读入到了一个列表中。列表中的每一个元素,即为每一行。 200 | 201 | ```python 202 | with open('114514.txt', 'w') as file: 203 | file.write('好') 204 | ``` 205 | 206 | 使用这种方式,我们可以实现文件写。并且,如果欲使对象进行换行。则须在最后添上一个换行符。 207 | 208 | 如果我们不需要新建一个文件,那么我们可以将'w'改成'a'。 209 | 210 | 在python中,我们使用try-except来处理异常,效果类似于try-catch。在except块后,我们可以使用一个else块,来处理除了异常外的其他情况。 211 | 212 | 使用split函数,可以将读入的文件流分块。其会根据空格将文件流切片。 213 | 214 | Python中有个语句pass,从而表示让Python什么都不做。 215 | 216 | ```python 217 | person1 = True 218 | person2 = Fsonalse 219 | if person1: 220 | print('You agree!') 221 | else: 222 | pass 223 | if person2: 224 | print('You agree!') 225 | else: 226 | pass 227 | ``` 228 | 229 | 此外,我们可以使用json库来实现对json文件的读写。 230 | 231 | ```python 232 | import json 233 | with open('x.json', 'w') as file: 234 | a = [1, 2, 3] 235 | json.dump(a, file) 236 | ``` 237 | 238 | 如是,我们就实现了对json文件的写入。如果我们想要读出对应的内容,那么我们可以使用json.load函数。 239 | 240 | ```python 241 | with open('x.json') as file: 242 |     a = json.load(file) 243 | ``` 244 | 245 | 如是,便可从json文件中读出想要获得的数据。 246 | 247 | # 测试代码 248 | 249 | 类似于assert,在python中,我们可以引入unittest库。 250 | 251 | ```python 252 | self.assertEqual(a, 12313) 253 | ``` 254 | 255 | 类似的方法还有assertNotEqual,assertTrue, assertFalse, assertIn, assertNotIn 256 | 257 | 这样,显然就是在判断是否相等。在最后,我们可以用这样的代码来启动测试。 258 | 259 | ```python 260 | unittest.main() 261 | ``` 262 | 263 | 所有以test_开头的方法都会自动执行。 264 | 265 | 对于要测试的类,我们可以引入一个setup()方法,从而达到在开始测试使创建出一个用setup方法产生的类进行测试。 266 | -------------------------------------------------------------------------------- /others/Reinforcement Learning.md: -------------------------------------------------------------------------------- 1 | # 第一章 初探强化学习 2 | 3 | 强化学习,解决的是序贯决策的问题。目标是要找到一个最优的占用度量。占用度量,可以理解为在不同情况下,采取不同策略的概率分布模型。 4 | 5 | # 第二章 多臂老虎机(MAB)问题 6 | 7 | 有一台老虎机,其有k根拉杆,每根拉杆对应不同的奖励概率分布。如何在操作T次拉杆后,获得尽量高的奖励呢? 8 | 9 | 我们引入懊悔(regret)这一概念来刻画拉动一根拉杆的期望奖励和最优拉杆期望之间的差距,定义为二者之差。我们的目标,就是要最小化懊悔。显然,我们需要不断拉一根拉杆,才能对它产生的值有一个大概的估计。我们使用增量式估计来更新,而非重新计算。递推的复杂度更低。 10 | 11 | 操作实际上可以分为两种类型:探索和利用。 12 | 13 | ## $\epsilon-$贪婪算法 14 | 15 | 每次有$1-\epsilon$的概率拉下期望奖励最大的拉杆,否则,就随机选择一根拉杆。$\epsilon$可以设置为随着时间下降。 16 | 17 | ## 上置信界算法 18 | 19 | 显然,如果我们对一根拉杆测试较多,那么它的确认度较高,我们更会相信目前的结果是可靠的。原理依靠于霍夫丁不等式,即: 20 | 21 | $$ 22 | P(E[X]\geq\bar x_n+u)\leq e^{-2nu^2} 23 | $$ 24 | 25 | 我们假设这是第t次操作,拉下的是k号拉杆,那么不确定度为$\hat U(a_t)=\sqrt{\frac{-\log p}{2N(a_t)}}=\sqrt{\frac{-\log p}{2N(k)}}$ 26 | 27 | 根据霍夫丁不等式,$Q(a_t)<\hat Q(a_t)+\hat U(a_t)$成立的概率至少为$1-p$ 28 | 29 | 实际上,在具体操作过程中,我们分母会加2处理,避免出现除0错。同时,可以设置p依旧随时间衰减。由此可见,两种方法的idea还是比较接近的。一般而言。为了更好地控制,我们可以选择$\max[\hat Q(a)+c\cdot \hat U(a)]$的那根拉杆。 30 | 31 | ## 汤普森采样算法 32 | 33 | 我们采用贝塔分布来给每一个选择的概率进行建模。我们根据目前已经建模的情况,进行一次随机采样。然后,我们选择采样结果最高的那一个。 34 | 35 | # 第三章 马尔可夫决策过程 36 | 37 | ## 马尔可夫过程 38 | 39 | 随机过程(sticgastuc process)是我们研究的对象。如果一个状态转移的过程中,下一状态仅取决于当前状态,那么就称这个过程具有马尔可夫性质。 40 | 41 | 我们称具有马尔可夫性质的随机过程为马尔可夫过程,用$<\mathcal{S},\mathcal{P}>$来描述马尔可夫过程。其中,$\mathcal{S}$是状态集,$\mathcal{P}$是状态转移矩阵,有$\mathcal{P}_{ij}=P(s_j|s_i)$ 42 | 43 | 根据状态转移矩阵,我们可以轻松地画出状态之间的转移关系。 44 | 45 | ## 马尔可夫奖励过程 46 | 47 | 在马尔可夫过程的基础上,加上奖励函数$r$和折扣因子$\gamma$,即得到马尔可夫奖励过程,记作$<\mathcal{S},\mathcal{P},r,\gamma>$ 48 | 49 | $r(s)$表示转移为该状态时可以获得的奖励的期望。$\gamma$是为了控制短期影响和长期影响之间的权重关系。 50 | 51 | 假设我们考察从$t$时刻到最后的最后,定义$R_t$为第$t$时刻的可以获得的奖励,那么我们定义回报为: 52 | 53 | $$ 54 | G_t=\sum_{k=0}^\infin \gamma^k R_{t+k} 55 | $$ 56 | 57 | 我们定义,一个状态的期望回报称为这个状态的价值。 58 | 59 | 由于这是一个马尔可夫过程,所以我们有: 60 | 61 | $$ 62 | V(s)=E[G_t|S_t=s]\\ 63 | =E[R_t+\gamma G_{t+1}|S_t=s]\\ 64 | =E[R_t+\gamma V(S_{t+1})|S_t=s] 65 | $$ 66 | 67 | 所以,我们有: 68 | 69 | $$ 70 | V(s)=r(s)+\gamma\sum_{s'\in \mathcal{S}}P(s'|s)V(s') 71 | $$ 72 | 73 | 这就是贝尔曼方程。如果我们将每个状态的奖励和回报都写作列向量,那么,我们可以得到: 74 | 75 | $$ 76 | V=R+\gamma PV\\ 77 | V=(I-\gamma P)^{-1}R 78 | $$ 79 | 80 | 这个方法很好。但是它的复杂度是$O(|S|^3)$,这是不可接受的。 81 | 82 | ## 马尔可夫决策过程 83 | 84 | 在马尔可夫奖励过程的基础上,加上一个外来的“智能体”(agent),可以对当前的状态做出影响,就得到了马尔可夫决策过程,记作$<\mathcal{S},\mathcal{A},P,r,\gamma>$,其中$\mathcal{A}$为所有动作的集合。此后,我们采用状态转移函数,而非状态转移矩阵来描述这一过程。因为自变量增多了。 85 | 86 | 我们定义智能体的策略为$\pi(a|s)=P(A_t=a|S_t=s)$ 87 | 88 | 类似地扩充,我们紧接着定义$V^\pi(s)=E_\pi[G_t|S_t=s]$ 89 | 90 | 因为我们的选择还与动作有关,所以我们额外定义一个动作价值函数$Q^\pi(s,a)=E_\pi[G_t|S_t=s,A_t=a]$ 91 | 92 | 二者之间存在着这样的联系:$V^\pi(s)=\sum_{a\in\mathcal{A}}\pi(a|s)Q^\pi(s,a)$ 93 | 94 | $Q^\pi(s,a)=r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)V^\pi(s')$ 95 | 96 | 这两个式子是符合直觉的。 97 | 98 | 对于二者分别取期望,可以得到贝尔曼期望方程: 99 | 100 | $$ 101 | Q^\pi(s,a)=r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)\sum_{a'\in\mathcal{A}}\pi(a'|s')Q^\pi(s',a')\\ 102 | V^\pi(s)=\sum_{a\in\mathcal{A}}\pi(a|s)(r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)V^\pi(s') 103 | $$ 104 | 105 | 仔细看看这两个式子,还是可以理解其朴素的意图的。 106 | 107 | ### 蒙特卡罗方法 108 | 109 | 通过模拟爆算,近似地试探出每个状态的价值函数。我们采样很多条序列。在一个序列计算结束后,我们根据每个状态经过时之总回报进行平均处理,得到一个对状态价值的估计。在大量采样之后,我们在对每条序列中某一个状态的价值进行平均取样。根据大数定律,这样会趋近于$V^\pi(s)$。 110 | 111 | ## 占用度量 112 | 113 | 因为不同的策略,会使得agent访问到不同的概率分布的状态,所以我们需要考察在某一策略下的状态访问分布。我们定义$P_t^\pi(s)$表示策略$\pi$使得$t$时刻状态为$s$的概率。下式中的$1-\gamma$用于归一化概率。初始状态分布记为$v_0(s)$ 114 | 115 | $$ 116 | v^\pi(s)=(1-\gamma)\sum_{t=0}^\infin\gamma^t P_t^\pi(s)\\ 117 | v^\pi(s')=(1-\gamma)v_0(s')+\gamma\int P(s'|s,a)\pi(a|s)v^\pi(s)dsda 118 | $$ 119 | 120 | 这里需要稍体察其用意。 121 | 122 | 定义占用度量为 123 | 124 | $$ 125 | \rho^\pi(s,a)=(1-\gamma)\sum_{t=0}^\infin\gamma^t P_t^\pi(s)\pi(a|s) 126 | $$ 127 | 128 | 这可以用来表征一个状态-动作对被访问到的概率。二者之间存在这样的关系 129 | 130 | $$ 131 | \rho^\pi(s,a)=v^\pi(s)\pi(a|s) 132 | $$ 133 | 134 | Theorem1:二者的占用度量相等,当且仅当策略相同。 135 | 136 | Theorem2:给定一可行的占用度量,可生成其的唯一策略是$\pi_\rho={\rho(s,a)\over \sum_{a'}\rho(s,a')}$ 137 | 138 | 也就是说,这可以认为是个不动点? 139 | 140 | ## 最优策略 141 | 142 | 这是强化学习的目标。一个策略是最优策略,当且仅当在任意状态下,它都不比其他策略差,那么它就是最优策略。我们可以定义一系列最优函数: 143 | 144 | $$ 145 | V^*(s)=\max_\pi V^\pi(s)\\ 146 | Q^*(s,a)=\max_\pi Q^\pi(s,a)\\ 147 | Q^*(s,a)=r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)V^*(s')\\ 148 | V^*(s)=\max_{a\in\mathcal{A}}Q^*(s,a) 149 | $$ 150 | 151 | 第三式的产生,是由最优性保证的。 152 | 153 | 根据二者之间的关系,我们可以得到贝尔曼最优方程: 154 | 155 | $$ 156 | V^*(s)=\max_{a\in\mathcal{A}}\{r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)V^*(s')\}\\ 157 | Q^*(s,a)=r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)\max_{a'\in\mathcal{A}}Q^*(s',a') 158 | $$ 159 | 160 | # 第四章 动态规划算法 161 | 162 | 主要有两种基于动态规划的强化学习算法:策略迭代(policy iteration)和价值迭代(value iteration)。策略迭代由策略评估(policy evaluation)和策略提升(policy improvement)两部分共同构成。 163 | 164 | ## 悬崖漫步环境 165 | 166 | 策略评估:用上一轮得到的结果来更新每一个策略的状态价值函数。即 167 | 168 | $$ 169 | V^{k+1}(s)=\sum_{a\in\mathcal{A}}\pi(a|s)(r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)V^k(s')) 170 | $$ 171 | 172 | 测试轮数足够多的话,会有$V^k(s)\approx V^\pi(s)$ 173 | 174 | 策略提升:在测试的过程中,对策略本身进行改进。想法是如果进行了足够次数的测试后,如果有: 175 | 176 | $$ 177 | Q^\pi(s,\pi'(s))\geq V^\pi(s) 178 | $$ 179 | 180 | 对任意$s$恒成立,那么 181 | 182 | $$ 183 | V^{\pi '}(s)\geq V^\pi 184 | $$ 185 | 186 | 此为策略提升定理。这一点从直觉上去考虑是成立的。 187 | 188 | 策略迭代的过程,就是测试、策略评估、策略提升依次进行的过程。 189 | 190 | 价值迭代也是类似的过程。即 191 | 192 | $$ 193 | V^{k+1}(s)=\max_{a\in\mathcal{A}}\{r(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'|s,a)V^k(s')\} 194 | $$ 195 | 196 | # 第五章 时序差分算法 197 | 198 | $$ 199 | V(s_t)\leftarrow V(s_t)+\alpha[G_t-V(s_t)] 200 | $$ 201 | 202 | 这是蒙特卡洛算法中对状态价值函数的更新。由于我们需要$G_t$,所以必须要计算完整个序列才能进行改动。为了在更新过程中,就可以对其进行改动,我们可以这样处理: 203 | 204 | $$ 205 | V(s_t)\leftarrow V(s_t)+\alpha[r_t+\gamma V(s_{t+1})-V(s_t)] 206 | $$ 207 | 208 | 我们称$r_t+\gamma V(s_{t+1})-V(s_t)$为**时序差分误差**。 209 | 210 | Sarsa算法:类似于状态价值的更新,我们可以用这样的方式进行迭代: 211 | 212 | $$ 213 | Q(s_t,a_t)\leftarrow Q(s_t,a_t)+\alpha[r_t+\gamma Q(s_{t+1},a_{t+1})-Q(s_t,a_t)] 214 | $$ 215 | 216 | 在每一个状态下,我们可以贪心地选择动作价值最大的那一种选择进行计算。这样的计算过程中,是实时进行更新的。但是,如果我们始终选择贪心算法所指明的策略,很可能会有不少状态-动作对没有得到探索。因此,我们可以参考在MAB问题中的思想,引入一个概率值$\epsilon$,有一定的概率选择其他动作,在剩下的概率中选择目前最好的动作并进行更新。这就是Sarsa算法的思想。 217 | 218 | 这样的方案下,每一次计算所得的结果,相较于蒙特卡洛方法而言,方差应该是小不少的。但是,这样的方式是有偏的,可能会导致最终结果的出入。为了弥补这一点,我们引入了多步Sarsa算法,即迭代过程中,考察多步的价值。即: 219 | 220 | $$ 221 | Q(s_t,a_t)\leftarrow Q(s_t,a_t)+\alpha[r_t+\sum_{i=1}^n\gamma^iQ(s_{t+i},a_{t+i})-Q(s_t,a_t)] 222 | $$ 223 | 224 | Q-learning算法与Sarsa算法非常相似。它的更新迭代方式仅有一些微小的不同,即: 225 | 226 | $$ 227 | Q(s_t,a_t)\leftarrow Q(s_t,a_t)+\alpha[r_t+\gamma\max_{a}Q(s_{t+1},a)-Q(s_t,a_t)] 228 | $$ 229 | 230 | 在决策过程中,依旧采用类似Sarsa算法中的$\epsilon$贪心算法进行决策的选取。随后再在所有决策中,选择最大值。 231 | 232 | 所以,Sarsa算法和Q-learning算法之间的显著区别,就是前者在计算价值时,必须采用当次探索时的行为结果,但是Q-learning算法则并不是这样。我们把Sarsa这样的算法称为在线策略算法,而把Q-learning这样的算法称为离线策略算法。 233 | 234 | 我们称,采样数据的策略为行为策略,称用采样数据来更新的策略为目标策略。在线策略,表示行为策略即目标策略,而离线策略,表示行为策略和目标策略不是同一个策略。 235 | 236 | # 第六章 Dyna-Q算法 237 | 238 | 强化学习算法分为两种:基于模型的强化学习和无模型的强化学习。 239 | 240 | 基于模型的话,就要先对环境建模。比如状态转移概率,奖励模型等。而无模型的强化学习则不用考虑这些。无模型的强化学习直接学习概率,而不用学习这个模型。无模型强化学习采样效率低,但是简单,性能较好;基于模型的强化学习,采样效率较高。第四章中的方法,就是基于模型的;第五章中的算法,就是不基于模型的。 241 | 242 | Dyna-Q算法采用一种被称为Q-planning的方法来基于模型生成数据。 243 | 244 | 基本思路是这样的:进行$\epsilon$采样,更新$Q(s,a)$,并且基于当且获得的奖励去更新原有模型$M(s,a)$。然后,进行一定数量的循环,随机选择一个曾经访问过的状态,并且采取一个曾经执行过的策略,后用$M(s_m,a_m)$去更新$r_m$和$s'_m$。话说的比较抽象,但实际上是好理解的:就是探索,更新当前节点数据,在用这个节点数据去更新一部分已经探测过的数据。 245 | 246 | # 第七章 DQN算法 247 | 248 | 考察到动作价值矩阵$Q$,会随着数据规模的增大,呈多项式速度增长。是故,之前的动作价值矩阵$Q$应当不是我们最终运用的方法。最终,我们要用函数去拟合动作价值矩阵$Q$。 249 | 250 | DQN算法,解决的是在连续状态下,动作有限的问题。 251 | 252 | 在DQN算法中,我们引入车杆环境来模拟这一点。什么意思呢?就是一辆小车上有一根杆子。agent的目标,是要想办法尽量保持杆处于竖直的状态。如果杆倾角过大,或者车的移动距离过大,我们就认为agent失败了。 253 | 254 | 考察到,在Q-learning算法中,我们为了要对函数进行更新,我们需要取出该状态下,采取某一动作可以获得的奖励最大值。是故,动作必须是离散的,换言之,动作的数量必须是有限个。 255 | 256 | 一切的一切,还是归结到了神经网络。我们可以使用神经网络来拟合$Q$函数。我们假设,神经网络的参数集合为$\omega$,我们用$Q_\omega(s,a)$来表示在这个神经网络下,状态动作对的价值。 257 | 258 | 我们定义损失函数如下: 259 | 260 | $$ 261 | \omega^*=\text{arg}\min_\omega\frac{1}{2N}\sum_{i=1}^N[Q_\omega(s_i,a_i)-(r_i+\gamma\max_{a'\in\mathcal{A}}Q_{\omega}(s_{i+1},a'))^2] 262 | $$ 263 | 264 | 我们称之为深度Q网络。从直觉上看看,这个损失函数貌似在刻画自洽性? 265 | 266 | 经验回放的概念:将每次采样得到的四元组数据存储在回放缓冲区中。在之后的训练中,也会从回放缓冲区中随机地挑选一些样本来参与数据更新。这样做有两个目的。一方面,可以提高样本的复用率。另一方面,考虑到我们在一次采用过程中的样本不是独立的,适当地加入一些回放的样本,可以提高独立性,使之可以满足独立性假设。 267 | 268 | 在实际的实现过程中,我们一般会使用两个网络。一个,是实时更新的网络$\omega$,我们称之为训练网络;一个,是每隔$C$步才会和训练网络参数进行一次同步的网络。我们称之为目标网络$\omega_-$。在计算损失函数的过程中,我们使用目标网络的参数,也就是上式中的第二项改变为$\omega_-$;在更新的过程中,我们更新训练网络的参数。 269 | 270 | # 第八章 DQN改进算法 271 | 272 | ## Double DQN算法 273 | 274 | 一般的DQN算法,会出现过高估计的问题。为了解决这一问题,有Double DQN算法。 275 | 276 | 在上面的更新中,我们用了 277 | 278 | $$ 279 | (r_i+\gamma\max_{a'\in\mathcal{A}}Q_{\omega}(s_{i+1},a')) 280 | $$ 281 | 282 | 来更新数据。在Double DQN算法中,我们改为: 283 | 284 | $$ 285 | (r_i+\gamma Q_{\omega_-}(s',\text{arg}\max_{a'\in\mathcal{A}}Q_{\omega}(s_{i+1},a')) 286 | $$ 287 | 288 | 也就是说,我们用一套网络来选策略,用一套网络来估值,从而来减少过高估计的问题。(玄学?) 289 | 290 | ## Dueling DQN算法 291 | 292 | 我们定义优势函数为: 293 | 294 | $$ 295 | A(s,a)=Q(s,a)-V(s) 296 | $$ 297 | 298 | 在同一个状态下,所有动作的优势值之和为0(???写错了吧,怎么想都不会是对的吧。说的应当是按照策略概率加权后的结果。或者说,优势的期望值是0)。 299 | 300 | 建模为: 301 | 302 | $$ 303 | Q_{\eta,\alpha,\beta}(s,a)=V_{\eta,\alpha}(s)+A_{\eta,\beta}(s,a) 304 | $$ 305 | 306 | 其中$\eta$是状态价值函数和优势函数共享的网络参数,$\alpha,\beta$为状态价值函数和优势函数的参数。从而,我们将$Q$值分解为了对两个函数参数的计算,分别获得价值函数和优势函数。这样做的目的是,有些时候,我们可能并不关注不同动作之间价值的差异。 307 | 308 | 为了保证建模的唯一性,我们定义,优势函数最高的一个对象的优势值为0。 309 | 310 | # 第九章 策略提升算法 311 | 312 | 在之前的操作中,我们尝试去构造一个价值函数,从而对每个状态进行比较合理化的估值。在这里,我们可以考虑对策略本身进行建模。 313 | 314 | 我们定义,$\pi_\theta$为策略函数参数为$\theta$下的策略。 315 | 316 | 我们的目标,应当是最大化$J(\theta)=E_{s_0}[V^{\pi_\theta}(s_0)]$ 317 | 318 | 其中$s_0$是初始状态。 319 | 320 | 通过推导,我们可以得到: 321 | 322 | $$ 323 | \Delta_\theta J(\theta)\propto E_{\pi_\theta}[Q^{\pi_\theta}(s,a)\nabla_\theta\log\pi_\theta(a|s)] 324 | $$ 325 | 326 | 这个推导过程还是比较复杂的。 327 | 328 | 那么,我们可以从初始样本开始采样,随后根据梯度对参数进行调整。 329 | 330 | 因为,有: 331 | 332 | $$ 333 | Q^{\pi_\theta}=\sum_{t=0}^T(\sum_{t'=t}^T\gamma^{t'-t}r_{t'}) 334 | $$ 335 | 336 | 所以我们可以将这一部分代换,从而不必对状态价值函数进行建模。 337 | 338 | # 第十章 Actor-Critic算法 339 | 340 | 在第九章的策略提升算法中,我们采用随机采样的方式(蒙特卡洛方式?)来进行策略的更新。在Actor-Critic算法中,会尝试将采样的结果拟合成一个值函数去指导策略的学习。 341 | 342 | 在上面,我们提到过: 343 | 344 | $$ 345 | \Delta_\theta J(\theta)\propto E_{\pi_\theta}[Q^{\pi_\theta}(s,a)\nabla_\theta\log\pi_\theta(a|s)]\\ 346 | Q^{\pi_\theta}=\sum_{t=0}^T(\sum_{t'=t}^T\gamma^{t'-t}r_{t'}) 347 | $$ 348 | 349 | 如果将上面式子中的$Q^{\pi_\theta}$改写为另外的函数,那么我们就得到了另外一种类型的“梯度”。可以将其替换为时序差分残差$r_t+\gamma V^{\pi_\theta}(s_{t+1})-V^{\pi_\theta}(s_t)$,或者是重新估计一个函数。(rmk:莫名又联想到了DL中的一些想法。认为一部分参数“不准确”,从而通过计算的方式来更精确地刻画,最终达到提升结果的目的。) 350 | 351 | 或者说,在这个过程中,我们实际上让网络尝试去记忆那些曾经取样过的数据。我们要训练两个网络,一个就是策略的网络,另外一个是拟合价值函数的神经网络。这里依旧使用了梯度下降的做法。 352 | 353 | # 第十一章 TRPO算法 354 | 355 | 针对之前提到的策略提升算法,在参数更新的过程中,可能因为参数调整幅度过大,导致整体性能下降。所以,TRPO算法的思路是先确认一个置信域,在当前参数的某一个高维球邻域内,则信任之。 356 | 357 | 经过推导,有: 358 | 359 | $$ 360 | J(\theta')-J(\theta)=\frac{1}{1-\gamma}E_{s\sim v^{\pi_{\theta'}}}E_{a\sim\pi_{\theta'}(\cdot|s)} 361 | [A^{\pi_{\theta}}(s,a)] 362 | $$ 363 | 364 | 就我简单的理解而言,第一个期望,表征的是预期在经过一段时间后,我们在哪个状态;第二个期望,则是表征在这个状态下的预期动作。其中,$\theta$为原参数,而$\theta'$为新参数。但是这个方程求解起来并不简单,因为等式的右侧用到了我们要用于求解的$\theta'$。 365 | 366 | 因此,我们进行了一步近似操作。如果我们的策略并没有发生显著的改变,那么我们可以近似认为第一个期望在两组参数下,结果近似相同。所以,我们可以将上式转化为: 367 | 368 | $$ 369 | \frac{1}{1-\gamma}E_{s\sim v^{\pi_{\theta}}}E_{a\sim\pi_{\theta'}(\cdot|s)} 370 | [A^{\pi_{\theta}}(s,a)] 371 | $$ 372 | 373 | rmk:对于这个转换,感觉只能用常识上去解释?或者从参数$\to$策略$\to$动作$\to$状态这个链条上去看,改变参数,对动作的影响会更大些,对于状态的影响可能会偏小?(给我一种先射箭再画靶的感觉XD) 374 | 375 | 只需要简单地进行下变换,就可以得到: 376 | 377 | $$ 378 | \frac{1}{1-\gamma}E_{s\sim v^{\pi_{\theta}}}E_{a\sim\pi_{\theta}(\cdot|s)} 379 | [\frac{\pi_{\theta'}(a|s)}{\pi_\theta(a|s)}A^{\pi_{\theta}}(s,a)] 380 | $$ 381 | 382 | 我们用上面的式子来优化参数。并且,要求两组策略的KL散度小于一定的数值。 383 | -------------------------------------------------------------------------------- /others/Transformer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Seven-Streams/Notes/d3c3663b8355f6efdb184b409f2b54c664d804f3/others/Transformer.jpg -------------------------------------------------------------------------------- /others/basic operations of deep learning.md: -------------------------------------------------------------------------------- 1 | # Tensor中的常见操作 2 | 3 | ```python 4 | import torch 5 | X = torch.arange(12)#创建存有数字0~11的一维张量 6 | print(X.shape)#显示张量的形状 7 | X = X.reshape(3, 4)#将张量转换为3*4的形状 8 | print(X.numel())#张量中的元素个数 9 | Z = torch.zeros((2, 3, 4))#创建一个全0的张量,形状为2*3*4 10 | O = torch.ones((2, 3, 4))#创建一个全1的张量,形状为2*3*4 11 | R = torch.randn((3, 4))#创建一个形状为3*4的张量,其中的数据符合均值为0,标准差为1的正态分布 12 | print(R) 13 | L = torch.tensor([[1, 2, 3], [4, 5, 6]]) 14 | print(L) 15 | A = torch.tensor([1, 2, 3, 8]) 16 | B = torch.tensor([2, 3, 3, 2]) 17 | print(A + B) 18 | print(A - B) 19 | print(A * B) 20 | print(A / B) 21 | print(A ** B)#A中每个元素的B中元素次方 22 | E = torch.exp(A)#转化为e的k次方 23 | print(E) 24 | print(torch.cat((X, X), dim=0))#竖直连接,不改变总列数 25 | print(torch.cat((X, X), dim=1))#水平连接,不改变总行数 26 | print(A == B)#结果也是张量。元素为True和False 27 | print((A == B).sum())#求和,得到单元素张量 28 | T1 = torch.arange(3).reshape((3, 1)) 29 | T2 = torch.arange(2).reshape((1, 2)) 30 | print(T1 + T2)#broadcasting mechanism,这会自动扩展元素进行计算 31 | print(A[-2])#A的倒数第二个元素 32 | print(A[1:3])#index为2和3的元素 33 | print(X[1, 3])#第一行第三列元素 34 | X[0:2, :] = 12#改变了第二三行所有的元素 35 | print(X) 36 | Y = X 37 | X += Y#这样的操作等价于 X[:] = X + Y; X = X + Y会重新分配内存,不佳 38 | #更新时,使用X[:]=可以原地更新 39 | W = torch.tensor([1.2]) 40 | print(W.item())#这两种方式都可以把单元素张量转化为Py标量 41 | print(float(W)) 42 | ``` 43 | 44 | # Panda的使用 45 | 46 | ```python 47 | import pandas as pd 48 | data = pd.read_csv('data.csv') 49 | print(data) 50 | inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]#取索引 51 | inputs = pd.get_dummies(inputs, dummy_na=True) 52 | #该函数会把内容转换为独热编码。 53 | #dummy_na为True,表示会补充缺省值 54 | ``` 55 | 56 | # Linear Algebra 57 | 58 | ```python 59 | import torch 60 | A = torch.arange(20).reshape((5, 4)) 61 | print(A.T)#转置 62 | B = A.clone()#令B等于A的副本。若为B=A,则会导致二者共享相同内存 63 | A_sum0 = A.sum(axis=0) 64 | print(A_sum0)#按行降维。每行的元素相加。 65 | Total = A.sum(axis=[0, 1])#按行按列均相加 66 | print(Total) 67 | print(A.mean(dtype=float))#平均值 68 | sum_A = A.sum(axis=1, keepdims=True)#这样可以保持轴数不变 69 | print(sum_A) 70 | A = A.cumsum(axis=0)#这样得到的是A按行的元素累积总和 71 | print(A) 72 | x = torch.tensor([0, 1, 2, 3]) 73 | y = torch.ones(4, dtype=torch.long) 74 | print(torch.dot(x, y))#点积 75 | print(torch.mv(A, x))#矩阵向量积 76 | B = torch.ones(4, 3, dtype=torch.long) 77 | print(torch.mm(A, B))#矩阵矩阵乘积 78 | v = torch.tensor([3.0, 4.0]) 79 | print(torch.norm(v))#L2范数 80 | print(torch.abs(v).sum())#L1范数 81 | print(torch.norm(A,dtype=float))#矩阵的弗罗贝尼乌斯范数 82 | ``` 83 | 84 | # Automatic Differentiation 85 | 86 | ```python 87 | import torch 88 | x = torch.arange(4.0, requires_grad=True)#需要梯度 89 | print(x.grad) 90 | y = 2 * torch.dot(x, x) 91 | print(y) 92 | y.backward()#反向传播函数计算梯度 93 | print(x.grad) 94 | x.grad.zero_() 95 | y = x * x 96 | u = y.detach()#将此前的计算分离,反向传播时不会流经 97 | z = u * x 98 | z.sum().backward() 99 | print(x.grad == u) 100 | ``` 101 | -------------------------------------------------------------------------------- /others/numpy.md: -------------------------------------------------------------------------------- 1 | # 1、创建np数组 2 | 3 | 一般而言,有六种办法。 4 | 5 | ## 用python中的list或tuple创建 6 | 7 | ```python 8 | a_1d = np.array([1, 2, 3, 4]) 9 | a_2d = np.array([1, 2], [3, 4]) 10 | a_3d = np.array([[1, 2], [3, 4]], [[5, 6], [7, 8]]) 11 | ``` 12 | 13 | 上面这样,会创建一维,二维,三维的numpy数组。 14 | 15 | 在使用这种方式的时候,我们可以指定我们希望的类型。比如 16 | 17 | ```python 18 | a = np,array([127, 128, 129], dtype=np.int8) 19 | # a = array([127, -128, -127]) 20 | ``` 21 | 22 | ## 使用numpy内置的创建函数 23 | 24 | ```python 25 | a = np.arange(2, 10, 2) 26 | # a = array([2, 4, 6, 8]) 27 | ``` 28 | 29 | 类似于python中的方式。但是产生的是一个numpy数组。 30 | 31 | ```python 32 | a = np.linspace(1., 4., 6) 33 | # a = array([1., 1.6, 2.2, 2.8, 3.4, 4.]) 34 | ``` 35 | 36 | 可以看到,它的作用是把一个均匀的在一个区间中取k个值。 37 | 38 | ```python 39 | I = np.eye(3) 40 | #I is an identity matrix. 41 | a = np.eye(3, 5) 42 | # a is a conjunction of a 3*3 indentity matrix and two all-zero columns. 43 | ``` 44 | 45 | 这是取恒等矩阵的方法。 46 | 47 | ```python 48 | d = np.diag([1,2,3]) 49 | #一个三乘三的对角阵。值为1,2,3 50 | x = np.diag([1,2,3], 1) 51 | #意为,对角大斜线上方的第k条斜线的元素为1,2,3,说明这是个4*4的矩阵 52 | ``` 53 | 54 | 这样可以获得对角矩阵。 55 | 56 | ```python 57 | a = np.array([1, 2], [3, 4]) 58 | b = np.diag(a) 59 | # b = array([1, 4]) 60 | ``` 61 | 62 | 如果输入的对象是一个二维矩阵,那么会返回一个一维np数组,值为对角线上的元素。 63 | 64 | ```python 65 | a = np.vander([1, 2, 3, 4], 4) 66 | # a为 67 | # array([[1, 1, 1, 1], 68 | # [8, 4, 2, 1], 69 | # [27, 9, 3, 1], 70 | # [64, 16, 4, 1]]) 71 | ``` 72 | 73 | 也就是说,最后一列均为1,每一行为对应数字的几何级数。 74 | 75 | ```python 76 | a = np.zeros((1, 1, 4)) 77 | b = np.ones((5, 1)) 78 | c = np.random(4, 1, 9) 79 | ``` 80 | 81 | 这样子,可以按照我们想要的形状,创建对应数组。 82 | 83 | ```python 84 | a = np.indices((1, 9, 8)) 85 | ``` 86 | 87 | 这样子,生成的数组中,其每一维的值,恰等于其每一维的索引号。比如说,a[114][514][1919] = (114, 514, 1919) 88 | 89 | ## 从已有的np数组变化而来 90 | 91 | ```python 92 | a = [1, 2, 3, 4, 5, 6] 93 | b = a[:2] 94 | b += 1 95 | # a = array([2, 3, 3, 4, 5, 6]) 96 | ``` 97 | 98 | 可以看到,这样对b操作,也会影响到原有的a。 99 | 100 | ```python 101 | a = [1, 2, 3, 4, 5, 6] 102 | b = a[:2].copy() 103 | b += 1 104 | # a = array([1, 2, 3, 4]) 105 | ``` 106 | 107 | 这样的话,我们就斩断了a与b之间的联系。从而可以对b直接进行操作,而不影响a。 108 | 109 | ```python 110 | A = np.ones((2, 2)) 111 | B = np.eye(2, 2) 112 | C = np.zeros((2, 2)) 113 | D = np.diag((-3, -4)) 114 | np.block([[A, B], [C, D]]) 115 | ``` 116 | 117 | 这样,我们可以生成分块矩阵: 118 | 119 | $$ 120 | \begin{bmatrix} 121 | A&B\\ 122 | C&D 123 | \end{bmatrix} 124 | $$ 125 | 126 | ## 从硬盘数据生成 127 | 128 | 比较常见的方法就是: 129 | 130 | ```python 131 | np.loadtxt('a.csv', delimiter=',') 132 | ``` 133 | 134 | 这种方式我已经习惯会使用了。 135 | 136 | 剩下两种,就是从字节流,或者其他库函数生成。 137 | 138 | # 2、numpy数组的索引 139 | 140 | ## 单元素索引 141 | 142 | ```python 143 | x = np.arange(10) 144 | # x[2] == 2 145 | # x[-2] == 8 146 | # x.shape == (10,) 147 | ``` 148 | 149 | 如果我们要修改x的形状可以选择: 150 | 151 | ```python 152 | x.shape = (2, 5) 153 | # or x.shape = (2, -1) 154 | # x[0] = array([0, 1, 2, 3, 4]) 155 | # x[1][0] = 5 156 | # x[1, 0] = 5 157 | ``` 158 | 159 | 在这种情况下,我们就修改了x的形状。如果填写-1表示缺省,让python自行计算。我们修改了其形状后,可以用x[0]来访问其第一行。有两种方式可以访问单个元素。但第二种方式似乎效率更高。 160 | 161 | ## 切片 162 | 163 | ```python 164 | x = np.arange(10) 165 | x = x[1: -3: 2] 166 | # x = array([1, 3, 5]) 167 | x = np.arange(10) 168 | x = x[7: 3: -1] 169 | # x = array([7, 6, 5, 4]) 170 | ``` 171 | 172 | 这样可以控制步长对数组进行切片。 173 | 174 | ```python 175 | x = np.arange(10) 176 | x = x[5:] 177 | # x = array([5, 6, 7, 8, 9]) 178 | x = np.arange(10) 179 | x = x[:5] 180 | # x = array([0, 1, 2, 3, 4]) 181 | x = np.arange(10) 182 | x = x[1: 3] 183 | # x = array([1, 2]) 184 | ``` 185 | 186 | 这种方式,可以从index=k开始,并且获取之后的所有元素。或者,获取到index=k为止的所有元素。如果指定了两端,那么就会按照规则获得中间一段。 187 | 188 | ```python 189 | x = np.arange(27) 190 | x.shape = (3, 3, 3) 191 | x = x[:2] 192 | # x = array( 193 | # [[[ 0, 1, 2], 194 | # [ 3, 4, 5], 195 | # [ 6, 7, 8]], 196 | # 197 | # [[ 9, 10, 11], 198 | # [12, 13, 14], 199 | # [15, 16, 17]]]) 200 | ``` 201 | 202 | 如果输入的参数比维数少,那么之后的维数默认全选。 203 | 204 | ## 维数索引工具 205 | 206 | ```python 207 | x = np.arange(27) 208 | x.shape = (3, 3, 3) 209 | a = x[..., 0] 210 | b = x[:, :, 0] 211 | # a = b 212 | ``` 213 | 214 | 这是一个语法糖。使用省略号,表示之前的参数全选。 215 | 216 | ```python 217 | x = np.arange(5) 218 | x[:, np.newaxis] + x[np.newaxis, :] 219 | # [[0, 1, 2, 3, 4], 220 | # [1, 2, 3, 4, 5], 221 | # [2, 3, 4, 5, 6], 222 | # [3, 4, 5, 6, 7], 223 | # [4, 5, 6, 7, 8]] 224 | ``` 225 | 226 | 在上面的式子中,np.newaxis可以同义地替换为None。什么意思呢?相当于可以改变它的维度,比如说,x[:, np.newaxis].shape为[5, 1], x[np.newaxis, :].shape为[1, 5],然后运用广播机制,就得到了上面的结果。 227 | 228 | ## 使用numpy整型数组进行索引选择 229 | 230 | ```python 231 | x = np.arange(10) 232 | b = np.arange([1, 1, 4, 5, 1, 4]) 233 | c = x[b] 234 | # c = array([1, 1, 4, 5, 1, 4]) 235 | ``` 236 | 237 | 也就是说,我们可以用numpy整型数组作为下标运算符中的参数,表示选取。 238 | 239 | ```python 240 | y = np.arange(35).reshape(5, 7) 241 | a = y[np.array([0, 2, 4]), 1] 242 | b = y[np.array([0, 2, 4])] 243 | c = y[np.array([0,2,4]), np.array([0,2,4])] 244 | # a = array([1, 15, 29]) 245 | # c = array([0, 16, 32]) 246 | ``` 247 | 248 | 即,a为第一维选择0,2,4,第二维均为1。b则为第一维选择0,2,4,第二维全选。c则为选择了[0,0],[2,2],[4,4]三个元素。如c这种方式选取的话,两个数组的大小必须相同。 249 | 250 | ```python 251 | x = np.array([[ 0, 1, 2], 252 | [ 3, 4, 5], 253 | [ 6, 7, 8], 254 | [ 9, 10, 11] 255 | ]) 256 | rows = np.array([[0, 0], 257 | [3, 3]], dtype=np.intp) 258 | columns = np.array([[0, 2], 259 | [0, 2]], dtype=np.intp) 260 | y = x[rows, columns] 261 | # y = 262 | #array([[ 0, 2], 263 | # [ 9, 11]]) 264 | ``` 265 | 266 | 用这样的方法,可以在对应的位置获得自己想要的元素。 267 | 268 | 为了简化这一过程,我们可以这样操作: 269 | 270 | ```python 271 | ```python 272 | x = np.array([[ 0, 1, 2], 273 | [ 3, 4, 5], 274 | [ 6, 7, 8], 275 | [ 9, 10, 11] 276 | ]) 277 | ``` 278 | 279 | rows = np.array([0, 3], dtype=np.intp) 280 | columns = np.array([0, 2], dtype=np.intp) 281 | y = x[rows[:, np.newaxis], columns] 282 | 283 | # y = 284 | 285 | # array([[ 0, 2], 286 | 287 | # [ 9, 11]]) 288 | 289 | ``` 290 | 这样可以使用广播机制,自动地进行剩余对象的补全。以此观之,newaxis的一个重要作用就是类似于转置的功效。 291 | 292 | ```python 293 | x = np.arange(27) 294 | x.shape = (3,3,3) 295 | a = np.array([0,1]) 296 | b = x[a,a,a] 297 | c = x[np.ix_(a,a,a)] 298 | # b = array([0, 13]) 299 | # c = 300 | # array([[[ 0, 1], 301 | # [ 3, 4]], 302 | # 303 | # [[ 9, 10], 304 | # [12, 13]]]) 305 | ``` 306 | 307 | ix_函数可以做到newaxis的效果。 308 | 309 | ## 布尔数组索引 310 | 311 | ```python 312 | x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]]) 313 | b = x[~np.isnan(x)] 314 | # b = array([1., 2., 3.]) 315 | ``` 316 | 317 | 用逻辑函数的方法进行选取。 318 | 319 | ```python 320 | x = np.array([1., -1., -2., 3]) 321 | x[x < 0] += 20 322 | # x = array([ 1., 19., 18., 3.]) 323 | ``` 324 | 325 | 这样,可以定向地选择出numpy数组中想要的对象。 326 | 327 | ```python 328 | x = np.arange(35).reshape(5, 7) 329 | b = x > 20 330 | b[:, 5] 331 | # x = array([False, False, False, True, True]) 332 | ``` 333 | 334 | 这样,也可以做到类似的效果。 335 | 336 | ```python 337 | x = np.array([[0, 1], [1, 1], [2, 2]]) 338 | rowsum = x.sum(-1) 339 | a = x[rowsum <= 2, :] 340 | # a = 341 | # array([[0, 1], 342 | # [1, 1]]) 343 | ``` 344 | 345 | 选取了行和小于等于2的所有元素。 346 | 347 | ```python 348 | x = np.arange(30).reshape(2, 3, 5) 349 | b = np.array([[True, True, False], [False, True, True]]) 350 | c = x[b] 351 | ``` 352 | 353 | 这样的话,c就选取了x[0, 0, :], x[0, 1, :], x[1, 1, :], x[1, 2, :] 354 | 355 | ## 我们联合!——基本与高阶操作的混合 356 | 357 | 高阶操作依旧符合切片的需求。 358 | 359 | ```python 360 | y = np.arange(35).reshape(5,7) 361 | a = y[np.array([0, 2, 4]), 1:3] 362 | # a = 363 | # array([[ 1, 2], 364 | # [15, 16], 365 | # [29, 30]]) 366 | ``` 367 | 368 | ## 数组的作用域 369 | 370 | ```python 371 | x = np.ones((2, 2), dtype=[('a', np.int32), ('b', np.float64, (3, 3))]) 372 | # x = 373 | # array([[(1, [[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]), 374 | # (1, [[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])], 375 | # [(1, [[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]), 376 | # (1, [[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])]], 377 | # dtype=[('a', '