如何固定Conv2D初始核、查看核张量及种子设置疑问?
解决Conv2D固定初始化核及查看核张量的问题
一、让Conv2D每次初始化用相同核集合
方法1:复用带固定种子的初始化器实例
不要在循环内重复创建初始化器,把初始化器定义在循环外,确保每次创建Conv2D时使用同一个初始化器对象,避免TensorFlow全局随机状态干扰:
import tensorflow as tf from tensorflow.keras.layers import Conv2D import matplotlib.pyplot as plt # 初始化器定义在循环外,固定种子 fixed_init = tf.keras.initializers.RandomNormal(seed=42) kernel_values = [] for _ in range(100): conv = Conv2D(filters=1, kernel_size=(1,1), kernel_initializer=fixed_init) # 传入dummy输入触发层初始化 conv(tf.random.normal((1,1,1,1))) # 提取核的数值 kernel_val = conv.get_weights()[0].flatten()[0] kernel_values.append(kernel_val) plt.plot(kernel_values) plt.show()
方法2:用固定张量作为核(最稳妥)
提前生成固定的核张量,用Constant初始化器,确保每次初始化完全一致:
import tensorflow as tf from tensorflow.keras.layers import Conv2D import matplotlib.pyplot as plt # 生成固定的1x1核张量 fixed_kernel = tf.random.normal((1,1,1,1), seed=42) fixed_init = tf.keras.initializers.Constant(fixed_kernel) kernel_values = [] for _ in range(100): conv = Conv2D(filters=1, kernel_size=(1,1), kernel_initializer=fixed_init) conv(tf.random.normal((1,1,1,1))) kernel_val = conv.get_weights()[0].flatten()[0] kernel_values.append(kernel_val) plt.plot(kernel_values) plt.show()
问题原因解释
你之前的代码每次循环都新建RandomNormal(seed=42),虽然种子相同,但TensorFlow的全局随机状态会在每次初始化后更新,导致生成的随机数不同。复用初始化器或用固定张量就能避免这个问题。
二、查看Conv2D的核张量
Keras层是延迟初始化的,必须先传入输入触发权重创建,之后通过以下方式获取核:
- 通过
kernel属性直接获取:
conv = Conv2D(filters=3, kernel_size=(3,3), input_shape=(28,28,1)) # 传入dummy输入初始化权重 conv(tf.random.normal((1,28,28,1))) # 获取核张量的numpy数值 print("核形状:", conv.kernel.shape) print("核数值:\n", conv.kernel.numpy())
- 通过
get_weights()方法获取:
weights = conv.get_weights() # weights[0]是核张量,weights[1]是偏置(如果启用的话) kernel = weights[0] print("核数值:\n", kernel)
内容的提问来源于stack exchange,提问作者user385323
相关产品推荐
相关产品推荐

