-

【深度学习】知识汇总

+

【深度学习】DeepL知识汇总

@@ -288,6 +290,10 @@

深度学习知识汇总

href="https://link.zhihu.com/?target=https%3A//blog.csdn.net/xys430381_1/article/details/80680167">https://link.zhihu.com/?target=https%3A//blog.csdn.net/xys430381_1/article/details/80680167

优化器 https://zhuanlan.zhihu.com/p/78622301

+

BN https://zhuanlan.zhihu.com/p/93643523

+

神经网络权重初始化 https://blog.csdn.net/kebu12345678/article/details/103084851

https://zhuanlan.zhihu.com/p/667048896

逻辑回归和线性回归

@@ -326,6 +332,67 @@

实现参数稀疏

残差网络的出现解决了构建深层神经网络时网络退化即梯度消失/爆炸的问题。残差结构主要设计有两个,快捷连接(shortcut connection)和恒等映射(identity mapping),快捷连接使得残差变得可能,而恒等映射使得网络变深,恒等映射主要有两个:跳跃连接和激活函数

+

Adam与SGD的区别

+

SGD缺点是其更新方向完全依赖于当前batch计算出的梯度,因而十分不稳定。

+

Adam的优点主要在于:

+
    +
  • 考虑历史步中的梯度更新信息,能够降低梯度更新噪声。
  • +
  • 此外经过偏差校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
  • +
+

但是Adam也有其自身问题:可能会对前期出现的特征过拟合,后期才出现的特征很难纠正前期的拟合效果。二者似乎都没法很好避免局部最优问题。

+

softmax如何防止指数上溢

+

在计算softmax函数时,指数上溢是一个常见的问题,特别是当输入的数值非常大时,指数函数的计算结果可能会溢出。为了解决这个问题,可以采取以下几种方法:

+
    +
  1. 数值稳定性技巧:为了避免指数函数的溢出,可以将输入的数值减去一个常数,使得输入相对较小,从而减少指数函数的值。通常,可以通过找到输入向量中的最大值,并将所有元素减去这个最大值来实现数值稳定性。

    +

    image-20240222173542613

    +

    这样做可以保持相对稳定,防止指数函数的溢出。

  2. +
  3. 利用性质:softmax函数的分子和分母同时除以一个相同的常数并不会改变函数的值。因此,我们可以在计算softmax时,将所有输入向量的值都减去向量中的最大值,然后进行softmax计算。

  4. +
+

以上两种方法都可以有效地避免指数上溢的问题,并保持softmax函数的数值稳定性。在实际应用中,通常会使用这些技巧来计算softmax函数,以确保模型的稳定性和数值精度。

+

训练过程中发现loss快速增大应该从哪些方面考虑?

+
    +
    1. +
    2. 学习率过大
    3. +
    4. 训练样本中有坏数据
    5. +
  1. +
  2. +
  3. model.eval vs和torch.no_grad区别

  4. +
    • +
    • model.eval(): +依然计算梯度,但是不反传;dropout层保留概率为1;batchnorm层使用全局的mean和var
    • +
    • with torch.no_grad: 不计算梯度
    • +
  5. +
  6. +
  7. +
  8. Dropout和Batch norm能否一起使用?

  9. +
  10. 可以,但是只能将Dropout放在Batch +norm之后使用。因为Dropout训练时会改变输入X的方差,从而影响Batch +norm训练过程中统计的滑动方差值;而测试时没有Dropout,输入X的方差和训练时不一致,这就导致Batch +norm测试时期望的方差和训练时统计的有偏差。

  11. +
  12. +
  13. 梯度消失和梯度爆炸

  14. +
  15. 梯度消失的原因和解决办法

  16. +
  17. (1)隐藏层的层数过多

  18. +
  19. 反向传播求梯度时的链式求导法则,某部分梯度小于1,则多层连乘后出现梯度消失

  20. +
  21. (2)采用了不合适的激活函数

  22. +
  23. 如sigmoid函数的最大梯度为1/4,这意味着隐藏层每一层的梯度均小于1(权值小于1时),出现梯度消失。

  24. +
  25. 解决方法:1、relu激活函数,使导数衡为1 2、batch norm +3、残差结构

  26. +
  27. 梯度爆炸的原因和解决办法

  28. +
  29. (1)隐藏层的层数过多,某部分梯度大于1,则多层连乘后,梯度呈指数增长,产生梯度爆炸。

  30. +
  31. (2)权重初始值太大,求导时会乘上权重

  32. +
  33. 解决方法:1、梯度裁剪 2、权重L1/L2正则化 3、残差结构 4、batch +norm

  34. +
  35. +
