如何在TensorFlow中随机初始化权重?含CNN层场景解决方案
解决TensorFlow预定义CNN层的权重随机初始化问题
先给你理清两个关键点:
- 默认初始化不是0:你用的
tf.layers.conv2d默认采用的是glorot_uniform_initializer(Xavier均匀初始化),会根据层的输入输出维度生成随机权重,不是固定的0值。 - 初始损失相同的原因:TensorFlow的随机数生成器默认会使用固定的初始种子,导致每次启动会话后,权重初始化的随机值完全一致,所以初始损失没变化。
接下来针对你的CNN代码,给预定义层指定自定义随机初始化器非常简单——tf.layers.conv2d提供了kernel_initializer参数,直接传入你想要的初始化器即可。
常用的随机初始化器选项
- He初始化:特别适合搭配ReLU激活函数(你的网络正好用了ReLU),有正态和均匀两种:
tf.initializers.he_normal()、tf.initializers.he_uniform() - 正态分布初始化:
tf.random_normal_initializer(mean=0.0, stddev=0.01),可以自定义均值和标准差 - 均匀分布初始化:
tf.random_uniform_initializer(minval=-0.1, maxval=0.1),指定随机值的范围 - 如果你想保留默认的Xavier初始化,但希望每次运行的初始权重不同,只需要设置不同的随机种子即可
修改你的代码示例
这里给你示范两种不同的初始化方式,分别应用到conv1和conv2层:
# 定义He正态初始化器,可选设置种子(设置后每次初始化的随机值固定;不设则每次运行随机) he_normal_init = tf.initializers.he_normal(seed=42) conv1 = tf.layers.conv2d( inputs=input_layer, filters=32, kernel_size=[3,3], padding="same", activation=tf.nn.relu, name="conv_chad_1", kernel_initializer=he_normal_init # 给conv1指定He初始化 ) pool1 = tf.layers.max_pooling2d(inputs=conv1,pool_size=[2,2],strides=2) # 给conv2用均匀分布初始化,自定义取值范围 conv2 = tf.layers.conv2d( inputs=pool1, filters=64, kernel_size=[3,3], padding="same", activation=tf.nn.relu, name="conv_chad_2", kernel_initializer=tf.random_uniform_initializer(minval=-0.05, maxval=0.05, seed=123) ) pool2 = tf.layers.max_pooling2d(inputs=conv2,pool_size=[2,2],strides=2, name="pool_chad_2")
让每次运行的初始权重都不同的小技巧
如果你希望每次启动程序时,初始化的权重都不一样,可以在代码开头设置全局随机种子为当前时间戳(TensorFlow 1.x版本):
import tensorflow as tf import time tf.set_random_seed(int(time.time()))
这样每次运行时,随机数生成器的初始状态都会变化,权重初始化的结果也就不同了,初始损失值自然会有差异。
另外,如果你想验证权重的初始化结果,可以用以下代码获取指定层的权重变量:
conv1_weights = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope="conv_chad_1") print(sess.run(conv1_weights))
内容的提问来源于stack exchange,提问作者kwagjj
相关产品推荐
相关产品推荐

