神经网络各种初始化方法(normal,uniform,xavier)的numpy实现以及表现对比

本文通过使用Numpy在MNIST数据集上实验了不同的权重初始化方法对多层感知机(MLP)网络的影响,包括zeros、ones、normal、xavier_normal等,并对比了不同激活函数下的网络表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Numpy实现

if self.initialization == 'zeros':
    self.W[layer] = np.zeros([out_dim, in_dim])
    self.b[layer] = np.zeros([out_dim])
elif self.initialization == 'ones':
    self.W[layer] = np.ones([out_dim, in_dim])
    self.b[layer] = np.ones([out_dim])
elif self.initialization == 'normal':
    self.W[layer] = np.random.normal(loc=0., scale=1., size=[out_dim, in_dim])
    self.b[layer] = np.random.normal(loc=0., scale=1., size=[out_dim])
elif self.initialization == 'xavier_Glorot_normal':
    self.W[layer] = np.random.normal(loc=0., scale=1., size=[out_dim, in_dim]) / np.sqrt(in_dim)
    self.b[layer] = np.random.normal(loc=0., scale=1., size=[out_dim]) / np.sqrt(in_dim)
elif self.initialization == 'xavier_normal':
    std = np.sqrt(2. / (in_dim + out_dim))
    self.W[layer] = np.random.normal(loc=0., scale=std, size=[out_dim, in_dim])
    self.b[layer] = np.random.normal(loc=0., scale=std, size=[out_dim])
elif self.initialization == 'uniform':
    a = np.sqrt(1. / in_dim)
    self.W[layer] = np.random.uniform(low=-a, high=a, size=[out_dim, in_dim])
    self.b[layer] = np.random.uniform(low=-a, high=a, size=[out_dim])
elif self.initialization == 'xavier_uniform':
    a = np.sqrt(6. / (in_dim + out_dim))
    self.W[layer] = np.random.uniform(low=-a, high=a, size=[out_dim, in_dim])
    self.b[layer] = np.random.uniform(low=-a, high=a, size=[out_dim])
else:
    print("initialization error!")
    exit(1)

表现对比

Mnist数据集 input_feature_dim=784(28*28)

MLP-64-64-softmax网络(自己用numpy搭建的,可能有问题)

SGD优化方法 batch_size=128 max_epoch=100 lr=0.05 

以下数值为test set上的accuracy

需要注意的是:只跑了100个epoch(100*128=12800个shuffled training samples)

 

zeros

ones

normal

xavier_Glorot

xavier_normal

uniform

xavier_uniform

sigmoid

not convergence

not convergence

0.838

0.756

0.623

0.347

0.645

relu

not convergence

not convergence

not convergence

0.895

0.895

0.881

0.896


参考:

神经网络参数初始化 xavier_Glorot

https://blog.youkuaiyun.com/qq_26972735/article/details/81984111

初始化函数 uniform, normal, const, Xavier, He initialization

https://blog.youkuaiyun.com/dss_dssssd/article/details/83959474

常用权重初始化方法Xavier,He initialization的推导

https://xubin.blog.youkuaiyun.com/article/details/107890916

### 定义神经网络可见层和隐藏层神经元数量的最佳实践 在设计神经网络时,定义可见层(即输入层)和隐藏层的神经元数量是一个重要的决策。通常情况下: - **输入层神经元的数量**取决于输入数据的维度。例如,如果是图像分类任务,输入层的神经元数量等于图像像素总数乘以通道数(RGB)。对于其他类型的输入数据,输入层神经元数量应匹配特征向量的长度[^1]。 - **隐藏层神经元的数量**则没有固定的规则,但有一些经验法则可以帮助指导选择: - 隐藏层神经元的数量一般介于输入层和输出层神经元数量之间。 - 如果模型欠拟合,可以尝试增加隐藏层神经元的数量;如果过拟合,则减少其数量。 - 使用交叉验证技术评估不同的配置,找到最佳的隐藏层规模[^2]。 ### 连接权重初始化方法的选择 连接权重的初始化神经网络的训练效果至关重要。以下是几种常见的初始化方法及其适用场景: #### 1. 高斯分布初始化 这种方法从具有零均值和小标准差的正态分布中抽取权重值。它适用于浅层网络,但对于深层网络可能会导致梯度消失或爆炸问题[^3]。 ```python import numpy as np weights = np.random.normal(loc=0.0, scale=0.01, size=(input_dim, hidden_dim)) ``` #### 2. 均匀分布初始化 在这种方法中,权重是从一个指定范围内的均匀分布中随机采样得到的。该方法同样适合较简单的网络结构[^3]。 ```python weights = np.random.uniform(low=-r, high=r, size=(input_dim, hidden_dim)) ``` #### 3. Xavier/Glorot 初始化 Xavier 初始化旨在使每一层的激活值和梯度的方差保持一致,特别适合使用 Sigmoid 或 Tanh 激活函数的网络。具体实现如下[^3]: ```python from tensorflow.keras import initializers initializer = initializers.GlorotNormal() # 或 GlorotUniform() weights = initializer(shape=(input_dim, hidden_dim)) ``` #### 4. He 初始化 He 初始化针对 ReLU 和类似的非线性激活函数进行了优化,能够有效缓解梯度消失问题。它的核心思想是根据前一层神经元的数量调整权重的标准差。 ```python initializer = initializers.HeNormal() # 或 HeUniform() weights = initializer(shape=(input_dim, hidden_dim)) ``` #### 5. 其他特殊初始化方式 某些特定应用可能需要更复杂的初始化策略,例如预设部分权重为常数值或者引入外部知识来引导初始权值分配[^4]。 ### 注意事项 无论选用哪种初始化方案,都应该避免将所有权重统一设定为相同的值(如全零),因为这会导致所谓的“对称破环”问题,阻碍有效的学习过程发生[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值