Keras中如何实现符合框架规范的自定义kernel_initializer方法
Keras实现自定义核初始化的方法
Keras对传入kernel_initializer的对象有明确的接口要求:只要是接收权重形状shape、**权重数据类型dtype**两个入参,返回形状与shape完全一致、数据类型匹配dtype的张量/数组的可调用对象,都可以作为合法的初始化器使用。
基础实现方式(无参数自定义初始化)
直接定义符合接口要求的函数即可,传参时直接传入函数对象,不要加括号提前调用:
- 函数第一个入参:框架自动传入的当前层权重张量的形状,比如输入维度30、输出维度20的Dense层,kernel的shape就是
(30,20) - 函数第二个入参:框架自动传入的权重要求的数据类型,一般为float32
- 返回值:和shape尺寸完全匹配的初始化数值,支持numpy数组、TensorFlow张量
示例代码:
import numpy as np import tensorflow as tf def my_custom_initialization(shape, dtype=None): # 此处可替换为任意自定义初始化规则 # 示例1:[-0.07, 0.07]范围均匀分布初始化 init_arr = np.random.uniform(low=-0.07, high=0.07, size=shape) # 示例2:均值0、标准差0.06的正态分布初始化 # init_arr = np.random.normal(loc=0, scale=0.06, size=shape) # 示例3:全0初始化/自定义固定值初始化 # init_arr = np.zeros(shape=shape) return tf.convert_to_tensor(init_arr, dtype=dtype) # 传参时直接写函数名,不要加括号 model.add(Dense(units=20, activation='relu', kernel_initializer=my_custom_initialization))
带参数的自定义初始化(匹配预期传参形式)
如果需要灵活调整初始化的参数(比如自定义均匀分布的上下界),可以写工厂闭包函数,调用后返回符合接口要求的初始化函数,这时候就可以用函数名(参数)的形式传参:
def custom_uniform_init(low=-0.1, high=0.1, seed=42): # 内部定义符合Keras接口要求的初始化函数 def _init(shape, dtype=None): rng = np.random.default_rng(seed) init_arr = rng.uniform(low=low, high=high, size=shape) return tf.convert_to_tensor(init_arr, dtype=dtype) return _init # 传参时可以自定义参数 model.add(Dense( units=20, activation='relu', kernel_initializer=custom_uniform_init(low=-0.05, high=0.05) ))
可直接运行的完整修改示例
基于提供的乳腺癌分类代码,替换为自定义初始化后的完整代码如下:
import numpy as np import keras from keras.models import Sequential from keras.layers import Dense from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split import tensorflow as tf # 定义自定义初始化 def my_custom_initialization(shape, dtype=None): # 这里替换成自己的初始化逻辑即可 return tf.random.uniform(shape=shape, minval=-0.08, maxval=0.08, dtype=dtype) X,y = load_breast_cancer(return_X_y =True) X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=1) model = Sequential() model.add(Dense(units=30,input_dim=X_train.shape[1],activation='relu',kernel_initializer=my_custom_initialization)) model.add(Dense(units=20,activation='relu',kernel_initializer=my_custom_initialization)) model.add(Dense(units=1,activation='sigmoid',kernel_initializer=my_custom_initialization)) model.compile(optimizer='sgd',loss='binary_crossentropy',metrics=['accuracy']) model.fit(X_train,y_train,validation_data=(X_test,y_test),epochs=200,batch_size=40,verbose=1)
注意事项
- 自定义函数返回的数组/张量形状必须和入参
shape完全一致,否则会触发形状不匹配报错 - 如果需要复现实验结果,记得在初始化逻辑里固定随机种子,同时全局固定numpy、TensorFlow的随机种子
- 复杂初始化场景可以继承
tf.keras.initializers.Initializer基类实现类形式的初始化器,简单场景用函数即可满足需求
内容的提问来源于stack exchange,提问作者user466534
相关产品推荐
相关产品推荐

