一些概念
全连接层
- 输入和输出通过一种运算直接连接的层
- 全连接层忽略了空间结构特性,因此不适合用于在方位上找Pattern的任务
- 理解:https://zhuanlan.zhihu.com/p/33841176
多层感知机
线性回归、softmax回归与logistic回归
- softmax处理多分类问题,logistic处理二分类问题
- 线性回归是y=w1x1+w2x2+b的模式,只有一个输出;softmax通过softmax运算符实现多个输出神经元的分类预测。
- softmax的各分类概率相加为1,用于找概率最大的那个。sigmoid的各分类为0-1之间的值,概率总和不一定为1,用于发现多种可能。
欠拟合与过拟合
隐藏层
- 每个隐藏层的输出通过激活函数进行变换,实现非线性变换。隐藏层的作用:
- 每个隐藏层的输出通过激活函数进行变换,实现非线性变换。隐藏层的作用:
batch概念 & 作用
- 通常将样本分为多组,每组中样本数量即为batch_size
- batch太大会训练慢,太小会梯度下降方向性差,但偏大比较好。
梯度下降
本质就是当前点的cost函数对w1,w2,b等各个系数的偏导,从而求得该点的梯度,然后通过梯度乘以学习率,然后进行反向传播,即可实现梯度下降。
例:w := w - a * dw, dw即为损失函数对w的偏导。注意损失函数中的y是要替换成sigmod(z),然后z换成wx+b,从而可以求对w的偏导。
1 | demo: |
Module构造模型
1 | import torch |
这里的模型定义倒是很简单,需要注意的是784*256和256*10的关系。
如下图,784就是x也就是特征的个数,784256为w的数量,也就是要训练的参数的数量。这就好像softmax中的w,是3\3的,而x是1*3的。
因此这里实际上就是:
[1*784] * [784*256] * [256*10] = [1*10]
卷积神经网络
强烈推荐: https://github.com/fengdu78/deeplearning_ai_books
卷积层
需要熟悉的概念:
- 卷基层主要作用是提取图像中的局部特征
- 卷积(互相关)运算、卷积核
- 填充(padding)、步幅(stride)
- 多输入输出通道(多输入通道只需要增加核的通道数,想要多输出通道需要增加核的组数)
池化层
需要熟悉的概念:
- 主要作用是缓解卷积层对位置的过度敏感性,降低数据数量,防止过拟合
- 输出通道数与输入通道数相同
CNN的反向传播
CNN的参数就是卷积核,因此反向传播就是求cost对卷积核的偏导,然后梯度下降。
LeNet
模型解读(重要):
这里需要搞懂各种形状的变换,这是核心。理解了这里,看其他几个网络也会轻松很多。
整个模型为:卷积-池化-卷积-池化-全连接
注意数据通道数、维度的变化:首先卷积-池化两层将输入变为6通道,14*14的矩阵,然后再通过一个卷积层变为16通道,10*10的矩阵,注意这里的卷积核是:6通道,16组。
最后全连接层为5*5*16 -> 120, 形状是:
[1,[16,5,5]],然后展开和[[16,5,5],120]相乘,最后结果就是[1,120],这和之前MLP中隐藏层的算法是一样的。
关于CNN中卷积层后为何要跟隐藏层(激活函数的作用):
激活函数的主要作用是提供网络的非线性建模能力。在卷积层中,我们主要采用了卷积的方式来处理,也就是对每个像素点赋予一个权值,这个操作显然就是线性的。但是对于我们样本来说,不一定是线性可分的,为了解决这个问题,我们可以进行线性变化,或者我们引入非线性因素,解决线性模型所不能解决的问题。如果没有激活函数,那么该网络仅能够表达线性映射,此时即便有再多的隐藏层,其整个网络跟单层神经网络也是等价的。因此也可以认为,只有加入了激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。
不过我还是没懂池化层之后为啥不需要激活。。
使用:
只写一下前向传播吧,conv是前边的一堆卷积池化,然后全连接。注意全连接是256->10的,因此需要feature.view把16*4*4转成256。
1 | def forward(self, img): |
AlexNet & VGG
VGG就是很多个VGG block叠在一起,理解上和LeNet没有本质区别。
残差网络:ResNet
非常深层的网络因为深度存在梯度消失和梯度爆炸的问题。因此需要使用跳跃连接,可以将某一层网络的激活迅速传给更深处。
残差网络最重要的是理解残差块,举个例子:
正常的plain block,a[l] -> a[l+2]需要经过这两个线性/激活层,然后才能往后传播。
而残差块并不需要经过这两层,而是直接通过short cut传递到了后边relu函数,这样就能做到不经过中间层,直接向后传播,也就能实现全局最优解。
引用吴恩达的话就是“这些残差块学习恒等函数非常容易,因此可以保证网络性能不受深度影响,甚至提高性能”。
a[l+2]=g(Wa[l+1]+b+a[l])
GoogLeNet
Inception块原理:
批量归一化
// TODO
循环神经网络
一定要去看吴恩达的课。。网上那些教程写的就像一坨坨屎
基本原理
https://cuijiahua.com/blog/2018/12/dl-11.html 这篇写的不错。
一共维护三个参数VUW,V是输出层的参数,W是将状态传递到下一次运算的参数,U是下一次和Xt运算的参数。
如何将字符序列输入网络
one_hot,其实就是将一串n个字符的输入表示成一个n维矩阵,矩阵中只有当前那个词是1,其他都是0
基于时间的反向传播
还就是logistic回归的那个cost,但是具体怎么计算的还没搞懂。。
LSTM
关于LSTM的记忆细胞为什么能解决梯度消失问题:
https://www.jianshu.com/p/95d5c461924c
不过为什么之前的信息能这样保存我还没理解
最近写的Webshell直接用上了双向循环LSTM,效果还不错。RNN是几分类,输出的最后一维就是几。
有关输出的问题:
LSTM的输出格式是output, (h_n, c_n),output是三维的,格式为(token_len, batch_size, hidden_size*(bidirectional?1:2))。
time step数量等于token_len,output保存了最后一层的每个time step的输出h,如果是双向LSTM,每个time step的输出h=[h正向, h逆向]
https://zhuanlan.zhihu.com/p/39191116
使用:
input_size是embedding的维度,hidden_size是隐藏单元数量,num_layers是RNN层数,bidirectional True表示双向RNN。
1 | self.encoder = nn.LSTM(input_size=embedding_dim, |
word embedding
one hot的各个词向量之间内积为0,没法表示两个词之间的关系(比如近义词),因此提出词嵌入。
核心思路是给词的表示加一个维度,这个维度表示词的一些特征的数量,用embedding_dim表示。比如下图:
性别、年龄等特征种,与其相关的词的这一属性的值就会相近,这样就能找到相近的关系。
因此,pytorch中使用embedding只需要两个参数:词的属性数量(维度)和词的数量。
1 | self.embedding = nn.Embedding(token_size, embedding_dim) |
pytorch常用操作
tensor切片: https://blog.csdn.net/weicao1990/article/details/93599947
图神经网络学习
// TODO
很多信号与系统的知识看不懂,有时间了还是得系统的从同看一遍。
图神经网络用在静态分析上应该可行。
Transform学习
self attention/multi-head attention很巧妙,现在的NLP都是用transform了
http://www.sxlwork.top/2020/12/22/2020-12-22-NLP%E4%B9%8BSelf-Attention%E4%B8%8ETransformer/