dropout层、线性层、layernorm

dropout层:防止过拟合

nn.dropout 每次将 p 元素设置为 0,剩下的元素乘以 1/(1-p)

eval()模式不进行dropout

使用方法如下:

In [1]: import torch

In [2]: p = 0.5

In [3]: module = torch.nn.Dropout(p)

In [4]: module.training
Out[4]: True

In [5]: inp = torch.ones(3,5)

In [6]: print(inp)
tensor([[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]])

In [7]: module(inp)
Out[7]:
tensor([[0., 0., 0., 2., 0.],
        [2., 2., 0., 0., 2.],
        [2., 0., 2., 2., 2.]])

In [10]: 1/(1-p)
Out[10]: 2.0

In [11]: module.eval()
Out[11]: Dropout(p=0.5, inplace=False)

In [12]: module.training
Out[12]: False

In [13]: module(inp)
Out[13]:
tensor([[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]])

Linear层

In [1]: import torch

In [2]: module = torch.nn.Linear(10,20)

In [3]: module
Out[3]: Linear(in_features=10, out_features=20, bias=True)

In [4]: n_samples = 40

In [5]: inp_2d = torch.rand(n_samples,10)

In [6]: module(inp_2d).shape
Out[6]: torch.Size([40, 20])

In [7]: inp_3d = torch.rand(n_samples,33,10)

In [8]: module(inp_3d).shape
Out[8]: torch.Size([40, 33, 20])

In [10]: input_7d = torch.rand(n_samples,2,3,4,5,6,10)

In [12]: module(input_7d).shape
Out[12]: torch.Size([40, 2, 3, 4, 5, 6, 20])

LayerNorm属性

可学习参数为0

In [1]: import torch

In [2]: inp = torch.tensor([[0,4.],[-1,7],[3,5]])

In [3]: n_samples,n_features = inp.shape

In [4]: print(n_samples)
3

In [5]: module = torch.nn.LayerNorm(n_features, elementwise_affine=False)

In [6]: sum(p.numel() for p in module.parameters() if p.requires_grad)
Out[6]: 0

In [7]: inp.mean(-1),inp.std(-1,unbiased=False)
Out[7]: (tensor([2., 3., 4.]), tensor([2., 4., 1.]))

In [8]: module(inp).mean(-1),module(inp).std(-1,unbiased=False)
Out[8]:
(tensor([ 0.0000e+00, -2.9802e-08,  1.1921e-07]),
 tensor([1.0000, 1.0000, 1.0000]))

可学习参数为4

In [9]: module = torch.nn.LayerNorm(n_features, elementwise_affine=True)

In [10]: sum(p.numel() for p in module.parameters() if p.requires_grad)
Out[10]: 4

In [11]: (module.bias,module.weight)
Out[11]:
(Parameter containing:
 tensor([0., 0.], requires_grad=True),
 Parameter containing:
 tensor([1., 1.], requires_grad=True))

In [12]: module(inp).mean(-1),module(inp).std(-1,unbiased=False)
Out[12]:
(tensor([ 0.0000e+00, -2.9802e-08,  1.1921e-07], grad_fn=<MeanBackward1>),
 tensor([1.0000, 1.0000, 1.0000], grad_fn=<StdBackward1>))

In [13]: module.bias.data += 1

In [14]: module.weight.data *= 4

In [15]: module(inp).mean(-1),module(inp).std(-1,unbiased=False)
Out[15]:
(tensor([1.0000, 1.0000, 1.0000], grad_fn=<MeanBackward1>),
 tensor([4.0000, 4.0000, 4.0000], grad_fn=<StdBackward1>))

只更新n_features,样本间独立,与n_samples无关

In [16]: module(torch.rand(n_samples,2,3,4,5,6,n_features)).shape
Out[16]: torch.Size([3, 2, 3, 4, 5, 6, 2])

