├── .nojekyll ├── 神经网络 ├── 损失函数 │ └── README.md ├── 多层神经网络.md ├── 反向传播 │ └── 99~参考资料 │ │ └── A Step by Step Backpropagation Example.md ├── 丢弃法.md ├── 正向传播与反向传播.md ├── 激活函数 │ ├── ReLU.md │ ├── tanh.md │ ├── sigmoid.md │ └── README.md └── README.md ├── 00~导论 ├── 深度学习前沿.md ├── 深度学习算法.md └── 深度学习简史.md ├── INTRODUCTION.md ├── 99~参考资料 ├── 2023~The Engineer's Guide To Deep Learning │ ├── Part-04 │ │ ├── README.md │ │ ├── display-sparse-attentions.py │ │ └── attic │ │ │ └── ffn.py │ ├── .gitignore │ ├── Appendix │ │ ├── README.md │ │ ├── attic │ │ │ ├── autograd_test.py │ │ │ └── sigmoid_tanh.py │ │ ├── gd.py │ │ └── Dice.py │ ├── DataSets │ │ ├── small_vocabulary_sentences │ │ │ ├── eng-14.txt │ │ │ └── eng-41.txt │ │ ├── README.md │ │ ├── sentiment_labelled_sentences │ │ │ └── readme.txt │ │ └── keras │ │ │ └── spa-eng │ │ │ └── _about.txt │ ├── Part-03 │ │ ├── attic │ │ │ └── embedding_sample.py │ │ ├── README.md │ │ ├── Attention.py │ │ ├── Bigram-count-based.py │ │ ├── Trigram-count-based.py │ │ └── Tokenizer.py │ ├── Common │ │ ├── README.md │ │ ├── ActivationFunctions.py │ │ └── Optimizer.py │ ├── Part-01.cnn │ │ └── README.md │ ├── Part-02 │ │ ├── README.md │ │ ├── DataSet.py │ │ ├── attic │ │ │ └── sin.py │ │ ├── RNN_keras.py │ │ ├── LSTM_keras.py │ │ ├── GRU_keras.py │ │ ├── RNN_tf.py │ │ ├── GRU_tf.py │ │ └── LSTM_tf.py │ ├── Part-01 │ │ ├── attic │ │ │ ├── debug-relu.py │ │ │ ├── debug-softmax.py │ │ │ ├── debug-dense.py │ │ │ └── activation_func_graphs.py │ │ ├── SVM.py │ │ ├── README.md │ │ ├── KNeighborsClassifier.py │ │ ├── XOR-gate-keras-softmax.py │ │ ├── binary-to-decimal-conversion-keras.py │ │ ├── XOR-gate-keras.py │ │ ├── AND-gate.py │ │ ├── XOR-gate-modularized.py │ │ ├── XOR-gate-pt.py │ │ └── XOR-gate-tf-softmax.py │ └── README.md ├── 2021~李沐~《动手学习深度学习》 │ ├── 30~第二部分完结竞赛:图片分类.md │ ├── 38~第二次竞赛树叶分类结果.md │ ├── 15~实战Kaggle比赛:预测房价.md │ ├── 48~全连接卷积神经网络(FCN).md │ ├── 50~课程竞赛:牛仔行头检测.md │ ├── 61~编码器~解码器架构.md │ ├── 00~预告.md │ ├── 16~Pytorch神经网络基础.md │ ├── 32~深度学习硬件.md │ ├── 54~循环神经网络RNN.md │ ├── 33~单机多卡并行.md │ ├── 37~微调.md │ ├── 01~课程安排.md │ ├── 63~束搜索.md │ ├── 58~深层循环神经网络.md │ ├── 49~样式迁移.md │ ├── 70~BERT 微调.md │ ├── 43~树叶分类竞赛技术总结.md │ ├── 25~使用块的网络 VGG.md │ ├── 47~转置卷积.md │ ├── 46~语义分割.md │ ├── 35~分布式训练.md │ ├── 34~多GPU训练实现(only QA).md │ ├── 72~优化算法.md │ ├── 68~Transformer.md │ ├── 27~GoogLeNet.md │ ├── 62~序列到序列学习.md │ ├── codes │ │ └── 13-丢弃法.ipynb │ ├── 56~GRU.md │ ├── 36~数据增广.md │ ├── 20~填充和步幅.md │ ├── 03~安装.md │ ├── 19~卷积层.md │ ├── 18~预测房价竞赛总结.md │ ├── 44~物体检测算法:R~CNN,SSD,YOLO.md │ ├── 26~NiN.md │ ├── 51~序列模型.md │ ├── 31~CPU和GPU.md │ ├── 08~线性回归+基础优化算法.md │ ├── 65~注意力分数.md │ ├── 13~丢弃法.md │ └── 21~多输入输出通道.md ├── 2019~《Deep Learning Book》 │ ├── 13~Linear Factor Models.ipynb │ └── README.md └── 2019~Andrew Ng~深度学习课程 │ ├── notation.md │ └── README.md └── .gitignore /.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /神经网络/损失函数/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /00~导论/深度学习前沿.md: -------------------------------------------------------------------------------- 1 | # 深度学习前沿 2 | -------------------------------------------------------------------------------- /INTRODUCTION.md: -------------------------------------------------------------------------------- 1 | # 本篇导读 2 | -------------------------------------------------------------------------------- /神经网络/多层神经网络.md: -------------------------------------------------------------------------------- 1 | # 多层神经网络 2 | 3 | # 隐藏层 4 | -------------------------------------------------------------------------------- /神经网络/反向传播/99~参考资料/A Step by Step Backpropagation Example.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /神经网络/丢弃法.md: -------------------------------------------------------------------------------- 1 | # 丢弃法 2 | 3 | # Links 4 | 5 | - http://zh.gluon.ai/chapter_deep-learning-basics/dropout.html 6 | -------------------------------------------------------------------------------- /00~导论/深度学习算法.md: -------------------------------------------------------------------------------- 1 | # 深度学习算法 2 | 3 | # Links 4 | 5 | - https://theaisummer.com/Deep-Learning-Algorithms/#neural-networks 6 | -------------------------------------------------------------------------------- /神经网络/正向传播与反向传播.md: -------------------------------------------------------------------------------- 1 | # 正向传播与反向传播 2 | 3 | # Links 4 | 5 | - http://zh.gluon.ai/chapter_deep-learning-basics/backprop.html 6 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-04/README.md: -------------------------------------------------------------------------------- 1 | ## Part 4: Transformer 2 | 3 | 1. [Transformer-tf.py](./Transformer-tf.py) 4 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | References/ 4 | */__pycache__/ 5 | Part-03/checkpoints/ 6 | Part-04/checkpoints/ 7 | */NULL.txt 8 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Appendix/README.md: -------------------------------------------------------------------------------- 1 | ## Part 0: Basic Knowlegde 2 | 3 | 1. [gd.py](./gd.py): Demonstrate the Gradient Descent Algorithm. 4 | 5 | 2. [Dice.py](./Dice.py): Virtual Dice. 6 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/30~第二部分完结竞赛:图片分类.md: -------------------------------------------------------------------------------- 1 | ## 30 第二部分完结竞赛:图片分类 2 | 3 | 竞赛地址:https://www.kaggle.com/c/classify-leaves 4 | 5 | 任务:给出叶子图片预测树种,共20000张图,176类,每类至少50张图。训练样本18353张,测试样本8800张。 6 | 7 | 这次公榜私榜是随机分的,正常来说两榜的名次差别不会太大。 -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/DataSets/small_vocabulary_sentences/eng-14.txt: -------------------------------------------------------------------------------- 1 | Go on in. 2 | I can go. 3 | Go for it. 4 | I like it. 5 | Tom is in. 6 | Tom is up. 7 | We can go. 8 | I like Tom. 9 | I like him. 10 | I like you. 11 | You like Tom. 12 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/38~第二次竞赛树叶分类结果.md: -------------------------------------------------------------------------------- 1 | ## 第二次竞赛树叶分类结果 2 | 3 | ### 任务简介 4 | 5 | 对176种叶子进行分类,每类叶子的数据大约有100张图片,数据较干净,没有复杂背景且颜色并不关键,模型只要能识别出形状即可 6 | 7 | ### 结果 8 | 9 | 165个队伍参加,1800次提交,私榜排名第一的同学正确率有0.99272,李沐老师私下使用AutoML训练大约0.98,由于结果较好,6-20名的队伍如果分享代码也可获得签名书 10 | 11 | ### 方法总结 12 | 13 | 待参加比赛的同学分享代码后下周课程上讲解,但B站视频并未上传此部分。 -------------------------------------------------------------------------------- /神经网络/激活函数/ReLU.md: -------------------------------------------------------------------------------- 1 | # ReLU 函数 2 | 3 | ReLU(rectified linear unit)函数提供了一个很简单的非线性变换。给定元素 $x$,该函数定义为: 4 | 5 | $$ 6 | \operatorname{ReLU}(x)=\max (x, 0) 7 | $$ 8 | 9 | ![ReLU 对比](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230416205129.png) 10 | 11 | 显然,当输入为负数时,ReLU 函数的导数为 0;当输入为正数时,ReLU 函数的导数为 1。尽管输入为 0 时 ReLU 函数不可导,但是我们可以取此处的导数为 0。 12 | -------------------------------------------------------------------------------- /神经网络/激活函数/tanh.md: -------------------------------------------------------------------------------- 1 | # tanh 函数 2 | 3 | tanh(双曲正切)函数可以将元素的值变换到-1 和 1 之间: 4 | 5 | $$ 6 | \tanh (x)=\frac{1-\exp (-2 x)}{1+\exp (-2 x)} 7 | $$ 8 | 9 | 我们接着绘制 tanh 函数。当输入接近 0 时,tanh 函数接近线性变换。虽然该函数的形状和 sigmoid 函数的形状很像,但 tanh 函数在坐标系的原点上对称。 10 | 11 | ![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230416204757.png) 12 | 13 | 依据链式法则,tanh 函数的导数: 14 | 15 | $$ 16 | \tanh ^{\prime}(x)=1-\tanh ^{2}(x) 17 | $$ 18 | -------------------------------------------------------------------------------- /神经网络/激活函数/sigmoid.md: -------------------------------------------------------------------------------- 1 | # sigmoid 函数 2 | 3 | sigmoid 函数可以将元素的值变换到 0 和 1 之间: 4 | 5 | $$ 6 | \operatorname{sigmoid}(x)=\frac{1}{1+\exp (-x)} 7 | $$ 8 | 9 | sigmoid 函数在早期的神经网络中较为普遍,但它目前逐渐被更简单的 ReLU 函数取代。 10 | 11 | ![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230416204701.png) 12 | 13 | 依据链式法则,sigmoid 函数的导数为: 14 | 15 | $$ 16 | \text { sigmoid }^{\prime}(x)=\operatorname{sigmoid}(x)(1-\operatorname{sigmoid}(x)) 17 | $$ 18 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/15~实战Kaggle比赛:预测房价.md: -------------------------------------------------------------------------------- 1 | ### 实战Kaggle比赛:预测房价 2 | 3 | - 实际上这个时间竞赛已经结束了。 4 | 5 | - 这节目的是提供大家一个实际操作的机会,使用的大多是前面学到的知识。课程提供了代码样本,酒体内容详见含注释的代码中。 6 | - 简单介绍一下数据集的内容,数据集是加州2020年几乎全部的房子交易记录,这里选择前半年的数据作为训练集,后半年作为验证集,包括许多的信息,如:ID,洗手间个数,卧室个数,政府预测价格等等共41个特征,连结如下:https://www.kaggle.com/c/california-house-prices/data?select=train.csv 需要大家自行下载数据集(没有kaglle账户的要注册才可以下载) 7 | - 在真实数据集上,已经提供的程序得到的效果会很差,需要我们使用各种方法来优化,例如dropout,weught decay等,期待大家取得好成绩! -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-03/attic/embedding_sample.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import layers 3 | 4 | target_sentence = [14, 12, 2, 15, 0] # Wait. 5 | embedding_dim = 3 6 | 7 | embedding_layer = layers.Embedding(max(target_sentence) + 1, embedding_dim) 8 | 9 | for s in target_sentence: 10 | result = embedding_layer(tf.constant(s)).numpy() 11 | print("{:>10} => {}".format(s, result)) 12 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/48~全连接卷积神经网络(FCN).md: -------------------------------------------------------------------------------- 1 | ## 48.全连接卷积神经网络(FCN) 2 | 3 | - [48.全连接卷积神经网络(FCN)](#48全连接卷积神经网络fcn) 4 | - FCN 是深度神经网络来做语义分割的奠定性工作,现在用的不多了 5 | - 他用**转置卷积层**来替换 CNN 最后的全连接层(还有池化层),从而实现每个像素的预测。(如果输入的图片是 224 x 224,经过 CNN 变成 7 x 7,经过 transposed conv,可以还原到 224 x 224 x k,k 为通道数) 6 | 7 |
8 | image 9 |
10 | 11 | - 代码 12 | 13 | - 见 code 14 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Common/README.md: -------------------------------------------------------------------------------- 1 | ## Common 2 | 3 | 1. [ActivationFunctions.py](./ActivationFunctions.py) : A collection of activation and their derivative functions, including sigmoid, tanh, linear, ReLU and softmax. 4 | 2. [LanguageTranslationHelper.py](./LanguageTranslationHelper.py) : Helper modules for language translation. 5 | 3. [Layers.py](./Layers.py) : A collection of basic layers including dense (aka Fully Connection), Conv2D, MaxPolling2D and Flatten. 6 | 4. [Optimizer.py](./Optimizer.py) : Stochastic Optimizer(s) 7 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/50~课程竞赛:牛仔行头检测.md: -------------------------------------------------------------------------------- 1 | ## 课程竞赛:牛仔行头检测 2 | 3 | ### 主要内容 4 | 5 | 图像中的目标检测,检测牛仔的装备,主要包括:夹克,墨镜,靴子,牛仔帽,腰带 6 | 7 | 有 6937 张训练图片,12660 个标注框,数据集使用 MS-COCO 格式,可以调用 pycocotools 库,评测使用 mAP(评测对每个类预测的框的好坏) 8 | 9 | 挑战:五个类别出现次数不同,墨镜、夹克次数多,牛仔帽、靴子其次,腰带很少 10 | 11 | ![数据统计](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/50/数据统计.png) 12 | 13 | ### 安排 14 | 15 | Kaggle 不支持 mAP,提交结果 csv 文件时网址不同 16 | 17 | 公私榜分配和之前不同,之前 kaggle 从所有数据中选出一部分作为私榜,本次限定了时间公榜结束后 12 小时内拿到私榜数据并提交结果,至多提交三次 18 | 19 | 提供了一个示例程序 20 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01.cnn/README.md: -------------------------------------------------------------------------------- 1 | ## Appendix 2 | 3 | ### Convolutional Neural Networks 4 | 5 | #### CNN From scratch 6 | 7 | 1. [CNN_from_scratch-1.py](./CNN_from_scratch-1.py) : CNN + Flatten + Softmax 8 | 2. [CNN_from_scratch-2.py](./CNN_from_scratch-2.py) : CNN + MaxPooling + Flatten + Softmax 9 | 3. [CNN_from_scratch-3.py](./CNN_from_scratch-3.py) : CNN + MaxPooling + CNN + MaxPooling + Flatten + Softmax 10 | 11 | #### TensorFlow version 12 | 13 | 1. [CNN_tf_mnist.py](./CNN_tf_mnist.py) : CNN using TensorFlow 14 | 15 | #### Keras verion 16 | 17 | 1. [CNN_keras_mnist.py](./CNN_keras_mnist.py) : CNN using Keras 18 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Appendix/attic/autograd_test.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 4 | 5 | from autograd import grad 6 | 7 | # ======================================== 8 | # 9 | # ======================================== 10 | 11 | x = 0.5 12 | 13 | # Back Propagation 14 | _grad = 12 * x**2 * (2*x**3 + 3) 15 | 16 | print("grad =", _grad) 17 | 18 | print("===================") 19 | 20 | # ======================================== 21 | # 22 | # ======================================== 23 | 24 | def z(x): 25 | y = 2 * x**3 + 3 26 | z = y**2 27 | return z 28 | 29 | gradient_fun = grad(z) 30 | _grad = gradient_fun(x) 31 | print("grad =", _grad) 32 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/61~编码器~解码器架构.md: -------------------------------------------------------------------------------- 1 | ## 编码器-解码器架构 2 | 3 | ### CNN 中的解释 4 | 5 | 考虑一个 CNN 模型: 6 | 7 | ![CNN](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/61/CNN.png) 8 | 9 | 整个 CNN 实际上可以看作一个编码器,解码器两部分。 10 | 11 | - 底层的神经网络,也就是编码器将输入编码成能被模型识别的中间表达形式,也就是特征 12 | - 解码器将中间结果解码为输出 13 | 14 | ### RNN 中的解释 15 | 16 | 对于 RNN 而言,同样有着类似的划分 17 | 18 | ![RNN](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/61/RNN.png) 19 | 20 | - 编码器将输入文本表示为向量 21 | - 解码器将向量表示为输出 22 | 23 | ### 抽象的编码器-解码器架构 24 | 25 | 指一个模型被分为两块: 26 | 27 | - 一块是编码器,也叫 encoder,用于将输入处理为一个中间状态 28 | - 一块是解码器,也叫 decoder,用于将中间状态表示为输出 29 | - 解码器也可以有额外的输入提供信息 30 | 31 | ![encoder-decoder](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/61/encoder-decoder.png) 32 | -------------------------------------------------------------------------------- /神经网络/激活函数/README.md: -------------------------------------------------------------------------------- 1 | # 激活函数 2 | 3 | 构建神经网络中非常重要的一个环节就是选择合适的激活函数(Activation Function),激活函数是为了增加神经网络模型的非线性,也可以看做从数据空间到最终表达空间的一种映射。全连接层只是对数据做仿射变换(affine transformation),而多个仿射变换的叠加仍然是一个仿射变换。解决问题的一个方法是引入非线性变换,例如对隐藏变量使用按元素运算的非线性函数进行变换,然后再作为下一个全连接层的输入。 4 | 5 | ![激活函数对比](https://s1.ax1x.com/2020/10/08/0wN5cQ.png) 6 | 7 | # 激活函数对比 8 | 9 | 仅就 sigmod 与 tahn 相比时,在大部分情况下我们应该优先使用 tahn 函数;除了在最终的输出层,因为输出层我们需要得到的是 0~1 范围内的概率表示。譬如在上面介绍的浅层神经网络中,我们就可以使用 sigmod 作为隐层的激活函数,而使用 tahn 作为输出层的激活函数。 10 | 11 | 不过 sigmod 与 tahn 同样都存在在极大值或者极小值处梯度较小、收敛缓慢的问题。并且采用 sigmoid 等函数,算激活函数时(指数运算),计算量大,反向传播求误差梯度时,求导涉及除法,计算量相对大;而采用 ReLU(rectified linear unit) 激活函数,整个过程的计算量节省很多。此外,ReLU 会使一部分神经元的输出为 0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。 12 | 13 | # Links 14 | 15 | - [从 ReLU 到 GELU,一文概览神经网络的激活函数](https://zhuanlan.zhihu.com/p/98863801) 16 | 17 | - [一文概览深度学习中的激活函数(入门篇)](https://zhuanlan.zhihu.com/p/98472075) 18 | -------------------------------------------------------------------------------- /神经网络/README.md: -------------------------------------------------------------------------------- 1 | # Neural Network 2 | 3 | # Activation Function | 激活函数 4 | 5 | ## Sigmod 6 | 7 | 神经网络中的激活函数,其作用就是引入非线性。具体的非线性形式,则有多种选择。sigmoid 的优点在于输出范围有限,所以数据在传递的过程中不容易发散。当然也有相应的缺点,就是饱和的时候梯度太小。sigmoid 还有一个优点是输出范围为 (0, 1),所以可以用作输出层,输出表示概率。Sigmoid 函数是一个在生物学中常见的 S 型的函数,也称为 S 形生长曲线。Sigmoid 函数由下列公式定义: 8 | 9 | $$ S(x) = \frac{1}{1+ e^{-x}} $$ 10 | 11 | Geoff Hinton covered exactly this topic in his coursera course on neural nets. The problem with sigmoids is that as you reach saturation (values get close to 1 or 0), the gradients vanish. This is detrimental to optimization speed. Softmax doesn't have this problem, and in fact if you combine softmax with a cross entropy error function the gradients are just (z-y), as they would be for a linear output with least squares error. 12 | 13 | 其导数 $f'(x)=f(x)\*[1-f(x)]$,可以节约计算时间 14 | 15 | # Links 16 | 17 | - https://www.zhihu.com/question/314879954/answer/638380202 18 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/00~预告.md: -------------------------------------------------------------------------------- 1 | ## 00-预告 2 | 3 | ### 本节目录 4 | 5 | - [1. 学习深度学习关键是动手](#1-学习深度学习关键是动手) 6 | - [2. 参考书目《动手学深度学习》](#2-参考书目动手学深度学习) 7 | - [3.总结](#3总结) 8 | ### 1. 学习深度学习关键是动手 9 | 10 | - 深度学习是人工智能最热的领域 11 | - 核心是神经网络 12 | - 神经网络是一门语言 13 | - 应该像学习Python/C++一样学习深度学习 14 | 15 | ### 2. 参考书目《动手学深度学习》 16 | 17 | - 是一本深度学习的教科书 18 | - 覆盖90年代至今的重要模型 19 | 20 | - 每一章是一个Jupyter记事本 21 | - 提供所有模型的完整实现 22 | - 在真实数据上运行 23 | 24 | - **原书链接**:[动手学深度学习(原书中文版)](https://zh.d2l.ai/) 25 | 26 | - **项目链接**:[Github项目](https://github.com/d2l-ai/d2l-zh) 27 | 28 | 29 | 30 | - 英文版:2019年推出 31 | 重写了所有章节 32 | 33 | - 加入50%新内容(如Transformer) 34 | Numpy/MXNet, Pytorch和TensorFlow2.0的代码实现 35 | 36 | 37 | 38 | - 课程对应网站:[课程主页](https://courses.d2l.ai/zh-v2/)(包含原视频**课件**等资源) 39 | 40 | - b站**视频**网站:[视频合集](https://space.bilibili.com/1567748478/channel/seriesdetail?sid=358497) 41 | 42 | ### 3.总结 43 | 44 | - 如何学习深度学习——动手跑代码 45 | - 课程资源:书籍、视频、课件等 46 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/DataSets/README.md: -------------------------------------------------------------------------------- 1 | ## DataSets 2 | 3 | ### keras 4 | 5 | This subdirectory contains an English-to-Spanish translation dataset, 6 | which is from "http://download.tensorflow.org/data/spa-eng.zip". 7 | (The original is provided by [Anki](https://www.manythings.org/anki/).) 8 | 9 | ### small_vocabulary_sentences 10 | 11 | This subdirectory contains datasets of small vocabulary sentences that are created from the English-to-Spanish translation dataset in the above subdirectory. 12 | 13 | The "eng-14.txt" file contains sentences with 14 vocabulary words, the "eng-99.txt" file contains sentences with 99 vocabulary words, and so on. 14 | 15 | 16 | ### sentiment_labelled_sentences 17 | 18 | This subdirectory contains three datasets: amazon_cells_labelled.txt, imdb_labelled.txt, and yelp_labelled.txt 19 | 20 | These are downloaded from the site:[Sentiment Labelled Sentences](https://archive.ics.uci.edu/dataset/331/sentiment+labelled+sentences). 21 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/README.md: -------------------------------------------------------------------------------- 1 | ## Part 2: Recurrent Neural Networks 2 | 3 | 4 | ### Simple RNN 5 | 6 | 1. [RNN_from_scratch.py](./RNN_from_scratch.py) : Simple RNN from scratch version. 7 | 2. [RNN_tf.py](./RNN_tf.py) : Simple RNN TensorFlow version. 8 | 3. [RNN_keras.py](./RNN_keras.py) : Simple RNN Keras version. 9 | 4. [RNN_pt.py](./RNN_pt.py) : Simple RNN PyTorch version. 10 | 11 | ### LSTM 12 | 13 | 1. [LSTM_from_scratch.py](./LSTM_from_scratch.py) : LSTM from scratch version. 14 | 2. [LSTM_tf.py](./LSTM_tf.py) : LSTM TensorFlow version. 15 | 3. [LSTM_keras.py](./LSTM_keras.py) : LSTM Keras version. 16 | 4. [LSTM_pt.py](./LSTM_pt.py) : LSTM PyTorch version. 17 | 18 | ### GRU 19 | 20 | 1. [GRU_from_scratch.py](./GRU_from_scratch.py) : GRU from scratch version. 21 | 2. [GRU_tf.py](./GRU_tf.py) : GRU TensorFlow version. 22 | 3. [GRU_keras.py](./GRU_keras.py) : GRU Keras version. 23 | 4. [GRU_pt.py](./GRU_pt.py) : GRU PyTorch version. 24 | 25 | ### Utils 26 | 27 | 1. [DataSet.py](./DataSet.py) 28 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/DataSet.py: -------------------------------------------------------------------------------- 1 | # 2 | # Data set generator. 3 | # 4 | # Developed environment: 5 | # Python 3.9.13 6 | # pip 23.1.2 7 | # conda 22.11.1 8 | # numpy 1.23.3 9 | 10 | import numpy as np 11 | 12 | # Create a sine wave. 13 | def create_wave(n_data=100, noise=0.05): 14 | _x_range = np.linspace(0, 2 * 2 * np.pi, n_data) 15 | return np.sin(_x_range) + noise * np.random.randn(len(_x_range)) 16 | 17 | # Generate a data set. 18 | def dataset(wave, n_sequence=25, return_sequences=False): 19 | 20 | n_sample = len(wave) - n_sequence 21 | 22 | x = np.zeros((n_sample, n_sequence, 1, 1)) 23 | if return_sequences == True: 24 | y = np.zeros((n_sample, n_sequence, 1)) 25 | else: 26 | y = np.zeros((n_sample, 1, 1)) 27 | 28 | for i in range(n_sample): 29 | x[i, :, 0, 0] = wave[i : i + n_sequence] 30 | if return_sequences == True: 31 | y[i, :, 0] = wave[i + 1 : i + n_sequence + 1] 32 | else: 33 | y[i, 0] = wave[i + n_sequence] 34 | 35 | return x, y 36 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/16~Pytorch神经网络基础.md: -------------------------------------------------------------------------------- 1 | ## Pytorch神经网络基础 2 | 3 | ### 层和块 4 | 5 | 在之前的内容中,我们认识了一些神经网络,比如:线性回归,Softmax回归,多层感知机;他们有的是整个模型,有的是一层神经网络,有的甚至只是一个单元,他们的功能以及复杂程度也各不相同,但他们都有着如下三个特征: 6 | 7 | * 接受一些输入 8 | * 产生对应的输出 9 | * 由一组可调整参数描述 10 | 11 | 对于一些复杂的网络,研究讨论比层大但比整个模型小的部分很有意义,因为复杂的网络中经常有重复出现的部分,每个部分也常常有自己的功能。考虑到上面的三个特征,这就使得我们思考是否可以对这些部分进行一个抽象,这就得到了块的概念:块指单个层,多个层组成的部分,或者整个模型本身。使用块对整个模型进行描述就简便许多,这一过程是递归的,块的内部还可以划分为多个块,直至满足需要为止。 12 | 13 | PyTorch帮我们实现了块的大部分所需功能,包括自动求导,我们只需从nn.Module继承并改写其中的一部分就能得到我们需要的块以及模型,具体做法和细节见代码中的注释 14 | 15 | ### 参数管理 16 | 17 | 在选择了架构并设置了超参数后,我们就进入了训练阶段。此时,我们的目标是找到使损失函数最小化的模型参数值。经过训练后,我们将需要使用这些参数来做出未来的预测。此外,有时我们希望提取参数,以便在其他环境中复用它们,将模型保存下来,以便它可以在其他软件中执行,或者为了获得科学的理解而进行检查。 18 | 19 | 此部分主要为代码实现,笔记见代码中的注释 20 | 21 | ### 延后初始化 22 | 23 | 有时在建立网络时,我们不会指定网络的输入输出维度,也就不能确定网络的参数形状,深度学习框架支持延后初始化,即当第一次将数据传入模型时自动的得到所有的维度,然后初始化所有的参数。 24 | 25 | PyTorch也支持这一点,比如nn.LazyLinear,但本门课程中并未介绍。 26 | 27 | ### 自定义层 28 | 29 | 深度学习成功背后的一个因素是神经网络的灵活性:我们可以用创造性的方式组合不同的层,从而设计出适用于各种任务的架构。例如,研究人员发明了专门用于处理图像、文本、序列数据和执行动态规划的层。同样的,对于层而言,深度学习框架并不能满足我们所有的需求,然而,层本身也具有极大的灵活性,我们可以自定义想要的层。 30 | 31 | 此部分主要为代码实现,笔记见代码中的注释 32 | 33 | ### 读写文件 34 | 35 | 到目前为止,我们讨论了如何处理数据,以及如何构建、训练和测试深度学习模型。然而,有时我们希望保存训练的模型,以备将来在各种环境中使用(比如在部署中进行预测)。此外,当运行一个耗时较长的训练过程时,最佳的做法是定期保存中间结果,以确保在服务器电源被不小心断掉时,我们不会损失几天的计算结果。 -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/DataSets/sentiment_labelled_sentences/readme.txt: -------------------------------------------------------------------------------- 1 | This dataset was created for the Paper 'From Group to Individual Labels using Deep Features', Kotzias et. al,. KDD 2015 2 | Please cite the paper if you want to use it :) 3 | 4 | It contains sentences labelled with positive or negative sentiment, extracted from reviews of products, movies, and restaurants 5 | 6 | ======= 7 | Format: 8 | ======= 9 | sentence \t score \n 10 | 11 | 12 | ======= 13 | Details: 14 | ======= 15 | Score is either 1 (for positive) or 0 (for negative) 16 | The sentences come from three different websites/fields: 17 | 18 | imdb.com 19 | amazon.com 20 | yelp.com 21 | 22 | For each website, there exist 500 positive and 500 negative sentences. Those were selected randomly for larger datasets of reviews. 23 | We attempted to select sentences that have a clearly positive or negative connotaton, the goal was for no neutral sentences to be selected. 24 | 25 | 26 | 27 | For the full datasets look: 28 | 29 | imdb: Maas et. al., 2011 'Learning word vectors for sentiment analysis' 30 | amazon: McAuley et. al., 2013 'Hidden factors and hidden topics: Understanding rating dimensions with review text' 31 | yelp: Yelp dataset challenge http://www.yelp.com/dataset_challenge 32 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-03/README.md: -------------------------------------------------------------------------------- 1 | ## Part 3: Natural Language Processing and Attention Mechanisms 2 | 3 | ### Language Models 4 | 5 | 1. [Bigram-count-based.py](./Bigram-count-based.py) : Last word prediction using Bigram 6 | 2. [Trigram-count-based.py](./Trigram-count-based.py) : Last word prediction using Trigram 7 | 3. [LanguageModel-RNN-tf.py](./LanguageModel-RNN-tf.py) : Last word prediction using RNN-based language model 8 | 9 | ### Sequence Classification 10 | 11 | 1. [SentimentAnalysis-GRU-tf.py](./SentimentAnalysis-GRU-tf.py) : Sentiment Analysis using RNN-based language model 12 | 2. [SentimentAnalysis-GRU-tf-attention.py](./SentimentAnalysis-GRU-tf-attention.py) : Sentiment Analysis using RNN-based language model with attention mechanism 13 | 14 | ### Natural Language Translation 15 | 16 | 1. [seq2seq-tf.py](./seq2seq-tf.py) : A translator from Spanish to English by encoder-decoder model 17 | 2. [seq2seq-tf-attention.py](./seq2seq-tf-attention.py) : A translator from Spanish to English by encoder-decoder model with attention mechanism 18 | 19 | 20 | ### Utils 21 | 22 | 1. [Attention.py](./Attention.py) : A class of Attention mechanisms 23 | 2. [Tokenizer.py](./Tokenizer.py) : A subset class of the [LanguageTranslationHelper.py](../Common/LanguageTranslationHelper.py)@Common 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all 2 | * 3 | 4 | # Unignore all with extensions 5 | !*.* 6 | 7 | # Unignore all dirs 8 | !*/ 9 | 10 | .DS_Store 11 | 12 | # Logs 13 | logs 14 | *.log 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (https://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | jspm_packages/ 49 | 50 | # TypeScript v1 declaration files 51 | typings/ 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | 71 | # next.js build output 72 | .next 73 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Appendix/gd.py: -------------------------------------------------------------------------------- 1 | # 2 | # Gradient Descent Algorithm 3 | # 4 | 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | from matplotlib.animation import FuncAnimation 8 | 9 | # 10 | # Define functions 11 | # 12 | bias = 4 13 | 14 | 15 | def L(x): 16 | return (x - bias) ** 2 / 2 17 | 18 | def dL(x): 19 | # Calculates the gradient of the function L(x) at a given x. 20 | return (x - bias) 21 | 22 | 23 | # 24 | # Gradient Descent Algorithm 25 | # 26 | 27 | # learning rate 28 | lr = 0.1 29 | 30 | # initialize x 31 | x = 14 32 | 33 | # Training loop 34 | val_list = [] 35 | grad_list = [] 36 | 37 | for epoch in range(300): 38 | 39 | # update x 40 | x = x - lr * dL(x) 41 | 42 | val_list.append((np.round(x, 3), np.round(L(x), 5))) 43 | grad_list.append(np.round(dL(x), 5)) 44 | 45 | print("x_min = {:.3f}\t=> L({:.3f}) = {:.3f}".format(x, x, L(x))) 46 | 47 | # 48 | # Display animation 49 | # 50 | fig, ax = plt.subplots() 51 | 52 | x = np.linspace(-5, 15) 53 | 54 | L = L(x) 55 | plt.plot(x, L) 56 | plt.ylabel("L(x)") 57 | plt.xlabel("x") 58 | 59 | 60 | def draw_step(i, val_list): 61 | ax.scatter(val_list[i][0], val_list[i][1], s=30, c="red") 62 | 63 | 64 | ani = FuncAnimation(fig, draw_step, frames=len(val_list), fargs=(val_list,)) 65 | 66 | plt.show() 67 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/32~深度学习硬件.md: -------------------------------------------------------------------------------- 1 | ## 32-深度学习硬件 2 | ### 目录 3 | - [32-深度学习硬件](#32-深度学习硬件) 4 | - [目录](#目录) 5 | - [1.DSP:数字信号处理](#1dsp数字信号处理) 6 | - [2.可编程阵列(FPGA)](#2可编程阵列fpga) 7 | - [3.AI ASIC](#3ai-asic) 8 | - [总结](#总结) 9 | 10 | - 本节我们介绍除了 GPU CPU 之外更多的芯片 11 | - 引入:手机内部的芯片有很多——GPU CPU ISP WIFI…… 12 | 13 | ### 1.DSP:数字信号处理 14 | 15 | - 为数字信号处理算法设计:点积、卷积、FFT 16 | 17 | - 低功耗,高性能 18 | - 比移动GPU快5倍,功耗更低 19 | - VLIW:very long instruction word 20 | - 频率低,核少,但是一条指令可以进行上百次的累加,便于重复 21 | - 缺点:编程和调试困难,编译器良莠不齐(做的人少,工具不是很好用) 22 | 23 | ### 2.可编程阵列(FPGA) 24 | 25 | - 有大量的可以用来编程的逻辑单元和可配置链接 26 | - 可以配置成计算复杂函数 27 | - 编程语言:VHDL Verilog 28 | - 通常比通用硬件更高效,但是体积更大不方便 29 | - 缺点:工具链质量良莠不齐,一次编译需要数个小时(烧一次板子,物理上的改变) 30 | - 用途:主要用来模拟,看看效果好不好,如果好可以进一步造芯片 31 | 32 | ### 3.AI ASIC 33 | 34 | - 深度学习热门领域(针对特定领域) 35 | - 大公司都在造自己的芯片(Intel Qualcomm Google Amazon Facebook) 36 | - Google TPU 是标志性芯片(听说在Google内部已经盛行 取代GPU了) 37 | - 能够媲美 Nvidia GPU性能 38 | - 在Google 大量部署 39 | - 核心是 systolic array(时间快 容易造) 40 | - systolic array 41 | - 计算单元(PE)阵列 42 | - 特别适合做矩阵乘法 43 | - 设计和制造相对简单(核少) 44 | - 矩阵乘法例子:见PPT 45 | - 对于一般的矩阵乘法:通过切开、填充来匹配SA大小 46 | - 批量输入来降低延迟(避免空等,先出的硬件空闲) 47 | - 通常有其他硬件单元来处理别的NN操作子,例如激活层 48 | - 缺点:只针对深度学习这方面有用,别的方面效果不大 49 | 50 | ### 总结 51 | 52 | - 灵活性、易用性:Intel(CPU) > GPU > DSP > FPGA > ASIC 53 | - 性能功耗:Intel(CPU) < GPU < DSP < FPGA < ASIC -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/attic/debug-relu.py: -------------------------------------------------------------------------------- 1 | # 2 | # Debugging for ReLU 3 | # 4 | # 5 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 6 | 7 | import autograd.numpy as np 8 | from autograd import grad 9 | 10 | units_size = 10 11 | 12 | # 13 | # Prepare inputs and outputs 14 | # 15 | 16 | x = np.arange(units_size) / 10 - units_size/ 20 17 | x = x.reshape(units_size, 1) 18 | 19 | Y = np.arange(units_size) / 10 - units_size/ 20 20 | Y = Y.reshape(units_size, 1) 21 | 22 | # =================== 23 | # ReLU 24 | # =================== 25 | 26 | y = np.maximum(0, x) 27 | Y = np.maximum(0, x) * 0.1 28 | 29 | ################################################ 30 | # Back Propagation 31 | ################################################ 32 | 33 | dL = (y - Y) 34 | 35 | dh = np.where(x > 0, 1, 0) * dL 36 | 37 | print("========== BP ==========") 38 | 39 | print("dh =", dh) 40 | 41 | ################################################ 42 | # CHECK 43 | ################################################ 44 | 45 | print("========== Autograd ==========") 46 | 47 | def relu(x): 48 | return np.maximum(0, x) 49 | 50 | 51 | def loss(x, Y): 52 | return np.sum((relu(x) - Y) ** 2 / 2) 53 | 54 | gradient_fun = grad(loss) 55 | 56 | weights = gradient_fun(x, Y) 57 | print("{} = {}".format("dh", weights)) 58 | print("\t=> OK") if np.allclose(weights, dh) else print("***** ERROR!!!") 59 | 60 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/54~循环神经网络RNN.md: -------------------------------------------------------------------------------- 1 | - [循环神经网络RNN](#循环神经网络rnn) 2 | - [使用潜变量](#使用潜变量) 3 | - [RNN](#rnn) 4 | - [困惑度](#困惑度) 5 | - [梯度裁剪](#梯度裁剪) 6 | - [更多的应用RNNs](#更多的应用rnns) 7 | 8 | ### 使用潜变量 9 | 10 | - RNN使用了隐藏层来记录过去发生的所有事件的信息,从而引入时许的特性,并且避免常规序列模型每次都要重新计算前面所有已发生的事件而带来的巨大计算量。![截屏2022-02-12 下午2.17.32](https://github.com/kinza99/DeepLearning-MuLi-Notes/blob/main/imgs/54/54-01.png) 11 | 12 | ### RNN 13 | 14 | - 流程如下,首先有一个输入序列,对于时刻t,我们用t-1时刻的输入x~t-1~和潜变量h~t-1~来计算新的潜变量h~t~。同时,对于t时刻的输出o~t~,则直接使用h~t~来计算得到。注意,计算第一个潜变量只需要输入即可(因为前面并不存在以往的潜变量)。![截屏2022-02-12 下午2.34.14](https://github.com/kinza99/DeepLearning-MuLi-Notes/blob/main/imgs/54/54-02.png) 15 | - 值得注意的是,RNN本质也是一种MLP,尤其是将h~t-1~这一项去掉时就完全退化成了MLP。RNN的核心其实也就是h~t-1~这一项,它使得模型可以和前面的信息联系起来,将时序信息储存起来,可以把RNN理解为是包含时序信息的MLP。 16 | 17 | ### 困惑度 18 | 19 | - 为了衡量一个语言模型的好坏,例如分类模型,可以使用平均交叉熵来衡量,就是将预测概率的负对数值求和之后再去平均,即常用的交叉熵损失。但是由于某些历史原因,NLP往往不是用这种方式,而是在这种方式的基础上最后再取指数,即exp,这样得到的结果如果是1,说明完美;如果是无穷大,说明结果很差。 20 | 21 | ### 梯度裁剪 22 | 23 | - 在T个时间步中进行反向传播,会由于产生O(T)长度的梯度乘法链,导致导数数值不稳定,这里使用一个限制θ,通常为5到10,来控制梯度乘法链的长度。使用如下的公式![截屏2022-02-12 下午3.10.38](https://github.com/kinza99/DeepLearning-MuLi-Notes/blob/main/imgs/54/54-03.png)在这个公式中,如果梯度长度大于θ,梯度g会变为 24 | $$ 25 | \frac{\theta}{\Vert g \Vert} g 26 | $$ 27 | 这样再对g求2范式就变成了θ,所以可以把梯度限制在θ以下。 28 | 29 | ### 更多的应用RNNs 30 | 31 | - 基本的应用如下图![截屏2022-02-12 下午3.36.29](https://github.com/kinza99/DeepLearning-MuLi-Notes/blob/main/imgs/54/54-04.png) 32 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Appendix/attic/sigmoid_tanh.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | 4 | np.random.seed(0) 5 | 6 | def sigmoid(x): 7 | return 1 / (1 + np.exp(-x)) 8 | 9 | 10 | def deriv_sigmoid(x): 11 | return sigmoid(x) * (1 - sigmoid(x)) 12 | 13 | 14 | def tanh(x): 15 | return np.tanh(x) 16 | 17 | def deriv_tanh(x): 18 | return (1 - np.tanh(x)**2) 19 | 20 | 21 | 22 | Range = 10 23 | Div = 10 24 | 25 | # 26 | # Sigmoid 27 | # 28 | X = [] 29 | func = [] 30 | d1_func = [] 31 | 32 | for J in range(-1 * Range * Div, Range * Div): 33 | i = float(J / Div) 34 | X.append(i) 35 | 36 | func.append(sigmoid(i)) 37 | d1_func.append(deriv_sigmoid(i)) 38 | 39 | plt.plot(X, func, color="b", label="f(x) = sigmoid(x)") 40 | plt.plot(X, d1_func, color="r", label="df(x)/dx") 41 | 42 | plt.title("sigmoid function") 43 | plt.xlabel("x") 44 | plt.ylabel("f(x)") 45 | plt.legend() 46 | plt.show() 47 | 48 | # 49 | # Tanh 50 | # 51 | X = [] 52 | func = [] 53 | d1_func = [] 54 | 55 | for J in range(-1 * Range * Div, Range * Div): 56 | i = float(J / Div) 57 | X.append(i) 58 | 59 | func.append(tanh(i)) 60 | d1_func.append(deriv_tanh(i)) 61 | 62 | plt.plot(X, func, color="b", label="f(x) = tanh(x)") 63 | plt.plot(X, d1_func, color="r", label="df(x)/dx") 64 | 65 | plt.title("tanh function") 66 | plt.xlabel("x") 67 | plt.ylabel("f(x)") 68 | plt.legend() 69 | plt.show() 70 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/33~单机多卡并行.md: -------------------------------------------------------------------------------- 1 | ## 单机多卡并行 2 | 3 | 一台机器可以安装多个 GPU(一般为 1-16 个),在训练和预测时可以将一个小批量计算切分到多个 GPU 上来达到加速目的,常用的切分方案有数据并行,模型并行,通道并行。 4 | 5 | ### 数据并行 6 | 7 | 将小批量的数据分为 n 块,每个 GPU 拿到完整的参数,对这一块的数据进行前向传播与反向传播,计算梯度。 8 | 9 | 数据并行通常性能比模型并行更好,因为对数据进行划分使得各个 GPU 的计算内容更加均匀。 10 | 11 | #### 数据并行的大致流程 12 | 13 | ![DataParallel](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/33/DataParallel.png) 14 | 15 | 主要分为五部 16 | 17 | - 1:每个 GPU 读取一个数据块(灰色部分) 18 | - 2:每个 GPU 读取当前模型的参数(橙色部分) 19 | - 3:每个 GPU 计算自己拿到数据块的梯度(绿色部分) 20 | - 4:GPU 将计算得到的梯度传给内存(CPU)(绿色箭头) 21 | - 5:利用梯度对模型参数进行更新(橙色箭头) 22 | 23 | 数据并行并行性较好,主要因为当每个 GPU 拿到的数据量相同时计算量也相似,各个 GPU 的运算时间相近,幸能较好 24 | 25 | ### 模型并行 26 | 27 | 将整个模型分为 n 个部分,每个 GPU 拿到这个部分的参数和负责上一个部分的 GPU 的输出作为输入来进行计算,反向传播同理。 28 | 29 | 模型并行通常用于模型十分巨大,参数众多,即使在每个 mini-batch 只有一个样本的情况下单个 GPU 的显存仍然不够的情况,但并行性较差,可能有时会有 GPU 处于等待状态。 30 | 31 | ### 通道并行 32 | 33 | 通道并行是数据并行和模型并行同时进行 34 | 35 | ### 总结 36 | 37 | - 当一个模型能用单卡计算时,通常使用数据并行扩展到多卡 38 | - 模型并行则用在超大模型上 39 | 40 | ### Q&A(部分有价值的) 41 | 42 | - 问 1:若有 4 块 GPU,两块显存大两块显存小怎么办? 43 | - 答 1: 44 | 若 GPU 运算性能相同,则训练取决于小显存的 GPU 的显存大小,更大的显存相当于浪费掉 45 | 若 GPU 运算性能不同,一般即为显存大的 GPU 性能更好,可以在分配数据时多分配一点 46 | - 47 | - 问 2:数据拆分后,需存储的数据量会变大吗?会降低性能吗? 48 | - 答 2:每个 GPU 都单独存储了一份模型,这部分的数据量变大了,但如果只考虑运算时的中间变量,则中间变量的大小与数据量呈线性关系,每个 GPU 的数据小了,中间变量也会变小,所有 GPU 的中间变量加起来大小是不变的。 49 | 数据拆分后性能会变低,在下节课讲解(数据通讯的开销,每个 GPU 的 batch-size 变小可能无法跑满 GPU,总 batch-size 变大则相同计算量下训练次数变少) 50 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/37~微调.md: -------------------------------------------------------------------------------- 1 | # 微调 2 | 3 | - [微调](#微调) 4 | - [背景](#背景) 5 | - [步骤](#步骤) 6 | - [总结](#总结) 7 | 8 | ### 背景 9 | 10 | - 很多时候,例如我们想对家具进行分类,但是往往在努力收集数据得到的数据集也比较小假如我们想识别图片中不同类型的椅子,然后向用户推荐购买链接。一种可能的方法是首先识别 100 把普通椅子,为每把椅子拍摄 1000 张不同角度的图像,然后在收集的图像数据集上训练一个分类模型。尽管这个椅子数据集可能大于 Fashion-MNIST 数据集,但实例数量仍然不到 ImageNet 中的十分之一。适合 ImageNet 的复杂模型可能会在这个椅子数据集上过拟合。此外,由于训练样本数量有限,训练模型的准确性可能无法满足实际要求。为了避免这种情况,我们可以有两种方法: 11 | - 显然的想法就是收集更多的数据,但是,收集和标记数据可能需要大量的时间和金钱。例如,为了收集 ImageNet 数据集,研究人员花费了数百万美元的研究资金。尽管目前的数据收集成本已大幅降低,但这一成本仍不能忽视。 12 | - 我们可以考虑迁移学习将从*源数据集*学到的知识迁移到*目标数据集*。例如,尽管 ImageNet 数据集中的大多数图像与椅子无关,但在此数据集上训练的模型可能会提取更通用的图像特征,这有助于识别边缘、纹理、形状和对象组合。这些类似的特征也可能有效地识别椅子。 13 | 14 | ### 步骤 15 | 16 | - 如图所示,微调包括以下四个步骤: 17 | 1. 在源数据集(例如 ImageNet 数据集)上预训练神经网络模型,即**_源模型_**。 18 | 2. 创建一个新的神经网络模型,即**_目标模型_**。这将复制源模型上的所有模型设计及其参数(输出层除外)。我们假定这些模型参数包含从源数据集中学到的知识,这些知识也将适用于目标数据集。我们还假设源模型的输出层与源数据集的标签密切相关;因此不在目标模型中使用该层。 19 | 3. 向目标模型添加输出层,其输出数是目标数据集中的类别数。然后随机初始化该层的模型参数。 20 | 4. 在目标数据集(如椅子数据集)上训练目标模型。输出层将从头开始进行训练,而所有其他层的参数将根据源模型的参数进行微调。 21 | 22 |
23 | image 24 |
25 | 26 | 5. 通常来讲,微调速度更快,并且具有较强的正则性,一般学习率比较小,也不需要很多轮的数据迭代,对于不同的任务往往只需要改变最后输出层,这一层随机初始化即可。 27 | 28 | ### 总结 29 | 30 | - 迁移学习将从源数据集中学到的知识“迁移”到目标数据集,微调是迁移学习的常见技巧。 31 | - 除输出层外,目标模型从源模型中复制所有模型设计及其参数,并根据目标数据集对这些参数进行微调。但是,目标模型的输出层需要从头开始训练。 32 | - 通常,微调参数使用较小的学习率,而从头开始训练输出层可以使用更大的学习率。 33 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/01~课程安排.md: -------------------------------------------------------------------------------- 1 | ## 01-课程安排 2 | 3 | ### 本节目录 4 | 5 | - [1. 课程目标](#1-课程目标) 6 | - [2. 内容](#2-内容) 7 | - [3. 学到什么](#3-学到什么) 8 | - [4. 基本要求](#4-基本要求) 9 | - [5. 课程资源](#5-课程资源) 10 | - [6. 总结](#6-总结) 11 | 12 | ### 1. 课程目标 13 | 14 | - 介绍深度学习经典和最新模型 15 | - LeNet, ResNet, LSTM, BERT, ... 16 | - 机器学习基础 17 | - 损失函数、目标函数、过拟合、优化 18 | - 实践 19 | - 使用 Pytorch 实现介绍的知识点 20 | - 在真实数据上体验算法效果 21 | 22 | ### 2. 内容 23 | 24 | > 深度学习基础:线性神经网络,多层感知机 25 | > 26 | > 卷积神经网络:LeNet, AlexNet, VGG, Inception, ResNet 27 | > 28 | > 循环神经网络:RNN,GRU,LSTM,seq2seq 29 | > 30 | > 注意力机制:Attention,Transformer 31 | > 32 | > 优化算法:SGD,Momentum,Adam 33 | > 34 | > 高性能计算:并行,多 GPU,分布式 35 | > 36 | > 计算机视觉:目标检测,语义分割 37 | > 38 | > 自然语言处理:词嵌入,BERT 39 | 40 | ### 3. 学到什么 41 | 42 | - What:深度学习有哪些技术,以及哪些技术可以帮你解决问题 43 | - How:如何实现(产品 or paper)和调参(精度 or 速度) 44 | - Why:背后的原因(直觉、数学) 45 | 46 | ### 4. 基本要求 47 | 48 | - **AI 相关从业人员**(产品经理等):掌握 What,知道名词,能干什么 49 | - **数据科学家、工程师**:掌握 What、How,手要快,能出活 50 | - **研究员、学生**:掌握 What、How、Why,除了知道有什么和怎么做,还要知道为什么,思考背后的原因,做出新的突破 51 | 52 | ### 5. 课程资源 53 | 54 | - 课程主页:[https://courses.d2l.ai/zh-v2/](https://courses.d2l.ai/zh-v2/) 55 | - 教材:[https://zh-v2.d2l.ai/](https://zh-v2.d2l.ai/) 56 | - 课程论坛讨论:[https://discuss.d2l.ai/c/chinese-version/16](https://discuss.d2l.ai/c/chinese-version/16) 57 | - Pytorch 论坛:[https://discuss.pytorch.org/](https://discuss.pytorch.org/) 58 | - b 站视频合集:[https://space.bilibili.com/1567748478/channel/seriesdetail?sid=358497]( 59 | 60 | ### 6. 总结 61 | 62 | - 课程目标、内容和要求 63 | - 相关课程资源链接 64 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/63~束搜索.md: -------------------------------------------------------------------------------- 1 | ## 束搜索 2 | 3 | 在序列生成问题中,常用的方法是一个个词元地进行生成,但是先前步生成的词元会影响之后词元的概率分布,为此,我们需要使用搜索算法来得到一个较好的序列 4 | 5 | ### 贪心搜索 6 | 7 | 贪心搜索即每个时间步都选择具有最高条件概率的词元。 8 | 9 | $$ 10 | y_{t'} = \operatorname*{argmax}_{y \in \mathcal{Y}} P(y \mid y_1, \ldots, y_{t'-1}, \mathbf{c}) 11 | $$ 12 | 13 | 我们的目标是找到一个最有序列,他的联合概率,也就是每步之间的条件概率的乘积,最大。 14 | 15 | $$ 16 | \prod_{t'=1}^{T'} P(y_{t'} \mid y_1, \ldots, y_{t'-1}, \mathbf{c}) 17 | $$ 18 | 19 | 然而,贪心搜索很可能搜索到的不是最优解,例如:![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/63/Greedy_or_not.png) 20 | 21 | 左侧的搜索方式为贪心搜索,每次找到当前条件概率最大的选项进行预测,但是这样可能会导致之后的条件概率较小,从而导致最终的联合概率较小,生成的序列不优。 22 | 23 | 而右侧的选择方式虽然在第二步选择了较小的选项,但之后在第三步时有了条件概率为 0.6 选项,最终结果反而更好。 24 | 25 | ### 穷举搜索 26 | 27 | 穷举搜索枚举所有可能的输出序列及其概率,然后选择概率最大的作为最终的输出,枚举搜索可以保证得到最优解,但是计算复杂度很高,难以实现 28 | 29 | ### 束搜索(beam search) 30 | 31 | 束搜索综合了贪心搜索和穷举搜索,在能接受的计算成本下得到比贪心搜索更好的结果。 32 | 33 | 束搜索有一个超参数,名为**束宽(beam size)**$k$,束搜索的具体流程如下: 34 | 35 | - 1:在第一时间步选择条件概率最高的 k 个选项 36 | - 2:对随后的每个时间步,基于上一时间步的 k 个候选输出序列预测这一时间步的所有可能选项的条件概率,从中取 k 个最大的 37 | 38 | - 3:最后基于每步得到的序列,删去截止符和其后元素,获得最终候选序列集合,取出加权条件概率最大的 39 | 40 | 加权条件概率公式如下: 41 | 42 | $$ 43 | \frac{1}{L^\alpha} \log P(y_1, \ldots, y_{L}\mid \mathbf{c}) = \frac{1}{L^\alpha} \sum_{t'=1}^L \log P(y_{t'} \mid y_1, \ldots, y_{t'-1}, \mathbf{c}), 44 | $$ 45 | 46 | 式中$\frac{1}{L^\alpha}$用于调整长序列的评估值使得长短序列间的比较公平 47 | 48 | 束宽 k 的选择: 49 | 50 | - k=1 时实际为贪心搜索 51 | - k 越小搜索速度越快,但结果越差,k 越大则搜索速度越慢,但结果越好 52 | 53 | 束搜索只在测试时使用 54 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/58~深层循环神经网络.md: -------------------------------------------------------------------------------- 1 | ## 58 深层循环神经网络 2 | 3 | ### 目录 4 | 5 | * [1.深层循环神经网络](#1深层循环神经网络) 6 | * [2.公式](#2公式) 7 | * [3.总结](#3总结) 8 | * [4.QA](#4qa) 9 | 10 | ### 1.深层循环神经网络 11 | 12 | 之前讲的RNN都只有一个隐藏层(序列变长不算是深度),而一个隐藏层的RNN一旦做的很宽就容易出现过拟合。因此我们考虑将网络做的更深而非更宽,每层都只做一点非线性,靠层数叠加得到更加非线性的模型。 13 | 14 | 浅RNN:输入-隐层-输出 15 | 16 | 深RNN:输入-隐层-隐层-...-输出 17 | 18 | 58-01 19 | 20 | (课程视频中的图片有错误,最后输出层后一时间步是不受前一步影响的,即没有箭头) 21 | 22 | ### 2.公式 23 | 24 |
25 | 26 | ![](http://latex.codecogs.com/svg.latex?\mathbf{H}_t^1=f_1(\mathbf{H_{t-1}^1},\mathbf{X_t})) 27 | 28 |
29 | 30 | *第一层的第t步状态是关于第一层第t-1步状态和第t步输入的函数* 31 |
32 | 33 | ![](http://latex.codecogs.com/svg.latex?\mathbf{H}_t^j=f_j(\mathbf{H_{t-1}^j},\mathbf{H_{t}^{j-1})}) 34 | 35 |
36 | *第j层的第t步状态是关于当前层上一步步状态和上一层当前步的函数* 37 | 38 |
39 | 40 | ![](http://latex.codecogs.com/svg.latex?\mathbf{O}_t=g(\mathbf{H}_t^L)) 41 | 42 |
43 | *由最后一个隐藏层得到输出* 44 | 45 | ### 3.总结 46 | 47 | - 深度循环神经网络使用多个隐藏层来获得更多的非线性性 48 | 49 | 将RNN/GRU/LSTM做深都是一个道理,三者只是使用的函数f不同。 50 | 51 | ### 4.QA 52 | 53 | Q1: NLP那个方向好找工作?文本翻译是不是现在只在学术研究中才需要自己实现?(2021-7-27) 54 | 55 | > 文本翻译已经是一个很成熟的领域,NLP挺好找工作,人产生的文本远多于图片。 56 | 57 | Q2: 关于BPTT 58 | 59 | > 课上不讲,书上有讲原理 60 | 61 | Q3: 深层RNN是不是每层都需要一个初始hidenstate? 62 | 63 | > 是的 64 | 65 | Q4: 可不可以手动实现hidden_size不一样的多层RNN? 66 | 67 | > 应该没问题,但通常大家不会去调hidden_size,因为网络不会做的很深,最后还有全连接层。 68 | 69 | Q5: 关于课上提到的classifier 70 | 71 | > 分类的任务在最后的全连接层完成 72 | -------------------------------------------------------------------------------- /99~参考资料/2019~《Deep Learning Book》/13~Linear Factor Models.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# The Deep Learning Book (Simplified)\n", 8 | "## Part II - Modern Practical Deep Networks\n", 9 | "*This is a series of blog posts on the [Deep Learning book](http://deeplearningbook.org)\n", 10 | "where we are attempting to provide a summary of each chapter highlighting the concepts that we found to be the most important so that other people can use it as a starting point for reading the chapters, while adding further explanations on few areas that we found difficult to grasp. Please refer [this](http://www.deeplearningbook.org/contents/notation.html) for more clarity on \n", 11 | "notation.*\n", 12 | "\n", 13 | "\n", 14 | "## Chapter 13: Linear Factor Models" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": null, 20 | "metadata": {}, 21 | "outputs": [], 22 | "source": [] 23 | } 24 | ], 25 | "metadata": { 26 | "kernelspec": { 27 | "display_name": "Python 2", 28 | "language": "python", 29 | "name": "python2" 30 | }, 31 | "language_info": { 32 | "codemirror_mode": { 33 | "name": "ipython", 34 | "version": 2 35 | }, 36 | "file_extension": ".py", 37 | "mimetype": "text/x-python", 38 | "name": "python", 39 | "nbconvert_exporter": "python", 40 | "pygments_lexer": "ipython2", 41 | "version": "2.7.12" 42 | } 43 | }, 44 | "nbformat": 4, 45 | "nbformat_minor": 2 46 | } 47 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/49~样式迁移.md: -------------------------------------------------------------------------------- 1 | ## 样式迁移 2 | 3 | 样式迁移类似于手机相机中的滤镜,指的是给定内容图片和风格图片,合成一张新的图片,使得他的内容与内容图片相似,而风格却是风格图片的样子,如下例: 4 | 5 | ![样式迁移示例](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/49/样式迁移示例.png) 6 | 7 | ### 方法 8 | 9 | 如下图所示,可以用一个预训练好的神经网络来实现样式迁移: 10 | 11 | - 1:复制内容图片来初始化一张图片,之后将这张图片中的像素作为参数进行更新,最终得到合成的图片 12 | - 2:将内容图片,当前的合成图片,样式图片分别输入一个相同的预训练好的神经网络 13 | - 3:假设该神经网络的不同层分别提取与内容和风格相关的信息,可以据此得到一个损失: 14 | - 将合成图片与**内容**相关的层的输出与**内容**图片对应层的输出进行处理,得到**内容损失** 15 | - 将合成图片与**风格**相关的层的输出与**风格**图片对应层的输出进行处理,得到**风格损失** 16 | - 对合成图片本身,统计图片中的高频噪点(即过明或过暗像素点),得到**全变分损失** 17 | - 将三部分损失加起来得到总的样式迁移的**损失函数** 18 | - 4:利用 3 定义的损失函数,以合成图片的每个像素点为参数进行梯度下降,得到最终合成的图片 19 | 20 | ![CNN实现](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/49/CNN实现.png) 21 | 22 | ### 内容损失 23 | 24 | 神经网络内容相关层的输出的相似度可以直接反应两张图片在内容上的相似度,因此内容损失可以直接将对应层的输出视为内容直接求平方差损失。 25 | 26 | ### 风格损失:格拉姆矩阵 27 | 28 | 对于内容层,可以直接将对应层的输出求平方差损失,但是对于风格则略有不同 29 | 30 | 一般认为,风格层对应的输出的多个通道分别对应着不同类型的信息,如果将输出的形状从$[batch\_size=1,channels,h,w]$转化为$[channels,h*w]$就能得到通道数个向量,以$x_1,x_2...x_c$表示,代表不同通道所提取出的不同信息,而风格可以视作这些信息之间的关联,即相似度。 31 | 32 | 定义格拉姆矩阵$\bold X * \bold X^T \in R^{c \cdot c}$,矩阵的第 i 行第 j 列即向量$x_i$与$x_j$的内积,这个矩阵就代表了一张图片的风格。 33 | 34 | 对于生成图片和风格图片的格拉姆矩阵求平方差损失就能得到所需的风格损失 35 | 36 | 此外,为了让风格损失不受格拉姆矩阵及向量的大小影响,实际将格拉姆矩阵除以这些大小$channnels*h*w$。 37 | 38 | ### 全变分损失 39 | 40 | 用于去除高频噪点(过明过暗像素点) 41 | 42 | $$ 43 | \sum_{i, j} \left|x_{i, j} - x_{i+1, j}\right| + \left|x_{i, j} - x_{i, j+1}\right| 44 | $$ 45 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/SVM.py: -------------------------------------------------------------------------------- 1 | # 2 | # Support Vector Machine for learning XOR gate 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | from sklearn import svm 17 | from sklearn.metrics import accuracy_score 18 | 19 | # ======================================== 20 | # Create datasets 21 | # ======================================== 22 | 23 | # Inputs 24 | X = [[0, 0], [1, 0], [0, 1], [1, 1]] 25 | 26 | # The ground-truth labels 27 | Y = [0, 1, 1, 0] 28 | 29 | # ======================================== 30 | # Create model 31 | # ======================================== 32 | model = svm.SVC() 33 | 34 | # ======================================== 35 | # Training 36 | # ======================================== 37 | model.fit(X, Y) 38 | 39 | # ======================================== 40 | # Test 41 | # ======================================== 42 | result = model.predict(X) 43 | 44 | print("---------------------") 45 | print("x0 XOR x1 => result") 46 | print("=====================") 47 | 48 | for i in range(len(X)): 49 | x = X[i] 50 | print(" {} XOR {} => {}".format(x[0], x[1], int(result[i]))) 51 | 52 | print("=====================") 53 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/README.md: -------------------------------------------------------------------------------- 1 | ## Part 1: Basic Neural Networks 2 | 3 | ### Perceptron 4 | 5 | 6 | 1. [AND-gate.py](./AND-gate.py) : Perceptron for learning AND gate 7 | 8 | 9 | ### Neural Networks from scratch 10 | 11 | 1. [XOR-gate.py](./XOR-gate.py) 12 | 2. [XOR-gate-modularized.py](./XOR-gate-modularized.py) 13 | 3. [binary-to-decimal-conversion.py](./binary-to-decimal-conversion.py) 14 | 4. [XOR-gate-softmax.py](./XOR-gate-softmax.py) 15 | 5. [XOR-gate-adam.py](./XOR-gate-adam.py) 16 | 6. [XOR-gate-multi-hidden-layers.py](./XOR-gate-multi-hidden-layers.py) 17 | 7. [XOR-gate-residual-connection-layers.py](./XOR-gate-residual-connection-layers.py) 18 | 19 | #### TensorFlow version 20 | 21 | 1. [XOR-gate-tf.py](./XOR-gate-tf.py) 22 | 2. [binary-to-decimal-conversion-tf.py](./binary-to-decimal-conversion-tf.py) 23 | 3. [XOR-gate-tf-softmax.py](./XOR-gate-tf-softmax.py) 24 | 25 | #### Keras version 26 | 27 | 1. [XOR-gate-keras.py](./XOR-gate-keras.py) 28 | 2. [binary-to-decimal-conversion-keras.py](./binary-to-decimal-conversion-keras.py) 29 | 3. [XOR-gate-keras-softmax.py](./XOR-gate-keras-softmax.py) 30 | 31 | #### Pytorch version 32 | 33 | 1. [XOR-gate-pt.py](./XOR-gate-pt.py) 34 | 2. [binary-to-decimal-conversion-pt.py](./binary-to-decimal-conversion-pt.py) 35 | 3. [XOR-gate-pt-softmax.py](./XOR-gate-pt-softmax.py) 36 | 37 | ### ML 38 | 39 | 1. [SVM.py](./SVM.py) : Support Vector Machine for learning XOR gate. 40 | 41 | 2. [KNeighborsClassifier.py](./KNeighborsClassifier.py) : KNeighbors Classifier for learning XOR gate. 42 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/attic/debug-softmax.py: -------------------------------------------------------------------------------- 1 | # 2 | # Debugging for Softmax 3 | # 4 | # 5 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 6 | 7 | import autograd.numpy as np 8 | from autograd import grad 9 | 10 | units_size = 10 11 | 12 | # 13 | # Prepare inputs and outputs 14 | # 15 | 16 | x = np.arange(units_size)/units_size - 0.5 17 | x = x.reshape(units_size, 1) 18 | 19 | Y = np.zeros(units_size) 20 | Y[0] = 1.0 21 | Y = Y.reshape(units_size, 1) 22 | 23 | # =================== 24 | # softmax 25 | # =================== 26 | 27 | exp = np.exp(x) 28 | y = exp / (np.sum(exp, axis=0) + 1e-8) 29 | 30 | 31 | ################################################ 32 | # Back Propagation 33 | ################################################ 34 | 35 | dL = - Y / (y + 1e-8) 36 | 37 | #dh = np.zeros(units_size) 38 | dh = y * (1 + dL) 39 | 40 | # Convert row vector into column vector. 41 | dh = dh.reshape(units_size, 1) 42 | 43 | print("========== BP ==========") 44 | 45 | print("dh =", dh) 46 | 47 | 48 | ################################################ 49 | # CHECK 50 | ################################################ 51 | 52 | print("========== Autograd ==========") 53 | 54 | def softmax(x): 55 | exp = np.exp(x) 56 | return exp / (np.sum(exp, axis=0) + 1e-8) 57 | 58 | def loss(x, Y): 59 | return -np.sum(Y * np.log(softmax(x) + 1e-8)) 60 | 61 | gradient_fun = grad(loss) 62 | 63 | weights = gradient_fun(x, Y) 64 | print("{} = {}".format("dh", weights)) 65 | print("\t=> OK") if np.allclose(weights, dh) else print("***** ERROR!!!") 66 | 67 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-04/display-sparse-attentions.py: -------------------------------------------------------------------------------- 1 | # 2 | # Display sparse transformer's strided and fixed attentions 3 | # 4 | # Generating Long Sequences with Sparse Transformers: https://arxiv.org/pdf/1904.10509.pdf 5 | 6 | import math 7 | 8 | N = 12 # max token size 9 | s = 3 # Stride. Close to sqrt N 10 | c = 1 # Hyperparameter 11 | 12 | 13 | style = "UNICODE" 14 | if style == "UNICODE": 15 | fil = "\u2B1B" 16 | emp = "\u2B1C" 17 | else: 18 | fil = "1 " 19 | emp = "0 " 20 | 21 | 22 | def strided(i, j): 23 | if ((i + s) > j and j > (i - s)) or (i - j) % s == 0: 24 | return True 25 | else: 26 | return False 27 | 28 | 29 | def fixed(i, j): 30 | if (math.floor(j / s) == math.floor(i / s)) or ((j % s) >= (s - c)): 31 | return True 32 | else: 33 | return False 34 | 35 | 36 | print("== Strided Attention ==") 37 | for i in range(N): 38 | for j in range(N): 39 | if strided(i, j): 40 | print(fil, end="") 41 | else: 42 | print(emp, end="") 43 | print("") 44 | 45 | 46 | print("== Fixed Attention ==") 47 | for i in range(N): 48 | for j in range(N): 49 | if fixed(i, j): 50 | print(fil, end="") 51 | else: 52 | print(emp, end="") 53 | print("") 54 | 55 | """ 56 | print("== Strided & Fixed Attention ==") 57 | for i in range(N): 58 | for j in range(N): 59 | if strided(i, j) or fixed(i, j): 60 | print(fil, end="") 61 | else: 62 | print(emp, end="") 63 | print("") 64 | """ 65 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Common/ActivationFunctions.py: -------------------------------------------------------------------------------- 1 | # 2 | # Activation and their Derivative functions 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | 18 | # 19 | # Sigmoid 20 | # 21 | def sigmoid(x): 22 | return 1 / (1 + np.exp(-x)) 23 | 24 | 25 | def deriv_sigmoid(x): 26 | return sigmoid(x) * (1 - sigmoid(x)) 27 | 28 | 29 | # 30 | # Tanh 31 | # 32 | def tanh(x): 33 | return np.tanh(x) 34 | 35 | def deriv_tanh(x): 36 | return (1 - np.tanh(x)**2) 37 | 38 | # 39 | # Linear 40 | # 41 | def linear(x): 42 | return x 43 | 44 | def deriv_linear(x): 45 | return np.ones(x.shape) 46 | 47 | # 48 | # ReLU 49 | # 50 | def relu(x): 51 | return np.maximum(0, x) 52 | 53 | def deriv_relu(x): 54 | return np.where(x > 0, 1, 0) 55 | 56 | 57 | # 58 | # Softmax 59 | # 60 | # Assume that the loss function is the Cross-Entropy (CE). 61 | # 62 | class Softmax: 63 | 64 | def activate_func(self, x): 65 | exp = np.exp(x) 66 | self.y = exp / (np.sum(exp, axis=0) + 1e-8) 67 | return self.y 68 | 69 | # dL should be (- Label / output) because of CE. 70 | def deriv_activate_func(self, _, dL): 71 | return self.y * (1 + dL) 72 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/KNeighborsClassifier.py: -------------------------------------------------------------------------------- 1 | # 2 | # KNeighbors Classifier for learning XOR gate 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | from sklearn.neighbors import KNeighborsClassifier 17 | from sklearn.metrics import accuracy_score 18 | 19 | # ======================================== 20 | # Create datasets 21 | # ======================================== 22 | 23 | # Inputs 24 | X = [[0, 0], [1, 0], [0, 1], [1, 1]] 25 | 26 | # The ground-truth labels. 27 | Y = [0, 1, 1, 0] 28 | 29 | # ======================================== 30 | # Create model 31 | # ======================================== 32 | model = KNeighborsClassifier(n_neighbors=1) 33 | 34 | # ======================================== 35 | # Training 36 | # ======================================== 37 | model.fit(X, Y) 38 | 39 | # ======================================== 40 | # Test 41 | # ======================================== 42 | result = model.predict(X) 43 | 44 | print("---------------------") 45 | print("x0 XOR x1 => result") 46 | print("=====================") 47 | 48 | for i in range(len(X)): 49 | x = X[i] 50 | print(" {} XOR {} => {}".format(x[0], x[1], int(result[i]))) 51 | 52 | print("=====================") 53 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-04/attic/ffn.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | 4 | d_model = 8 5 | d_ffn = 6 6 | 7 | 8 | def relu(x): 9 | return np.maximum(0, x) 10 | 11 | 12 | def ffn(d_model, d_ffn): 13 | return tf.keras.Sequential( 14 | [ 15 | tf.keras.layers.Dense(d_ffn, activation="relu"), 16 | tf.keras.layers.Dense(d_model), 17 | ] 18 | ) 19 | 20 | 21 | class FFN: 22 | def __init__(self): 23 | super(FFN, self).__init__() 24 | 25 | self.w1 = tf.keras.layers.Dense(d_ffn, activation="relu", use_bias=False) 26 | self.w2 = tf.keras.layers.Dense(d_model, use_bias=False) 27 | self.ffn = tf.keras.Sequential([self.w1, self.w2]) 28 | 29 | def call(self, x): 30 | y = self.ffn(x) 31 | return y, self.w1.weights, self.w2.weights 32 | 33 | 34 | n = np.arange(20).reshape(4, 5) 35 | N = tf.constant(n) 36 | 37 | ffn = FFN() 38 | 39 | X, w1, w2 = ffn.call(N) 40 | 41 | print("Input matrix:n\n", n) 42 | 43 | x_tf = X.numpy() 44 | 45 | print("=== FFN Result: ===") 46 | 47 | print("FFN(n)=\n", x_tf) 48 | 49 | print("=== Manual Calculation Result: ===") 50 | m = [] 51 | for i in range(len(n)): 52 | a = np.dot(relu(np.dot(n[i], w1)), w2) 53 | print( 54 | "np.dot(relu(np.dot(n[{}], w1)), w2) = M[{}] = {}".format( 55 | str(i), str(i), str(a[0][0]) 56 | ) 57 | ) 58 | m.append(a[0][0].tolist()) 59 | print("=== Comparison of Results: ===") 60 | 61 | if np.allclose(m, x_tf): 62 | print("FFN == M") 63 | else: 64 | print("FFN != N --> NG!!!") 65 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/70~BERT 微调.md: -------------------------------------------------------------------------------- 1 | ## 70 BERT微调 2 | 3 | ### 目录 4 | 5 | * [1.intro](#1intro) 6 | * [2.具体应用](#2具体应用) 7 | + [2.1句子分类](#21句子分类) 8 | + [2.2命名实体识别](#22命名实体识别) 9 | + [2.3问题回答](#23问题回答) 10 | * [3.总结](#3总结) 11 | * [4.QA](#4qa) 12 | 13 | 14 | 15 | ### 1.intro 16 | 17 | 与图片分类不同,BERT预训练时使用的两个任务没有什么实际应用场景,所以使用BERT时多需要进行微调。 18 | 19 | BERT对每一个token都返回一个特定长度的特征向量(课堂演示为128,bert-base是768,bert-large是1024),这些特征向量抽取了上下文信息。不同的任务使用不同的特征。 20 | 21 | ### 2.具体应用 22 | 23 | #### 2.1句子分类 24 | 25 | 将句首的\token对应的向量输入到全连接层分类。对于一对句子也是同理,句子中间用\分开但仍只用第一个\对应的向量。 26 | 27 | 关于为什么要使用\是因为预训练中判断句子是否连续任务中使用的是\,因此模型会“知道”\是句子级别分类用的向量,表示的信息应与句子整体有关。当然我们也可以不使用\选定自己想要的token,之后在微调中更新bert的权重即可。 28 | 29 | #### 2.2命名实体识别 30 | 31 | 命名实体识别即识别一个词元是不是命名实体,例如人名、机构、位置。其方法是将每一个非特殊词元的向量放进全连接层分类(二分类多分类均可)。 32 | 33 | #### 2.3问题回答 34 | 35 | 给定一个问题和描述文字,找出一个判断作为回答,微调方法为对片段中的每个词元预测它是不是回答的开头或结束。 36 | 37 | 总体而言,无论是句子级别还是词级别的分类任务,都只需要在bert的基础上加全连接层,bert中的权重是可以直接从预训练模型得到的,真正需要自己从头训练的只有全连接层的权重。 38 | 39 | ### 3.总结 40 | 41 | - 即使下游任务各有不同,使用BERT微调时均只需要增加输出层 42 | - 但根据任务的不同,输入的表示,和使用的BERT特征也会不一样 43 | 44 | 在BERT的基础上微调使得多数任务都变的简单许多且效果相比从零开始训练要好很多,至此自然语言处理也向计算机视觉一样转向微调路线。 45 | 46 | ### 4.QA 47 | 48 | Q1: BERT微调的时候固定预训练模型的参数吗? 49 | 50 | > 一般不固定,所有权重都进行训练。也可以固定住底部一些层来加速训练,但通常来说不固定效果更好。可以自行尝试固定哪几层在训练速度更快的前提下效果更好 51 | 52 | Q2: 为什么没讲YOLO? 53 | 54 | > YOLO的较新版本已经跟之前版本很不一样了,且里面的技术细节很杂多。纯Python实现的yolo效果不见得比其他算法好,之所以表现出众是因为加入了大量的技术细节。只给大家实现一个本身大家可能不会太感兴趣。 55 | 56 | Q3: BERT在实际应用中怎样部署?用C++写代码吗? 57 | 58 | > 一般不需要用C++,可以将模型编译到C++(框架通常有支持)。但搬到C++也不能解决速度问题,BERT本身比resnet之类慢很多。 59 | 60 | Q4: 如果设备性能不高是不是不建议用BERT? 61 | 62 | > 可以用简化版本的BERT,如蒸馏版的BERT大约只有原模型十分之一大小。 -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/attic/sin.py: -------------------------------------------------------------------------------- 1 | # Developed environment: 2 | # Python 3.9.13 3 | # pip 23.1.2 4 | # conda 22.11.1 5 | # numpy 1.23.3 6 | # matplotlib 3.6.0 7 | # 8 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 9 | 10 | #import numpy as np 11 | import matplotlib.pyplot as plt 12 | import DataSet as ds 13 | 14 | # start-end dot 15 | def plot_fig3(wave, start=0, end=25): 16 | for i in range(start, end): 17 | plt.plot(i - start, wave[i], marker='.', color="b") 18 | 19 | i = end 20 | plt.plot(i - start, wave[i], marker='.', color="r") 21 | #plt.legend() 22 | plt.ylim([-1.5, 1.5]) 23 | plt.xlim([-10, 110]) 24 | #plt.grid(True) 25 | plt.show() 26 | 27 | # start-end dot 28 | def plot_fig4(wave, start=0, end=25, input_end=25): 29 | for i in range(start, end): 30 | plt.plot(i, wave[i], marker='.', color="g") 31 | 32 | i = i + 1 33 | plt.plot(i, wave[i], marker='.', color="r") 34 | 35 | for i in range(start, input_end): 36 | plt.plot(i, wave[i], marker='.', color="b") 37 | 38 | #plt.legend() 39 | plt.ylim([-1.5, 1.5]) 40 | plt.xlim([-10, 110]) 41 | #plt.grid(True) 42 | plt.show() 43 | 44 | 45 | n_data = 100 46 | sin_data = ds.create_wave(n_data, 0.0) 47 | 48 | 49 | plot_fig3(sin_data, 0, 25) 50 | plot_fig4(sin_data, 0, 25) 51 | 52 | plot_fig3(sin_data, 1, 26) 53 | plot_fig4(sin_data, 0, 26) 54 | 55 | plot_fig3(sin_data, 2, 27) 56 | plot_fig4(sin_data, 0, 27) 57 | 58 | 59 | 60 | plot_fig3(sin_data, 74, 99) 61 | plot_fig4(sin_data, 0, 99) 62 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/43~树叶分类竞赛技术总结.md: -------------------------------------------------------------------------------- 1 | ## 43-树叶分类竞赛技术总结 2 | 3 | ### 目录 4 | 5 | - [1. 比赛结果](#1-比赛结果) 6 | - [2. 结果分析](#2-结果分析) 7 | - [3. 技术分析](#3-技术分析) 8 | - [4. 模型方面](#4-模型方面) 9 | - [5. AutoGluon](#5-autogluon) 10 | - [6. 总结](#6-总结) 11 | 12 | ### 1. 比赛结果 13 | 14 | - 176 类,18353 训练样本 15 | 16 |
17 | image 18 |
19 | 20 | - 165 只队伍参加 21 | - 41 只队伍精度 > 98% (非常好) 22 | - 83 只队伍精度 > 95% (够用) 23 | 24 | ### 2. 结果分析 25 | 26 | - 16 只队伍提供了代码: 27 | 28 | - [Classify Leaves | Kaggle](https://www.kaggle.com/c/classify-leaves/code) 29 | 30 | - 额外加上 Neko Kiku 31 | - 很多人参考了此代码 [simple resnet baseline | Kaggle](https://www.kaggle.com/nekokiku/simple-resnet-baseline) 32 | 33 | ### 3. 技术分析 34 | 35 | 相比于课程介绍的代码,同学们主要做了下面这些加强: 36 | 37 | - **数据增强**,在测试时多次使用稍弱的增强然后取平均 38 | 39 | - 使用**多个模型**预测,最后结果加权平均 40 | - 有使用 10 种模型的,也有使用单一模型的 41 | - **训练算法**和**学习率** 42 | - **清理数据** 43 | 44 | ### 4. 模型方面 45 | 46 | - 模型多为 ResNet 变种 47 | 48 | - DenseNet,ResNeXt,ResNeSt, ... 49 | - EfficientNet 50 | 51 | - 优化算法多为 Adam 或其变种 52 | - 学习率一般是 Cosine 或者训练不动时往下调 53 | 54 | ### 5. AutoGluon 55 | 56 | - 15 行代码,安装加训练耗时 100 分钟 57 | - [AutoGluon.vision: 0.96+ with 15 lines | Kaggle](https://www.kaggle.com/zhreshold/autogluon-vision-0-96-with-15-lines) 58 | - 精度 96% 59 | - 可以通过定制化提升精度 60 | - 下一个版本将搜索更多的模型超参数 61 | - AG 目前主要仍是关注工业界应用上,而非比赛 62 | 63 | ### 6. 总结 64 | 65 | - 提升精度思路:根据数据挑选增强,使用新模型、新优化算法,多个模型融合,测试时使用增强 66 | - 数据相对简单,排名有相对随机性 67 | - 在工业界应用中: 68 | - 少使用模型融合和测试时增强,计算代价过高 69 | - 通常固定模型超参数,而将精力主要花在提升数据质量 70 | 71 | 比赛/学术界:固定数据,调模型 72 | 73 | 工业界:固定模型,调数据 74 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/25~使用块的网络 VGG.md: -------------------------------------------------------------------------------- 1 | ## 25 使用块的网络 VGG 2 | 3 | ### 目录 4 | 5 | - [25 使用块的网络 VGG](#25-使用块的网络-vgg) 6 | - [目录](#目录) 7 | - [1. VGG 块](#1-vgg-块) 8 | - [2. VGG 架构](#2-vgg-架构) 9 | - [3. 总结](#3-总结) 10 | - [4. QA](#4-qa) 11 | 12 | Alexnet 最大的问题在于长得不规则,结构不甚清晰,也不便于调整。想要把网络做的更深更大需要更好的设计思想和标准框架。 13 | 14 | ### 1. VGG 块 15 | 16 | 直到现在更深更大的模型也是我们努力的方向,在当时 AlexNet 比 LeNet 更深更大得到了更好的精度,大家也希望把网络做的更深更大。选择之一是使用更多的全连接层,但全连接层的成本很高;第二个选择是使用更多的卷积层,但缺乏好的指导思想来说明在哪加,加多少。最终 VGG 采取了将卷积层组合成块,再把卷积块组合到一起的思路。 17 | 18 | VGG 块可以看作是 AlexNet 思路的拓展,AlexNet 中将三个相同的卷积层放在一起再加上一个池化层,而 VGG 将其拓展成可以使用任意个 3x3,不改变输入大小的的卷积层,最后加上一个 2x2 的最大池化层。 19 | 20 | 25-01 21 | 22 | 为什么选择 3x3 卷积呢?在计算量相同的情况下选用更大的卷积核涉及对网络会越浅,VGG 作者经过实验发现用 3x3 卷积的效果要比 5x5 好,也就是说神经网络库深且窄的效果会更好。 23 | 24 | ### 2. VGG 架构 25 | 26 | 多个 VGG 块后接全连接层,不同次数的重复块得到不同的架构,如 VGG-16, VGG-19 等,后面的数字取决于网络层数。 27 | 28 | 可以讲 VGG 看作是将 AlexNet 中连续卷积的部分取出加以推广和复制,并删去了 AlexNet 中不那么规整的前几层。 29 | 30 | 25-02 31 | 32 | VGG 较 AlexNet 相比性能有很大的提升,而代价是处理样本速度的降低和内存占用的增加。 33 | 34 | ### 3. 总结 35 | 36 | - VGG 使用可重复使用的卷积块来构建深度卷积网络 37 | 38 | - 不同卷积块个数和超参数可以得到不同复杂度的变种 39 | 40 | 这些思想影响了后面神经网络的设计,在之后的模型中被广泛使用。 41 | 42 | ### 4. QA 43 | 44 | Q1: 视觉领域人工特征的研究还有无进展? 45 | 46 | > 现在在计算机视觉做人工特征是一种“政治不正确”的事,可能会因被认为没有 novelty 而发不出 paper ;-) 47 | > 48 | > 老师认为人工特征提取确实应该被取代掉,随着技术进步可以把这部分工作交给机器,人去做更高级的事。 49 | 50 | Q2: 需要学习特征值/特征向量/奇异值分解的知识吗? 51 | 52 | > 这门课中不一定会讲,但很多深度学习模型用到矩阵分解的思想,但是用的不多,想学可以学。 53 | 54 | Q3: Colab 限时 12 小时与验证码的解决方法 55 | 56 | > 充钱 57 | 58 | Q4: 训练 loss 一直下降,测试 loss 一只不降的原因 59 | 60 | > 代码写错了/过拟合(训练集和测试集很不一样) 61 | 62 | Q5: 为什么 VGG(1,1,224,224)输入高宽减半后通道数是 64? 63 | 64 | > 第一个卷积层的输出通道选的是 64。(通道数变化是自定的,和高宽变化没有关系) 65 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/DataSets/keras/spa-eng/_about.txt: -------------------------------------------------------------------------------- 1 | ** Info ** 2 | 3 | Check for newest version here: 4 | http://www.manythings.org/anki/ 5 | Date of this file: 6 | 2018-05-13 7 | 8 | This data is from the sentences_detailed.csv file from tatoeba.org. 9 | http://tatoeba.org/files/downloads/sentences_detailed.csv 10 | 11 | 12 | 13 | ** Terms of Use ** 14 | 15 | See the terms of use. 16 | These files have been released under the same license as the 17 | source. 18 | 19 | http://tatoeba.org/eng/terms_of_use 20 | http://creativecommons.org/licenses/by/2.0 21 | 22 | Attribution: www.manythings.org/anki and tatoeba.org 23 | 24 | 25 | 26 | ** Warnings ** 27 | 28 | The data from the Tatoeba Project contains errors. 29 | 30 | To lower the number of errors you are likely to see, only 31 | sentences by native speakers and proofread sentences have 32 | been included. 33 | 34 | For the non-English language, I made these (possibly wrong) 35 | assumptions. 36 | Assumption 1: Sentences written by native speakers can be 37 | trusted. 38 | Assumption 2: Contributors to the Tatoeba Project are honest 39 | about what their native language is. 40 | 41 | For English, I used the sentences that I have proofread 42 | and thought were OK. 43 | Of course, I may have missed a few errors. 44 | 45 | 46 | 47 | ** Downloading Anki ** 48 | 49 | See http://ankisrs.net/ 50 | 51 | 52 | 53 | ** Importing into Anki ** 54 | 55 | Information is at http://ankisrs.net/docs/manual.html#importing 56 | 57 | Of particular interest may be about "duplicates" at http://ankisrs.net/docs/manual.html#duplicates-and-updating. 58 | You can choose: 59 | 1. not to allow duplicates (alternate translations) as cards. 60 | 2. allow duplicates (alternate translations) as cards. 61 | -------------------------------------------------------------------------------- /99~参考资料/2019~Andrew Ng~深度学习课程/notation.md: -------------------------------------------------------------------------------- 1 | # 深度学习符号 2 | 3 | _此笔记中使用的数学符号参考自《深度学习》和 Deep learning specialization_ 4 | 5 | ## 常用的定义 6 | 7 | - 原版符号定义中,$x^{(i)}$ 与 $x_i$ 存在混用的情况,请注意识别 8 | 9 | ### 数据标记与上下标 10 | 11 | - 上标 $^{(i)}$ 代表第 $i$ 个训练样本 12 | - 上标 $^{[l]}$ 代表第 $l$ 层 13 | - $m$ 数据集的样本数 14 | - 下标 $_x$ 输入数据 15 | - 下标 $_y$ 输出数据 16 | - $n_x$ 输入大小 17 | - $n_y$ 输出大小 (或者类别数) 18 | - $n_h^{[l]}$ 第 $l$ 层的隐藏单元数 19 | - $L$ 神经网络的层数 20 | - 在循环中 21 | - $n_x = n_h^{[0]}$ 22 | - $n_y = n_h^{[L + 1]}$ 23 | 24 | ### 神经网络模型 25 | 26 | - $X \in \mathbb{R}^{n_x \times m}$ 代表输入的矩阵 27 | - $x^{(i)} \in \mathbb{R}^{n_x}$ 代表第 $i$ 个样本的列向量 28 | - $Y \in \mathbb{R}^{n_y \times m}$ 是标记矩阵 29 | - $y^{(i)} \in \mathbb{R}^{n_y}$ 是第 $i$样本的输出标签 30 | - $W^{[l]} \in \mathbb{R}^{l \times (l-1)}$ 代表第 $[l]$ 层的权重矩阵 31 | - $b^{[l]} \in \mathbb{R}^{l}$ 代表第 $[l]$ 层的偏差矩阵 32 | - $\hat{y} \in \mathbb{R}^{n_y}$ 是预测输出向量 33 | - 也可以用 $a^{[L]}$ 表示 34 | 35 | #### 正向传播方程示例 36 | 37 | - $a = g^{[l]}(W_x x^{(i)}_ + b_1) = g^{[l]}(z_1)$ 38 | - 其中,$g^{[l]}$ 代表第 $l$ 层的激活函数 39 | - $\hat{y} = softmax(W_h h + b_2)$ 40 | 41 | #### 通用激活公式 42 | 43 | - $a_j^{[l]} = g^{[l]}(z_j^{[l]}) = g^{[l]}(\sum_k w_{jk}^{[l]}a_k^{[l-1]} + b_j^{[l]})$ 44 | - $j$ 当前层的维度 45 | - $k$ 上一层的维度 46 | 47 | #### 损失函数 48 | 49 | - $J(x, W, b, y)$ 或者 $J(\hat{y}, y)$ 50 | - 常见损失函数示例 51 | - $J_{CE}(\hat{y}, y) = -\sum_{i=0}^m y^{(i)}log\hat{y}^{(i)}$ 52 | - $J_1(\hat{y}, y) = -\sum_{i=0}^m |y^{(i)} - \hat{y}^{(i)}|$ 53 | 54 | ## 深度学习图示 55 | 56 | - 节点:代表输入、激活或者输出 57 | - 边:代表权重或者误差 58 | 59 | 提供两种等效的示意图 60 | 61 | ### 详细的网络 62 | 63 | ![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/Andrew-Ng-DeepLearning-AI/fe20e8766346d4e8d212e792888dd6fb.jpg) 64 | 65 | 常用于神经网络的表示,为了更好的审美,我们省略了一些在边上的参数的细节(如$w_{ij}^{[l]}$ 和$b_{i}^{[l]}$等)。 66 | 67 | ### 简化网络 68 | 69 | ![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/Andrew-Ng-DeepLearning-AI/08a2f8fea114cbc35c70d45d03a34d52.jpg) 70 | 71 | 两层神经网络的更简单的表示。 72 | 73 | _\*\*\*\*_ 74 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/47~转置卷积.md: -------------------------------------------------------------------------------- 1 | ### 47-转置卷积 2 | 3 | ### 本节目录 4 | 5 | - [1.转置卷积](#1转置卷积) 6 | - [2.转置卷积是一种卷积](#2转置卷积是一种卷积) 7 | 8 | ### 1.转置卷积 9 | 10 | - 转置卷积和卷积的区别: 11 | - 卷积不会增大输入的高宽,通常要么不变、要么减半 12 | - 转置卷积则可以用来增大输入高宽 13 | - 转置卷积的具体实现: 14 | 15 | image 16 | 17 | 如图所示,input 里的每个元素和 kernel 相乘,最后把对应位置相加,相当于卷积的逆变换 18 | 19 | - 为什么称之为“转置: 20 | - 对于卷积 Y=X\*W 21 | - 可以对 W 构造一个 V,使得卷积等价于矩阵乘法 Y'=VX' 22 | - 这里 Y',X'是 Y,X 对应的向量版本 23 | - 转置卷积等价于 Y'=VTX' 24 | - 如果卷积将输入从(h,w)变成了(h‘,w’) 25 | - 同样超参数的转置卷积则从(h‘,w’)变成为(h,w) 26 | 27 | ### 2.转置卷积是一种卷积 28 | 29 | - 重新排列输入和核 30 | 31 | - 当填充为 0 步幅为 1 时: 32 | - 将输入填充 k-1(k 时核窗口) 33 | - 将核矩阵上下、左右翻转 34 | - 然后做正常卷积(填充 0、步幅 1) 35 | 36 | image 37 | 38 | - 当填充为 p 步幅为 1 时: 39 | - 将输如填充 k-p-1(k 是核窗口) 40 | - 将核矩阵上下、左右翻转 41 | - 然后做正常卷积(填充 0、步幅 1) 42 | 43 | image 44 | 45 | - 当填充为 p 步幅为 s 时: 46 | 47 | - 在行和列之间插入 s-1 行或列 48 | 49 | - 将输如填充 k-p-1(k 是核窗口) 50 | - 将核矩阵上下、左右翻转 51 | - 然后做正常卷积(填充 0、步幅 1) 52 | 53 | image 54 | 55 | - 形状换算 56 | 57 | - 输入高(宽)为 n,核 k,填充 p,步幅 s: 58 | 59 | - 转置卷积:n‘=sn+k-2p-s 60 | 61 | - 卷积:n’=[(n-k-2p+s)/s]向下取整 62 | 63 | - 如果让高宽成倍增加,那么 k=2p+s 64 | 65 | - 同反卷积的关系 66 | 67 | - 数学上的反卷积是指卷积的逆运算 68 | - 若 Y=conv(X,K),那么 X=deconv(Y,K) 69 | - 反卷积很少用在深度学习中 70 | - 我们说的反卷积神经网络指用了转置卷积的神经网络 71 | 72 | - 总结 73 | 74 | - 转置卷积是一种变化了输入和核的卷积,来得到上采用的目的 75 | - 不等同于数学上的反卷积操作 76 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/46~语义分割.md: -------------------------------------------------------------------------------- 1 | ## 46 语义分割 2 | 3 | ### 目录 4 | 5 | - [1.语义分割](#1语义分割) 6 | - [2.应用](#2应用) 7 | - [3.实例分割](#3实例分割) 8 | - [4.QA](#4qa) 9 | 10 | ### 1.语义分割 11 | 12 | 有时只能实现框选的目标检测还是太粗糙了,无法得到更精细的信息。语义分割将图片中的每个像素分类到对应的类别。 13 | 14 | 分割这一概念在计算机视觉中由来已久。最早的图片分割对给定图片使用聚类等方法把语义上比较像的像素放在一起,但通常不会告诉我们这些像素到底是什么。而语义分割可以告诉我们每个像素对应的label是什么。 15 | 16 | 这也意味着我们需要对图片的每一个像素都做label,使得语义分割成为了一个比较精细且大的任务。语义分割的数据集成本也较高,往往规模小像素高。常用的数据集之一是Pascal VOC2012。 17 | 18 | 46-01 19 | 20 | ### 2.应用 21 | 22 | 背景虚化:传统的背景替换往往采用绿幕。在没有绿幕的情况下传统相机可以通过光圈来实现背景虚化,对于手机等设备而言背景虚化通常使用的都是语义分割或结合图像景深信息。 23 | 24 | 路面分割:如无人驾驶时用于实时识别周围物体,实现找路的功能。 25 | 26 | ### 3.实例分割 27 | 28 | 语义分割只关心像素属于哪一类,而实例分割则更进一步,如图片里有两只狗,则需要得出哪个像素属于哪一只狗。可以将其理解为目标检测的进化版本。 29 | 30 | 46-02 31 | 32 | ### 4.QA 33 | 34 | Q1: 能否做更细的语义分割如狗的头/身/腿? 35 | 36 | > 可以,有标注数据即可,不过可能会出现不同标注者对身体部位分界不同之类的问题。针对狗头这一例子可以考虑使用姿态识别得到关节点。 37 | 38 | Q2: 目标检测里做图像增广,目标框做对应变换后不再是矩形怎么办? 39 | 40 | > 如果很关心角度信息可以给框加入一个表示旋转角度的feature,也可以考虑在旋转后的原框外面画一个大框把它圈起来,这个大框是可以计算出来的。 41 | 42 | Q3: 把人像语义分割做到slides中的效果大概需要多少训练集? 43 | 44 | > 人像这块技术相对比较成熟,应该能找到很好的预训练模型在其基础上调整即可。人像的形状是比较容易做的,难点主要在于光照不同(可能使背景与人像/衣服模糊) 45 | 46 | Q4: 三维语义分割标注怎么做? 47 | 48 | > (这里把三维理解成有景深的图片)一个简单的做法是把图片压缩成2维,也可以使用三维卷积。三维的分割实际上是好做的,因为一个物体的像素景深往往是连续的且与背景差距较大。 49 | 50 | Q5: 自动驾驶用语义分割,实例分割还是目标检测更合适? 51 | 52 | > 自动驾驶需要用到大量不同的模型,语义分割主要用于路面分割,目标检测用于检测前车/行人及其距离/速度。 53 | 54 | Q6: 语义分割有什么标注工具? 55 | 56 | > 国内外的数据标注公司会有这方面的平台,可以自己找找,老师认为这个比较简单,工具大同小异。 57 | > 58 | > (弹幕提及较多:labelme) 59 | 60 | Q7: 摄像头怕过曝,逆光相关 61 | 62 | > 过曝不常见,但欠曝在光线不足时很常见,一种方法是做大量数据增广。逆光更难做一点,不过photoshop可以模拟出逆光效果用于数据增强,也可以在采集数据时采集一些逆光照片,检查低置信度的照片确认是否为逆光,之后加以标注对模型重新训练。这样的方法可能会涉及到数据隐私问题。 63 | 64 | Q8: 自动驾驶用纯视觉方案能不能做到很可靠? 65 | 66 | > tesla做的就是纯视觉,国内/Google用激光雷达(贵但精准),此外大家都会用摄像头和雷达。老师的广电是使用纯摄像头方案一方面是因为技术团队在这方面有积累,另一个可能的原因是摄像头便宜,第三个原因是tesla的算力很大能很好处理大量摄像头信息,最后是Tesla有大量的数据积累,大量的数据可以弥补传感器方面的劣势。 67 | > 68 | > 理论上纯视觉自动驾驶是可行的,但目前只有Tesla做的还算可靠。 69 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/README.md: -------------------------------------------------------------------------------- 1 | ## The Engineer's Guide to Deep Learning 2 | 3 | This is the repository of [The Engineer's Guide to Deep Learning](https://www.interdb.jp/dl/). 4 | 5 | ### Developing Environment 6 | 7 | ``` 8 | Python 3.11.5 9 | keras 2.15.0 10 | pip 24.0 11 | numpy 1.26.4 12 | matplotlib 3.9.0 13 | tensorflow 2.15.1 14 | tensorflow-metal 1.1.0 15 | scikit-learn 1.5.0 16 | ``` 17 | 18 | To ensure compatibility, please create the environment using the above versions before running the program. 19 | 20 | ### Note 21 | 22 | - I am happy to receive bug reports and assist with bug fixes. 23 | - I am unable to provide support for any installation issues. 24 | 25 | 26 | ### Part 1: [Basic Neural Networks](./Part-01/) 27 | 28 | 29 | ### Part 2: [Recurrent Neural Networks](./Part-02/) 30 | 31 | 32 | ### Part 3: [Natural Language Processing and Attention Mechanisms](./Part-03/) 33 | 34 | 35 | ### Part 4: [Transformer](./Part-04/) 36 | 37 | 38 | ### Appendix: [Basic Knowledge](./Appendix/) 39 | 40 | 41 | ### License 42 | 43 | [![License: CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC_BY--NC--SA_4.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/) 44 | 45 | 46 | ### Appendix: Installing TensorFlow on M1 Mac 47 | 48 | Reference: 49 | + [Get started with tensorflow-metal](https://developer.apple.com/metal/tensorflow-plugin/) 50 | 51 | Here's how I installed it on M1 Mac: 52 | 53 | #### [1] Installing Python 3.11.5 using pyenv 54 | 55 | ``` 56 | $ pyenv install 3.11.5 57 | $ pyenv global 3.11.5 58 | ``` 59 | 60 | #### [2] Installing TensorFlow under venv 61 | 62 | ``` 63 | $ python3 -m venv ~/venv-metal 64 | $ source ~/venv-metal/bin/activate 65 | $ python -m pip install -U pip 66 | $ pip install tensorflow==2.15.1 67 | $ pip install tensorflow-metal==1.1.0 68 | $ pip install matplotlib==3.9.0 69 | ``` 70 | 71 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/35~分布式训练.md: -------------------------------------------------------------------------------- 1 | ## 35-分布式训练 2 | 3 | ### 本节目录 4 | 5 | - [1.分布式计算](#1分布式计算) 6 | - [2. GPU 机器架构](#2-gpu机器架构) 7 | - [2.1 样例:计算一个小批量](#21-样例计算一个小批量) 8 | - [2.2 总结](#22-总结) 9 | - [3. 关于性能](#3--关于性能) 10 | - [3.1 对于**同步 SGD**:](#31-对于同步sgd) 11 | - [3.2 **性能**:](#32-性能) 12 | - [3.3 性能的权衡](#33-性能的权衡) 13 | - [4. 实践时的建议](#4-实践时的建议) 14 | - [5. 总结](#5-总结) 15 | 16 | ### 1.分布式计算 17 | 18 | - 本质上来说和之前讲的单机多卡并行没有区别。二者之间的区别是分布式计算是通过网络把数据从一台机器搬到另一台机器 19 | 20 | image 21 | 22 | ### 2. GPU 机器架构 23 | 24 | - 总的来说,gpu 到 gpu 的通讯是很快的,gpu 到 cpu 慢一点。机器到机器更慢。因而总体性能的关键就是尽量在本地做通讯而少在机器之间做通讯 25 | 26 | ##### 2.1 样例:计算一个小批量 27 | 28 | - 每个 worker 从参数服务器那里获取模型参数:首先把样本复制到机器的内存,然后把样本分到每个 gpu 上 29 | - 复制参数到每个 gpu 上:同样,先把每一次的参数放到内存里,然后再复制到每个 gpu 上 30 | - 每个 gpu 计算梯度 31 | - 再主内存上把所有 gpu 上的梯度加起来 32 | - 梯度从主内存传回服务器 33 | - 每个服务器对梯度求和,并更新参数 34 | 35 | ##### 2.2 总结 36 | 37 | - 由于 gpu 到 gpu 和 gpu 到内存的通讯速度还不错,因此我们尽量再本地做聚合(如梯度相加),并减少再网络上的多次通讯 38 | 39 | ### 3. 关于性能 40 | 41 | ##### 3.1 对于**同步 SGD**: 42 | 43 | - 这里每个 worker 都是同步计算一个批量,称为同步 SGD 44 | - 假设有 n 个 ggpu,每个 gpu 每次处理 b 个样本,那么同步 SGD 等价于再单 gpu 运行批量大小为 nb 的 SGD 45 | - 再理想情况下,n 个 gpu 可以得到相对单 gpu 的 n 倍加速 46 | 47 | ##### 3.2 **性能**: 48 | 49 | - t1 = 在单 gpu 上计算 b 个样本梯度时间 50 | - 假设有 m 个参数,一个 worker 每次发送和接受 m 个参数、梯度 51 | - t2 = 发送和接受所用时间 52 | - 每个批量的计算时间为 max(t1,t2) 53 | - 选取足够大的 b 使 t1>t2 54 | - 增加 b 或 n 导致更大的批量 大小,当值需要更多计算来得到给定的模型精度 55 | 56 | ##### 3.3 性能的权衡 57 | 58 | image 59 | 60 | ### 4. 实践时的建议 61 | 62 | - 使用一个大数据集 63 | - 需要好的 gpu-gpu 和机器-机器带宽 64 | - 高效的数据读取和预处理 65 | - 模型需要有好的计算和通讯比 66 | - Inception>ResNet>AlexNet 67 | - 使用足够大的批量大小来得到更好的系统性能 68 | - 使用高效的优化算法对应大批量大小 69 | 70 | ### 5. 总结 71 | 72 | - 分布式同步数据并行是多 gpu 数据并行在多机器上的拓展 73 | - 网络通讯通常是瓶颈 74 | - 需要注意使用特别大的批量大小时的收敛效率 75 | - 更复杂的分布式有异步、模型并行(这里没有介绍) 76 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/34~多GPU训练实现(only QA).md: -------------------------------------------------------------------------------- 1 | ## 34 多GPU训练实现 2 | 3 | 本讲内容为代码实现,这里整理QA,其余内容参考代码部分。 4 | 5 | Q1: keras从tf分离,书籍会不会需要重新整理? 6 | 7 | > 暂时不会有影响 8 | 9 | Q2: 是否可以通过把resnet中的卷积层全替换成mlp来实现一个很深的网络? 10 | 11 | > 可以,有这样做的paper,但是通过一维卷积(等价于全连接层)做的,如果直接换成全连接层很可能会过拟合。 12 | 13 | Q3: 为什么batch norm是一种正则但只加快训练不提升精度? 14 | 15 | > 老师也不太清楚并认为这是很好的问题,可以去查阅论文。 16 | 17 | Q4: all_reduce, all_gather主要起什么作用?实际使用时发现pytorch的类似分布式op不能传导梯度,会破坏计算图不能自动求导,如何解决? 18 | 19 | > all_reduce是把n个东西加在一起再把所有东西复制回去,all_gather则只是把来自不同地方东西合并但不相加。使用分布式的东西会破坏自动求导,跨GPU的自动求导并不好做,老师不确定pytorch能不能做到这一功能,如果不能就只能手写。 20 | 21 | Q5: 两个GPU训练时最后的梯度是把两个GPU上的梯度相加吗? 22 | 23 | > 是的。mini-batch的梯度就是每个样本的梯度求和,多GPU时同理,每个GPU向将自己算的那部分样本梯度求和,最后再将两个GPU的计算得的梯度求和。 24 | 25 | Q6: 为什么参数大的模型不一定慢?flop数多的模型性能更好是什么原理? 26 | 27 | > 性能取决于每算一个乘法需要访问多少个bit,计算量与内存访问的比值越高越好。通常CPU/GPU不会被卡在频率上而是访问数据/内存上,所以参数量小,算力高的模型性能较好(如卷积,矩阵乘法)。 28 | 29 | Q7: 为什么分布到多GPU上测试精度会比单GPU抖动大? 30 | 31 | > 抖动是因为学习率变大了,使用GPU数对测试精度没有影响,只会影响性能。但为了得到更好的速度需要把batchsize调大,使得收敛情况发生变化,把学习率上调就使得精度更抖。 32 | 33 | Q8: batchsize太大会导致loss nan吗? 34 | 35 | > 不会,batchsize中的loss是求均值的,理论上batchsize更大数值稳定性会更好,出现数值不稳定问题可能是学习率没有调好。 36 | 37 | Q9: GPU显存如何优化? 38 | 39 | > 显存手动优化很难,靠的是框架,pytorch的优化做的还不错。除非特别懂框架相关技术不然建议把batchsize调小或是把模型做简单一点。 40 | 41 | Q10: 对于精度来说batchsize=1是一种最好的情况吗? 42 | 43 | > 可能是。 44 | 45 | Q11: parameter server可以和pytorch结合吗,具体如何实现? 46 | 47 | > pytorch没有实现parameter server,但mxnet和tensorflow有。但是有第三方实现如byteps支持pytorch。 48 | 49 | Q12: 用了nn.DataParallel(),是不是数据集也被自动分配到了多个GPU上? 50 | 51 | > 是的。在算net.forward()的时候会分开。 52 | 53 | Q13: 验证集准确率震荡大那个参数影响最大? 54 | 55 | > 学习率。 56 | 57 | Q14: 为了让网络前几层能够训练能否采用不同stage采用不同学习率的方法? 58 | 59 | > 可以,主要的问题是麻烦,不好确定各部分学习率相差多少。 60 | 61 | Q15: 在用torch的数据并行中将inputs和labels放到GPU0是否会导致性能问题,因为这些数据最终回被挪一次到其他GPU上。 62 | 63 | > 数据相比梯度来说很少,不会对性能有太大影响。但这个操作看上去的确很多余,老师认为不需要做,但不这样做会报错。 64 | 65 | Q16: 为什么batchsize较小精度会不怎么变化? 66 | 67 | > 学习率太大了,batchsize小学习率就不能太大。 68 | 69 | Q17: 使用两块不同型号GPU影响深度学习性能吗? 70 | 71 | > 需要算好两块GPU的性能差。如一块GPU的性能是另一块的2倍,那么在分配任务时也应该分得2倍的任务量。保证各GPU在同样时间内算完同一部分。 72 | 73 | Q18: 课内竞赛直接用教材的VGG11但不收敛,同样的dataloader用resnet可以收敛,如何解决这一问题? 74 | 75 | > 可能是学习率太大,也可考虑加入batch normalization。 76 | 77 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-03/Attention.py: -------------------------------------------------------------------------------- 1 | # 2 | # Attention mechanisms 3 | # 4 | # 5 | # Developed environment: 6 | # Python 3.11.5 7 | # keras 2.15.0 8 | # pip 24.0 9 | # numpy 1.26.4 10 | # matplotlib 3.9.0 11 | # tensorflow 2.15.1 12 | # tensorflow-metal 1.1.0 13 | # scikit-learn 1.5.0 14 | # 15 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 16 | 17 | import tensorflow as tf 18 | 19 | """ 20 | Bahdanau Attention, a.k.a. Additive attention, Multi-Layer perceptron 21 | """ 22 | class BahdanauAttention(tf.keras.layers.Layer): 23 | def __init__(self, units): 24 | super(BahdanauAttention, self).__init__() 25 | self.W1 = tf.keras.layers.Dense(units) 26 | self.W2 = tf.keras.layers.Dense(units) 27 | self.V = tf.keras.layers.Dense(1) 28 | 29 | def call(self, query, values): 30 | query_with_time_axis = tf.expand_dims(query, 1) 31 | score = self.V(tf.nn.tanh(self.W1(values) + self.W2(query_with_time_axis))) 32 | attention_weights = tf.nn.softmax(score, axis=1) 33 | context_vector = attention_weights * values 34 | context_vector = tf.reduce_sum(context_vector, axis=1) 35 | 36 | return context_vector, attention_weights 37 | 38 | """ 39 | Luong attention, a.k.a. Bilinear Attention, General Attention. 40 | """ 41 | class LuongAttention(tf.keras.layers.Layer): 42 | def __init__(self, units): 43 | super(LuongAttention, self).__init__() 44 | self.W = tf.keras.layers.Dense(units) 45 | 46 | def call(self, query, values): 47 | query_with_time_axis = tf.expand_dims(query, 1) 48 | score = tf.transpose(tf.matmul(query_with_time_axis, self.W(values), transpose_b=True), perm=[0, 2, 1]) 49 | 50 | attention_weights = tf.nn.softmax(score, axis=1) 51 | context_vector = attention_weights * values 52 | context_vector = tf.reduce_sum(context_vector, axis=1) 53 | 54 | return context_vector, attention_weights 55 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/72~优化算法.md: -------------------------------------------------------------------------------- 1 | ## 72.优化算法 2 | 3 | ### 目录 4 | 5 | - [72.优化算法](#72优化算法) 6 | - [目录](#目录) 7 | - [1.优化问题](#1优化问题) 8 | - [2.局部最小 vs 全局最小](#2局部最小-vs-全局最小) 9 | - [3.凸集和凸函数](#3凸集和凸函数) 10 | - [4.梯度下降](#4梯度下降) 11 | - [5.冲量法](#5冲量法) 12 | - [6.Adam](#6adam) 13 | - [总结](#总结) 14 | 15 | ### 1.优化问题 16 | 17 |
18 | image 19 |
20 | 21 | ### 2.局部最小 vs 全局最小 22 | 23 |
24 | image 25 |
26 | 27 | ### 3.凸集和凸函数 28 | 29 | - 凸集:形象化来说,就是这个集合上任意两个点连一条线,这个线在集合里面 30 | - 凸函数:形象上来说函数上任取两个点连线,函数都在该线下面 31 | - 凸优化问题:局部最小一定是全局最小。严格凸优化问题有唯一的全局最小。 32 | - 凸:线性回归,softmax 回归 33 | - 非凸:其他(MLP,CNN,RNN,attention) 34 | 35 | ### 4.梯度下降 36 | 37 | - 梯度下降——最简单的迭代求解算法 38 | - 随机梯度下降 39 | - 求导数需要求所有样本导数,样本多的情况下代价太大 40 | - 理论依据:所用样本,和随机选取一个样本得到的数学期望是一样的。 41 | - 小批量随机梯度下降(实际应用的) 42 | - 计算原因:计算单样本的梯度难以完全利用硬件资源 43 | - 采集一个随机子集 44 | - 理论依据:无偏近,但降低了方差 45 | 46 | ### 5.冲量法 47 | 48 | - 使用平滑过的梯度对权重更新,不容易震荡 49 | - momentum 50 | 51 |
52 | image 53 |
54 | 55 | ### 6.Adam 56 | 57 | - 非常平滑,对于学习率不敏感 58 | - 对于 t 比较小的时候,由于$v_0=0$,所以会导致一开始值比较小,做了一个修正。 59 | 60 |
61 | image 62 |
63 | 64 | - 为什么除以$\sqrt{\widehat{s}_t}+\epsilon$? 65 | - 在 nlp 里面常用,起到正则化的作用,控制每个维度的值在合适的大小。 66 | 67 |
68 | image 69 |
70 | 71 | ### 总结 72 | 73 | - 深度学习模型大部分是非凸的 74 | - 小批量随机梯度下降是最常见的优化算法 75 | - 冲量是对梯度做平滑 76 | - Adam 是对梯度做平滑,且对梯度各个维度值做重新调整,对于学习率不敏感 77 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/68~Transformer.md: -------------------------------------------------------------------------------- 1 | ## 68-Transformer 2 | 3 | ### 目录 4 | 5 | - [68-Transformer](#68-transformer) 6 | - [目录](#目录) 7 | - [1.transformer 架构](#1transformer架构) 8 | - [2.多头注意力](#2多头注意力) 9 | - [3.有掩码的多头注意力](#3有掩码的多头注意力) 10 | - [4.基于位置的前馈网络](#4基于位置的前馈网络) 11 | - [5.层归一化](#5层归一化) 12 | - [6.信息传递](#6信息传递) 13 | - [7.预测](#7预测) 14 | - [总结](#总结) 15 | - [QA](#qa) 16 | 17 | ### 1.transformer 架构 18 | 19 | - 基于 encoder-decoder 架构来处理序列对 20 | - 跟使用注意力的 seq2seq 不同,transformer 是纯基于注意力 21 | 22 |
23 | image 24 |
25 | 26 | ### 2.多头注意力 27 | 28 | - 对同一 key,value,query,希望抽取不同的信息 29 | - 例如短距离关系和长距离关系 30 | - 多头注意力使用 h 个独立的注意力池化 31 | 32 | - 合并各个头(head)输出得到最终输出 33 | 34 | -
35 | image 36 |
37 | 38 | - 数学表达式 39 | 40 |
41 | image 42 |
43 | 44 | ### 3.有掩码的多头注意力 45 | 46 | - 解码器对序列中一个元素输出的时候,不应该考虑该元素之后的元素 47 | - 可以用掩码来实现 48 | - 也就是计算$x_i$输出的时候,假装当前序列长度为 i 49 | 50 | ### 4.基于位置的前馈网络 51 | 52 | - 将输入形状变化(b,n,d)变换成(bn,d);输出形状由(bn,d)变成(b,n,d) 53 | - 作用两个全连接层 54 | - 等价于两层核窗口为 1 的一维卷积层(全连接) 55 | 56 | ### 5.层归一化 57 | 58 | - 批量归一化对每个特征/通道里元素进行归一化 59 | - 不适合序列长度会变的 nlp 应用 60 | - 层归一化对每个样本里面的元素进行归一化(layer norm ) 61 | 62 | ### 6.信息传递 63 | 64 | - 将编码器输出作为解码中第 i 个 transformer 块中多头注意力的 key 和 value 65 | - query 来自目标序列 66 | - 意味着编码器和解码器中块的个数,输出维度都是一样的 67 | 68 | ### 7.预测 69 | 70 | - 预测第 t+1 个输出时 71 | - 解码器中输入前 t 个预测值(顺序) 72 | - 在自注意力中,前 t 个预测值作为 key 和 value,第 t 个预测值还作为 query 73 | 74 | ### 总结 75 | 76 | - transformer 是一个纯使用注意力的 encoder-decoder 77 | - 编码器和解码器都有 n 个 transformer 块 78 | - 每个块里面使用多头注意力,基于位置的前馈网络,层归一化 79 | 80 | ### QA 81 | 82 | - 多头注意力,concat 和相加取平均怎么选择? 83 | - 老师认为 concat 保留的信息更全面,更好 84 | - 为什么在获取词向量之后,需要对词向量进行缩放(乘以 embedding size 的开方之后再加上 PE) 85 | - embedding 之后,向量长度变长,元素值变小,乘以之后可以保证在-1,1 之间,和 position 大小差不多 86 | - num of head 是什么? 87 | - 类似卷积的多通道,多个 attention 关注的是不同的特征 88 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/27~GoogLeNet.md: -------------------------------------------------------------------------------- 1 | ## GooLeNet 2 | 3 | #### 目录 4 | 5 | - [GooLeNet](#goolenet) 6 | - [目录](#目录) 7 | - [含并行连结的网络](#含并行连结的网络) 8 | - [Inception 块](#inception块) 9 | - [GooLeNet 模型](#goolenet模型) 10 | - [总结](#总结) 11 | 12 | #### 含并行连结的网络 13 | 14 | - GoogLeNet 吸收了 NiN 中串联网络的思想,并在此基础上做了改进。我们往往不确定到底选取什么样的层效果更好,到底是 3X3 卷积层还是 5X5 的卷积层,诸如此类的问题是 GooLeNet 选择了另一种思路“小学生才做选择,我全都要”,这也使得 GooLeNet 成为了第一个模型中超过 1000 个层的模型。 15 | 16 | #### Inception 块 17 | 18 | - 在 GoogLeNet 中,基本的卷积块被称为*Inception 块*(Inception block) 19 | 20 | ![截屏2022-01-23 上午10.11.18](https://github.com/kinza99/DeepLearning-MuLi-Notes/blob/main/imgs/27/27-1.png) 21 | 22 | - Inception 块由四条并行路径组成。前三条路径使用窗口大小为 1×11×1、3×33×3 和 5×55×5 的卷积层,从不同空间大小中提取信息。中间的两条路径在输入上执行 1×11×1 卷积,以减少通道数,从而降低模型的复杂性。第四条路径使用 3×33×3 最大汇聚层,然后使用 1×11×1 卷积层来改变通道数。这四条路径都使用合适的填充来使输入与输出的高和宽一致,最后我们将每条线路的输出在通道维度上连结,并构成 Inception 块的输出。在 Inception 块中,通常调整的超参数是每层输出通道数。 23 | 24 | #### GooLeNet 模型 25 | 26 | - GoogLeNet 一共使用 9 个 Inception 块和全局平均汇聚层的堆叠来生成其估计值。Inception 块之间的最大汇聚层可降低维度。第一个模块类似于 AlexNet 和 LeNet,Inception 块的组合从 VGG 继承,全局平均汇聚层避免了在最后使用全连接层。![截屏2022-01-23 上午10.17.11](https://github.com/kinza99/DeepLearning-MuLi-Notes/blob/main/imgs/27/27-2.png) 27 | - 第一个模块是 7×7 卷积层。 28 | - 第二个模块使用两个卷积层:第一个卷积层是 1×1 卷积层;第二个卷积层使用将通道数量增加三倍的 3×3 卷积层。这对应于 Inception 块中的第二条路径。 29 | - 第三个模块串联两个完整的 Inception 块。第一个 Inception 块的输出通道数为 64+128+32+32=25664+128+32+32=256,四个路径之间的输出通道数量比为 64:128:32:32=2:4:1:164:128:32:32=2:4:1:1。第二个和第三个路径首先将输入通道的数量分别减少到 96/192=1/296/192=1/2 和 16/192=1/1216/192=1/12,然后连接第二个卷积层。第二个 Inception 块的输出通道数增加到 128+192+96+64=480128+192+96+64=480,四个路径之间的输出通道数量比为 128:192:96:64=4:6:3:2128:192:96:64=4:6:3:2。第二条和第三条路径首先将输入通道的数量分别减少到 128/256=1/2128/256=1/2 和 32/256=1/832/256=1/8。 30 | - 第四模块更加复杂,它串联了 5 个 Inception 块,其输出通道数分别是 192+208+48+64=512192+208+48+64=512、160+224+64+64=512160+224+64+64=512、128+256+64+64=512128+256+64+64=512、112+288+64+64=528112+288+64+64=528 和 256+320+128+128=832256+320+128+128=832。这些路径的通道数分配和第三模块中的类似,首先是含 3×3 卷积层的第二条路径输出最多通道,其次是仅含 1×1 卷积层的第一条路径,之后是含 5×5 卷积层的第三条路径和含 3×3 最大汇聚层的第四条路径。其中第二、第三条路径都会先按比例减小通道数。这些比例在各个 Inception 块中都略有不同。 31 | 32 | #### 总结 33 | 34 | - Inception 块相当于一个有 4 条路径的子网络。它通过不同窗口形状的卷积层和最大汇聚层来并行抽取信息,并使用 1×1 卷积层减少每像素级别上的通道维数从而降低模型复杂度。 35 | 36 | - GoogLeNet 将多个设计精细的 Inception 块与其他层(卷积层、全连接层)串联起来。其中 Inception 块的通道数分配之比是在 ImageNet 数据集上通过大量的实验得来的。 37 | 38 | - GoogLeNet 和它的后继者们一度是 ImageNet 上最有效的模型之一:它以较低的计算复杂度提供了类似的测试精度。 39 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Appendix/Dice.py: -------------------------------------------------------------------------------- 1 | # 2 | # Virtual Dice 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import matplotlib.pyplot as plt 17 | import numpy as np 18 | 19 | """ 20 | import random as rn 21 | import os 22 | os.environ['PYTHONHASHSEED'] = '0' 23 | np.random.seed(0) 24 | rn.seed(0) 25 | """ 26 | 27 | 28 | class Dice: 29 | def __init__(self, num=6): 30 | assert num > 0 31 | self.num = num 32 | 33 | def toss(self): 34 | return np.random.randint(1, self.num + 1) 35 | 36 | def get_sequence(self, sequence_size): 37 | assert sequence_size > 0 38 | seq = np.zeros(sequence_size, dtype=int) 39 | for i in range(sequence_size): 40 | seq[i] = self.toss() 41 | return seq 42 | 43 | 44 | # ======================================== 45 | # Create dataset 46 | # ======================================== 47 | sequence_size = 30000 48 | dice = Dice() 49 | 50 | seq = dice.get_sequence(sequence_size) 51 | 52 | # ======================================== 53 | # Sampling 54 | # ======================================== 55 | 56 | count = np.zeros(dice.num, dtype=int) 57 | 58 | for i in range(len(seq)): 59 | count[seq[i] - 1] += 1 60 | 61 | if len(seq) > 0: 62 | prob = count / sequence_size 63 | 64 | # ======================================== 65 | # Show the probability 66 | # ======================================== 67 | 68 | print("========================================") 69 | print("P(Event) = |event|/|trial| = Probability") 70 | print("----------------------------------------") 71 | for i in range(1, len(prob) + 1): 72 | print( 73 | " P({}) => {:>5d} /{:>6d} = {:>1.5f}".format( 74 | i, count[i - 1], sequence_size, prob[i - 1] 75 | ) 76 | ) 77 | print("----------------------------------------") 78 | 79 | 80 | x = np.arange(1, len(prob) + 1) 81 | plt.bar(x, prob, tick_label=x, align="center") 82 | #plt.ylim(0, 1) 83 | plt.ylabel("prob.") 84 | 85 | plt.show() 86 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/62~序列到序列学习.md: -------------------------------------------------------------------------------- 1 | ## 62-序列到序列学习 2 | 3 | ### 1. 应用举例:机器翻译 4 | 5 | - 给定一个源语言的句子,自动翻译成目标语言 6 | - 这两个句子可以有不同的长度 7 | 8 | ### 2. 模型架构:Seq2seq 9 | 10 |
11 | 12 |
13 | 14 | - 序列到序列模型由**编码器-解码器**构成。 15 | 16 | - **编码器**RNN 可以是**双向**,由于输入的句子是完整地,可以正着看,也可以反着看;而**解码器**只能是**单向**,由于预测时,只能正着去预测。 17 | - 编码器,解码器采用**不同的 RNN**,此 RNN 也可以是 GRU,LSTM 等。 18 | 19 | ### 3. 编码器-解码器细节 20 | 21 |
22 | 23 |
24 | 25 | - 编码器的 RNN**没有**连接**输出层** 26 | 27 | - **编码器**的**最后时间步的隐状态**用作**解码器**的**初始隐状态**(图中箭头的传递) 28 | 29 | ### 4. 训练和推理 30 | 31 |
32 | 33 |
34 | 35 | - 第 3 节中提到编码器没有输出层,只有解码器有,于是损失函数的计算只关注解码器的输出层。 36 | - 训练和预测(推理)有区别的,训练时解码器使用目标句子(真值)作为输入,以指导模型训练;而推理时无法提前得知真值,需要一步一步进行预测。 37 | 38 | ### 5. 衡量生成序列的好坏:BLEU 39 | 40 | #### 5.1 BLUE 值定义: 41 | 42 |
43 | 44 |
45 | 46 | 宗成庆老师《统计自然语言处理》(第二版)一书中关于 BLEU 的定义: 47 | 48 |
49 | 50 |
51 | 52 | 同时,吴恩达深度学习课程中也是使用这一方式定义。但观察两种方式,BP 惩罚因子的计算是一致的,pn 也是使用了几何平均的方式,只是对于 wn 这一加权值的选择有所不同。 53 | 54 | #### 5.2 定义式解析 55 | 56 |
57 | 58 |
59 | 60 | BLEU 值衡量的是精确率,而且对不同 n-gram 进行集成打分。 61 | 62 | - BP 惩罚因子:为了惩罚过短的句子,由于过短的句子基数小,精确率容易提升,所以加上一个 BP 乘子,当预测句子长度<参考句子长度,则 BP<1。 63 | 64 | - wn 的选择:李沐老师课程中是采用了$\frac{1}{2^n}$​ 作为加权因子,n 越大,加权因子越小,但由于 pn<1,赋予的权重越大,即长匹配具有更高的权重。而宗老师的书中所述:在 BLEU 的基线系统中取 N = 4,wn = 1/N,也可以参考。 65 | 66 | ### 6. QA 67 | 68 | 问题:LSTM、GRU、Seq2Seq 的区别是什么? 69 | 70 | > Seq2Seq 是一种由编码器和解码器组成的框架,而 LSTM、GRU 是组成编码器和解码器的一种单元。 71 | 72 | 问题:encoder 的输出和 decoder 的输入,拼接和按位相加起来有什么区别么? 73 | 74 | > 不能够按位加,由于 encoder 的输出最后维度是 hidden_size,而 decoder 的输入最后维度是 embedding_size,可能不一样,所以用拼接。 75 | 76 | 问题:embedding 层是做 word2vec 吗? 77 | 78 | > 这里不是,这里是从头开始训练。现在用的比较多得都是预训练,BERT 等。 79 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/codes/13-丢弃法.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 6, 6 | "id": "d5195177", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import torch\n", 11 | "from torch import nn\n", 12 | "from d2l import torch as d2l\n", 13 | "\n", 14 | "def dropout_layer (X,dropout): #X为dropout层的输入,dropout为设置的丢弃概率\n", 15 | " assert 0<=dropout<=1 #丢弃概率介于0,1之间\n", 16 | " if dropout == 1:\n", 17 | " return torch.zeros_like(X) #若丢弃概率为1,则X的全部项均被置0\n", 18 | " if dropout == 0:\n", 19 | " return X #若丢弃概率为0,不对X作丢弃操作,直接返回X\n", 20 | " mask=(torch.Tensor(X.shape).uniform_(0,1)>dropout).float() #用uniform函数生成0-1间的随机实数,利用”>\",将大于dropout的记为1,小于dropout的记为0,实现丢弃操作\n", 21 | " return mask*X/(1-dropout) #将mask与X相乘实现丢弃操作,并除以(1-dropout),这里不使用选中X中元素置0的原因是相乘操作相比选中操作更快" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 7, 27 | "id": "8ff5ba10", 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "tensor([[ 0., 1., 2., 3., 4., 5., 6., 7.],\n", 35 | " [ 8., 9., 10., 11., 12., 13., 14., 15.]])\n", 36 | "tensor([[ 0., 1., 2., 3., 4., 5., 6., 7.],\n", 37 | " [ 8., 9., 10., 11., 12., 13., 14., 15.]])\n", 38 | "tensor([[ 0., 0., 4., 0., 0., 10., 0., 14.],\n", 39 | " [16., 18., 20., 0., 0., 26., 0., 30.]])\n", 40 | "tensor([[0., 0., 0., 0., 0., 0., 0., 0.],\n", 41 | " [0., 0., 0., 0., 0., 0., 0., 0.]])\n" 42 | ] 43 | } 44 | ], 45 | "source": [ 46 | "#丢弃法测试\n", 47 | "X=torch.arange(16,dtype=torch.float32).reshape((2,8))\n", 48 | "print(X)\n", 49 | "print(dropout_layer (X,0.)) #丢弃率设置为0\n", 50 | "print(dropout_layer (X,0.5)) #丢弃率设置为0.5\n", 51 | "print(dropout_layer (X,1)) #丢弃率设置为1" 52 | ] 53 | } 54 | ], 55 | "metadata": { 56 | "kernelspec": { 57 | "display_name": "Python [conda env:py36torch040]", 58 | "language": "python", 59 | "name": "conda-env-py36torch040-py" 60 | }, 61 | "language_info": { 62 | "codemirror_mode": { 63 | "name": "ipython", 64 | "version": 3 65 | }, 66 | "file_extension": ".py", 67 | "mimetype": "text/x-python", 68 | "name": "python", 69 | "nbconvert_exporter": "python", 70 | "pygments_lexer": "ipython3", 71 | "version": "3.6.13" 72 | } 73 | }, 74 | "nbformat": 4, 75 | "nbformat_minor": 5 76 | } 77 | -------------------------------------------------------------------------------- /99~参考资料/2019~Andrew Ng~深度学习课程/README.md: -------------------------------------------------------------------------------- 1 | **Coursera 深度学习教程中文笔记** 2 | 3 | 课程概述 4 | 5 | https://mooc.study.163.com/university/deeplearning_ai#/c 6 | 7 | 这些课程专为已有一定基础(基本的编程知识,熟悉**Python**、对机器学习有基本了解),想要尝试进入人工智能领域的计算机专业人士准备。介绍显示:“深度学习是科技业最热门的技能之一,本课程将帮你掌握深度学习。” 8 | 9 | 在这 5 堂课中,学生将可以学习到深度学习的基础,学会构建神经网络,并用在包括吴恩达本人在内的多位业界顶尖专家指导下创建自己的机器学习项目。**Deep Learning Specialization**对卷积神经网络 (**CNN**)、递归神经网络 (**RNN**)、长短期记忆 (**LSTM**) 等深度学习常用的网络结构、工具和知识都有涉及。 10 | 11 | 课程中也会有很多实操项目,帮助学生更好地应用自己学到的深度学习技术,解决真实世界问题。这些项目将涵盖医疗、自动驾驶、和自然语言处理等时髦领域,以及音乐生成等等。**Coursera**上有一些特定方向和知识的资料,但一直没有比较全面、深入浅出的深度学习课程——《深度学习专业》的推出补上了这一空缺。 12 | 13 | 课程的语言是**Python**,使用的框架是**Google**开源的**TensorFlow**。最吸引人之处在于,课程导师就是吴恩达本人,两名助教均来自斯坦福计算机系。完成课程所需时间根据不同的学习进度,大约需要 3-4 个月左右。学生结课后,**Coursera**将授予他们**Deep Learning Specialization**结业证书。 14 | 15 | “我们将帮助你掌握深度学习,理解如何应用深度学习,在人工智能业界开启你的职业生涯。”吴恩达在课程页面中提到。 16 | 17 | 本人黄海广博士,以前写过吴恩达老师的机器学习个人笔记。目前我正在组织团队整理中文笔记,由热心的朋友无偿帮忙制作整理,并持续更新。我们的团队的劳动致力于**AI**在国内的推广,不会损害**Coursera**以及吴恩达老师的商业利益。 18 | 19 | 本人水平有限,如有公式、算法错误,请及时指出,发邮件给我。 20 | 21 | 黄海广 22 | 23 | [我的知乎](https://www.zhihu.com/people/fengdu78/activities) 24 | 25 | | 主要编写人员: | **黄海广、林兴木(第四所有底稿,第五课第一二周,第三周前三节)、祝彦森:(第三课所有底稿)、**贺志尧(第五课第三周底稿)、王翔、胡瀚文、余笑)、郑浩、李怀松、朱越鹏、陈伟贺、曹越、路皓翔、邱牧宸、唐天泽、张浩、陈志豪、游忍、泽霖、沈伟臣、贾红顺、时超、陈哲、赵一帆、胡潇杨、段希、于冲、张鑫倩 | 26 | | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 27 | | 主要 编辑 人员(排名不分先后): | 黄海广 陈康凯 石晴路[EdwinXiang](https://gitee.com/EdwinXiang) [uirboyan](https://gitee.com/uirboyan) 严凤龙**LeoTsui** 贺志尧 段希 陈瑶 林家泳 王翔 谢士晨 蒋鹏 | 28 | 29 | 2018-04-14 30 | 31 | **本课程视频教程地址:** 32 | 33 | **有同学提供了一个离线视频的下载**:链接:https://yun.baidu.com/s/13taPOjUUppI8gexqmC2UcQ 密码:j7tf 34 | 35 | (该视频从www.deeplearning.ai 网站下载,因众所周知的原因,国内用户观看某些在线视频非常不容易,故一些学者一起制作了离线视频,旨在方便国内用户个人学习使用,请勿用于商业用途。视频内嵌中英文字幕,推荐使用 potplayer 播放。版权属于吴恩达老师所有,若在线视频流畅,请到官方网站观看。) 36 | 37 | [笔记网站(适合手机阅读)](http://www.ai-start.com) 38 | 39 | 吴恩达老师的机器学习课程笔记和视频:https://github.com/fengdu78/Coursera-ML-AndrewNg-Notes 40 | 41 | **此文档免费,请不要用于商业用途,可以自由传播。** 42 | 43 | **赠人玫瑰,手有余香!** 44 | 45 | haiguang2000@qq.com 46 | 47 | 本文件夹的与**images**文件夹一起放在同一目录即可运行。 48 | 49 | 转载请注明出处:https://github.com/fengdu78/deeplearning_ai_books 50 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/attic/debug-dense.py: -------------------------------------------------------------------------------- 1 | # 2 | # Debugging for Dense 3 | # 4 | # 5 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 6 | 7 | import autograd.numpy as np 8 | from autograd import grad 9 | 10 | input_units = 2 11 | hidden_units = 3 12 | 13 | # 14 | # Define functions 15 | # 16 | def tanh(Z): 17 | return np.tanh(Z) 18 | 19 | def deriv_tanh(Z): 20 | return 1.0 - np.tanh(Z) ** 2 21 | 22 | # 23 | # Initialize Weights and Bias 24 | # 25 | W = np.arange(1, input_units * hidden_units + 1).reshape((hidden_units, input_units)) / 10 26 | b = np.arange(1, 1 * hidden_units + 1).reshape((hidden_units, 1)) / 10 27 | 28 | # 29 | # Prepare inputs and outputs 30 | # 31 | 32 | x = np.arange(input_units) / 10 33 | x = x.reshape(input_units, 1) 34 | 35 | Y = np.arange(hidden_units) / 20 36 | Y = Y.reshape(hidden_units, 1) 37 | 38 | # =================== 39 | # Forward Propagation 40 | # =================== 41 | 42 | # Dense 43 | h = np.dot(W, x) + b 44 | y = tanh(h) 45 | 46 | ################################################ 47 | # Back Propagation 48 | ################################################ 49 | 50 | dW = np.zeros_like(W) 51 | db = np.zeros_like(b) 52 | 53 | dL = (y - Y) 54 | 55 | # Dense 56 | dW = np.zeros_like(W) 57 | db = np.zeros_like(b) 58 | dx = np.zeros_like(x) 59 | 60 | db = deriv_tanh(h) * dL 61 | dW = np.dot(db, x.T) 62 | dx = np.dot(W.T, db) 63 | 64 | print("========== BP ==========") 65 | 66 | print("dW =", dW) 67 | print("db =", db) 68 | print("dx =", dx) 69 | 70 | ################################################ 71 | # CHECK 72 | ################################################ 73 | 74 | """ 75 | h = np.dot(W, x) + b 76 | y = tanh(np.dot(W, x) + b) 77 | """ 78 | 79 | def dense(W, b, x): 80 | return tanh(np.dot(W, x) + b) 81 | 82 | def loss(_W, y): 83 | return np.sum((forwardprop(_W) - Y) ** 2 / 2) 84 | 85 | gradient_fun = grad(loss) 86 | 87 | def eval_grad(_W, _dW, param): 88 | weights = gradient_fun(_W, Y) 89 | print("{} = {}".format(str(param), weights)) 90 | print("\t=> OK") if np.allclose(weights, _dW) else print("***** ERROR!!!") 91 | 92 | print("========== Autograd ==========") 93 | 94 | ############### 95 | # W, b, x 96 | ############### 97 | 98 | # W 99 | def forwardprop(W): 100 | return dense(W, b, x) 101 | 102 | eval_grad(W, dW, "dW") 103 | 104 | # b 105 | def forwardprop(b): 106 | return dense(W, b, x) 107 | 108 | eval_grad(b, db, "db") 109 | 110 | # x 111 | def forwardprop(x): 112 | return dense(W, b, x) 113 | 114 | eval_grad(x, dx, "dx") 115 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/56~GRU.md: -------------------------------------------------------------------------------- 1 | ## 56-门控循环单元(GRU) 2 | 3 | ### 1. 动机:如何关注一个序列 4 | 5 | - 不是每个观察值都是同等重要 6 | 7 |
8 | 9 |
10 | 11 | 比如上图中的序列,若干个猫中出现了一个鼠,那么我们应该重点关注这个鼠,而中间重复出现的猫则减少关注。文本序列同理,通常长文本我们需要关注的是几个关键词,关键句。 12 | 13 | - 想只记住相关的观察需要: 14 | - 能**关注**的机制(**更新门**):顾名思义,是否需要根据我的输入,更新隐藏状态 15 | - 能**遗忘**的机制(**重置门**):更新候选项时,是否要考虑前一隐藏状态。 16 | 17 | ### 2. 门的概念 18 | 19 | - 更新门 Zt,重置门 Rt 的公式大体相同,唯一不同的是学习到的参数。 20 | 21 | - 需要注意的是,计算门的方式和原来 RNN 的实现中计算新的隐状态相似,只是激活函数改成了 sigmoid。 22 | - 门本来是电路中的一个概念,0,1 代表不同的电平,可以用于控制电路的通断。此处 sigmoid 将门的数值归一化到 0 到 1 之间,是一种"软更新"方式。而从后面的公式上可以看出,本讲课程采用的是低电平有效(越靠近 0,门的作用越明显)的方式控制。 23 | 24 |
25 | 26 |
27 | 28 | ### 3. 候选隐状态 29 | 30 |
31 | 32 |
33 | 34 | - 候选隐状态,如果抛开公式中的$R_{t}$遗忘门来说,这个和之前 RNN 中计算当前步的隐状态没有差别。 35 | 36 | - 但是这里引入了遗忘门,如果$R_{t}$无限接近于 0,那么此时候选隐状态将不再考虑前一隐状态的影响,也就是和 MLP 没有区别,起到“遗忘”的作用; 37 | - 反之,如果$R_{t}$无限接近于 1,那么与 RNN 计算隐状态的过程没有差别,不进行遗忘。 38 | - 公式中的 ⊙ 表示逐元素乘积。 39 | 40 | > 为什么叫候选隐状态? 41 | > 42 | > 在 RNN 中,这个所谓的候选隐状态就是当前步的隐状态($R_{t}$无限接近 1 时)。但是由于引入了更新门,我们需要考虑是直接沿用上一步的隐藏状态,还是像 RNN 一样使用当前步计算的隐状态。所以这个结合了当前输入计算的隐状态,不能立马变成当前的$H_{t}$,而是需要用更新门和前一隐状态$H_{t-1}$做一个加权,所以它是一个候选项。 43 | 44 | ### 4. 隐状态 45 | 46 |
47 | 48 |
49 | 50 | 用更新门对**候选隐状态**和**前一隐状态**做加权,得到当前步**隐状态**的值。 51 | 52 | 如果$Z_{t}$无限接近于 0,更新起作用,候选隐状态“转正”,变为当前隐状态。 53 | 54 | 如果$Z_{t}$无限接近于 1,更新不起作用,当前隐状态还是沿用前一隐状态。 55 | 56 | ### 5. 总结 57 | 58 |
59 | 60 |
61 | 62 | 上图四行公式概括了 GRU 模型。在 RNN 的基础上,最重要的是引入了**更新门和重置门**,来决定前一隐状态对当前隐状态的影响。以最开始的猫鼠序列的例子来说,如果我的模型一直看到猫,模型可以学习到隐状态不怎么去更新,于是隐状态一直保留了猫的信息,而看到老鼠,隐状态才进行更新。 63 | 64 | - 对于一个更具体的例子而言(语言模型): 65 | 66 | “The cat, which already ate ……, \_\_(is/ was) full.”,假设我的句子很长,预测完前面的词后需要预测下一个词 is 还是 was,如果引入这种更新/重置的机制,那我们的模型可以在 was 这个词之前尽可能去保持隐状态的信息,从而即使阅读了一个很长的定语从句,但我们还是保留了 cat 这个词的单数信息,从而模型预测下一个词为'was'。 67 | 68 | - 一个与 RNN 的联动在于: 69 | 70 | 如果更新门完全发挥作用(无限接近于 0),重置门不起作用(无限接近于 1),此时 GRU 模型退化为 RNN 模型。 71 | 72 | ### 6. QA 73 | 74 | 问题:GRU 为什么需要两个门? 75 | 76 | > 重置门和更新门各司其职。重置门单方面控制自某个节点开始,之前的记忆(隐状态)不在乎了,直接清空影响,同时也需要更新门帮助它实现记忆的更新。更新门更多是用于处理梯度消失问题,可以选择一定程度地保留记忆,防止梯度消失。 77 | > 78 | > 重置门影响的是当前步新的候选隐状态的计算,更新门影响的是当前步隐状态的更新程度。 79 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/DataSets/small_vocabulary_sentences/eng-41.txt: -------------------------------------------------------------------------------- 1 | Go on in. 2 | I can go. 3 | Go for it. 4 | I like it. 5 | Tom is in. 6 | Tom is up. 7 | We can go. 8 | I like Tom. 9 | I like him. 10 | I like you. 11 | I want Tom. 12 | This is it. 13 | We like it. 14 | We want it. 15 | You can go. 16 | As you like. 17 | Go with Tom. 18 | I can do it. 19 | I had to go. 20 | I like that. 21 | I like this. 22 | I want that. 23 | I want this. 24 | It is on me. 25 | It is there. 26 | That is all. 27 | This is Tom. 28 | This is his. 29 | Tom will go. 30 | We like Tom. 31 | We like him. 32 | We like you. 33 | We want Tom. 34 | Do it for me. 35 | He is not in. 36 | I do want it. 37 | I have to go. 38 | I want to go. 39 | That was Tom. 40 | That will do. 41 | They want me. 42 | We can do it. 43 | Do it with me. 44 | I can do that. 45 | I can do this. 46 | I do like Tom. 47 | I do like you. 48 | I have had it. 49 | There you are. 50 | Tom can do it. 51 | Tom has to go. 52 | We have to go. 53 | We want to go. 54 | We were there. 55 | You can do it. 56 | Do as you like. 57 | Do as you want. 58 | Do not do that. 59 | Do that for me. 60 | I had to do it. 61 | It was for Tom. 62 | They want this. 63 | This is on you. 64 | We can do that. 65 | You have to go. 66 | Do what you can. 67 | He is not there. 68 | It is up to you. 69 | It was from Tom. 70 | This is for you. 71 | We all like him. 72 | Do what you like. 73 | Do what you want. 74 | Do what you will. 75 | Go there with me. 76 | I want you to go. 77 | It is what it is. 78 | It was like that. 79 | She is not there. 80 | Tom is with Mary. 81 | We have to do it. 82 | We have to go on. 83 | All I want is you. 84 | Tom was with Mary. 85 | Tom will be there. 86 | Tom, this is Mary. 87 | You have to do it. 88 | I have to be there. 89 | I have what I want. 90 | I want to go there. 91 | Tom has to do this. 92 | We can all do this. 93 | You do what you can. 94 | I was there with Tom. 95 | This is all I can do. 96 | This is for you, Tom. 97 | I want to be with Tom. 98 | I want to be with you. 99 | I want to go with Tom. 100 | I want to go with you. 101 | Do what you have to do. 102 | I want him to go there. 103 | I want you to have this. 104 | You have what they want. 105 | I do want to go with you. 106 | They want to be with you. 107 | This is all I want to do. 108 | This is all he has to do. 109 | This is not what we want. 110 | You can do what you want. 111 | I want you to go with Tom. 112 | This is all Tom has to do. 113 | This is what I have to do. 114 | I want to go with you, Tom. 115 | They will go there with me. 116 | This is what you have to do. 117 | Tom and Mary will go with me. 118 | This is what I can do for you. 119 | I want you to do what you have to do. 120 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Common/Optimizer.py: -------------------------------------------------------------------------------- 1 | # 2 | # Stochastic Optimizer(s) 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | 18 | 19 | # 20 | # Gradients clipping. 21 | # 22 | def clip_gradient_norm(grads, max_norm=0.25): 23 | """ 24 | g = (max_nrom/|g|)*g 25 | """ 26 | max_norm = float(max_norm) 27 | total_norm = 0 28 | 29 | for grad in grads: 30 | grad_norm = np.sum(np.power(grad, 2)) 31 | total_norm += grad_norm 32 | 33 | total_norm = np.sqrt(total_norm) 34 | clip_coef = max_norm / (total_norm + 1e-6) 35 | 36 | if clip_coef < 1: 37 | for grad in grads: 38 | grad *= clip_coef 39 | 40 | return grads 41 | 42 | # 43 | # Update weights. 44 | # 45 | def update_weights(layers, lr=0.01, optimizer=None, max_norm=None): 46 | 47 | grads = [] 48 | params = [] 49 | for layer in layers: 50 | grads.extend(layer.get_grads()) 51 | params.extend(layer.get_params()) 52 | 53 | # Clip gradient 54 | if max_norm is not None: 55 | grads = clip_gradient_norm(grads, max_norm) 56 | 57 | # Weights and Bias Update 58 | if optimizer == None: 59 | # gradient descent 60 | for i in range(len(grads)): 61 | params[i] -= lr * grads[i] 62 | else: 63 | # ADAM 64 | optimizer.update(params, grads) 65 | 66 | # 67 | # ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION 68 | # https://arxiv.org/pdf/1412.6980v8.pdf 69 | # 70 | class Adam: 71 | 72 | def __init__(self, lr=0.001, beta1=0.9, beta2=0.999): 73 | self.lr = lr # Learning rate 74 | self.beta1 = beta1 # m's attenuation rate 75 | self.beta2 = beta2 # v's attenuation rate 76 | self.iter = 0 77 | self.m = None # Momentum 78 | self.v = None # Adaptive learning rate 79 | 80 | def update(self, params, grads): 81 | 82 | if self.m is None: 83 | self.m = [] 84 | self.v = [] 85 | for param in params: 86 | self.m.append(np.zeros_like(param)) 87 | self.v.append(np.zeros_like(param)) 88 | 89 | self.iter += 1 90 | lr_t = (self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter)) 91 | for i in range(len(params)): 92 | self.m[i] = (self.beta1 * self.m[i] + (1 - self.beta1) * grads[i]) 93 | self.v[i] = self.beta2 * self.v[i] + (1 - self.beta2) * (grads[i] ** 2) 94 | params[i] -= lr_t * self.m[i] / (np.sqrt(self.v[i]) + 1e-7) 95 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/36~数据增广.md: -------------------------------------------------------------------------------- 1 | ## 36 数据增广 2 | 3 | ### 目录 4 | 5 | * [1. 使用增强数据训练](#1-使用增强数据训练) 6 | * [2. 增强手段](#2-增强手段) 7 | + [2.1 翻转](#21-翻转) 8 | + [2.2 切割](#22-切割) 9 | + [2.3 颜色](#23-颜色) 10 | + [2.4 其他](#24-其他) 11 | * [3. 总结](#3-总结) 12 | * [4. QA](#4-qa) 13 | 14 | 数据增广不仅用于处理图片,也可用于文本和语音,这里只涉及到图片。 15 | 16 | ### 1. 使用增强数据训练 17 | 18 | 采集数据得到的训练场景与实际部署场景不同是常见的问题,这种变化有时会显著影响模型表现。在训练集中尽可能模拟部署时可能遇到的场景对模型的泛化性十分重要。 19 | 20 | 数据增强是指在一个已有数据集上操作使其有更多的多样性。对语音来说可以加入不同的背景噪音,对图片而言可以改变其颜色,形状等。 21 | 22 | 一般来说不会先将数据集做增广后存下来再用于训练;而是直接在线生成,从原始数据中读图片并随机做数据增强,再进入模型训练。通常只在训练时做数据增强而测试时不用。可以将数据增强理解为一个正则项。 23 | 24 | ### 2. 增强手段 25 | 26 | #### 2.1 翻转 27 | 28 | 一些例子:左右翻转,上下翻转 29 | 30 | 要注意不是所有增强策略都总是可行,如建筑图片上下翻转就不太合适,而之前的树叶分类竞赛中的树叶图片就没关系。 31 | 32 | 36-01 33 | 34 | #### 2.2 切割 35 | 36 | 从图片中切割一块然后变形到固定形状。一般做法是随机取一个高宽比,随机取图片大小(切下部分占原图的百分数),随机取位置。 37 | 38 | 36-02 39 | 40 | #### 2.3 颜色 41 | 42 | 改变色调,饱和度,明亮度。 43 | 44 | 36-03 45 | 46 | #### 2.4 其他 47 | 48 | 还可以有很多种不同的方法,如高斯模糊,部分像素变黑,图片变形,锐化等等。理论上讲Photoshop能做到的都可以用作图片数据增强,但效果好坏另当别论。如果测试集中有类似的效果那么相应的数据增广手段会更有效。 49 | 50 | 36-04 51 | 52 | ### 3. 总结 53 | 54 | - 数据增广通过变形数据来获取多样性从而使得模型泛化性能更好 55 | - 常见图片增广包括翻转,切割,变色 56 | 57 | ### 4. QA 58 | 59 | Q1: 理论上是不是原始样本足够多就不需要做增广? 60 | 61 | > 是的,但实际情况中很难有足够多样性的图片能覆盖测试的所有情况。 62 | > 63 | > 数据量大也不一定意味着足够多样,可能简单情况已经很充分,但对于很难的情况覆盖率不够。 64 | 65 | Q2: (代码实现中的)num_worker值是不是根据GPU性能而定? 66 | 67 | > 是。 68 | > 69 | > 这里老师还提到虽然深度学习主要用GPU,但CPU也不能太差,否则可能数据预处理跟不上,CPU的内存带宽和到显卡的带宽不够。具体决定num_worker可以自己定一个值然后跑一个epoch看看耗时。 70 | 71 | Q3: 金融风控领域经常面临极度偏斜数据(欺诈样本极少),是否可对正样本做数据增广? 72 | 73 | > 可以,类似地震预测等等正样本少的情况都可以尝试对正样本做增广,负样本可以不用。 74 | 75 | Q4: 测试一般做什么样的增广?如何理解对测试集增广能提高精度? 76 | 77 | > 一般不对测试集做增广。也可以对一张测试图像做增广,将每个增广出的图片都做一次预测最后取平均,会一定程度改善精度。但这样会使得对每张图片预测计算量成倍增长,所以使用较少。 78 | 79 | Q5: 课件里提到的对比实验固定了所有随机种子吗?昨晚增广后训练精度下降是不是意味着还可以继续训练减少gap? 80 | 81 | > 没有。 82 | > 83 | > 是的,课堂演示时往往跑的epoch较少,另外训练到后期gap一般不会减少。 84 | 85 | Q6: 图片增广后需要人工一张张确认效果吗? 86 | 87 | > 不用全看,大概看看效果即可。 88 | 89 | Q7: 图片增广后训练数据与测试数据分布可能不同,会对模型最终精度有影响吗? 90 | 91 | > 首先多数图片增广手段不改变数据分布,因为亮度变化等是随机的,数据的均值不变,翻转不影响分布,crop可能会有改变但影响不大。 92 | > 93 | > 后面还有问题提到对增广不改变数据分布的理解,可理解成增广不改变均值但稍微增大方差。很多时候讨论训练集和测试集分布是否相同不是看原始的像素分布而是看各label比例或图片色调等是否差不多。 94 | 95 | Q8: 关于图神经网络 96 | 97 | > 图神经网络很强大但不好训练,目前落地还太早了 98 | 99 | Q9: 关于mosaic和crop 100 | 101 | > 把多张图片拼起来训练。这里老师理解错了问题,提到了加马赛克和本节代码中一次展示八张图片只是一起显示而不是使用了crop方法。 102 | 103 | Q10: 用对一个事物的视频描述做数据集是不是会比增广更有效? 104 | 105 | > 可以这么认为,但拍视频是很贵的事情,获取视频往往划不来。 106 | 107 | Q11: 多张图片叠加是否也是有效的增广方式? 108 | 109 | > 是的,这种方法叫mix-up,非常有用。 110 | > 111 | > 后面有问到为什么mix-up有用,老师也不清楚。 112 | > 113 | > lable的叠加是对两张图片label按特定分布随机取权重加权求和 114 | 115 | Q12: 做车辆位置识别如果实际应用场景摄像头高度角度清晰度都和训练集不一样,是不是只能针对场景单独采集数据重新打标训练? 116 | 117 | > 是,可以考虑将实际部署时识别错误的数据加入训练集使得训练集测试集分布趋同 118 | 119 | Q13: 是否会出现图像增广减小类间差异,混淆不同类别的情况? 120 | 121 | > 那倒不会。可以考虑不要crop太小的区域。 122 | 123 | Q14: 实际操作用torchvision还是albumentation? 124 | 125 | > 都差不多 126 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/20~填充和步幅.md: -------------------------------------------------------------------------------- 1 | ## 20-填充和步幅 2 | 3 | ### 1. 填充 4 | 5 | **填充**(Padding)指的是在输入周围添加额外的行/列 6 | 7 |
8 | image 9 |
10 | 11 | **维度变化**: 12 | 13 |
14 | image 15 |
16 | 17 | **两种不同的卷积方式**: 18 | ①Valid 卷积:不进行填充,卷积运算过后得到的矩阵形状为(n-f+1)×(n-f+1)。 19 | 20 | ②Same 卷积:先对矩阵进行填充,然后再进行卷积运算,使得运算前后矩阵大小不变。 21 | 22 |
23 | image 24 |
25 | 26 | ### 2. 步幅 27 | 28 | **想法来源:**如果按照原来的操作(卷积步长为 1),那么给定输入大小为 224x224,在使用 5x5 卷积核的情况下,需要**55 层**才能将输出降低到 4x4,也就是说,需要大量的计算才能得到维度较小的输出。 29 | 30 | **步幅**是指行/列的滑动步长 31 | 32 |
33 | image 34 |
35 | 36 | **维度变化**: 37 | 38 |
39 | image 40 |
41 | 注意:第三点可以当做结论来记(Same卷积或Valid卷积(且s≥k时))。一般来说,如果n是偶数,s取2,池化层做Valid卷积(不填充)且k=2,此时输出维度直接可以写成n/2 x n/2。如果怕搞混,直接记第一个公式每次现推也可。 42 | 43 | ### 3. 总结 44 | 45 | - 填充和步幅是卷积层的**超参数** 46 | 47 | - **填充**(padding)在输入周围添加额外的行/列,来控制输出形状的减少量 48 | - **步幅**(stride)是每次滑动核窗口时的行/列的步长,可以成倍地减少输出形状 49 | 50 | ### 4. 代码 51 | 52 | #### 4.1 填充和步幅 53 | 54 | **导入包,定义 comp_conv2d 函数 (进行卷积操作, 输出后两维,便于观察高宽的维度变化)** 55 | 56 | ```python 57 | import torch 58 | from torch import nn 59 | 60 | def comp_conv2d(conv2d, X): 61 | X = X.reshape((1, 1) + X.shape) #X的维度之前加入批量大小数(batch_size)和输入通道数(channel_in) 62 | Y = conv2d(X) 63 | return Y.reshape(Y.shape[2:]) #去掉前面的两维后(原来四维) 进行输出 64 | ``` 65 | 66 | #### 4.2 padding 67 | 68 | **在所有侧边填充 1 个像素(padding=1, 即(1,1))** 69 | 70 | ```python 71 | conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1) #输入输出通道数为1, 卷积核大小3x3, 填充为1(上下左右各填充一行) 72 | X = torch.rand(size=(8, 8)) 73 | comp_conv2d(conv2d, X).shape 74 | ``` 75 | 76 | ```python 77 | >>> torch.Size([8, 8]) 78 | ``` 79 | 80 | **填充不同的高度和宽度(padding=(2,1))** 81 | 82 | ```python 83 | conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1)) 84 | comp_conv2d(conv2d, X).shape 85 | ``` 86 | 87 | ```python 88 | >>> torch.Size([8, 8]) 89 | ``` 90 | 91 | #### 4.3 stride 92 | 93 | **将高度和宽度的步幅设置为 2** 94 | 95 | ```python 96 | conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2) 97 | comp_conv2d(conv2d, X).shape 98 | ``` 99 | 100 | ```python 101 | >>> torch.Size([4, 4]) 102 | ``` 103 | 104 | **一个稍微复杂的例子** 105 | 106 | ```python 107 | conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4)) 108 | comp_conv2d(conv2d, X).shape 109 | ``` 110 | 111 | ```python 112 | >>> torch.Size([2, 2]) 113 | ``` 114 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/03~安装.md: -------------------------------------------------------------------------------- 1 | ## 03-安装 2 | 3 | ### 本节目录 4 | 5 | - [1.安装 python](#1安装python) 6 | - [2.安装 Miniconda/Anaconda](#2安装minicondaanaconda) 7 | - [2.1 安装 Miniconda](#21-安装miniconda) 8 | - [2.2 Miniconda 环境操作](#22-miniconda环境操作) 9 | - [3.安装 Pytorch, d2l, jupyter 包](#3安装pytorch-d2l-jupyter包) 10 | - [4. 总结](#4-总结) 11 | 12 | ### 1.安装 python 13 | 14 | 首先前提是安装 python,这里推荐安装 python3.8 输入命令 **_sudo apt install python3.8_** 即可 15 | 16 | ### 2.安装 Miniconda/Anaconda 17 | 18 | - 然后第二步,安装 Miniconda(如果已经安装 conda 或者 Miniconda,则可以跳过该步骤)。 19 | 20 | #### 2.1 安装 Miniconda 21 | 22 | - 安装 MIniconda 的好处是可以创建很多虚拟环境,并且不同环境之间互相不会有依赖关系,对日后的项目有帮助,如果只想在本地安装的话,不装 Miniconda 只使用 pip 即可,第二步可以跳过。 23 | - 如果是 Windows 系统,输入命令 **_wget https://repo.anaconda.com/miniconda/Miniconda3-py38_4.10.3-Windows-x86_64.exe_** 24 | - 如果是 macOS,输入命令 **_wget https://repo.anaconda.com/miniconda/Miniconda3-py38_4.10.3-MacOSX-x86_64.sh_** 之后要输入命令 **_sh Miniconda3-py38_4.10.3-MacOSX-x86_64.sh -b_** 25 | - 如果是 Linux 系统,输入命令 **_wget https://repo.anaconda.com/miniconda/Miniconda3-py38_4.10.3-Linux-x86_64.sh_** 之后输入命令 **_sh Miniconda3-py38_4.10.3-Linux-x86_64.sh -b_** 26 | - 以上都是基于 python3.8 版本,对于其他版本,可以访问 ***https://docs.conda.io/en/latest/miniconda.html*** ,下载对应版本即可。 27 | 28 | #### 2.2 Miniconda 环境操作 29 | 30 | - 对于第一次安装 Miniconda 的,要初始化终端 shell,输入命令 **_~/miniconda3/bin/conda init_** 31 | - 这样我们就可以使用 **_conda create --name d2l python=3.8 -y_** 来创建一个名为 xxx 的环境,这里命名为 d2l 32 | - 打开 xxx 环境命令: **_conda activate xxx_** ;关闭命令:**_conda deactivate xxx_**。对于基础 conda 环境不用添加名 33 | 34 | ### 3.安装 Pytorch, d2l, jupyter 包 35 | 36 | - 第三步,安装深度学习框架和`d2l`软件包 37 | 38 | 在安装深度学习框架之前,请先检查你的计算机上是否有可用的 GPU(为笔记本电脑上显示器提供输出的 GPU 不算)。例如,你可以查看计算机是否装有 NVIDIA GPU 并已安装[CUDA](https://developer.nvidia.com/cuda-downloads)。如果你的机器没有任何 GPU,没有必要担心,因为你的 CPU 在前几章完全够用。但是,如果你想流畅地学习全部章节,请提早获取 GPU 并且安装深度学习框架的 GPU 版本。 39 | 40 | - 你可以按如下方式安装 PyTorch 的 CPU 或 GPU 版本: 41 | 42 | ``` 43 | pip install torch==1.8.1 44 | pip install torchvision==0.9.1 45 | ``` 46 | 47 | - 也可以访问官网 ***https://pytorch.org/get-started/locally/*** 选择适合自己电脑 pytorch 版本下载![03-01](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/DeepLearning-MuLi-Notes/imgs/02/03-01.png) 48 | 49 | - 本课程的 jupyter notebook 代码详见 ***https://zh-v2.d2l.ai/d2l-zh.zip*** 50 | 51 | - 下载 jupyter notebook :输入命令 **_pip install jupyter notebook_** (若 pip 失灵可以尝试 pip3),输入密命令 **_jupyter notebook_** 即可打开。 52 | 53 | ### 4. 总结 54 | 55 | - 本节主要介绍**安装 Miniconda**、**CPU 环境下的 Pytorch**和其它课程所需**软件包**(d2l, jupyter)。对于前面几节来说,CPU 已经够用了。 56 | - 如果您**已经安装**了 Miniconda/Anaconda, Pytorch 框架和 jupyter 记事本, 您只需再安装**d2l 包**,就可以跳过本节视频了**开启深度学习之旅**了; 如果希望后续章节在**GPU 下跑深度学习**, 可以**新建环境**安装**CUDA 版本的 Pytorch**。 57 | - 如果需要在 Windows 下**安装 CUDA 和 Pytorch**(cuda 版本),用**本地 GPU 跑深度学习**,可以参考李沐老师[Windows 下安装 CUDA 和 Pytorch 跑深度学习](https://www.zhihu.com/zvideo/1363284223420436480),如果网慢总失败的同学可以参考[cuda11.0 如何安装 pytorch? - Glenn1Q84 的回答 - 知乎](https://www.zhihu.com/question/425647129/answer/2278290137)。当然,如果不方便在本地进行配置(如无 GPU, GPU 显存过低等),也可以选择[Colab](https://colab.research.google.com/)(需要科学上网),或其它**云服务器**GPU 跑深度学习。 58 | - 如果 pip 安装比较慢,可以用镜像源安装: 59 | 60 | ```bash 61 | pip install torch torchvision -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com 62 | ``` 63 | 64 | - 如果安装时经常报错, 可以参考课程评论区部分。 65 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/19~卷积层.md: -------------------------------------------------------------------------------- 1 | ## 19-卷积层 2 | 3 | #### 本讲文字介绍部分请参考沐神在线书籍~:https://zh-v2.d2l.ai/chapter_convolutional-neural-networks/why-conv.html 4 | 5 | #### 代码 6 | ```python 7 | import torch 8 | from torch import nn 9 | 10 | def corr2d(X,K): #X为输入,K为核矩阵 11 | h,w=K.shape #h得到K的行数,w得到K的列数 12 | Y=torch.zeros((X.shape[0]-h+1,X.shape[1]-w+1)) #用0初始化输出矩阵Y 13 | for i in range(Y.shape[0]): #卷积运算 14 | for j in range(Y.shape[1]): 15 | Y[i,j]=(X[i:i+h,j:j+w]*K).sum() 16 | return Y 17 | ``` 18 | 19 | 20 | ```python 21 | #样例点测试 22 | X=torch.tensor([[0,1,2],[3,4,5],[6,7,8]]) 23 | K=torch.tensor([[0,1],[2,3]]) 24 | corr2d(X,K) 25 | ``` 26 | 27 | 28 | 29 | 30 | >>> tensor([[19., 25.], 31 | [37., 43.]]) 32 | 33 | 34 | 35 | 36 | ```python 37 | #实现二维卷积层 38 | class Conv2d(nn.Module): 39 | def _init_(self,kernel_size): 40 | super()._init_() 41 | self.weight=nn.Parameter(torch.rand(kerner_size)) 42 | self.bias=nn.Parameter(torch.zeros(1)) 43 | def forward(self,x): 44 | return corr2d(x,self.weight)+self.bias 45 | ``` 46 | 47 | 48 | ```python 49 | X=torch.ones((6,8)) 50 | X[:,2:6]=0 51 | X 52 | ``` 53 | 54 | 55 | 56 | 57 | >>> tensor([[1., 1., 0., 0., 0., 0., 1., 1.], 58 | [1., 1., 0., 0., 0., 0., 1., 1.], 59 | [1., 1., 0., 0., 0., 0., 1., 1.], 60 | [1., 1., 0., 0., 0., 0., 1., 1.], 61 | [1., 1., 0., 0., 0., 0., 1., 1.], 62 | [1., 1., 0., 0., 0., 0., 1., 1.]]) 63 | 64 | 65 | 66 | 67 | ```python 68 | K=torch.tensor([[-1,1]]) #这个K只能检测垂直边缘 69 | Y=corr2d(X,K) 70 | Y 71 | ``` 72 | 73 | 74 | 75 | 76 | >>> tensor([[ 0., -1., 0., 0., 0., 1., 0.], 77 | [ 0., -1., 0., 0., 0., 1., 0.], 78 | [ 0., -1., 0., 0., 0., 1., 0.], 79 | [ 0., -1., 0., 0., 0., 1., 0.], 80 | [ 0., -1., 0., 0., 0., 1., 0.], 81 | [ 0., -1., 0., 0., 0., 1., 0.]]) 82 | 83 | 84 | 85 | 86 | ```python 87 | corr2d(X.t(),K) 88 | ``` 89 | 90 | 91 | 92 | 93 | >>> tensor([[0., 0., 0., 0., 0.], 94 | [0., 0., 0., 0., 0.], 95 | [0., 0., 0., 0., 0.], 96 | [0., 0., 0., 0., 0.], 97 | [0., 0., 0., 0., 0.], 98 | [0., 0., 0., 0., 0.], 99 | [0., 0., 0., 0., 0.], 100 | [0., 0., 0., 0., 0.]]) 101 | 102 | 103 | 104 | 105 | ```python 106 | conv2d = nn.Conv2d(1, 1, kernel_size=(1, 2), bias=False) 107 | 108 | X = X.reshape((1, 1, 6, 8)) 109 | Y = Y.reshape((1, 1, 6, 7)) 110 | 111 | for i in range(10): 112 | Y_hat = conv2d(X) 113 | l = (Y_hat - Y)**2 114 | conv2d.zero_grad() 115 | l.sum().backward() 116 | conv2d.weight.data[:] -= 3e-2 * conv2d.weight.grad 117 | if (i + 1) % 2 == 0: 118 | print(f'batch {i+1}, loss {l.sum():.3f}') 119 | ``` 120 | 121 | >>> batch 2, loss 3.852 122 | batch 4, loss 1.126 123 | batch 6, loss 0.386 124 | batch 8, loss 0.145 125 | batch 10, loss 0.057 126 | 127 | 128 | 129 | ```python 130 | conv2d.weight.data.reshape((1, 2)) 131 | ``` 132 | 133 | 134 | 135 | 136 | >>> tensor([[-1.0173, 0.9685]]) 137 | 138 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/attic/activation_func_graphs.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | 4 | 5 | def sigmoid(x): 6 | return 1 / (1 + np.exp(-x)) 7 | 8 | 9 | def deriv_sigmoid(x): 10 | return sigmoid(x) * (1 - sigmoid(x)) 11 | 12 | 13 | def tanh(x): 14 | return np.tanh(x) 15 | 16 | 17 | def deriv_tanh(x): 18 | return 1 - np.tanh(x) ** 2 19 | 20 | 21 | def relu(x): 22 | return x if x >= 0 else 0 + 0.023 23 | 24 | 25 | def deriv_relu(x): 26 | return 1 if x >= 0 else 0 27 | 28 | 29 | X = [] 30 | _sigmoid = [] 31 | _tanh = [] 32 | _relu = [] 33 | _deriv_relu = [] 34 | 35 | Range = 3 36 | Div = 50 37 | 38 | for J in range(-1 * Range * Div, Range * Div): 39 | i = float(J / Div) 40 | X.append(i) 41 | 42 | _sigmoid.append(sigmoid(i)) 43 | _tanh.append(tanh(i)) 44 | _relu.append(relu(i)) 45 | 46 | 47 | plt.plot(X, _sigmoid, color="b", label="f(x)=sigmoid(x)") 48 | plt.plot(X, _tanh, color="r", label="f(x)=tanh(x)") 49 | plt.plot(X, _relu, color="g", label="f(x)=ReLu(x)") 50 | 51 | plt.xlabel("x") 52 | plt.ylabel("f(x)") 53 | plt.grid() 54 | plt.legend() 55 | plt.show() 56 | 57 | 58 | 59 | # 60 | # Sigmoid 61 | # 62 | Range = 10 63 | Div = 10 64 | 65 | X = [] 66 | func = [] 67 | d1_func = [] 68 | 69 | for J in range(-1 * Range * Div, Range * Div): 70 | i = float(J / Div) 71 | X.append(i) 72 | 73 | func.append(sigmoid(i)) 74 | d1_func.append(deriv_sigmoid(i)) 75 | 76 | # 77 | plt.plot(X, func, color="b", label="f(x) = sigmoid(x)") 78 | plt.plot(X, d1_func, color="r", label="df(x)/dx") 79 | 80 | plt.title("sigmoid function") 81 | plt.xlabel("x") 82 | plt.ylabel("f(x)") 83 | plt.legend() 84 | plt.show() 85 | 86 | # 87 | # Tanh 88 | # 89 | Range = 10 90 | Div = 10 91 | 92 | X = [] 93 | func = [] 94 | d1_func = [] 95 | 96 | for J in range(-1 * Range * Div, Range * Div): 97 | i = float(J / Div) 98 | X.append(i) 99 | 100 | func.append(tanh(i)) 101 | d1_func.append(deriv_tanh(i)) 102 | 103 | # 104 | plt.plot(X, func, color="b", label="f(x) = tanh(x)") 105 | plt.plot(X, d1_func, color="r", label="df(x)/dx") 106 | 107 | plt.title("tanh function") 108 | plt.xlabel("x") 109 | plt.ylabel("f(x)") 110 | plt.legend() 111 | plt.show() 112 | 113 | 114 | # 115 | # ReLU 116 | # 117 | 118 | 119 | 120 | 121 | X = [] 122 | _sigmoid = [] 123 | _tanh = [] 124 | _relu = [] 125 | _deriv_relu = [] 126 | 127 | Range = 3 128 | Div = 50 129 | 130 | for J in range(-1 * Range * Div, Range * Div): 131 | i = float(J / Div) 132 | X.append(i) 133 | 134 | """ 135 | _sigmoid.append(sigmoid(i)) 136 | _tanh.append(tanh(i)) 137 | _relu.append(relu(i)) 138 | """ 139 | _relu.append(relu(i)) 140 | if i == 0.0: 141 | _deriv_relu.append(None) 142 | else: 143 | _deriv_relu.append(deriv_relu(i)) 144 | # 145 | """ 146 | plt.plot(X, _sigmoid, color="b", label="f(x)=sigmoid(x)") 147 | plt.plot(X, _tanh, color="r", label="f(x)=tanh(x)") 148 | plt.plot(X, _relu, color="g", label="f(x)=ReLu(x)") 149 | """ 150 | 151 | plt.plot(X, _relu, color="b", label="f(x) = relu(x)") 152 | plt.plot(X, _deriv_relu, color="r", label="df(x)/dx") 153 | 154 | 155 | plt.xlabel("x") 156 | plt.ylabel("f(x)") 157 | # plt.grid() 158 | plt.legend() 159 | plt.show() 160 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/XOR-gate-keras-softmax.py: -------------------------------------------------------------------------------- 1 | # 2 | # A Neural Network with Softmax layer for learning XOR gate. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | from keras.models import Sequential 17 | try: 18 | from keras.layers.core import Activation, Dense 19 | except: 20 | from keras.layers import Activation, Dense 21 | from keras.optimizers import Adam 22 | import numpy as np 23 | import matplotlib.pyplot as plt 24 | 25 | # np.random.seed(0) 26 | 27 | # ======================================== 28 | # Create datasets 29 | # ======================================== 30 | 31 | # Inputs 32 | X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 33 | 34 | # The ground-truth labels 35 | Y = np.array([[1, 0], [0, 1], [0, 1], [1, 0]]) 36 | 37 | # Convert row vectors into column vectors. 38 | X = X.reshape(4, 2, 1) 39 | Y = Y.reshape(4, 2, 1) 40 | 41 | # ======================================== 42 | # Create model 43 | # ======================================== 44 | input_nodes = 2 45 | hidden_nodes = 3 46 | output_nodes = 2 47 | 48 | model = Sequential() 49 | model.add(Dense(hidden_nodes, input_dim=input_nodes)) 50 | model.add(Activation("sigmoid")) 51 | model.add(Dense(output_nodes)) 52 | model.add(Activation("softmax")) 53 | 54 | optimizer = Adam(learning_rate=0.1) 55 | 56 | # model.compile(loss="binary_crossentropy", optimizer=optimizer) 57 | model.compile(loss="categorical_crossentropy", optimizer=optimizer) 58 | 59 | print(model.summary()) 60 | 61 | 62 | # ======================================== 63 | # Training 64 | # ======================================== 65 | 66 | n_epochs = 500 67 | 68 | # Run through the data `epochs` times 69 | history = model.fit(X, Y, epochs=n_epochs, batch_size=1, verbose=1) 70 | 71 | # 72 | # Show loss history 73 | # 74 | plt.plot(history.history["loss"], color="b", label="loss") 75 | plt.title("Training Loss History") 76 | plt.xlabel("Number of Epochs") 77 | plt.ylabel("Loss") 78 | plt.legend() 79 | plt.grid(True) 80 | plt.show() 81 | 82 | # ======================================== 83 | # Test 84 | # ======================================== 85 | 86 | result = model.predict(X) 87 | 88 | print("-------------------------------------") 89 | print("x0 XOR x1 => prob(0) prob(1)") 90 | print("=====================================") 91 | for i in range(0, len(Y)): 92 | _x0 = X[i][0][0] 93 | _x1 = X[i][1][0] 94 | print( 95 | " {} XOR {} => {:.4f} {:.4f}".format(_x0, _x1, result[i][0], result[i][1]) 96 | ) 97 | print("=====================================") 98 | 99 | 100 | x = np.arange(2) 101 | plt.subplots_adjust(wspace=0.4, hspace=0.8) 102 | 103 | for i in range(4): 104 | plt.subplot(4, 1, i + 1) 105 | title = str(X[i][0][0]) + " XOR " + str(X[i][1][0]) 106 | plt.title(title) 107 | plt.bar(x, result[i], tick_label=x, align="center") 108 | plt.ylim(0, 1) 109 | plt.ylabel("prob.") 110 | 111 | plt.show() 112 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/RNN_keras.py: -------------------------------------------------------------------------------- 1 | # 2 | # Sine wave prediction using Simple-RNN of Keras. 3 | # 4 | # 5 | # Developed environment: 6 | # Python 3.11.5 7 | # keras 2.15.0 8 | # pip 24.0 9 | # numpy 1.26.4 10 | # matplotlib 3.9.0 11 | # tensorflow 2.15.1 12 | # tensorflow-metal 1.1.0 13 | # scikit-learn 1.5.0 14 | # 15 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 16 | 17 | import numpy as np 18 | from keras.models import Sequential 19 | from keras.layers import Dense, SimpleRNN 20 | from keras.optimizers import Adam 21 | import matplotlib.pyplot as plt 22 | import DataSet as ds 23 | 24 | 25 | def plot_fig(model, wave_data, n_sample, n_sequence): 26 | 27 | wave = wave_data 28 | z = wave[0:n_sequence] 29 | input = wave[0:n_sequence+1] 30 | sin = [None for i in range(n_sequence)] 31 | gen = [None for i in range(n_sequence)] 32 | 33 | for j in range(n_sample): 34 | y = model.predict(z.reshape(1, n_sequence, 1)) 35 | z = np.append(z, y)[1:] 36 | gen.append(y[0][0]) 37 | sin.append(wave[j+n_sequence]) 38 | 39 | plt.plot(input, color="b", label="input") 40 | plt.plot(sin, "--", color="#888888", label="sine wave") 41 | plt.plot(gen, color="r", label="predict") 42 | plt.title("Prediction") 43 | plt.legend() 44 | plt.ylim([-2, 2]) 45 | plt.grid(True) 46 | plt.show() 47 | 48 | # ============================ 49 | # Data creation 50 | # ============================ 51 | n_sequence = 25 52 | n_data = 100 53 | 54 | n_sample = n_data - n_sequence # number of sample 55 | 56 | sin_data = ds.create_wave(n_data, 0.05) 57 | X, Y = ds.dataset(sin_data, n_sequence, False) 58 | 59 | X = X.reshape(X.shape[0], X.shape[1], 1) 60 | Y = Y.reshape(Y.shape[0], Y.shape[1]) 61 | 62 | # ============================ 63 | # Model creation 64 | # ============================ 65 | 66 | lr = 0.001 67 | 68 | input_units = 1 69 | hidden_units = 32 70 | output_units = 1 71 | 72 | model = Sequential() 73 | model.add( 74 | SimpleRNN( 75 | hidden_units, 76 | activation="tanh", 77 | use_bias=True, 78 | input_shape=(n_sequence, input_units), 79 | return_sequences=False, 80 | ) 81 | ) 82 | model.add(Dense(output_units, activation="linear", use_bias=True)) 83 | model.compile(loss="mean_squared_error", optimizer=Adam(lr)) 84 | 85 | print(model.summary()) 86 | 87 | 88 | # ============================ 89 | # Training 90 | # ============================ 91 | 92 | n_epochs = 50 93 | 94 | batch_size = 5 95 | 96 | history_rst = model.fit( 97 | X, 98 | Y, 99 | batch_size=batch_size, 100 | epochs=n_epochs, 101 | validation_split=0.1, 102 | shuffle=True, 103 | verbose=1, 104 | ) 105 | 106 | 107 | plt.plot(history_rst.history["loss"], label="loss") 108 | plt.legend(loc="best") 109 | plt.title("Training Loss History") 110 | plt.xlabel("epochs") 111 | plt.ylabel("loss") 112 | plt.grid(True) 113 | plt.show() 114 | 115 | 116 | # ============================ 117 | # Prediction 118 | # ============================ 119 | 120 | sin_data = ds.create_wave(n_data, 0.0) 121 | plot_fig(model, sin_data, n_sample, n_sequence) 122 | -------------------------------------------------------------------------------- /99~参考资料/2019~《Deep Learning Book》/README.md: -------------------------------------------------------------------------------- 1 | # Deep-Learning-Book-Chapter-Summaries 2 | This repository provides a summary for each chapter of the Deep Learning [book](http://deeplearningbook.org) by Ian Goodfellow, Yoshua Bengio and Aaron Courville and attempts to explain some of the concepts in greater detail. Some of the tougher chapters have blog post(s) dedicated to them which can be found on http://medium.com/inveterate-learner. 3 | 4 | ## Chapters 5 | 6 | - **Part I: Applied Math and Machine Learning Basics** 7 | - Chapter 2: Linear Algebra [[chapter](http://www.deeplearningbook.org/contents/linear_algebra.html)] 8 | - Chapter 3: Probability and Information Theory [[chapter](http://www.deeplearningbook.org/contents/prob.html)] 9 | - Chapter 4: Numerical Computation [[chapter](http://www.deeplearningbook.org/contents/numerical.html)] 10 | - Chapter 5: Machine Learning Basics [[chapter](http://www.deeplearningbook.org/contents/ml.html)] 11 | 12 | - **Part II: Modern Practical Deep Networks** 13 | - Chapter 6: Deep Feedforward Networks [[chapter](http://www.deeplearningbook.org/contents/mlp.html)] 14 | - Chapter 7: Regularization for Deep Learning [[chapter](http://www.deeplearningbook.org/contents/regularization.html)] 15 | - Chapter 8: Optimization for Training Deep Models [[chapter](http://www.deeplearningbook.org/contents/optimization.html)] 16 | - Chapter 9: Convolutional Networks [[chapter](http://www.deeplearningbook.org/contents/convnets.html)] 17 | - Chapter 10: Sequence Modeling: Recurrent and Recursive Nets [[chapter](http://www.deeplearningbook.org/contents/rnn.html)] 18 | - Chapter 11: Practical Methodology [[chapter](http://www.deeplearningbook.org/contents/guidelines.html)] 19 | - Chapter 12: Applications [[chapter](http://www.deeplearningbook.org/contents/applications.html)] 20 | 21 | - **Part III: Deep Learning Research** 22 | - Chapter 13: Linear Factor Models [[chapter](http://www.deeplearningbook.org/contents/linear_factors.html)] 23 | - Chapter 14: Autoencoders [[chapter](http://www.deeplearningbook.org/contents/autoencoders.html)] 24 | - Chapter 15: Representation Learning [[chapter](http://www.deeplearningbook.org/contents/representation.html)] 25 | - Chapter 16: Structured Probabilistic Models for Deep Learning [[chapter](http://www.deeplearningbook.org/contents/graphical_models.html)] 26 | - Chapter 17: Monte Carlo Methods [[chapter](http://www.deeplearningbook.org/contents/monte_carlo.html)] 27 | - Chapter 18: Confronting the Partition Function [[chapter](http://www.deeplearningbook.org/contents/partition.html)] 28 | - Chapter 19: Approximate Inference [[chapter](http://www.deeplearningbook.org/contents/inference.html)] 29 | - Chapter 20: Deep Generative Models [[chapter](http://www.deeplearningbook.org/contents/generative_models.html)] 30 | 31 | ## Contributors 32 | - [Aman Dalmia](https://github.com/dalmia) 33 | - [Ameya Godbole](https://github.com/ameyagodbole) 34 | 35 | ## Contributing 36 | 37 | Please feel free to open a Pull Request to contribute a summary for the chapters 5, 6 and 12 as we might not be able to cover them owing to other commitments. Also, if you think there's any section that requires more/better explanation, please use the issue tracker to let us know about the same. 38 | 39 | ## Support 40 | 41 | If you like this repo and find it useful, please consider (★) starring it (on top right of the page) so that it can reach a broader audience. 42 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/18~预测房价竞赛总结.md: -------------------------------------------------------------------------------- 1 | ## 18-预测房价竞赛总结 2 | 3 | ### 本节目录 4 | 5 | - [1.方法总结](#1方法总结) 6 | - [2.分析](#2分析) 7 | - [3.关于 automl](#3关于automl) 8 | - [3.1 课程内容](#31-课程内容) 9 | - [3.2 补充内容](#32-补充内容) 10 | - [AutoGluon](#autogluon) 11 | - [4.总结](#4总结) 12 | - [5.预测房价竞赛总结 Q&A](#5预测房价竞赛总结-qa) 13 | 14 | ### 1.方法总结 15 | 16 | > 下面提供了排行榜前几使用的方法介绍链接 17 | 18 | - 第二和第七:autogluon 19 | 20 | https://www.bilibili.com/video/BV1rh411m7Hb/ 21 | 22 | - 第三:h2o 23 | 24 | https://www.kaggle.com/wuwawa/automl-using-h2o 25 | 26 | - 第四:随机森林 27 | 28 | https://www.kaggle.com/jackzh/the-4th-place-approach-random-forest 29 | 30 | ### 2.分析 31 | 32 | - 已知的排名靠前的 4 个成绩均使用了集成学习 33 | 34 | - 目前不知道是否有使用书中的 mlp 取得好成绩 35 | 36 | > 通过调参数,是能够取得很好的结果的 37 | 38 | 对于 mlp 来说,特征预处理和超参数的调节是取得好成绩的基础 39 | 40 | - 数据的难点 41 | 42 | - 数值较大 43 | 44 | > 梯度相对较大,容易发生梯度爆炸 45 | 46 | 一个解决方案是可以对数据取对数,再进行标准化 47 | 48 | - 有文本特征(地址,介绍) 49 | 50 | > 这些文字可能含有较多的噪声,对模型产生影响 51 | 52 | 解决办法日后会讲解,比如第二名用的 transformer 53 | 54 | - 训练数据是前 6 个月,公榜是后 3 个月,私榜是再往后 3 个月 55 | 56 | > 利用历史的数据进行训练,在实践中自然会有不同的影响(可能过拟合) 57 | > 58 | > 因此公榜与私榜的排名有一定差异 59 | 60 | 这个问题称为Covariate Shift,没有特别好的解决方案 ,可以让模型尽可能稳定,不去仔细调参 61 | 62 | ### 3.关于 automl 63 | 64 | #### 3.1 课程内容 65 | 66 | > 这一部分李沐老师要表达的主要是我们应该深入去了解本后的原理,不要因为有"自动化"深度学习而产生一种依赖心理或者变得没有深究深度学习的动力,学习 deep learning 仍然是有意义的 67 | 68 | - 数据科学家 80%时间在处理数据,20%调模型 69 | 70 | > 处理数据是 automl 不能做的,automl 的作用主要在调模型这块,数据科学家仍然能大展身手 71 | 72 | - Automl 现在能处理一些基础的情况 73 | 74 | > 目前节省 10%时间,未来节省 20%时间 75 | 76 | - 为什么还要学习深度学习 77 | 78 | 正如买菜只需要用到四则运算甚至不用,我们仍然需要学习三角函数去进行更深入的科学研究等其他事情。当人人都会用 Automl 的时候,我们仍然需要懂得一些底层的原理,毕竟 Automl 也是有局限性的,需要我们不断改进,或者想出其他算法。另一方面,我们也要肯定 Automl 带来的便利。 79 | 80 | #### 3.2 补充内容 81 | 82 | ##### AutoGluon 83 | 84 | > 与大部分 automl 框架是基于超参数搜索技术的不同,Autogluon 会利用多个机器学习包来训练模型 85 | 86 | - 房价预测竞赛中模型的改动 87 | 88 | > 1.对于数据中数值比较大且数据变化大的数值取 log,CPU 上训练 2 个小时,最终排第七 89 | > 90 | > 2.房子描述里包含大量文本,使用 mutimodal 选项来用 transformer 提取特征,并做多模型融合,用 GPU 才跑得动,排名第二 91 | 92 | - AutoGluon 背后的技术 93 | 94 | > 1.stacking 95 | > 96 | > 2.k-则交叉 bagging 97 | > 98 | > 3.多层 stacking 99 | 100 | - 总结 101 | 102 | > 1.autogluon 在合理的计算开销下得到还不错的模型 103 | > 104 | > 2.虽然 autogluon 可以做自动特征抽取,但是当加入一些人工数据处理也是不错的方法 105 | > 106 | > 3.对于比较大的数据集计算开销仍然是瓶颈,需要使用 GPU 甚至多台机器做分布式训练,这仍是 AutoML 未来的研究方向 107 | > 108 | > 4.具体讲解可参考:https://www.bilibili.com/video/BV1F84y1F7Ps/?spm_id_from=333.788.recommend_more_video.1 109 | 110 | ### 4.总结 111 | 112 | 这节课本身就是一次对预测房价竞赛的总结,主要介绍了排名的分布情况以及一些队伍使用的方法。 113 | 114 | ### 5.预测房价竞赛总结 Q&A 115 | 116 | **Q1: 统计学专业本科生未来从事人工智能如何规划** 117 | 118 | > 注重动手能力的培养 119 | 120 | **Q2: 避免 overfit 是调参好还是不调参好?老师有何经验分享?** 121 | 122 | > 调参是需要的,首先最好有一个比较好的验证集;当你找到一个在验证集效果比较好的超参数值的时候,最好在这一值上调或下调一点看看是否敏感,如果比较敏感说明这点可能只是在这点凑巧效果好罢了,泛化性就不好;当然在实践中调参并没有像在竞赛中那么重要 123 | 124 | **Q3: 老师说的 80%时间处理数据是指的找数据、清理数据这些?数据搭建 pipeline 不就好了,?为什么改进模型等等不占主要时间?** 125 | 126 | > 处理数据并不是搭建 pipeline 就好了,你需要决定从哪里获取数据、怎样获取数据、如何处理噪音(清理数据)......这些都是很费时间的 127 | 128 | **Q4: AutoML 与 ML 有严格的特征区别吗** 129 | 130 | > AutoML 可以看作是 ML 中的一类算法 131 | 132 | **Q5: 用 mlp 做竞赛时发现层数深的时候预测出来的房价全是一样的,层数浅一点还不会出现这个问题,为什么?** 133 | 134 | > 应该是梯度爆炸,或者梯度消失,也就是数值稳定性出现问题 135 | 136 | **Q6:MLP 有值得精细调参的价值吗?** 137 | 138 | > 有。 139 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/LSTM_keras.py: -------------------------------------------------------------------------------- 1 | # 2 | # Sine wave prediction using LSTM of Keras. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | from keras.models import Sequential 18 | from keras.layers import Dense, LSTM 19 | from keras.optimizers import Adam 20 | import matplotlib.pyplot as plt 21 | import DataSet as ds 22 | 23 | def plot_fig(model, wave_data, n_sample, n_sequence): 24 | 25 | wave = wave_data 26 | z = wave[0:n_sequence] 27 | input = wave[0:n_sequence+1] 28 | sin = [None for i in range(n_sequence)] 29 | gen = [None for i in range(n_sequence)] 30 | 31 | for j in range(n_sample): 32 | y = model.predict(z.reshape(1, n_sequence, 1)) 33 | z = np.append(z, y)[1:] 34 | gen.append(y[0][0]) 35 | sin.append(wave[j+n_sequence]) 36 | 37 | plt.plot(input, color="b", label="input") 38 | plt.plot(sin, "--", color="#888888", label="sine wave") 39 | plt.plot(gen, color="r", label="predict") 40 | plt.title("Prediction") 41 | plt.legend() 42 | plt.ylim([-2, 2]) 43 | plt.grid(True) 44 | plt.show() 45 | 46 | 47 | # ============================ 48 | # Data creation 49 | # ============================ 50 | n_sequence = 25 51 | n_data = 100 52 | 53 | n_sample = n_data - n_sequence # number of sample 54 | 55 | sin_data = ds.create_wave(n_data, 0.05) 56 | X, Y = ds.dataset(sin_data, n_sequence, False) 57 | 58 | X = X.reshape(X.shape[0], X.shape[1], 1) 59 | Y = Y.reshape(Y.shape[0], Y.shape[1]) 60 | 61 | # ============================ 62 | # Model creation 63 | # ============================ 64 | 65 | lr = 0.001 66 | 67 | input_units = 1 68 | hidden_units = 32 69 | output_units = 1 70 | 71 | model = Sequential() 72 | model.add( 73 | LSTM( 74 | hidden_units, 75 | activation="tanh", 76 | recurrent_activation="sigmoid", 77 | use_bias=True, 78 | batch_input_shape=(None, n_sequence, input_units), 79 | return_sequences=False, 80 | ) 81 | ) 82 | model.add(Dense(output_units, activation="linear", use_bias=True)) 83 | model.compile(loss="mean_squared_error", optimizer=Adam(lr)) 84 | 85 | print(model.summary()) 86 | 87 | 88 | # ============================ 89 | # Training 90 | # ============================ 91 | 92 | n_epochs = 50 93 | 94 | batch_size = 5 95 | 96 | history_rst = model.fit( 97 | X, 98 | Y, 99 | batch_size=batch_size, 100 | epochs=n_epochs, 101 | validation_split=0.1, 102 | shuffle=True, 103 | verbose=1, 104 | ) 105 | 106 | 107 | plt.plot(history_rst.history["loss"], label="loss") 108 | plt.legend(loc="best") 109 | plt.title("Training Loss History") 110 | plt.xlabel("epochs") 111 | plt.ylabel("loss") 112 | plt.grid(True) 113 | plt.show() 114 | 115 | 116 | # ============================ 117 | # Prediction 118 | # ============================ 119 | 120 | sin_data = ds.create_wave(n_data, 0.0) 121 | plot_fig(model, sin_data, n_sample, n_sequence) 122 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/GRU_keras.py: -------------------------------------------------------------------------------- 1 | # 2 | # Sine wave prediction using GRU of Keras. 3 | # 4 | # NOTE: Keras 3.0+ not supported 5 | # 6 | # Developed environment: 7 | # Python 3.11.5 8 | # keras 2.15.0 9 | # pip 24.0 10 | # numpy 1.26.4 11 | # matplotlib 3.9.0 12 | # tensorflow 2.15.1 13 | # tensorflow-metal 1.1.0 14 | # scikit-learn 1.5.0 15 | # 16 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 17 | 18 | import numpy as np 19 | from keras.models import Sequential 20 | from keras.layers import Dense, GRU 21 | from keras.optimizers import Adam 22 | import matplotlib.pyplot as plt 23 | import DataSet as ds 24 | 25 | 26 | def plot_fig(model, wave_data, n_sample, n_sequence): 27 | 28 | wave = wave_data 29 | z = wave[0:n_sequence] 30 | input = wave[0:n_sequence+1] 31 | sin = [None for i in range(n_sequence)] 32 | gen = [None for i in range(n_sequence)] 33 | 34 | for j in range(n_sample): 35 | y = model.predict(z.reshape(1, n_sequence, 1)) 36 | z = np.append(z, y)[1:] 37 | gen.append(y[0][0]) 38 | sin.append(wave[j+n_sequence]) 39 | 40 | plt.plot(input, color="b", label="input") 41 | plt.plot(sin, "--", color="#888888", label="sine wave") 42 | plt.plot(gen, color="r", label="predict") 43 | plt.title("Prediction") 44 | plt.legend() 45 | plt.ylim([-2, 2]) 46 | plt.grid(True) 47 | plt.show() 48 | 49 | # ============================ 50 | # Data creation 51 | # ============================ 52 | n_sequence = 25 53 | n_data = 100 54 | 55 | n_sample = n_data - n_sequence # number of sample 56 | 57 | sin_data = ds.create_wave(n_data, 0.05) 58 | X, Y = ds.dataset(sin_data, n_sequence, False) 59 | 60 | X = X.reshape(X.shape[0], X.shape[1], 1) 61 | Y = Y.reshape(Y.shape[0], Y.shape[1]) 62 | 63 | # ============================ 64 | # Model creation 65 | # ============================ 66 | 67 | lr = 0.001 68 | 69 | input_units = 1 70 | hidden_units = 32 71 | output_units = 1 72 | 73 | model = Sequential() 74 | model.add( 75 | GRU( 76 | hidden_units, 77 | activation="tanh", 78 | recurrent_activation="sigmoid", 79 | use_bias=True, 80 | batch_input_shape=(None, n_sequence, input_units), 81 | return_sequences=False, 82 | ) 83 | ) 84 | model.add(Dense(output_units, activation="linear", use_bias=True)) 85 | model.compile(loss="mean_squared_error", optimizer=Adam(lr)) 86 | 87 | print(model.summary()) 88 | 89 | 90 | # ============================ 91 | # Training 92 | # ============================ 93 | 94 | n_epochs = 100 95 | 96 | batch_size = 5 97 | 98 | history_rst = model.fit( 99 | X, 100 | Y, 101 | batch_size=batch_size, 102 | epochs=n_epochs, 103 | validation_split=0.1, 104 | shuffle=True, 105 | verbose=1, 106 | ) 107 | 108 | 109 | plt.plot(history_rst.history["loss"], label="loss") 110 | plt.legend(loc="best") 111 | plt.title("Training Loss History") 112 | plt.xlabel("epochs") 113 | plt.ylabel("loss") 114 | plt.grid(True) 115 | plt.show() 116 | 117 | 118 | # ============================ 119 | # Prediction 120 | # ============================ 121 | 122 | sin_data = ds.create_wave(n_data, 0.0) 123 | plot_fig(model, sin_data, n_sample, n_sequence) 124 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/binary-to-decimal-conversion-keras.py: -------------------------------------------------------------------------------- 1 | # 2 | # A Neural Network with Softmax layer for learning binary to decimal conversion. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import keras 17 | from keras.models import Sequential 18 | try: 19 | from keras.layers.core import Activation, Dense 20 | except: 21 | from keras.layers import Activation, Dense 22 | from keras.optimizers import Adam 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | 26 | # np.random.seed(0) 27 | 28 | # ======================================== 29 | # Create datasets 30 | # ======================================== 31 | 32 | # Inputs 33 | X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 34 | 35 | # The ground-truth labels 36 | Y = np.array([[0], [1], [2], [3]]) 37 | 38 | # Convert into One-Hot vector 39 | Y = keras.utils.to_categorical(Y, 4) 40 | 41 | """ 42 | Y = [[1. 0. 0. 0.] 43 | [0. 1. 0. 0.] 44 | [0. 0. 1. 0.] 45 | [0. 0. 0. 1.]] 46 | """ 47 | 48 | # Convert row vectors into column vectors. 49 | X = X.reshape(4, 2, 1) 50 | Y = Y.reshape(4, 4, 1) 51 | 52 | # ======================================== 53 | # Create model 54 | # ======================================== 55 | input_nodes = 2 56 | hidden_nodes = 3 57 | output_nodes = 4 58 | 59 | model = Sequential() 60 | model.add(Dense(hidden_nodes, input_dim=input_nodes)) 61 | model.add(Activation("sigmoid")) 62 | model.add(Dense(output_nodes)) 63 | model.add(Activation("softmax")) 64 | 65 | optimizer = Adam(learning_rate=0.1) 66 | 67 | model.compile(loss="categorical_crossentropy", optimizer=optimizer) 68 | 69 | print(model.summary()) 70 | 71 | 72 | # ======================================== 73 | # Training 74 | # ======================================== 75 | 76 | n_epochs = 300 77 | 78 | # Run through the data `epochs` times 79 | history = model.fit(X, Y, epochs=n_epochs, batch_size=1, verbose=1) 80 | 81 | # 82 | # Show loss history 83 | # 84 | plt.plot(history.history["loss"], color="b", label="loss") 85 | plt.title("Training Loss History") 86 | plt.xlabel("Number of Epochs") 87 | plt.ylabel("Loss") 88 | plt.legend() 89 | plt.grid(True) 90 | plt.show() 91 | 92 | # ======================================== 93 | # Test 94 | # ======================================== 95 | 96 | result = model.predict(X) 97 | 98 | print("-------------------------------------------") 99 | print("(x0 x1) => prob(0) prob(1) prob(2) prob(3)") 100 | print("===========================================") 101 | 102 | for i in range(0, len(Y)): 103 | _x0 = X[i][0][0] 104 | _x1 = X[i][1][0] 105 | print( 106 | "({} {}) => {:.4f} {:.4f} {:.4f} {:.4f}".format( 107 | _x0, _x1, result[i][0], result[i][1], result[i][2], result[i][3] 108 | ) 109 | ) 110 | 111 | print("===========================================") 112 | 113 | x = np.arange(output_nodes) 114 | plt.subplots_adjust(wspace=0.4, hspace=0.8) 115 | 116 | for i in range(4): 117 | plt.subplot(4, 1, i + 1) 118 | x_i = X[i] 119 | title = str(x_i[0][0]) + " " + str(x_i[1][0]) 120 | plt.title(title) 121 | plt.bar(x, result[i], tick_label=x, align="center") 122 | plt.ylim(0, 1) 123 | plt.ylabel("prob.") 124 | 125 | plt.show() 126 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/44~物体检测算法:R~CNN,SSD,YOLO.md: -------------------------------------------------------------------------------- 1 | ## 44.物体检测算法:R-CNN,SSD,YOLO 2 | 3 | ### 目录 4 | 5 | - [44.物体检测算法:R-CNN,SSD,YOLO](#44物体检测算法r-cnnssdyolo) 6 | - [1.区域卷积神经网络](#1区域卷积神经网络) 7 | - [1.1.R-CNN](#11r-cnn) 8 | - [1.2 Fast RCNN](#12-fast-rcnn) 9 | - [1.3 Faster RCNN](#13-faster-rcnn) 10 | - [1.4 Mask RCNN](#14-mask-rcnn) 11 | - [1.5 总结](#15-总结) 12 | - [2. 单发多框检测(SSD single shot detection)](#2-单发多框检测ssd-single-shot-detection) 13 | - [3. YOLO(you only look once)](#3-yoloyou-only-look-once) 14 | 15 | ### 1.区域卷积神经网络 16 | 17 | #### 1.1.R-CNN 18 | 19 | - 使用启发式搜索算法来选择锚框 20 | - 使用预训练模型来对每个锚框抽取特征(每个锚框当作一个图片,用 CNN) 21 | - 训练一个 SVM 来类别分类(神经网络之前,category prediction) 22 | - 训练一个线性回归模型来预测边缘框偏移(bounding box prediction) 23 | - 兴趣区域(Rol)池化层 24 | - 给定一个锚框,均匀分割(如果没法均匀分割,取整)成 n x m 块,输出每块的最大值(max pooling) 25 | - 不管锚框多大,总是输出 nm 个值 26 | - 目的:每个锚框都可以变成想要的形状 27 | 28 | #### 1.2 Fast RCNN 29 | 30 | - RCNN 需要对每个锚框进行 CNN 运算,这些特征抽取计算有重复,并且锚框数量大,特征抽取的计算量也大。Fast RCNN 改进了这种计算量大的问题 31 | 32 | - 使用 CNN 对整张图片抽取特征(快的关键) 33 | 34 | - 使用 Rol 池化层对每个锚框(将在原图片中搜索到的锚框,映射到 CNN 得到的结果上),生成固定长度的特征 35 | 36 |
37 | image 38 |
39 | 40 | #### 1.3 Faster RCNN 41 | 42 | - 在 Fast RCNN 基础上变得更快 43 | - 使用一个 **区域提议网络来替代启发式搜索获得更好的锚框** 44 | - 如下图所示,将 CNN 结果输入到卷积层,然后用锚框去圈区域,这些锚框很多有好有坏,然后进行预测,binary 预测是预测这个锚框的好坏,即有没有有效的圈住物体,bounding box prediction 预测是对锚框进行一些改进,最后用 NMS(非极大值抑制)对锚框进行合并。 45 | - 具体来说,区域提议网络的计算步骤如下: 46 | 1. 使用填充为 1 的 3×3 的卷积层变换卷积神经网络的输出,并将输出通道数记为 c。这样,卷积神经网络为图像抽取的特征图中的每个单元均得到一个长度为 c 的新特征。 47 | 2. 以特征图的每个像素为中心,生成多个不同大小和宽高比的锚框并标注它们。 48 | 3. 使用锚框中心单元长度为 c 的特征,分别预测该锚框的二元类别(含目标还是背景)和边界框。 49 | 4. 使用非极大值抑制,从预测类别为目标的预测边界框中移除相似的结果。最终输出的预测边界框即是兴趣区域汇聚层所需的提议区域。 50 | 51 |
52 | image 53 |
54 | 55 | #### 1.4 Mask RCNN 56 | 57 | - 如果有**像素级别的标号**,使用 FCN(fully convolutional network)利用这些信息。可以提升 CNN 的性能 58 | - **Rol align**。之前的 Rol 进行池化的时候,如果没法整除,可以直接取整。但是像素级别的标号预测的时候,会造成偏差的累积,导致边界预测不准确。未来避免这种情况,使用 Rol align,也就是当没法整除,对每个像素值进行按比例分配。 59 | - 具体来说,Mask R-CNN 将兴趣区域汇聚层替换为了*兴趣区域对齐*层,使用*双线性插值*(bilinear interpolation)来保留特征图上的空间信息,从而更适于像素级预测。兴趣区域对齐层的输出包含了所有与兴趣区域的形状相同的特征图。它们不仅被用于预测每个兴趣区域的类别和边界框,还通过额外的全卷积网络预测目标的像素级位置。 60 | 61 |
62 | image 63 |
64 | 65 | #### 1.5 总结 66 | 67 | - R-CNN 是最早也是最有名的一类基于锚框和 CNN 的目标检测算法 68 | - Fast/Faster RCNN 持续提升性能 69 | - Faster RCNN 和 Mask RCNN 是在要求高精度场景下常用的算法(但是速度是最慢的) 70 | 71 | ### 2. 单发多框检测(SSD single shot detection) 72 | 73 | - 生成锚框 74 | - 对每个像素,生成多个以它为中心的锚框 75 | - 给定 n 个大小$s_1,...,s_n$和 m 个高宽比,生成 n+m-1 个锚框,其大小和高宽比分别为:$(s_1,r_1),(s_2,r_1)...,(s_n,r_1),(s_1,r_2),...,(s_1,r_m)$ 76 | - SSD 模型 77 | - 对多个分辨率下的卷积特征,生成锚框,预测 78 | - 一个基础网络,抽取特征,然后用多个卷积层来减半高宽 79 | - 在每段都生成锚框 80 | - 底部段拟合小物体 81 | - 顶部段拟合大物体 82 | - 对每个锚框预测类别和边缘框 83 | 84 |
85 | image 86 |
87 | 88 | - 总结 89 | - 速度快,精度很低。这么多年,作者没有持续的提升,但是启发了后面的一系列工作,实现上相对比较简单。 90 | - SSD 通过单神经网络来检测模型(single shot) 91 | - 以像素为中心的产生多个锚框 92 | - 在多个段的输出上进行多尺度的检测 93 | 94 | ### 3. YOLO(you only look once) 95 | 96 | - SSD 中锚框大量重复,因此浪费了很多计算资源 97 | - YOLO 将图片均分为 S X S 个锚框 98 | - 每个锚框预测 B 个边缘框(防止多个物体出现在一个锚框里面) 99 | - 后续版本 v2 v3 v4 有持续改进 100 | - 非锚框算法 101 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/26~NiN.md: -------------------------------------------------------------------------------- 1 | ## 26-网络中的网络(NiN) 2 | 3 | ### 1. 动机 4 | 5 | **全连接层的问题** 6 | 7 | - **卷积层**需要的**参数较少** 8 | - 而卷积层后的第一个**全连接层**的**参数较多** 9 | 10 |
11 | image 12 |
13 | 14 | 以 VGG 为例(图示),全连接层需要先 Flatten,输入维度为 512x7x7,输出维度为 4096,则需要参数个数为 512x7x7x4096=102M。 15 | 16 | ### 2. NiN 块 17 | 18 | - 核心思想:一个卷积层后面跟两个 1x1 的卷积层,后两层起到全连接层的作用。 19 | 20 |
21 | image 22 |
23 | 24 | ### 3. NiN 架构 25 | 26 | - 无全连接层 27 | - 交替使用 NiN 块和步幅为 2 的最大池化层 28 | - 逐步减小高宽和增大通道数 29 | - 最后使用全局平均池化得到输出 30 | - 其输入通道是类别数 31 | 32 | ### 4. NiN Networks 33 | 34 |
35 | image 36 |
37 | 38 | NiN 架构如上图右边所示,若干个 NiN 块(图示中为 4 个块)+池化层;前 3 个块后接最大池化层,最后一块连接一个全局平均池化层。 39 | 40 | ### 5. 总结 41 | 42 | - NiN 块结构:使用卷积层加两个 1x1 卷积层 43 | - 后者对每个像素增加了非线性性 44 | - NiN 使用全局平均池化层来替代 VGG 和 AlexNet 中的全连接层 45 | - 不容易过拟合,更少的参数个数 46 | 47 | ### 6.代码 48 | 49 | ```python 50 | # 如果在Colab上跑, 或没有安装过d2l包, 需要最开始pip install d2l 51 | !pip install git+https://github.com/d2l-ai/d2l-zh@release # installing d2l 52 | ``` 53 | 54 | **NiN 块** 55 | 56 | ```python 57 | import torch 58 | from torch import nn 59 | from d2l import torch as d2l 60 | 61 | # 定义NiN块 62 | def nin_block(in_channels, out_channels, kernel_size, strides, padding): 63 | return nn.Sequential( 64 | nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding), 65 | nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), 66 | nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), 67 | nn.ReLU()) 68 | ``` 69 | 70 | **NiN 模型** 71 | 72 | ```python 73 | net = nn.Sequential( 74 | nin_block(1, 96, kernel_size=11, strides=4, padding=0), 75 | nn.MaxPool2d(3, stride=2), 76 | nin_block(96, 256, kernel_size=5, strides=1, padding=2), 77 | nn.MaxPool2d(3, stride=2), 78 | nin_block(256, 384, kernel_size=3, strides=1, padding=1), 79 | nn.MaxPool2d(3, stride=2), nn.Dropout(0.5), 80 | # 标签类别数是10 81 | nin_block(384, 10, kernel_size=3, strides=1, padding=1), 82 | nn.AdaptiveAvgPool2d((1, 1)), #全局平均池化,高宽都变成1 83 | nn.Flatten()) #消掉最后两个维度, 变成(batch_size, 10) 84 | ``` 85 | 86 | **demo 测试,查看每个块的输出情况** 87 | 88 | ```python 89 | X = torch.rand(size=(1, 1, 224, 224)) 90 | for layer in net: 91 | X = layer(X) 92 | print(layer.__class__.__name__, 'output shape:\t', X.shape) 93 | ``` 94 | 95 | ```python 96 | >>> 97 | Sequential output shape: torch.Size([1, 96, 54, 54]) 98 | MaxPool2d output shape: torch.Size([1, 96, 26, 26]) 99 | Sequential output shape: torch.Size([1, 256, 26, 26]) 100 | MaxPool2d output shape: torch.Size([1, 256, 12, 12]) 101 | Sequential output shape: torch.Size([1, 384, 12, 12]) 102 | MaxPool2d output shape: torch.Size([1, 384, 5, 5]) 103 | Dropout output shape: torch.Size([1, 384, 5, 5]) 104 | Sequential output shape: torch.Size([1, 10, 5, 5]) 105 | AdaptiveAvgPool2d output shape: torch.Size([1, 10, 1, 1]) 106 | Flatten output shape: torch.Size([1, 10]) 107 | ``` 108 | 109 | **训练模型** 110 | 111 | ```python 112 | lr, num_epochs, batch_size = 0.1, 10, 128 113 | train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224) 114 | d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu()) 115 | ``` 116 | 117 | ```python 118 | >>>
119 | ``` 120 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/51~序列模型.md: -------------------------------------------------------------------------------- 1 | # 序列模型 2 | 3 | ### 1.目录 4 | 5 | - [序列模型](#序列模型) 6 | - [1.目录](#1目录) 7 | - [2.序列数据](#2序列数据) 8 | - [2.1 更多例子](#21-更多例子) 9 | - [3.统计工具](#3统计工具) 10 | - [4.序列模型](#4序列模型) 11 | - [4.1 方案 A:马尔科夫假设](#41-方案a马尔科夫假设) 12 | - [4.2 方案 B:潜变量模型](#42-方案b潜变量模型) 13 | - [5.总结](#5总结) 14 | - [6.Q&A:](#6qa) 15 | 16 | ### 2.序列数据 17 | 18 | - 实际中很多数据是有时序的 19 | - 电影的评价随时间变化而变化 20 | - 拿了奖后评分上升,直到奖项被遗忘 21 | - 看了很多好电影后,人们的期望变高 22 | - 季节性:贺岁片,暑期档 23 | - 导演、演员的负面报道导致评分变低 24 | 25 | #### 2.1 更多例子 26 | 27 | - 音乐、文本、语言和视频都是连续的 28 | 29 | - 标题“狗咬人”远没有“人咬狗”那么令人惊讶 30 | 31 | - 大地震发生后,很有可能会有几次较小的余震 32 | - 人的互动是连续的,从网上吵架可以看出 33 | - 预测明天的股价要比填补昨天遗失的股价更困难 34 | 35 | ### 3.统计工具 36 | 37 | - 在时间 t 观察到,那么得到 T 个不独立的随机变量 38 | 39 | - 使用条件概率展开 40 | 41 | 42 | 43 |
44 | image 45 |
46 | 47 | ### 4.序列模型 48 | 49 |
50 | image 51 |
52 | 53 | - 对条件概率建模 54 | 55 |
56 | image 57 |
58 | 59 | #### 4.1 方案 A:马尔科夫假设 60 | 61 |
62 | image 63 |
64 | 65 | - 假设当前数据只跟 τ 个过去数据点相关 66 | 67 |
68 | image 69 |
70 | 71 | #### 4.2 方案 B:潜变量模型 72 | 73 |
74 | image 75 |
76 | 77 | - 引入潜变量来表示过去信息 78 | - 这样 79 | 80 |
81 | image 82 |
83 | 84 | ### 5.总结 85 | 86 | - 时序模型中,当前数据跟之前观察到的数据相关 87 | - 自回归模型使用自身过去数据来预测未来 88 | - 马尔科夫模型假设当前只跟最近少数数据相关,从而简化模型 89 | - 潜变量模型使用潜变量来概括历史信息 90 | 91 | ### 6.Q&A: 92 | 93 | ##### Q1:在常规范围内 tau 是不是越大越好。刚才例子 tau=5 是不是比 4 好? 94 | 95 | > 当然比 4 好,也有局限性,tau 特别大,训练样本变小,模型变复杂 96 | 97 | ##### Q2:潜变量模型和隐马尔科夫模型有什么区别? 98 | 99 | > 没有太多联系,两个不同的观点,但是潜变量模型可以使用隐马尔科夫假设。潜变量-怎么建模,隐马尔科夫-这个数据和之前多少个数据有关。 100 | 101 | ##### Q3:若预测一个月,tau=30,预测 7 天,tau=7,是否有这样的关系? 102 | 103 | > tau 取决于对数据的理解,没有固定的规则 104 | 105 | ##### Q4:在预测未来方面,现在的 sota 模型能做到多好? 106 | 107 | > 具体问题具体分析,在有些领域做得好比如写作,写代码,在一些领域做的不好,比如预测股票。 108 | 109 | ##### Q5:tau 能够随着 xt 的变化而变化吗?这样感觉更符合实际情况 110 | 111 | > 当然可以,有计算量的增加,也不一定更好 112 | 113 | ##### Q6:预测电池之类很多参数的未来变化趋势时怎么长步预测? 114 | 115 | > 与数据关系比较大,负类样本较少,所以比较难训练 116 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/XOR-gate-keras.py: -------------------------------------------------------------------------------- 1 | # 2 | # Single Hidden Layer Neural Network for learning XOR gate 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | from keras.models import Sequential 17 | try: 18 | from keras.layers.core import Activation, Dense 19 | except: 20 | from keras.layers import Activation, Dense 21 | from keras.optimizers import Adam 22 | from keras.layers import Layer 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | import sys 26 | 27 | sys.path.append("..") 28 | from Common.ActivationFunctions import sigmoid 29 | 30 | 31 | # np.random.seed(0) 32 | 33 | # ======================================== 34 | # Create datasets 35 | # ======================================== 36 | 37 | # Inputs 38 | X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 39 | 40 | # The ground-truth labels 41 | Y = np.array([[0], [1], [1], [0]]) 42 | 43 | # Convert row vector into column vector. 44 | X = X.reshape(4, 2, 1) 45 | 46 | # ======================================== 47 | # Create model 48 | # ======================================== 49 | input_nodes = 2 50 | hidden_nodes = 3 51 | output_nodes = 1 52 | 53 | 54 | model = Sequential() 55 | model.add(Dense(hidden_nodes, input_dim=input_nodes)) 56 | model.add(Activation("sigmoid")) 57 | model.add(Dense(output_nodes)) 58 | model.add(Activation("sigmoid")) 59 | 60 | optimizer = Adam(learning_rate=0.1) 61 | 62 | model.compile(loss="mean_squared_error", optimizer=optimizer) 63 | 64 | print(model.summary()) 65 | 66 | 67 | # ======================================== 68 | # Training 69 | # ======================================== 70 | 71 | n_epochs = 300 72 | 73 | # Run through the data `epochs` times 74 | history = model.fit(X, Y, epochs=n_epochs, batch_size=1, verbose=1) 75 | 76 | # 77 | # Show loss history 78 | # 79 | plt.plot(history.history["loss"], color="b", label="loss") 80 | plt.title("Training Loss History") 81 | plt.xlabel("Number of Epochs") 82 | plt.ylabel("Loss") 83 | plt.legend() 84 | plt.grid(True) 85 | plt.show() 86 | 87 | # ======================================== 88 | # Test 89 | # ======================================== 90 | 91 | result = model.predict(X) 92 | 93 | print("------------------------") 94 | print("x0 XOR x1 => result") 95 | print("========================") 96 | 97 | for i in range(0, len(Y)): 98 | _x0 = X[i][0][0] 99 | _x1 = X[i][1][0] 100 | print(" {} XOR {} => {:.4f}".format(_x0, _x1, result[i][0])) 101 | print("========================") 102 | 103 | 104 | [W, b, U, c] = Layer.get_weights(model) 105 | 106 | hm = np.zeros((100, 100)) 107 | for i in range(100): 108 | for j in range(100): 109 | x = [float(i) / 100, float(j) / 100] 110 | _h = sigmoid(np.dot(W.T, x) + b) 111 | hm[i][j] = sigmoid(np.dot(U.T, _h) + c).item() 112 | 113 | plt.title("") 114 | plt.xlabel("X[0]") 115 | plt.ylabel("X[1]") 116 | plt.grid(False) 117 | plt.ylim([-10, 110]) 118 | plt.xlim([-10, 110]) 119 | plt.plot(0, 0, "*", markersize=10, color="b") 120 | plt.plot(100, 0, "*", markersize=10, color="r") 121 | plt.plot(0, 100, "*", markersize=10, color="r") 122 | plt.plot(100, 100, "*", markersize=10, color="b") 123 | 124 | plt.imshow(hm) 125 | plt.xticks([0, 50, 100], ["0", "0.5", "1.0"]) 126 | plt.yticks([0, 50, 100], ["0", "0.5", "1.0"]) 127 | 128 | cax = plt.axes([0.85, 0.1, 0.075, 0.8]) 129 | plt.colorbar(cax=cax) 130 | 131 | plt.show() 132 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/AND-gate.py: -------------------------------------------------------------------------------- 1 | # 2 | # Perceptron for learning AND gate 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | import matplotlib.pyplot as plt 18 | 19 | # np.random.seed(0) 20 | 21 | # ======================================== 22 | # Activation Function 23 | # ======================================== 24 | 25 | 26 | def activate_func(x): 27 | # step function 28 | return 1 if x > 0 else 0 29 | 30 | 31 | # ======================================== 32 | # Create datasets 33 | # ======================================== 34 | 35 | # Inputs 36 | X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 37 | 38 | # The ground-truth labels 39 | Y = np.array([[0], [0], [0], [1]]) 40 | OPERATION = "AND" 41 | 42 | """ 43 | Y = np.array([[0], [1], [1], [1]]) 44 | OPERATION = "OR" 45 | 46 | Y = np.array([[1], [1], [1], [0]]) 47 | OPERATION = "NAND" 48 | 49 | Y = np.array([[0], [1], [1], [0]]) 50 | OPERATION = "XOR" 51 | """ 52 | 53 | # ======================================== 54 | # Initialize random weights and bias 55 | # ======================================== 56 | 57 | W = np.random.uniform(size=(2)) 58 | b = np.random.uniform(size=(1)) 59 | 60 | # ======================================== 61 | # Training 62 | # ======================================== 63 | 64 | n_epochs = 150 # Epoch 65 | lr = 0.01 # Learning rate 66 | 67 | history_loss = [] 68 | 69 | # 70 | # Training loop 71 | # 72 | for epoch in range(1, n_epochs + 1): 73 | loss = 0.0 74 | 75 | for i in range(0, len(Y)): 76 | # Forward Propagation 77 | x0 = X[i][0] 78 | x1 = X[i][1] 79 | y_h = W[0] * x0 + W[1] * x1 + b[0] 80 | y = activate_func(y_h) 81 | 82 | # Updating Weights and Biases 83 | loss += (y - Y[i]) ** 2 / 2 84 | 85 | W[0] -= lr * (y - Y[i]) * x0 86 | W[1] -= lr * (y - Y[i]) * x1 87 | b[0] -= lr * (y - Y[i]) 88 | 89 | history_loss.append(loss / len(Y)) 90 | if epoch % 10 == 0 or epoch == 1: 91 | print("epoch: {} / {} Loss = {:.6f}".format(epoch, n_epochs, loss[0])) 92 | 93 | # 94 | # Show loss history 95 | # 96 | plt.plot(history_loss, color="b", label="loss") 97 | plt.title("Training Loss History") 98 | plt.xlabel("Number of Epochs") 99 | plt.ylabel("Loss") 100 | plt.grid(True) 101 | plt.legend() 102 | plt.show() 103 | 104 | # ======================================== 105 | # Test 106 | # ======================================== 107 | 108 | print("------------------------") 109 | print("x0 {} x1 => result".format(OPERATION)) 110 | print("========================") 111 | 112 | for x in X: 113 | y = activate_func(W[0] * x[0] + W[1] * x[1] + b[0]) 114 | print(" {} {} {} => {}".format(x[0], OPERATION, x[1], int(y))) 115 | 116 | print("========================") 117 | 118 | # 119 | # Show Decision Line (Separator) 120 | # 121 | slope = -W[0] / W[1] 122 | bias = -b[0] / W[1] 123 | 124 | fig, ax = plt.subplots(1, 1) 125 | title = "Decision Line (" + OPERATION + "-gate)" 126 | plt.title(title) 127 | plt.xlabel("X[0]") 128 | plt.ylabel("X[1]") 129 | plt.grid(False) 130 | plt.ylim([-0.1, 1.4]) 131 | plt.xlim([-0.1, 1.4]) 132 | 133 | for i in range(len(X)): 134 | x0, x1 = X[i] 135 | y = Y[i] 136 | color = "b" if y[0] == 0 else "r" 137 | plt.plot(x0, x1, "*", markersize=10, color=color) 138 | 139 | ax.axline((0, bias), slope=slope) 140 | 141 | plt.show() 142 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/31~CPU和GPU.md: -------------------------------------------------------------------------------- 1 | # CPU 和 GPU 2 | 3 | ### 本节目录: 4 | 5 | - [CPU 和 GPU](#cpu和gpu) 6 | - [本节目录:](#本节目录) 7 | - [1.CPU:](#1cpu) 8 | - [1.1 提升 CPU 利用率一:](#11-提升cpu利用率一) 9 | - [1.2 样例分析:](#12-样例分析) 10 | - [1.3 提升 CPU 利用率二:](#13-提升cpu利用率二) 11 | - [1.4 样例分析:](#14-样例分析) 12 | - [2.CPU vs GPU:](#2cpu-vs-gpu) 13 | - [2.1 提升 GPU 利用率](#21-提升gpu利用率) 14 | - [2.2 CPU/GPU 带宽](#22-cpugpu-带宽) 15 | - [2.3 更多的 CPUs 和 GPUs](#23-更多的cpus和gpus) 16 | - [2.4 CPU/GPU 高性能计算编程](#24-cpugpu高性能计算编程) 17 | - [3.总结](#3总结) 18 | - [4.Q&A](#4qa) 19 | 20 | ### 1.CPU: 21 | 22 | #### 1.1 提升 CPU 利用率一: 23 | 24 | - 在计算 a+b 之前,需要准备数据 25 | - 主内存->L3->L2->L1->寄存器 26 | 27 | - L1 访问延时:0.5ms 28 | - L2 访问延时:7ns(14XL1) 29 | - 主内存访问延时:100ns(200XL1) 30 | 31 | - 提升空间和时间的内存本地性 32 | - 时间:重用数据使它们在缓存里 33 | - 空间:按序读写数据是的可以预读取 34 | 35 | #### 1.2 样例分析: 36 | 37 | - 如果一个矩阵是按行存储,访问一行比访问一列要快 38 | - CPU 一次读取 64 字节(缓存线) 39 | - CPU 会“聪明的”提前读取下一个(缓存线) 40 | 41 |
42 | image 43 |
44 | 45 | #### 1.3 提升 CPU 利用率二: 46 | 47 | - 高端 CPU 有几十个核 48 | 49 | - EC2 P3.16xlarge:2 Intel Xeon CPUs,32 物理核 50 | 51 | - 并行来利用所用核 52 | - 超线程不一定提升性能,因为他们共享寄存器 53 | 54 | #### 1.4 样例分析: 55 | 56 | - 左边比右边慢(python) 57 | 58 |
59 | image 60 |
61 | 62 | - 左边调用 n 次函数,每次调用有开销 63 | - 右边很容易被并行(例如下面的 C++实现) 64 | 65 |
66 | image 67 |
68 | 69 | ### 2.CPU vs GPU: 70 | 71 |
72 | image 73 |
74 | 75 | #### 2.1 提升 GPU 利用率 76 | 77 | - 并行 78 | 79 | - 使用数千个线程 80 | 81 | - 内存本地性 82 | 83 | - 缓存更小,架构更简单 84 | 85 | - 少用控制语句 86 | - 支持有限 87 | - 同步开销大 88 | 89 | #### 2.2 CPU/GPU 带宽 90 | 91 |
92 | image 93 |
94 | 95 | #### 2.3 更多的 CPUs 和 GPUs 96 | 97 | - CPU:AMD,ARM 98 | - GPU:AMD,Intel,ARM,Qualcomm... 99 | 100 | #### 2.4 CPU/GPU 高性能计算编程 101 | 102 | - CPU:C++或者任何高性能语言 103 | - 编译器成熟 104 | - GPU 105 | - Nvida 上用 CUDA 106 | - 编译器和驱动成熟 107 | - 其他用 OpenCL 108 | - 质量取决于硬件厂商 109 | 110 | ### 3.总结 111 | 112 | - CPU:可以处理通用计算。性能优化考虑数据读写效率和多线程 113 | - GPU:使用更多的小核和更好的内存带宽,适合能大规模并行的计算任务 114 | 115 | ### 4.Q&A 116 | 117 | ##### Q1: 如果要提高泛化性,就要增加数据?调参的意思是不是最大? 118 | 119 | > 提高泛化性的有效手段是增加数据,但是数据的质量很重要,少量高质量数据和大量低质量数据可能有 1:10 或者 1:100 的换算关系。实际应用场景对调参要求不高,因为有不断增加的数据。 120 | 121 | ##### Q2:alexnet 模型比 resnet 要大,为什么计算上 resnet 比 alexnet 运算量大? 122 | 123 | > alexnet 后面用到的几个连续的全连接层使模型变大,但是 resnet 使用的卷积层在少量参数下更消耗计算资源。模型大小和计算复杂度不能直接换算。 124 | 125 | ##### Q3:训练时为什么使用 w-=lr\*w.grad,而不写做 w=w-lr\*w.grad? 126 | 127 | > 因为第二种写法定义了一个新的 tensor,梯度参数会成为 false 128 | 129 | ##### Q4:llc 是显存还是缓存,是 l1,l2,还是 l3? 130 | 131 | > llc 是缓存,last level cash,是最后一层缓存,具体是 ln 取决于一共有几层缓存。 132 | 133 | ##### Q5:做计算时把 for_lopps 运算尽可能向量化? 134 | 135 | > 是的,尽量不要用 python 写 for-loop 136 | 137 | ##### Q6:可视化时,需要把数据在 cpu 和 GPU 之间切换,如何避免频繁传输?常见的错误操作有哪些?怎么看到和排查这种错误? 138 | 139 | > 可视化操作不需要太担心,只要不是计算中来回传递就好。深度学习框架会有限制,只能在一个设备上做。框架没报错一般不会有太多问题 140 | 141 | ##### Q7:go 怎么样? 142 | 143 | > go 分布式系统做的很好,和深度学习的分布式不太一样 144 | 145 | ##### Q8:怎样复现论文? 146 | 147 | > 80%的论文无法复现,要读懂每一句话,和明白作者实现的细节。 148 | 149 | ##### Q9:分布式和高性能的区别? 150 | 151 | > 没有本质区别,分布式更多考虑容错。高性能是分布式的一个应用 152 | 153 | ##### Q10:自动驾驶烧钱,短时间难以落地是不是和 nas 一样? 154 | 155 | > 不是,自动驾驶有很好的商业前景。nas 没有太多意义。 156 | -------------------------------------------------------------------------------- /00~导论/深度学习简史.md: -------------------------------------------------------------------------------- 1 | # 深度学习简史 2 | 3 | # 起源 4 | 5 | 虽然深度学习似乎是最近几年刚兴起的名词,但它所基于的神经网络模型和用数据编程的核心思想已经被研究了数百年。自古以来,人类就一直渴望能从数据中分析出预知未来的窍门。实际上,数据分析正是大部分自然科学的本质,我们希望从日常的观测中提取规则,并找寻不确定性。 6 | 7 | 早在 17 世纪,雅各比·伯努利(1655–1705)提出了描述只有两种结果的随机过程(如抛掷一枚硬币)的伯努利分布。大约一个世纪之后,卡尔·弗里德里希·高斯(1777–1855)发明了今日仍广泛用在从保险计算到医学诊断等领域的最小二乘法。概率论、统计学和模式识别等工具帮助自然科学的实验学家们从数据回归到自然定律,从而发现了如欧姆定律(描述电阻两端电压和流经电阻电流关系的定律)这类可以用线性模型完美表达的一系列自然法则。 8 | 9 | 即使是在中世纪,数学家也热衷于利用统计学来做出估计。例如,在雅各比·科贝尔(1460–1533)的几何书中记载了使用 16 名男子的平均脚长来估计男子的平均脚长。 10 | 11 | ![在中世纪,16名男子的平均脚长被用来估计男子的平均脚长](https://s1.ax1x.com/2020/08/09/a7yW3F.md.png) 12 | 13 | 在这个研究中,16 位成年男子被要求在离开教堂时站成一排并把脚贴在一起,而后他们脚的总长度除以 16 得到了一个估计:这个数字大约相当于今日的一英尺。这个算法之后又被改进,以应对特异形状的脚:最长和最短的脚不计入,只对剩余的脚长取平均值,即裁剪平均值的雏形。 14 | 15 | 现代统计学在 20 世纪的真正起飞要归功于数据的收集和发布。统计学巨匠之一罗纳德·费雪(1890–1962)对统计学理论和统计学在基因学中的应用功不可没。他发明的许多算法和公式,例如线性判别分析和费雪信息,仍经常被使用。即使是他在 1936 年发布的 Iris 数据集,仍然偶尔被用于演示机器学习算法。 16 | 17 | 克劳德·香农(1916–2001)的信息论以及阿兰·图灵(1912–1954)的计算理论也对机器学习有深远影响。图灵在他著名的论文《计算机器与智能》中提出了“机器可以思考吗?”这样一个问题 [1]。在他描述的“图灵测试”中,如果一个人在使用文本交互时不能区分他的对话对象到底是人类还是机器的话,那么即可认为这台机器是有智能的。时至今日,智能机器的发展可谓日新月异。 18 | 19 | 另一个对深度学习有重大影响的领域是神经科学与心理学。既然人类显然能够展现出智能,那么对于解释并逆向工程人类智能机理的探究也在情理之中。最早的算法之一是由唐纳德·赫布(1904–1985)正式提出的。在他开创性的著作《行为的组织》中,他提出神经是通过正向强化来学习的,即赫布理论。赫布理论是感知机学习算法的原型,并成为支撑今日深度学习的随机梯度下降算法的基石:强化合意的行为、惩罚不合意的行为,最终获得优良的神经网络参数。 20 | 21 | 来源于生物学的灵感是神经网络名字的由来。这类研究者可以追溯到一个多世纪前的亚历山大·贝恩(1818–1903)和查尔斯·斯科特·谢灵顿(1857–1952)。研究者们尝试组建模仿神经元互动的计算电路。随着时间发展,神经网络的生物学解释被稀释,但仍保留了这个名字。时至今日,绝大多数神经网络都包含以下的核心原则。 22 | 23 | - 交替使用线性处理单元与非线性处理单元,它们经常被称为“层”。 24 | - 使用链式法则(即反向传播)来更新网络的参数。 25 | 26 | 在最初的快速发展之后,自约 1995 年起至 2005 年,大部分机器学习研究者的视线从神经网络上移开了。这是由于多种原因。首先,训练神经网络需要极强的计算力。尽管 20 世纪末内存已经足够,计算力却不够充足。其次,当时使用的数据集也相对小得多。费雪在 1936 年发布的的 Iris 数据集仅有 150 个样本,并被广泛用于测试算法的性能。具有 6 万个样本的 MNIST 数据集在当时已经被认为是非常庞大了,尽管它如今已被认为是典型的简单数据集。由于数据和计算力的稀缺,从经验上来说,如核方法、决策树和概率图模型等统计工具更优。它们不像神经网络一样需要长时间的训练,并且在强大的理论保证下提供可以预测的结果。 27 | 28 | # 深度学习与机器学习 29 | 30 | > “Deep learning is a branch of machine learning based on a set of algorithms that attempt to model high-level abstractions in data by using multiple processing layers, with complex structures or otherwise, composed of multiple non-linear transformations.” 31 | 32 | 传统的机器学习主要分两部分,一部分是特征提取,需要人工从数据中提取出特征,并且想办法用计算机能理解的格式来表达这些特征。另外一部分是是模型,使用计算机能理解的特征数据来训练模型。人工提取的特征慢,而且很容易遗漏。深度学习能够从原始数据中学习出特征,然后用来训练模型。理论上来说 参数越多的模型复杂度越高 “ 容量 ” (capacity) 越大, 这意味着它能完成吏复杂的学习任务 但一股倩形下, 复杂模型的训练效率低 易陷入过拟合, 因此难以受到人们青睐。机器学习研究如何使计算机系统利用经验改善性能。它是人工智能领域的分支,也是实现人工智能的一种手段。在机器学习的众多研究方向中,表征学习关注如何自动找出表示数据的合适方式,以便更好地将输入变换为正确的输出,而本书要重点探讨的深度学习是具有多级表示的表征学习方法。在每一级(从原始数据开始),深度学习通过简单的函数将该级的表示变换为更高级的表示。因此,深度学习模型也可以看作是由许多简单函数复合而成的函数。当这些复合的函数足够多时,深度学习模型就可以表达非常复杂的变换。 33 | 34 | 而随着云计算、大数据时代的到来 计算能力 的大幅提高可缓解训练低效性 训练数据的大幅增加则可降低过拟合 f 因此, 以 "深度学习” (deep1earning) 为代表的复杂模型开始受到人们的关注。典型的深度学习模型就是很深层的神经网络 . 显然, 对神经网络模型 提高容量的一个简单办法是增加隐层的数且 隐层多工 相应的神经元连接机 阈值等参数就会更多模型复杂度也可通过单纯增加隐层神经元的数目来实玑前面我们谈到过, 单隐层的多层呤前馈网络己具有很强大的学习能力 ; 但从增加模型复杂度的角觑肴 增加隐层的数目显然比增加隐层神经元的数目更眦因为增加隐层数不仅增加丁拥有激活函数的神经元数目, 还增加了激活函数嵌套的层数 然而, 多隐层神经网络难以直接用经典算法恻如标准 BP 算淘进行训练, 因为误差在多隐层内逆传播盹 往往会 “ 发散 ” (diverge) 而不能收敛到稳定状态 35 | 36 | 深度学习可以逐级表示越来越抽象的概念或模式。以图像为例,它的输入是一堆原始像素值。深度学习模型中,图像可以逐级表示为特定位置和角度的边缘、由边缘组合得出的花纹、由多种花纹进一步汇合得到的特定部位的模式等。最终,模型能够较容易根据更高级的表示完成给定的任务,如识别图像中的物体。值得一提的是,作为表征学习的一种,深度学习将自动找出每一级表示数据的合适方式。 37 | 38 | 因此,深度学习的一个外在特点是端到端的训练。也就是说,并不是将单独调试的部分拼凑起来组成一个系统,而是将整个系统组建好之后一起训练。比如说,计算机视觉科学家之前曾一度将特征抽取与机器学习模型的构建分开处理,像是 Canny 边缘探测 [20] 和 SIFT 特征提取 [21] 曾占据统治性地位达 10 年以上,但这也就是人类能找到的最好方法了。当深度学习进入这个领域后,这些特征提取方法就被性能更强的自动优化的逐级过滤器替代了。 39 | 40 | 相似地,在自然语言处理领域,词袋模型多年来都被认为是不二之选 [22]。词袋模型是将一个句子映射到一个词频向量的模型,但这样的做法完全忽视了单词的排列顺序或者句中的标点符号。不幸的是,我们也没有能力来手工抽取更好的特征。但是自动化的算法反而可以从所有可能的特征中搜寻最好的那个,这也带来了极大的进步。例如,语义相关的词嵌入能够在向量空间中完成如下推理:“柏林 - 德国 + 中国 = 北京”。可以看出,这些都是端到端训练整个系统带来的效果。 41 | 42 | 除端到端的训练以外,我们也正在经历从含参数统计模型转向完全无参数的模型。当数据非常稀缺时,我们需要通过简化对现实的假设来得到实用的模型。当数据充足时,我们就可以用能更好地拟合现实的无参数模型来替代这些含参数模型。这也使我们可以得到更精确的模型,尽管需要牺牲一些可解释性。 43 | 44 | 相对其它经典的机器学习方法而言,深度学习的不同在于:对非最优解的包容、对非凸非线性优化的使用,以及勇于尝试没有被证明过的方法。这种在处理统计问题上的新经验主义吸引了大量人才的涌入,使得大量实际问题有了更好的解决方案。尽管大部分情况下需要为深度学习修改甚至重新发明已经存在数十年的工具,但是这绝对是一件非常有意义并令人兴奋的事。 45 | 46 | 最后,深度学习社区长期以来以在学术界和企业之间分享工具而自豪,并开源了许多优秀的软件库、统计模型和预训练网络。正是本着开放开源的精神,本书的内容和基于它的教学视频可以自由下载和随意分享。我们致力于为所有人降低学习深度学习的门槛,并希望大家从中获益。 47 | 48 | # Deep Architectures 49 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/08~线性回归+基础优化算法.md: -------------------------------------------------------------------------------- 1 | ## 线性回归+基础优化算法 2 | 3 | - [线性回归+基础优化算法](#线性回归基础优化算法) 4 | - [1.线性回归](#1线性回归) 5 | - [2.基础优化算法](#2基础优化算法) 6 | - [3.线性回归的从零开始实现](#3线性回归的从零开始实现) 7 | - [4.新型回归的简洁实现](#4新型回归的简洁实现) 8 | - [5.- 线性回归+基础优化算法](#5--线性回归基础优化算法) 9 | 10 | ### 1.线性回归 11 | 12 | - 房价预测例子 13 | 14 | - **线性模型** 15 | 16 | - 输入:$x=[x_1,x_2,...,x_n]^T$ 17 | 18 | - 线性模型需要确定一个 n 维权重和一个标量偏差$\omega=[\omega_1,\omega_2,...,\omega_n]^T,b$ 19 | 20 | - 输出 :$y=\omega_1x_1+\omega_2x_2+...+\omega_nx_n+b$, 21 | 22 | 向量版本的是 $y=<\omega,x>+b$ 23 | 24 | - 线性模型可以看作是单层神经网络(图片) 25 | 26 | > - 神经网络源于神经科学(图片) 27 | > - 最早的神经网络是源自神经科学的,但是时至今日,很多神经网络已经远远高于神经科学,可解释性也不是很强,不必纠结 28 | 29 | - 衡量估计质量 30 | 31 | - 我们需要估计模型的预估值和真实值之间的差距,例如房屋售价和股价 32 | 33 | - 假设$y$是真实值,$\tilde{y}$是估计值,我们可以比较 34 | 35 | $l(y,\tilde{y})=\frac{1}{2}(y-\tilde{y})^2$,这个叫做**平方损失** 36 | 37 | - **训练数据** 38 | 39 | - 收集一些数据点来决定参数值(权重$\omega$和偏差$b$),例如 6 个月内被卖掉的房子。 40 | 41 | - 这被称之为训练数据 42 | 43 | - 通常越多越好。需要注意的是,现实世界的数据都是有限的,但是为了训练出精确的参数往往需要训练数据越多越好,当训练数据不足的时候,我们还需要进行额外处理。 44 | 45 | - 假设我们有 n 个样本,记为 46 | 47 | $X=[x_1,x_2,...,x_n]^T,y=[y_1,y_2,...y_n]^T$ 48 | 49 | $X$的每一行是一个样本,$y$的每一行是一个输出的实数值。 50 | 51 | - **参数学习** 52 | 53 | - **训练损失**。但我们训练参数的时候,需要定义一个损失函数来衡量参数的好坏,应用前文提过的平方损失有公式: 54 | 55 | ​ $l(X,x,\omega,b)=\frac{1}{2n}\sum_{i=1}^n(y_i--b)^2=\frac{1}{2n}||y-X\omega-b||^2$ 56 | 57 | - **最小化损失来学习参数**。训练参数的目的就是使损失函数的值尽可能小(这意味着预估值和真实值更接近)。最后求得的参数值可表示为: 58 | 59 | $\omega^*,b^*=argmin_{\omega,b}l(X,x,\omega,b)$ 60 | 61 | - **显示解** 62 | 63 | - 线性回归有显示解,即可以直接矩阵数学运算,得到参数 w 和 b 的最优解,而不是用梯度下降,牛顿法等参数优化方式一点点逼近最优解。 64 | 65 | - **推导过程**: 66 | 67 | - 为了方便矩阵表示和计算,将偏差加入权重,$X\gets[X,1],\omega\gets[\omega,b]$ 68 | 69 | - 损失函数是凸函数,最优解满足导数为 0,可解出显示解 70 | 71 | 令$\frac{\partial}{\partial\omega} l(X,y,\omega)=0$ 72 | 73 | 有$\frac{1}{n}(y-X\omega)^TX=0$ 74 | 75 | 解得$\omega^*=(X^TX)^{-1}X^Ty$ 76 | 77 | - 总结 78 | 79 | - 线性回归是对 n 维输入的加权,外加偏差 80 | - 使用**平方损失**来衡量预测值和真实值之间的误差 81 | - **线性回归有显示解** 82 | - 线性回归可以看作单层神经网络 83 | 84 | ### 2.基础优化算法 85 | 86 | - **梯度下降** 87 | 88 | - 当模型没有显示解的时候,应用梯度下降法逼近最优解。 89 | - 梯度下降法的具体步骤: 90 | - 挑选一个初始值$\omega_0$ 91 | - 重复迭代参数,迭代公式为:$\omega*t=\omega*{t-1}-\lambda\frac{\partial l}{\partial\omega\_{t-1} } $ 92 | - **$-\frac{\partial l}{\partial\omega_{t-1}}$为函数值下降最快的方向,学习率$\lambda$为学习步长。** 93 | - 选择学习率 94 | - 学习率$\lambda$为学习步长,代表了沿负梯度方向走了多远,这是超参数(人为指定的的值,不是训练得到的) 95 | - 学习率不能太大,也不能太小,需要选取适当。 96 | 97 | - **小批量随机梯度下降** 98 | 99 | - 在整个训练集上算梯度太贵了 100 | 101 | - 在实际应用中,很少直接应用梯度下降法,这是因为每次更新都需要计算训练集上所有的样本,耗费时间太长。一个深度神经网络模型,迭代一次可能需要数分钟甚至数小时。 102 | 103 | - 为了减少运算代价,我们可以==随机采样==b 个样本$i_1,i_2,...,i_b$来近似损失,损失函数为: 104 | 105 | ​ $\frac{1}{b}\sum_{i\in I_b}l(x_i,y_i,\omega)$ , 106 | 107 | 其中**b 是批量大小(batch size),也是超参数** 108 | 109 | - **选择批量大小** 110 | 111 | - b 也不能太大:内存消耗增加;浪费计算资源,一个极端的情况是可能会重复选取很多差不多的样本,浪费计算资源 112 | - b 也不能太小:每次计算量太小,很难以并行,不能最大限度利用 GPU 资源 113 | 114 | - **总结** 115 | 116 | - 梯度下降通过不断**沿着负梯度方向**更新参数求解 117 | - 小批量随机梯度下降是深度学习默认的求解算法(简单,稳定) 118 | - **两个重要的超参数:批量大小(batch size),学习率(lr)** 119 | 120 | ### 3.线性回归的从零开始实现 121 | 122 | - 代码 123 | 124 | ### 4.新型回归的简洁实现 125 | 126 | - 代码 127 | 128 | ### 5.- [线性回归+基础优化算法](#线性回归基础优化算法) 129 | 130 | - [1.线性回归](#1线性回归) 131 | - [2.基础优化算法](#2基础优化算法) 132 | - [3.线性回归的从零开始实现](#3线性回归的从零开始实现) 133 | - [4.新型回归的简洁实现](#4新型回归的简洁实现) 134 | - [5.QA](#5qa)QA 135 | 136 | - **1.为什么使用平方损失而不是绝对差值?** 137 | - 其实差别不大,最开始使用平方损失是因为它可导,现在其实都可以使用。 138 | - **2.损失为什么要求平均?** 139 | - 本质上没有关系,但是如果不求平均,梯度的数值会比较大,这时需要学习率除以 n。如果不除以 n,可能会随着样本数量的增大而让梯度变得很大。 140 | - **3.不管是梯度下降还是随机梯度下降,怎么找到合适的学习率?** 141 | - 选择对学习率不敏感的优化方法,比如 Adam 142 | - 合理参数初始化 143 | - **4.训练过程中,过拟合和欠拟合情况下,学习率和 batch_size 应该如何调整?** 144 | - 理论上学习率和 batch_size 对最后的拟合结果不会有影响 145 | - **5.深度学习上,设置损失函数的时候,需要考虑正则吗?** 146 | - 会考虑,但是和损失函数是分开的,深度学习中正则没有太大的用处,有很多其他的技术可以有正则的效果。 147 | - **6.如果样本大小不是批量数的整数倍,需要随机剔除多余的样本吗?** 148 | - 就取多余的样本作为一个批次 149 | - 直接丢弃 150 | - 从下一个 epoch 里面补少的样本 151 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/RNN_tf.py: -------------------------------------------------------------------------------- 1 | # 2 | # Sine wave prediction using Simple-RNN of Tensorflow. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | import tensorflow as tf 18 | import matplotlib.pyplot as plt 19 | from tensorflow.keras import optimizers, losses, metrics 20 | import DataSet as ds 21 | 22 | 23 | class RNN(tf.keras.Model): 24 | def __init__(self, hidden_units, output_units): 25 | super().__init__() 26 | self.simple_rnn = tf.keras.layers.SimpleRNN( 27 | hidden_units, 28 | activation="tanh", 29 | kernel_initializer="glorot_normal", 30 | recurrent_initializer="orthogonal", 31 | ) 32 | self.dense = tf.keras.layers.Dense(output_units, activation="linear") 33 | 34 | def call(self, x): 35 | x = self.simple_rnn(x) 36 | x = self.dense(x) 37 | return x 38 | 39 | 40 | def plot_fig(model, wave_data, n_sample, n_sequence): 41 | 42 | wave = wave_data 43 | z = wave[0:n_sequence] 44 | input = wave[0:n_sequence+1] 45 | sin = [None for i in range(n_sequence)] 46 | gen = [None for i in range(n_sequence)] 47 | 48 | for j in range(n_sample): 49 | y = model.predict(z.reshape(1, z.shape[0], 1)) 50 | z = np.append(z, y)[1:] 51 | gen.append(y[0][0]) 52 | sin.append(wave[j+n_sequence]) 53 | 54 | plt.plot(input, color="b", label="input") 55 | plt.plot(sin, "--", color="#888888", label="sine wave") 56 | plt.plot(gen, color="r", label="predict") 57 | plt.title("Prediction") 58 | plt.legend() 59 | plt.ylim([-2, 2]) 60 | plt.grid(True) 61 | plt.show() 62 | 63 | 64 | # ============================ 65 | # Data creation 66 | # ============================ 67 | n_sequence = 25 68 | n_data = 100 69 | 70 | n_sample = n_data - n_sequence # number of sample 71 | 72 | sin_data = ds.create_wave(n_data, 0.05) 73 | X, Y = ds.dataset(sin_data, n_sequence, False) 74 | 75 | X = X.reshape(X.shape[0], X.shape[1], 1) 76 | Y = Y.reshape(Y.shape[0], Y.shape[1]) 77 | 78 | # ============================ 79 | # Model creation 80 | # ============================ 81 | 82 | input_units = 1 83 | hidden_units = 32 84 | output_units = 1 85 | 86 | model = RNN(hidden_units, output_units) 87 | 88 | model.build(input_shape=(None, n_sequence, input_units)) 89 | model.summary() 90 | 91 | # ============================ 92 | # Training 93 | # ============================ 94 | 95 | lr = 0.001 96 | beta1 = 0.9 97 | beta2 = 0.999 98 | 99 | criterion = losses.MeanSquaredError() 100 | optimizer = optimizers.Adam(learning_rate=lr, beta_1=beta1, beta_2=beta2) 101 | train_loss = metrics.Mean() 102 | 103 | n_epochs = 300 104 | history_loss = [] 105 | 106 | for epoch in range(1, n_epochs + 1): 107 | 108 | with tf.GradientTape() as tape: 109 | preds = model(X) 110 | loss = criterion(Y, preds) 111 | grads = tape.gradient(loss, model.trainable_variables) 112 | optimizer.apply_gradients(zip(grads, model.trainable_variables)) 113 | train_loss(loss) 114 | 115 | history_loss.append(train_loss.result()) 116 | 117 | if epoch % 10 == 0: 118 | print("epoch: {}/{}, loss: {:.3}".format(epoch, n_epochs, train_loss.result())) 119 | 120 | # 121 | # 122 | # 123 | plt.plot(history_loss, label="loss") 124 | plt.legend(loc="best") 125 | plt.title("Training Loss History") 126 | plt.xlabel("epochs") 127 | plt.ylabel("loss") 128 | plt.grid(True) 129 | plt.show() 130 | 131 | 132 | # ============================ 133 | # Prediction 134 | # ============================ 135 | 136 | sin_data = ds.create_wave(n_data, 0.0) 137 | plot_fig(model, sin_data, n_sample, n_sequence) 138 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/GRU_tf.py: -------------------------------------------------------------------------------- 1 | # 2 | # Sine wave prediction using GRU of Tensorflow. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | import tensorflow as tf 18 | import matplotlib.pyplot as plt 19 | from tensorflow.keras import optimizers, losses, metrics 20 | import DataSet as ds 21 | 22 | 23 | class GRU(tf.keras.Model): 24 | def __init__(self, hidden_units, output_units): 25 | super().__init__() 26 | self.gru = tf.keras.layers.GRU( 27 | hidden_units, 28 | activation="tanh", 29 | recurrent_activation="sigmoid", 30 | kernel_initializer="glorot_normal", 31 | recurrent_initializer="orthogonal", 32 | ) 33 | self.dense = tf.keras.layers.Dense(output_units, activation="linear") 34 | 35 | def call(self, x): 36 | x = self.gru(x) 37 | x = self.dense(x) 38 | return x 39 | 40 | def plot_fig(model, wave_data, n_sample, n_sequence): 41 | 42 | wave = wave_data 43 | z = wave[0:n_sequence] 44 | input = wave[0:n_sequence+1] 45 | sin = [None for i in range(n_sequence)] 46 | gen = [None for i in range(n_sequence)] 47 | 48 | for j in range(n_sample): 49 | y = model.predict(z.reshape(1, z.shape[0], 1)) 50 | z = np.append(z, y)[1:] 51 | gen.append(y[0][0]) 52 | sin.append(wave[j+n_sequence]) 53 | 54 | plt.plot(input, color="b", label="input") 55 | plt.plot(sin, "--", color="#888888", label="sine wave") 56 | plt.plot(gen, color="r", label="predict") 57 | plt.title("Prediction") 58 | plt.legend() 59 | plt.ylim([-2, 2]) 60 | plt.grid(True) 61 | plt.show() 62 | 63 | 64 | # ============================ 65 | # Data creation 66 | # ============================ 67 | n_sequence = 25 68 | n_data = 100 69 | 70 | n_sample = n_data - n_sequence # number of sample 71 | 72 | sin_data = ds.create_wave(n_data, 0.05) 73 | X, Y = ds.dataset(sin_data, n_sequence, False) 74 | 75 | X = X.reshape(X.shape[0], X.shape[1], 1) 76 | Y = Y.reshape(Y.shape[0], Y.shape[1]) 77 | 78 | # ============================ 79 | # Model creation 80 | # ============================ 81 | 82 | input_units = 1 83 | hidden_units = 32 84 | output_units = 1 85 | 86 | model = GRU(hidden_units, output_units) 87 | 88 | model.build(input_shape=(None, n_sequence, input_units)) 89 | model.summary() 90 | 91 | # ============================ 92 | # Training 93 | # ============================ 94 | 95 | lr = 0.001 96 | beta1 = 0.9 97 | beta2 = 0.999 98 | 99 | criterion = losses.MeanSquaredError() 100 | optimizer = optimizers.Adam(learning_rate=lr, beta_1=beta1, beta_2=beta2) 101 | train_loss = metrics.Mean() 102 | 103 | n_epochs = 300 104 | history_loss = [] 105 | 106 | for epoch in range(1, n_epochs + 1): 107 | 108 | with tf.GradientTape() as tape: 109 | preds = model(X) 110 | loss = criterion(Y, preds) 111 | grads = tape.gradient(loss, model.trainable_variables) 112 | optimizer.apply_gradients(zip(grads, model.trainable_variables)) 113 | train_loss(loss) 114 | 115 | history_loss.append(train_loss.result()) 116 | 117 | if epoch % 10 == 0: 118 | print("epoch: {}/{}, loss: {:.3}".format(epoch, n_epochs, train_loss.result())) 119 | 120 | # 121 | # 122 | # 123 | plt.plot(history_loss, label="loss") 124 | plt.legend(loc="best") 125 | plt.title("Training Loss History") 126 | plt.xlabel("epochs") 127 | plt.ylabel("loss") 128 | plt.grid(True) 129 | plt.show() 130 | 131 | 132 | # ============================ 133 | # Prediction 134 | # ============================ 135 | 136 | sin_data = ds.create_wave(n_data, 0.0) 137 | plot_fig(model, sin_data, n_sample, n_sequence) 138 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-02/LSTM_tf.py: -------------------------------------------------------------------------------- 1 | # 2 | # Sine wave prediction using LSTM of Tensorflow. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | import tensorflow as tf 18 | import matplotlib.pyplot as plt 19 | from tensorflow.keras import optimizers, losses, metrics 20 | import DataSet as ds 21 | 22 | 23 | class LSTM(tf.keras.Model): 24 | def __init__(self, hidden_units, output_units): 25 | super().__init__() 26 | self.lstm = tf.keras.layers.LSTM( 27 | hidden_units, 28 | activation="tanh", 29 | recurrent_activation="sigmoid", 30 | kernel_initializer="glorot_normal", 31 | recurrent_initializer="orthogonal", 32 | ) 33 | self.dense = tf.keras.layers.Dense(output_units, activation="linear") 34 | 35 | def call(self, x): 36 | x = self.lstm(x) 37 | x = self.dense(x) 38 | return x 39 | 40 | 41 | def plot_fig(model, wave_data, n_sample, n_sequence): 42 | 43 | wave = wave_data 44 | z = wave[0:n_sequence] 45 | input = wave[0:n_sequence+1] 46 | sin = [None for i in range(n_sequence)] 47 | gen = [None for i in range(n_sequence)] 48 | 49 | for j in range(n_sample): 50 | y = model.predict(z.reshape(1, z.shape[0], 1)) 51 | z = np.append(z, y)[1:] 52 | gen.append(y[0][0]) 53 | sin.append(wave[j+n_sequence]) 54 | 55 | plt.plot(input, color="b", label="input") 56 | plt.plot(sin, "--", color="#888888", label="sine wave") 57 | plt.plot(gen, color="r", label="predict") 58 | plt.title("Prediction") 59 | plt.legend() 60 | plt.ylim([-2, 2]) 61 | plt.grid(True) 62 | plt.show() 63 | 64 | 65 | # ============================ 66 | # Data creation 67 | # ============================ 68 | n_sequence = 25 69 | n_data = 100 70 | 71 | n_sample = n_data - n_sequence # number of sample 72 | 73 | sin_data = ds.create_wave(n_data, 0.05) 74 | X, Y = ds.dataset(sin_data, n_sequence, False) 75 | 76 | X = X.reshape(X.shape[0], X.shape[1], 1) 77 | Y = Y.reshape(Y.shape[0], Y.shape[1]) 78 | 79 | # ============================ 80 | # Model creation 81 | # ============================ 82 | 83 | input_units = 1 84 | hidden_units = 32 85 | output_units = 1 86 | 87 | model = LSTM(hidden_units, output_units) 88 | 89 | model.build(input_shape=(None, n_sequence, input_units)) 90 | model.summary() 91 | 92 | # ============================ 93 | # Training 94 | # ============================ 95 | 96 | lr = 0.001 97 | beta1 = 0.9 98 | beta2 = 0.999 99 | 100 | criterion = losses.MeanSquaredError() 101 | optimizer = optimizers.Adam(learning_rate=lr, beta_1=beta1, beta_2=beta2) 102 | train_loss = metrics.Mean() 103 | 104 | n_epochs = 300 105 | history_loss = [] 106 | 107 | for epoch in range(1, n_epochs + 1): 108 | 109 | with tf.GradientTape() as tape: 110 | preds = model(X) 111 | loss = criterion(Y, preds) 112 | grads = tape.gradient(loss, model.trainable_variables) 113 | optimizer.apply_gradients(zip(grads, model.trainable_variables)) 114 | train_loss(loss) 115 | 116 | history_loss.append(train_loss.result()) 117 | 118 | if epoch % 10 == 0: 119 | print("epoch: {}/{}, loss: {:.3}".format(epoch, n_epochs, train_loss.result())) 120 | 121 | # 122 | # 123 | # 124 | plt.plot(history_loss, label="loss") 125 | plt.legend(loc="best") 126 | plt.title("Training Loss History") 127 | plt.xlabel("epochs") 128 | plt.ylabel("loss") 129 | plt.grid(True) 130 | plt.show() 131 | 132 | 133 | # ============================ 134 | # Prediction 135 | # ============================ 136 | 137 | sin_data = ds.create_wave(n_data, 0.0) 138 | plot_fig(model, sin_data, n_sample, n_sequence) 139 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/65~注意力分数.md: -------------------------------------------------------------------------------- 1 | \- [65 注意力分数](#65-注意力分数) 2 | 3 | \- [掩蔽 softmax 操作](#掩蔽softmax操作) 4 | 5 | \- [加性注意力](#加性注意力) 6 | 7 | \- [缩放点积注意力](#缩放点积注意力) 8 | 9 | \- [小结](#小结) 10 | 11 | ### 65 注意力分数 12 | 13 | - 在上一节中,我们使用高斯核来对查询和键之间的关系建模。我们可以将上一节中的高斯核函数部分视为注意力评分函数,简称评分函数,然后把这个函数的输出结果输入到 softmax 函数中进行运算。通过上述步骤,我们将得到与键对应的值的概率分布(即注意力权重)。最后,注意力汇聚的输出就是基于这些注意力权重的值的加权和。 14 | 15 | ```python 16 | import math 17 | import torch 18 | from torch import nn 19 | from d2l import torch as d2l 20 | ``` 21 | 22 | #### 掩蔽 softmax 操作 23 | 24 | - 正如上面提到的,softmax 操作用于输出一个概率分布作为注意力权重。在某些情况下,并非所有的值都应该被纳入到注意力汇聚中。例如,为了在 [9.5 节](https://zh-v2.d2l.ai/chapter_recurrent-modern/machine-translation-and-dataset.html#sec-machine-translation)中高效处理小批量数据集,某些文本序列被填充了没有意义的特殊词元。为了仅将有意义的词元作为值来获取注意力汇聚,我们可以指定一个有效序列长度(即词元的个数),以便在计算 softmax 时过滤掉超出指定范围的位置。通过这种方式,我们可以在下面的`masked_softmax`函数中 实现这样的*掩蔽 softmax 操作*(masked softmax operation),其中任何超出有效长度的位置都被掩蔽并置为 0。 25 | 26 | ```python 27 | #@save 28 | def masked_softmax(X, valid_lens): 29 | """通过在最后一个轴上掩蔽元素来执行softmax操作""" 30 | # X:3D张量,valid_lens:1D或2D张量 31 | if valid_lens is None: 32 | return nn.functional.softmax(X, dim=-1) 33 | else: 34 | shape = X.shape 35 | if valid_lens.dim() == 1: 36 | valid_lens = torch.repeat_interleave(valid_lens, shape[1]) 37 | else: 38 | valid_lens = valid_lens.reshape(-1) 39 | # 最后一轴上被掩蔽的元素使用一个非常大的负值替换,从而其softmax输出为0 40 | X = d2l.sequence_mask(X.reshape(-1, shape[-1]), valid_lens, 41 | value=-1e6) 42 | return nn.functional.softmax(X.reshape(shape), dim=-1) 43 | ``` 44 | 45 | #### 加性注意力 46 | 47 | - 一般来说,当查询和键是不同长度的矢量时,我们可以使用加性注意力作为评分函数。 48 | 49 | ```python 50 | #@save 51 | class AdditiveAttention(nn.Module): 52 | """加性注意力""" 53 | def __init__(self, key_size, query_size, num_hiddens, dropout, **kwargs): 54 | super(AdditiveAttention, self).__init__(**kwargs) 55 | self.W_k = nn.Linear(key_size, num_hiddens, bias=False) 56 | self.W_q = nn.Linear(query_size, num_hiddens, bias=False) 57 | self.w_v = nn.Linear(num_hiddens, 1, bias=False) 58 | self.dropout = nn.Dropout(dropout) 59 | 60 | def forward(self, queries, keys, values, valid_lens): 61 | queries, keys = self.W_q(queries), self.W_k(keys) 62 | # 在维度扩展后, 63 | # queries的形状:(batch_size,查询的个数,1,num_hidden) 64 | # key的形状:(batch_size,1,“键-值”对的个数,num_hiddens) 65 | # 使用广播方式进行求和 66 | features = queries.unsqueeze(2) + keys.unsqueeze(1) 67 | features = torch.tanh(features) 68 | # self.w_v仅有一个输出,因此从形状中移除最后那个维度。 69 | # scores的形状:(batch_size,查询的个数,“键-值”对的个数) 70 | scores = self.w_v(features).squeeze(-1) 71 | self.attention_weights = masked_softmax(scores, valid_lens) 72 | # values的形状:(batch_size,“键-值”对的个数,值的维度) 73 | return torch.bmm(self.dropout(self.attention_weights), values) 74 | ``` 75 | 76 | #### 缩放点积注意力 77 | 78 | - 使用点积可以得到计算效率更高的评分函数,但是点积操作要求查询和键具有相同的长度*d*。假设查询和键的所有元素都是独立的随机变量,并且都满足零均值和单位方差,那么两个向量的点积的均值为 0,方差为*d*。为确保无论向量长度如何,点积的方差在不考虑向量长度的情况下仍然是 1,我们将点积除以 √d,在下面的缩放点积注意力的实现中,我们使用了暂退法进行模型正则化。 79 | 80 | ```python 81 | #@save 82 | class DotProductAttention(nn.Module): 83 | """缩放点积注意力""" 84 | def __init__(self, dropout, **kwargs): 85 | super(DotProductAttention, self).__init__(**kwargs) 86 | self.dropout = nn.Dropout(dropout) 87 | 88 | # queries的形状:(batch_size,查询的个数,d) 89 | # keys的形状:(batch_size,“键-值”对的个数,d) 90 | # values的形状:(batch_size,“键-值”对的个数,值的维度) 91 | # valid_lens的形状:(batch_size,)或者(batch_size,查询的个数) 92 | def forward(self, queries, keys, values, valid_lens=None): 93 | d = queries.shape[-1] 94 | # 设置transpose_b=True为了交换keys的最后两个维度 95 | scores = torch.bmm(queries, keys.transpose(1,2)) / math.sqrt(d) 96 | self.attention_weights = masked_softmax(scores, valid_lens) 97 | return torch.bmm(self.dropout(self.attention_weights), values) 98 | ``` 99 | 100 | #### 小结 101 | 102 | - 将注意力汇聚的输出计算可以作为值的加权平均,选择不同的注意力评分函数会带来不同的注意力汇聚操作。 103 | - 当查询和键是不同长度的矢量时,可以使用可加性注意力评分函数。当它们的长度相同时,使用缩放的“点-积”注意力评分函数的计算效率更高。 104 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/13~丢弃法.md: -------------------------------------------------------------------------------- 1 | ## 13-丢弃法 2 | 3 | ## 本节目录 4 | 5 | - [1.丢弃法动机、实现及原则](#1丢弃法动机实现及原则) 6 | - [1.1 动机](#11动机) 7 | - [1.2 如何实现模型的这一能力](#12如何实现模型的这一能力) 8 | - [1.3 加入噪音的原则](#13加入噪音的原则) 9 | - [2.丢弃法内容](#2丢弃法内容) 10 | - [3.丢弃法使用](#3丢弃法使用) 11 | - [3.1 丢弃法的使用位置](#31丢弃法的使用位置) 12 | - [3.2 训练中的丢弃法](#32训练中的丢弃法) 13 | - [4.总结](#4总结) 14 | - [5.代码部分](#5代码部分) 15 | - [5.1Dropout 部分](#51dropout部分) 16 | - [5.2 在神经网络中使用丢弃法](#52在神经网络中使用丢弃法) 17 | 18 | ### 1.丢弃法动机、实现及原则 19 | 20 | #### 1.1 动机 21 | 22 | - 一个好的模型需要对输入数据的扰动鲁棒(健壮性) 23 | 24 | #### 13-02 13-03 25 | 26 | #### 1.2 如何实现模型的这一能力 27 | 28 | - 使用有噪音的数据。 29 | - 丢弃法:在层之间加入噪音。 30 | 31 | #### 1.3 加入噪音的原则 32 | 33 | 13-01 34 | 35 | - 例如模型的功能是识别猫猫,加入噪音可以是输入模糊的猫猫图片,但尽量不要是狗狗的图片。 36 | 37 | ### 2.丢弃法内容 38 | 39 | - 丢弃法对每个元素作如下扰动 40 | 41 | 13-04 42 | 43 | - 能够满足加入噪音的期望相同原则 44 | 45 | 13-05 46 | 47 | ### 3.丢弃法使用 48 | 49 | #### 3.1 丢弃法的使用位置 50 | 51 | - 通常将丢弃法作用在隐藏全连接层的输出上 52 | 53 | 13-06 54 | 55 | - 随机选中某些神经元将其输出置位 0,因此模型不会过分依赖某些神经元 56 | 57 | 13-07 58 | 59 | #### 3.2 训练中的丢弃法 60 | 61 | - 正则项(丢弃法)仅在训练中使用:影响模型参数的更新,预测的时候便不再使用 62 | 63 | ### 4.总结 64 | 65 | - 丢弃法将一些输出项随机置 0 来控制模型复杂度 66 | - 常作用在多层感知机的隐藏层输出上 67 | - 丢弃概率是控制模型复杂度的超参数(常取 0.9,0.5,0.1) 68 | 69 | ### 5.代码部分 70 | 71 | #### 5.1Dropout 部分 72 | 73 | ```python 74 | import torch 75 | from torch import nn 76 | from d2l import torch as d2l 77 | 78 | def dropout_layer (X,dropout): #X为dropout层的输入,dropout为设置的丢弃概率 79 | assert 0<=dropout<=1 #丢弃概率介于0,1之间 80 | if dropout == 1: 81 | return torch.zeros_like(x) #若丢弃概率为1,则X的全部项均被置0 82 | if dropout == 0: 83 | return X #若丢弃概率为0,不对X作丢弃操作,直接返回X 84 | mask=(torch.Tensor(X.shape).uniform_(0,1)>dropout).float() #用uniform函数生成0-1间的随机实数,利用”>",将大于dropout的记为1,小于dropout的记为0,实现丢弃操作 85 | return mask*X/(1-dropout) #将mask与X相乘实现丢弃操作,并除以(1-dropout),这里不使用选中X中元素置0的原因是相乘操作相比选中操作更快 86 | ``` 87 | 88 | #### 5.2 在神经网络中使用丢弃法 89 | 90 | ```python 91 | num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256 92 | dropout1, dropout2 = 0.2, 0.5 93 | class Net(nn.Module) 94 | def _init_(self,num_inputs,num_outputs,num_outputs,num_hiddens1,num_hiddens2,is_training=True): 95 | super(Net,self)._init_() 96 | self.num_inputs=num_inputs 97 | self.training=is_training 98 | self.lin1=nn.Linear(num_inputs,num_hiddens1) 99 | self.lin2=nn.Linear(num_hiddens1,num_hiddens2) 100 | self.lin2=nn.Linear(num_hiddens2,num_outputs) 101 | self.relu=nn.ReLU() 102 | def forward(self,X): 103 | H1=self.relu(self.lin1(X.reshape((-1,self.num_inputs)))) 104 | if self.training == True: #丢弃法仅在训练中使用 105 | H1=dropout_layer(H1,dropout1) 106 | H2=self.relu(self.lin2(H1)) 107 | if self.training == True: #丢弃法仅在训练中使用 108 | H2=dropout_layer(H2,dropout2) 109 | out=self.lin3(H2) #output层不再使用丢弃法 110 | return out 111 | ``` 112 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-03/Bigram-count-based.py: -------------------------------------------------------------------------------- 1 | # 2 | # Bi-gram. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import matplotlib.pyplot as plt 17 | import numpy as np 18 | import Tokenizer as tokenizer 19 | import sys 20 | 21 | # input_text = 'eng-14.txt' 22 | # input_text = 'eng-41.txt' 23 | # input_text = 'eng-99.txt' 24 | # input_text = "eng-150.txt" 25 | # input_text = "eng-200.txt" 26 | # input_text = "eng-250.txt" 27 | input_text = "eng-300.txt" 28 | 29 | # ======================================== 30 | # Create dataset 31 | # ======================================== 32 | 33 | file_path = "../DataSets/small_vocabulary_sentences/" + input_text 34 | 35 | Lang = tokenizer.Tokenizer(file_path) 36 | Lang.read_dataset() 37 | vocab_size = Lang.vocab_size() 38 | 39 | print("=================================") 40 | print("Using Bigram") 41 | print("vocabulary size: {}".format(vocab_size)) 42 | print("number of sentences: {}".format(Lang.num_texts())) 43 | print("=================================") 44 | 45 | # ======================================== 46 | # Compute transition matrix 47 | # ======================================== 48 | 49 | transition_matrix = np.zeros((vocab_size, vocab_size)) 50 | 51 | for _, sentence in enumerate(Lang.sentences): 52 | for i in range(len(sentence) - 1): 53 | idx1 = sentence[i] 54 | idx2 = sentence[i + 1] 55 | transition_matrix[idx1][idx2] += 1 56 | 57 | s = np.sum(transition_matrix, axis=1) 58 | for i in range(len(s)): 59 | if s[i] > 0: 60 | transition_matrix[i] /= s[i] 61 | 62 | # ======================================== 63 | # Test 64 | # ======================================== 65 | 66 | if len(s) < 20: 67 | print(" ", end="") 68 | for i in range(len(s)): 69 | print("{:8s} ".format(Lang.idx2word[i]), end="") 70 | print("") 71 | 72 | for i in range(len(s)): 73 | print("{:8s}".format(Lang.idx2word[i]), end="") 74 | for j in range(len(s)): 75 | cp = transition_matrix[i][j] 76 | if cp == 0.0: 77 | print("0.0 ", end="") 78 | else: 79 | print("{:>3f} ".format(cp), end="") 80 | print("") 81 | 82 | else: 83 | keys = np.arange(len(s)) 84 | num_candidate = 5 85 | n = np.minimum(num_candidate, len(s)) 86 | keys = np.random.permutation(keys)[:n] 87 | words = [] 88 | vals = [] 89 | 90 | for key in keys: 91 | print("Text:{}".format(Lang.texts[key])) 92 | 93 | # Get the index of the second word from the end. 94 | # e.g. sentences[key][-1] := , sentences[key][-2] := last word. 95 | idx = Lang.sentences[key][-3] 96 | 97 | cp = transition_matrix[idx].copy() 98 | cp[Lang.word2idx['']] = 0.0 99 | sorted_list = sorted(cp, reverse=True) 100 | 101 | w = [] 102 | v = [] 103 | for _ in range(num_candidate): 104 | _max_idx = np.argmax(cp) 105 | _max_val = np.max(cp) 106 | w.append(Lang.idx2word[_max_idx]) 107 | v.append(_max_val) 108 | 109 | cp[_max_idx] = 0.0 110 | 111 | words.append(w) 112 | vals.append(v) 113 | 114 | print("Predicted last word:") 115 | for i in range(n): 116 | if v[i] > 0.0: 117 | print("\t{}\t=> {:>5f}".format(w[i], v[i])) 118 | print("") 119 | 120 | x = np.arange(len(keys)) 121 | plt.subplots_adjust(wspace=0.4, hspace=1.6) 122 | for i in x: 123 | plt.subplot(num_candidate, 1, i + 1) 124 | plt.title(Lang.texts[keys[i]]) 125 | plt.bar(x, vals[i], tick_label=words[i], align="center") 126 | plt.ylim(0, 1) 127 | plt.ylabel("prob.") 128 | 129 | plt.show() 130 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-03/Trigram-count-based.py: -------------------------------------------------------------------------------- 1 | # 2 | # Tri-gram. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import matplotlib.pyplot as plt 17 | import numpy as np 18 | import Tokenizer as tokenizer 19 | import sys 20 | 21 | # input_text = 'eng-14.txt' 22 | # input_text = 'eng-41.txt' 23 | # input_text = 'eng-99.txt' 24 | # input_text = "eng-150.txt" 25 | # input_text = "eng-200.txt" 26 | # input_text = "eng-250.txt" 27 | input_text = "eng-300.txt" 28 | 29 | # ======================================== 30 | # Create dataset 31 | # ======================================== 32 | 33 | file_path = "../DataSets/small_vocabulary_sentences/" + input_text 34 | 35 | Lang =tokenizer.Tokenizer(file_path) 36 | 37 | # Add two and before and after the sentences for consistent trigram calculations. 38 | # E.g. " Go for it . " => P("Go"| ,), P("for"| "Go",), etc. 39 | Lang.read_dataset(add_sos=2) 40 | vocab_size = Lang.vocab_size() 41 | 42 | 43 | print("=================================") 44 | print("Using Trigram") 45 | print("vocabulary size: {}".format(vocab_size)) 46 | print("number of sentences: {}".format(Lang.num_texts())) 47 | print("=================================") 48 | 49 | # ======================================== 50 | # Compute transition matrix 51 | # ======================================== 52 | 53 | transition_matrix = np.zeros((vocab_size, vocab_size, vocab_size)) 54 | 55 | for _, sentence in enumerate(Lang.sentences): 56 | for i in range(len(sentence) - 2): 57 | idx1 = sentence[i] 58 | idx2 = sentence[i + 1] 59 | idx3 = sentence[i + 2] 60 | transition_matrix[idx1][idx2][idx3] += 1 61 | 62 | for i in range(vocab_size): 63 | for j in range(vocab_size): 64 | _sum = np.sum(transition_matrix[i][j]) 65 | if _sum > 0: 66 | transition_matrix[i][j] /= _sum 67 | 68 | # ======================================== 69 | # Test 70 | # ======================================== 71 | 72 | # Because of Tri-gram 73 | n_sequence = 2 74 | 75 | 76 | def check_length(keys, n_sequence): 77 | for key in keys: 78 | if len(Lang.sentences[key]) <= n_sequence: 79 | return False 80 | return True 81 | 82 | 83 | num_candidate = 5 84 | 85 | while True: 86 | keys = np.arange(Lang.num_texts()) 87 | n = np.minimum(num_candidate, len(keys)) 88 | keys = np.random.permutation(keys)[:n] 89 | if check_length(keys, n_sequence): 90 | break 91 | 92 | words = [] 93 | vals = [] 94 | 95 | for key in keys: 96 | print("Text:{}".format(Lang.texts[i])) 97 | 98 | # Get the indexes of the second and third words from the end. 99 | # e.g. sentences[key][-1] := , sentences[key][-2] := , sentences[i][-3] := last word. 100 | idx1 = Lang.sentences[key][-5] 101 | idx2 = Lang.sentences[key][-4] 102 | 103 | cp = transition_matrix[idx1][idx2].copy() 104 | cp[Lang.word2idx['']] = 0.0 105 | sorted_list = sorted(cp, reverse=True) 106 | 107 | w = [] 108 | v = [] 109 | for _ in range(num_candidate): 110 | _max_idx = np.argmax(cp) 111 | _max_val = np.max(cp) 112 | w.append(Lang.idx2word[_max_idx]) 113 | v.append(_max_val) 114 | 115 | cp[_max_idx] = 0.0 116 | 117 | words.append(w) 118 | vals.append(v) 119 | 120 | print("Predicted last word:") 121 | for i in range(n): 122 | if v[i] > 0.0: 123 | print("\t{}\t=> {:>5f}".format(w[i], v[i])) 124 | print("") 125 | 126 | x = np.arange(len(keys)) 127 | plt.subplots_adjust(wspace=0.4, hspace=1.6) 128 | for i in x: 129 | plt.subplot(num_candidate, 1, i + 1) 130 | plt.title(Lang.texts[keys[i]]) 131 | plt.bar(x, vals[i], tick_label=words[i], align="center") 132 | plt.ylim(0, 1) 133 | plt.ylabel("prob.") 134 | 135 | plt.show() 136 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-03/Tokenizer.py: -------------------------------------------------------------------------------- 1 | # 2 | # Subset of the LanguageTranslationHelper.py@Common, which is a module for language translation. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # 7 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 8 | 9 | class Tokenizer: 10 | def __init__(self, file_name, category=False): 11 | self.word2idx = {} 12 | self.idx2word = {} 13 | self.sentences = [] 14 | self.labels = [] 15 | self.__vocab = set() 16 | self.__file_name = file_name 17 | self.__category = category 18 | 19 | def read_dataset(self, padding=False, add_sos=1): 20 | self.__padding = padding 21 | self.__add_sos = add_sos 22 | self._max_len = 0 23 | 24 | # Read sentences 25 | file_text = open(self.__file_name, "r") 26 | self.texts = file_text.readlines() 27 | file_text.close() 28 | 29 | if self.__category == False: 30 | self.__textA = self.texts.copy() 31 | else: 32 | _texts = self.texts.copy() 33 | self.__textA = [] 34 | 35 | for _text in _texts: 36 | _tmp = _text.rsplit("\t", maxsplit=1) 37 | self.__textA.append(_tmp[0]) 38 | self.labels.append(int(_tmp[1].strip())) 39 | 40 | self._num_texts = len(self.texts) 41 | 42 | # Preprocess sentences 43 | for i in range(self._num_texts): 44 | self.texts[i] = self.texts[i].strip() 45 | 46 | # Add self.__add_sos times 47 | if self.__add_sos > 0: 48 | for s in range(self.__add_sos): 49 | self.__textA[i] = " ".join(['', self.__textA[i]]) 50 | 51 | self.__textA[i] = self.__textA[i].strip() 52 | self.__textA[i] = self.__textA[i].replace(",", "").replace(".", "") 53 | self.__textA[i] = ( 54 | self.__textA[i].replace("'", "").replace("\?", "").replace("\!", "") 55 | ) 56 | 57 | # Add self.__add_sos times 58 | if self.__add_sos > 0: 59 | for s in range(self.__add_sos): 60 | self.__textA[i] = " ".join([self.__textA[i], '']) 61 | 62 | self.__textA[i] = self.__textA[i].lower().split(" ") 63 | 64 | if self._max_len < len(self.__textA[i]): 65 | self._max_len = len(self.__textA[i]) 66 | 67 | # Create vocabulary set 68 | for sentence in self.__textA: 69 | self.__vocab.update(sentence) 70 | 71 | self.__vocab = sorted(self.__vocab) 72 | if self.__padding == True: 73 | """ 74 | The index of "" must be 0, because the loss_function assumes it. 75 | """ 76 | self.__vocab.insert(0, '') 77 | 78 | self._vocab_size = len(self.__vocab) 79 | 80 | for i, w in enumerate(self.__vocab): 81 | self.word2idx[w] = i 82 | 83 | for w, i in self.word2idx.items(): 84 | self.idx2word[i] = w 85 | 86 | # Create tokenized dataset 87 | for i in range(len(self.__textA)): 88 | s = [self.word2idx[s] for s in self.__textA[i]] 89 | self.sentences.append(s) 90 | 91 | 92 | def max_len(self): 93 | return self._max_len 94 | 95 | def num_texts(self): 96 | return self._num_texts 97 | 98 | def vocab_size(self): 99 | return self._vocab_size 100 | 101 | def detokenize(self, tensors): 102 | sentence = "" 103 | for i in range(len(tensors)): 104 | if tensors[i] < self.vocab_size(): 105 | w = self.idx2word[tensors[i]] 106 | if i == 0: # '': 107 | sentence = w 108 | elif i == 1: 109 | sentence += ' ' + w.capitalize() 110 | elif w == ',' or w == '.': 111 | sentence += w 112 | else: 113 | if w == '': 114 | # remove '' 115 | continue 116 | else: 117 | sentence += ' ' + w 118 | 119 | return sentence 120 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/XOR-gate-modularized.py: -------------------------------------------------------------------------------- 1 | # 2 | # Single Hidden Layer Neural Network for learning XOR gate from scratch 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import numpy as np 17 | import matplotlib.pyplot as plt 18 | import sys 19 | 20 | sys.path.append("..") 21 | from Common import Layers 22 | from Common.Optimizer import update_weights 23 | from Common.ActivationFunctions import sigmoid, deriv_sigmoid 24 | 25 | """ 26 | import random as rn 27 | import os 28 | os.environ['PYTHONHASHSEED'] = '0' 29 | np.random.seed(0) 30 | rn.seed(0) 31 | """ 32 | 33 | # ======================================== 34 | # Create datasets 35 | # ======================================== 36 | 37 | # Inputs 38 | X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 39 | 40 | # The ground-truth labels 41 | Y = np.array([0, 1, 1, 0]) 42 | 43 | # Convert row vectors into column vectors. 44 | X = X.reshape(4, 2, 1) 45 | Y = Y.reshape(4, 1, 1) 46 | 47 | # ======================================== 48 | # Create Model 49 | # ======================================== 50 | 51 | input_nodes = 2 52 | hidden_nodes = 3 53 | output_nodes = 1 54 | 55 | dense_1 = Layers.Dense(input_nodes, hidden_nodes, sigmoid, deriv_sigmoid) 56 | dense_2 = Layers.Dense(hidden_nodes, output_nodes, sigmoid, deriv_sigmoid) 57 | 58 | # 59 | # Show parameters 60 | # 61 | params = 0 62 | print("_________________________________________________________________") 63 | print(" Layer (type) Output Shape Param #") 64 | print("=================================================================") 65 | param = dense_1.num_params() 66 | params += param 67 | print( 68 | " dense_1 (Dense) (None, {:>2}) {:>8}".format( 69 | hidden_nodes, param 70 | ) 71 | ) 72 | param = dense_2.num_params() 73 | params += param 74 | print( 75 | " dense_2 (Dense) (None, {:>2}) {:>8}".format( 76 | output_nodes, param 77 | ) 78 | ) 79 | print("=================================================================") 80 | print("Total params: {}\n".format(params)) 81 | 82 | 83 | # ======================================== 84 | # Training 85 | # ======================================== 86 | 87 | 88 | def train(x, Y, lr=0.001): 89 | 90 | # Forward Propagation 91 | y = dense_1.forward_prop(x) 92 | y = dense_2.forward_prop(y) 93 | 94 | # Back Propagation 95 | loss = np.sum((y - Y) ** 2 / 2) 96 | dL = y - Y 97 | 98 | dx = dense_2.back_prop(dL) 99 | _ = dense_1.back_prop(dx) 100 | 101 | # Weights and Bias Update 102 | update_weights([dense_1, dense_2], lr=lr) 103 | 104 | return loss 105 | 106 | 107 | n_epochs = 15000 # Epochs 108 | lr = 0.1 # Learning rate 109 | 110 | history_loss_gd = [] 111 | 112 | # 113 | # Training loop 114 | # 115 | for epoch in range(1, n_epochs + 1): 116 | 117 | loss = 0.0 118 | 119 | for i in range(0, len(Y)): 120 | loss += train(X[i], Y[i], lr) 121 | 122 | history_loss_gd.append(loss / len(Y)) 123 | if epoch % 1000 == 0 or epoch == 1: 124 | print("epoch: {} / {} Loss = {:.6f}".format(epoch, n_epochs, loss)) 125 | 126 | if loss <= 1e-7: 127 | break 128 | 129 | # 130 | # Show loss history 131 | # 132 | plt.plot(history_loss_gd, color="b", label="Gradient descent") 133 | plt.title("Training Loss History") 134 | plt.xlabel("Number of Epochs") 135 | plt.ylabel("Loss") 136 | plt.legend() 137 | plt.grid(True) 138 | plt.show() 139 | 140 | # ======================================== 141 | # Test 142 | # ======================================== 143 | 144 | print("------------------------") 145 | print("x0 XOR x1 => result") 146 | print("========================") 147 | 148 | for i in range(0, len(Y)): 149 | x = X[i] 150 | y = dense_1.forward_prop(x) 151 | y = dense_2.forward_prop(y) 152 | print(" {} XOR {} => {:.4f}".format(x[0][0], x[1][0], y[0][0])) 153 | 154 | print("========================") 155 | -------------------------------------------------------------------------------- /99~参考资料/2021~李沐~《动手学习深度学习》/21~多输入输出通道.md: -------------------------------------------------------------------------------- 1 | # 21-多个输入和输出通道 2 | 3 | ### 本节目录: 4 | 5 | - [21-多个输入和输出通道](#21-多个输入和输出通道) 6 | - [本节目录:](#本节目录) 7 | - [1.多个输入通道:](#1多个输入通道) 8 | - [2.多个输出通道](#2多个输出通道) 9 | - [3.多个输入和输出通道](#3多个输入和输出通道) 10 | - [4.1X1 卷积层](#41x1卷积层) 11 | - [5.二维卷积层](#5二维卷积层) 12 | - [6.总结](#6总结) 13 | - [7.Q&A](#7qa) 14 | 15 | ### 1.多个输入通道: 16 | 17 | - 彩色图像可能有 RGB 三个通道 18 | 19 | - 转换为灰度会丢失信息 20 | 21 |
22 | image 23 |
24 | 25 | - 每个通道都有一个卷积和,结果是所有通道卷积结果的和 26 | 27 |
28 | image 29 |
30 | 31 | - 输入**X**: 32 | - 核**W**: 33 | - 输出**Y**: 34 | 35 | 36 | 37 | 多个输入通道: 38 | 39 | ```python 40 | import torch 41 | from d2l import torch as d2l 42 | 43 | def corr2d_multi_in(X, K): 44 | return sum(d2l.corr2d(x, k) for x, k in zip(X, K)) 45 | ``` 46 | 47 | ### 2.多个输出通道 48 | 49 | - 无论有多少输入通道,到目前位置我们植绒到单输出通道 50 | - 我们可以有多个三维卷积核,每个核生成一个输出通道 51 | - 输入**X**: 52 | - 核**W**: 53 | - 输出**Y**: 54 | 55 | 56 | 57 | 多个输出通道: 58 | 59 | ```python 60 | def corr2d_multi_in_out(X, K): 61 | return torch.stack([corr2d_multi_in(X, k) for k in K], 0) 62 | ``` 63 | 64 | ### 3.多个输入和输出通道 65 | 66 | - 每个通道可以识别特定的模式 67 | 68 |
69 | image 70 |
71 | 72 | - 输入通道核识别并组合输入中的模式 73 | 74 | ### 4.1X1 卷积层 75 | 76 |
77 | image 78 |
79 | 80 | ```python 81 | def corr2d_multi_in_out_1x1(X, K): 82 | c_i, h, w = X.shape 83 | c_o = K.shape[0] 84 | X = X.reshape((c_i, h * w)) 85 | K = K.reshape((c_o, c_i)) 86 | Y = torch.matmul(K, X) 87 | return Y.reshape((c_o, h, w)) 88 | ``` 89 | 90 | ### 5.二维卷积层 91 | 92 |
93 | image 94 |
95 | 96 | ### 6.总结 97 | 98 | - 输出通道数是卷积层的超参数 99 | - 每个输入通道有独立的二维卷积和,所有通道结果相加得到一个输出通道结果 100 | - 每个输出通道有独立的三维卷积核 101 | 102 | ### 7.Q&A 103 | 104 | ##### Q1:网络越深,Padding 0 越多,这里是否会影响性能? 105 | 106 | > 这里性能分为计算性能和网络性能,Padding 0 不会影响网络精度,但会使计算复杂 107 | 108 | ##### Q2:计算卷积时,bias 的有无对结果影响大吗?bias 的作用怎么解释? 109 | 110 | > 因为正则化的操作,bias 对结果影响不大,但加入 bias 对计算性能基本无影响,故默认加入 bias 111 | 112 | ##### Q3:如果是一个 rgb 图像,加上深度图,相当于是四个通道吗? 113 | 114 | > 不是,输入输出通道单列,这里使用 3d 的卷积,输入变为 4 维,核是 5 维 115 | 116 | ##### Q4:怎么理解 1x1 卷积核不识别空间模式? 117 | 118 | > 因为输出的一个像素只对应输入的一个像素,所以没有获取到空间信息 119 | 120 | ##### Q5:是不是可以 3x3x3 和 1x1xN 的卷积层叠加,来进行空间信息的检测和信息融合,以及输出通道的调整? 121 | 122 | > 是的,mobile net 就是这种思想 123 | 124 | ##### Q6:3d 卷积是处理视频问题的吧?也可以处理 rgb 加深度信息吗? 125 | 126 | > 都可以,rgb 加深度信息甚至可以用 2d 卷积处理。 127 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/XOR-gate-pt.py: -------------------------------------------------------------------------------- 1 | # 2 | # Single Hidden Layer Neural Network for learning XOR gate 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # scikit-learn 1.5.0 11 | # torch 2.4.0.dev20240523 12 | # torchaudio 2.2.0.dev20240523 13 | # torchinfo 1.8.0 14 | # torchvision 0.19.0.dev20240523 15 | # 16 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 17 | 18 | import torch 19 | import torch.nn as nn 20 | import torch.nn.functional as F 21 | from torchinfo import summary 22 | import torch.optim as optim 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | 26 | if torch.cuda.is_available(): 27 | device = torch.device("cuda") 28 | elif torch.backends.mps.is_available(): 29 | device = torch.device("mps") 30 | else: 31 | device = torch.device("cpu") 32 | print(device) 33 | 34 | 35 | # ======================================== 36 | # Create datasets 37 | # ======================================== 38 | 39 | # Inputs 40 | X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 41 | 42 | # The ground-truth labels 43 | Y = np.array([[0], [1], [1], [0]]) 44 | 45 | # convert numpy array to tensor 46 | X = torch.from_numpy(X).float() 47 | Y = torch.from_numpy(Y).float() 48 | 49 | 50 | # ======================================== 51 | # Create Model 52 | # ======================================== 53 | 54 | input_nodes = 2 55 | hidden_nodes = 3 56 | output_nodes = 1 57 | 58 | 59 | class SimpleNN(nn.Module): 60 | def __init__(self, input_nodes, hidden_nodes, output_nodes): 61 | super(SimpleNN, self).__init__() 62 | self.fc1 = nn.Linear(input_nodes, hidden_nodes) 63 | self.fc2 = nn.Linear(hidden_nodes, output_nodes) 64 | 65 | # Forward Propagation 66 | def forward(self, x): 67 | x = self.fc1(x) 68 | x = F.sigmoid(x) 69 | x = self.fc2(x) 70 | x = F.sigmoid(x) 71 | return x 72 | 73 | 74 | model = SimpleNN(input_nodes, hidden_nodes, output_nodes).to(device) 75 | 76 | summary(model=SimpleNN(input_nodes, hidden_nodes, output_nodes), input_size=X.shape) 77 | 78 | # ======================================== 79 | # Training 80 | # ======================================== 81 | 82 | n_epochs = 10000 83 | 84 | # set training mode 85 | model.train() 86 | 87 | # set training parameters 88 | optimizer = torch.optim.Adam(model.parameters(), lr=0.001) 89 | criterion = nn.MSELoss() 90 | 91 | history_loss = [] 92 | 93 | # 94 | # Training loop 95 | # 96 | for epoch in range(1, n_epochs + 1): 97 | train_loss = 0.0 98 | 99 | optimizer.zero_grad() 100 | 101 | # forward propagation 102 | outputs = model(torch.Tensor(X).to(device)) 103 | 104 | # compute loss 105 | loss = criterion(outputs, torch.Tensor(Y).to(device)) 106 | 107 | # Weights and Bias Update 108 | loss.backward() 109 | optimizer.step() 110 | 111 | # save loss of this epoch 112 | train_loss += loss.item() 113 | history_loss.append(train_loss) 114 | 115 | if epoch % 100 == 0 or epoch == 1: 116 | print("epoch: {} / {} Loss = {:.4f}".format(epoch, n_epochs, loss)) 117 | 118 | 119 | # 120 | # Show loss history 121 | # 122 | plt.plot(history_loss, color="b", label="loss") 123 | plt.title("Training Loss History") 124 | plt.xlabel("Number of Epochs") 125 | plt.ylabel("Loss") 126 | plt.legend() 127 | plt.grid(True) 128 | plt.show() 129 | 130 | 131 | # ======================================== 132 | # Test 133 | # ======================================== 134 | 135 | print("------------------------") 136 | print(" x0 XOR x1 => result") 137 | print("========================") 138 | 139 | model.eval() 140 | 141 | for i in range(0, len(Y)): 142 | x0 = X[i][0] 143 | x1 = X[i][1] 144 | with torch.no_grad(): 145 | result = model( 146 | torch.from_numpy(np.array([[x0, x1]])).to( 147 | dtype=torch.float32, device=device 148 | ) 149 | ) 150 | result = result.to("cpu").detach().numpy().copy() 151 | 152 | print(" {} XOR {} => {:.4f}".format(int(x0), int(x1), float(result))) 153 | 154 | print("========================") 155 | -------------------------------------------------------------------------------- /99~参考资料/2023~The Engineer's Guide To Deep Learning/Part-01/XOR-gate-tf-softmax.py: -------------------------------------------------------------------------------- 1 | # 2 | # A Neural Network with Softmax layer for learning XOR gate. 3 | # 4 | # Developed environment: 5 | # Python 3.11.5 6 | # keras 2.15.0 7 | # pip 24.0 8 | # numpy 1.26.4 9 | # matplotlib 3.9.0 10 | # tensorflow 2.15.1 11 | # tensorflow-metal 1.1.0 12 | # scikit-learn 1.5.0 13 | # 14 | # Copyright (c) 2024, Hironobu Suzuki @ interdb.jp 15 | 16 | import tensorflow as tf 17 | from tensorflow.keras import optimizers, losses, metrics 18 | import numpy as np 19 | import matplotlib.pyplot as plt 20 | 21 | # np.random.seed(0) 22 | # tf.random.set_seed(0) 23 | 24 | # ======================================== 25 | # Create datasets 26 | # ======================================== 27 | 28 | # Inputs 29 | X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 30 | 31 | # The ground-truth labels 32 | Y = np.array([[1, 0], [0, 1], [0, 1], [1, 0]]) 33 | 34 | # ======================================== 35 | # Create model 36 | # ======================================== 37 | 38 | input_nodes = 2 39 | hidden_nodes = 3 40 | output_nodes = 2 41 | 42 | 43 | class SimpleNN(tf.keras.Model): 44 | def __init__(self, input_nodes, hidden_nodes, output_nodes): 45 | super(SimpleNN, self).__init__() 46 | 47 | # Hidden layer 48 | self.f = tf.keras.layers.Dense( 49 | units=hidden_nodes, 50 | input_dim=input_nodes, 51 | activation="sigmoid", 52 | ) 53 | 54 | # Output layer 55 | self.g = tf.keras.layers.Dense( 56 | units=output_nodes, 57 | activation="softmax", 58 | ) 59 | 60 | # Forward Propagation 61 | def call(self, x, training=None): 62 | h = self.f(x) 63 | y = self.g(h) 64 | return y 65 | 66 | 67 | model = SimpleNN(input_nodes, hidden_nodes, output_nodes) 68 | 69 | # loss_func = losses.BinaryCrossentropy() 70 | loss_func = losses.CategoricalCrossentropy() 71 | optimizer = optimizers.Adam(learning_rate=0.1) 72 | 73 | model.build(input_shape=(None, 2)) 74 | model.summary() 75 | 76 | # ======================================== 77 | # Training 78 | # ======================================== 79 | 80 | # 81 | # Training function 82 | # 83 | @tf.function 84 | def train(X, Y): 85 | with tf.GradientTape() as tape: 86 | # Forward Propagation 87 | y = model(X) 88 | 89 | loss = loss_func(Y, y) 90 | 91 | # Back Propagation 92 | grad = tape.gradient(loss, model.trainable_variables) 93 | 94 | # Weights and Bias Update 95 | optimizer.apply_gradients(zip(grad, model.trainable_variables)) 96 | 97 | return loss 98 | 99 | 100 | n_epochs = 800 101 | 102 | history_loss = [] 103 | 104 | # 105 | # Training loop 106 | # 107 | for epoch in range(1, n_epochs + 1): 108 | _loss = 0.0 109 | 110 | loss = train(X, Y) 111 | 112 | _loss += loss.numpy() 113 | history_loss.append(_loss) 114 | 115 | if epoch % 100 == 0 or epoch == 1: 116 | print("epoch: {} / {} Loss = {:.6f}".format(epoch, n_epochs, _loss)) 117 | 118 | 119 | # 120 | # Show loss history 121 | # 122 | plt.plot(history_loss, color="b", label="loss") 123 | plt.title("Training Loss History") 124 | plt.xlabel("Number of Epochs") 125 | plt.ylabel("Loss") 126 | plt.legend() 127 | plt.grid(True) 128 | plt.show() 129 | 130 | # ======================================== 131 | # Test 132 | # ======================================== 133 | 134 | result = model.predict(X) 135 | 136 | print("-------------------------------------") 137 | print("x0 XOR x1 => prob(0) prob(1)") 138 | print("=====================================") 139 | for i in range(0, len(Y)): 140 | _x0 = X[i][0] 141 | _x1 = X[i][1] 142 | print( 143 | " {} XOR {} => {:.4f} {:.4f}".format(_x0, _x1, result[i][0], result[i][1]) 144 | ) 145 | print("=====================================") 146 | 147 | 148 | x = np.arange(2) 149 | plt.subplots_adjust(wspace=0.4, hspace=0.8) 150 | 151 | for i in range(4): 152 | plt.subplot(4, 1, i + 1) 153 | title = str(X[i][0]) + " XOR " + str(X[i][1]) 154 | plt.title(title) 155 | plt.bar(x, result[i], tick_label=x, align="center") 156 | plt.ylim(0, 1) 157 | plt.ylabel("prob.") 158 | 159 | plt.show() 160 | --------------------------------------------------------------------------------