+

pytorch实现自注意力和多头注意力

+

自注意力

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from math import sqrt
import torch
import torch.nn as nn

class SelfAttention(nn.Module):
def __init__(self, dim_in, dim_k, dim_v):
super(SelfAttention, self).__init__()
self.dim_in = dim_in
self.dim_k = dim_k
self.dim_v = dim_v
self.linear_q = nn.Linear(dim_in, dim_k, bias=False)
self.linear_k = nn.Linear(dim_in, dim_k, bias=False)
self.linear_v = nn.Linear(dim_in, dim_v, bias=False)
self._norm_fact = 1/sqrt(dim_k)


def forward(self, x):
batch, n, dim_in = x.shape
assert dim_in == self.dim_in

q = self.linear_q(x) #batch, n, dim_k
k = self.linear_k(x)
v = self.linear_v(x)

dist = torch.bmm(q, k.transpose(1,2))* self._norm_fact #batch, n, n
dist = torch.softmax(dist, dim=-1)

att = torch.bmm(dist, v)
return att

+

多头注意力机制

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from math import sqrt
import torch
import torch.nn as nn

class MultiHeadAttention(nn.Module):
#dim_in input dimention
#dim_k kq dimention
#dim_v value dimention
#num_heads number of heads

def __init__(self, dim_in, dim_k, dim_v, num_heads=8):
super(MultiHeadAttention, self).__init__()
assert dim_k% num_heads ==0 and dim_v% num_heads ==0

self.dim_in = dim_in
self.dim_k = dim_k
self.dim_v = dim_v
self.num_heads = num_heads
self.linear_q = nn.Linear(dim_in, dim_k, bias==False)
self.linear_k = nn.Linear(dim_in, dim_k, bias==False)
self.linear_v = nn.Linear(dim_in, dim_v, bias==False)
self._norm_fact = 1/sqrt(dim_k//num_heads)

def forwards(self, x):
# x: tensor of shape(batch, n, dim_in)
batch, n, dim_in = x.shape
assert dim_in = self.dim_in

nh = self.num_heads
dk = self.dim_k // nh
dv = self.dim_v // nh

q = self.linear_q(x).reshape(batch, n, nh, dk).transpose(1, 2)
k = self.linear_k(x).reshape(batch, n, nh, dk).transpose(1, 2)
v = self.linear_v(x).reshape(batch, n, nk, dk).transpose(1, 2)

dist = torch.matmul(q, k.transpose(2,3))*self._norm_fact
dist = torch.softmax(dist, dim=-1)

att = torch.matmul(dist, v)
att = att.transpose(1,2).reshape(batch, n, self.dim_v)
+

Batch Normalization

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MyBN:
def __init__(self, momentum=0.01, eps=1e-5, feat_dim=2):
self._running_mean = np.zeros(shape = (feat_dim,))
self._running_var = np.ones(shape = (fear_dim,))
self._momentum = momentum
#防止分母计算为0
self._eps = eps

#对应batch norm中需要更新beta 和 gamma, 采用pytorch文档中的初始化
self._beta = np.zeros(shape=(feat_dim,))
self._gamma = np.ones(shape=(feat_dim,))


def batch_norm(self, x):
if self.training:
x_mean = x.mean(axis=0)
x_var = x.var(axis=0)
#对应running_mean的更新公式
self._running_mean = (1-self._momentum)*x_mean +self._momentum*self._running_mean
self._running_var = (1-self._momentum)*x_var + self._momentum*self._running_var
#对应论文中计算BN公式
x_hat = (x-x_mean)/np.sqrt(x_var+self._eps)
else:
x_hat = (x-self._running_mean)/np.sqrt(self._running_var+self._eps)
return self._gamma*x_hat + self._beta