目录

深度学习Dropout

深度学习Dropout

一、概念

Dropout是为了解决过拟合,当层数加深,就有可能过拟合,这个时候模型太复杂就会过拟合,那么可以让模型变得简单一点,所以就可以随机挑一些神经元,让某些神经元的输出是0,只保留部分神经元的输出给下一层,这个过程是随机的。但是在推理的时候这些神经元相当于变得透明,不再随机。丢多少的比例就是超参。

https://i-blog.csdnimg.cn/direct/43a6e15e8b79464bbc0a1e6fb867be26.png

二、AlphaDropout

AlphaDropout是Dropout的一个变种,在应用Dropout时使用了一个额外的缩放因子alpha。与标准Dropout相比,AlphaDropout在将一些输出设置为0的同时,也会对剩余输出进行缩放,来保持网络权重的期望值不变(均值和方差)。这种缩放可以增加训练的稳定性。

三、代码

只在第一层加AlphaDropout,i可以控制加多少AlphaDropout,这里没加,注释掉了。

class NeuralNetwork(nn.Module):
    def __init__(self, layers_num=2):
        super().__init__()
        self.transforms = transforms
        self.flatten = nn.Flatten()
        # 多加几层
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28 * 28, 100),  # in_features=784, out_features=300
            nn.ReLU(),
            nn.AlphaDropout(p=0.2) # 增加dropout,p=0.2表示以0.2的概率将某些神经元置0,防止过拟合
        )
        # 加19层
        for i in range(1, layers_num):
            self.linear_relu_stack.add_module(f"Linear_{i}", nn.Linear(100, 100))
            self.linear_relu_stack.add_module(f"relu", nn.ReLU())
            if i<3:
                # self.linear_relu_stack.add_module(f"dropout_{i}", nn.AlphaDropout(p=0.2))
                pass
             # 增加dropout
        # 输出层
        self.linear_relu_stack.add_module("Output Layer", nn.Linear(100, 10))
        
        # 初始化权重
        self.init_weights()
        
    def init_weights(self):
        """使用 xavier 均匀分布来初始化全连接层的权重 W"""
        for m in self.modules():
            if isinstance(m, nn.Linear):
                nn.init.xavier_uniform_(m.weight)
                nn.init.zeros_(m.bias)

    def forward(self, x):
        # x.shape [batch size, 1, 28, 28]
        x = self.transforms(x)
        x = self.flatten(x)  
        # 展平后 x.shape [batch size, 28 * 28]
        logits = self.linear_relu_stack(x)
        # logits.shape [batch size, 10]
        return logits

print(f"{'layer_name':^40}\tparamerters num")
for idx, (key, value) in enumerate(NeuralNetwork(20).named_parameters()):
    print("{:<40}\t{:^10}".format(key, np.prod(value.shape)))