In [17]: module(torch.rand(n_samples,2,3,4,5,6,n_features)).mean(-1)
Out[17]:
tensor([[[[[[1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000]],

            [[1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
            [1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000]]]]]],
       grad_fn=<MeanBackward1>)

In [18]: module(torch.rand(n_samples,2,3,4,5,6,n_features)).std(-1,unbiased=False)
Out[18]:
tensor([[[[[[3.9998, 3.9962, 3.9993, 3.9966, 3.9657, 3.9954],
            [3.9998, 3.9997, 3.9996, 3.9981, 3.9981, 3.9983],
            [3.9799, 3.9996, 3.9657, 3.9998, 3.9998, 3.9986],
            [3.9990, 3.9950, 3.9885, 3.9996, 3.9582, 3.9996],
            [3.9987, 3.9989, 3.9900, 3.9992, 3.9992, 3.9994]],

           [[3.9996, 3.9996, 3.9972, 3.9931, 3.9998, 3.5468],
            [3.9998, 3.9808, 3.9974, 3.9985, 3.9992, 3.9986],
            [1.1207, 3.9993, 3.9998, 3.6870, 3.9997, 3.9981],
            [3.9998, 3.9998, 3.9986, 3.9676, 3.9999, 3.9998],
            [3.9993, 3.9999, 3.9998, 3.9852, 3.9993, 3.9891]]]]]],
       grad_fn=<StdBackward1>)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 要将二维Transformer添加到模型中,需要使用PyTorch等深度学习框架提供的二维卷积,例如nn.Conv2d。以下是一个简单的例子,展示如何在PyTorch中实现一个基本的二维Transformer: ```python import torch.nn as nn class TwoDTransformer(nn.Module): def __init__(self, input_channels, output_channels, num_heads, hidden_dim, dropout): super(TwoDTransformer, self).__init__() self.conv_q = nn.Conv2d(input_channels, hidden_dim, kernel_size=1) self.conv_k = nn.Conv2d(input_channels, hidden_dim, kernel_size=1) self.conv_v = nn.Conv2d(input_channels, hidden_dim, kernel_size=1) self.conv_out = nn.Conv2d(hidden_dim, output_channels, kernel_size=1) self.num_heads = num_heads self.head_dim = hidden_dim // num_heads self.attention = nn.MultiheadAttention(hidden_dim, num_heads, dropout=dropout) self.norm1 = nn.LayerNorm(hidden_dim) self.norm2 = nn.LayerNorm(hidden_dim) self.dropout = nn.Dropout(dropout) def forward(self, x): q = self.conv_q(x) # query k = self.conv_k(x) # key v = self.conv_v(x) # value # reshape the tensors to have shape (batch_size*num_heads, head_dim, height, width) batch_size, _, height, width = q.size() q = q.view(batch_size*self.num_heads, self.head_dim, height, width) k = k.view(batch_size*self.num_heads, self.head_dim, height, width) v = v.view(batch_size*self.num_heads, self.head_dim, height, width) # calculate the attention attn_output, _ = self.attention(q, k, v) attn_output = attn_output.view(batch_size, self.num_heads*self.head_dim, height, width) # skip connection and layer normalization x = x + self.dropout(attn_output) x = self.norm1(x) # feedforward network x = self.conv_out(x) x = self.dropout(x) x = self.norm2(x) return x ``` 在这个例子中,我们使用了nn.MultiheadAttention来实现注意力机制。我们首先将输入张量x通过三个卷积分别变换为query、key和value张量,然后将它们reshape成(batch_size*num_heads, head_dim, height, width)的形状,以便在注意力计算中使用。然后,我们将query、key和value张量输入到nn.MultiheadAttention中,并将处理后的输出reshape回(batch_size, num_heads*head_dim, height, width)的形状。接下来,我们将原始输入和注意力输出进行相加,并通过归一化和Feedforward网络来产生最终输出。 在实践中,您可能需要根据您的具体任务和数据集来修改这个例子中的参数和模型结构。 ### 回答2: 要加入二维Transformer,首先需要理解Transformer的工作原理。Transformer是一种基于自注意力机制的序列到序列模型,用于处理序列数据,如自然语言处理任务。 在加入二维Transformer之前,我们需要将输入数据由一维序列转换为二维矩阵形式。假设输入是一个二维图片,可以将图片的每个像素位置看作是一个位置编码。然后,将每个像素位置的特征向量作为输入的序列,以及其位置编码,构成Transformer的输入。 在构建二维Transformer时,需要考虑以下几个关键步骤: 1. 多头自注意力机制:将输入序列和位置编码输入到多个注意力头中,利用自注意力机制计算每个位置的注意力得分。然后,将得到的注意力加权的特征向量进行合并。 2. 前馈神经网络:将特征向量经过一简单的前馈神经网络进行非线性变换。 3. 残差连接和归一化:为了避免梯度消失和加速训练过程,可以在每个的输入和输出之间添加残差连接,并进行归一化。 4. 正则化和损失函数:可以采用Dropout来随机丢弃一部分特征向量,以防止过拟合。同时,需要确定适当的损失函数,如交叉熵损失函数,来评估模型的性能。 最后,在训练过程中,可以使用反向传播算法来更新模型参数,以最小化损失函数。可以使用优化器(如Adam)来自动调整学习率。 需要注意的是,二维Transformer通常与其他(如卷积)结合使用,以捕捉图像的局部和全局特征。因此,在构建模型架构时,需要根据具体任务和数据的特点来设计。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非零因子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值