Python 具有每次迭代更新的活动正则化器的KERA
我正在使用Keras构建一个简单的神经网络。它具有活动正则化,因此唯一隐藏层的输出必须具有较小的值。代码如下:Python 具有每次迭代更新的活动正则化器的KERA,python,python-3.x,tensorflow,keras,neural-network,Python,Python 3.x,Tensorflow,Keras,Neural Network,我正在使用Keras构建一个简单的神经网络。它具有活动正则化,因此唯一隐藏层的输出必须具有较小的值。代码如下: import numpy as np import math import keras from keras.models import Model, Sequential from keras.layers import Input, Dense, Activation from keras import regularizers from keras import backend
import numpy as np
import math
import keras
from keras.models import Model, Sequential
from keras.layers import Input, Dense, Activation
from keras import regularizers
from keras import backend as K
a=1
def my_regularizer(inputs):
means=K.mean((inputs),axis=1)
return a*K.sum(means)**2
x_train=np.random.uniform(low=-1,high=1,size=(200,2))
model=Sequential([
Dense(20,input_shape=(2,),activity_regularizer=my_regularizer),
Activation('tanh'),
Dense(2,),
Activation('linear')
])
model.compile(optimizer='adam',loss='mean_squared_error')
model.fit(x_train,x_train,epochs=20,validation_split=0.1)
问题:
1) 目前,参数a是在开始时设置的,不会更改。如何更改代码,以便在每次迭代后更新参数a,从而
a_new=f(a_old,输入)
其中输入为隐藏层的值,f(.)为任意函数
2) 我希望在应用第一个激活函数tanh之后应用活动正则化器。我的代码写对了吗?术语“活动\正则化器=我的\正则化器”
使我感觉正则化器正在应用于激活函数tanh之前的值。您可以-但首先,您需要一个有效的Keras
正则化器对象(您的函数将不起作用):
类MyActivityRegularizer(正则化器):
定义初始化(self,a=1):
self.a=K.variable(a,name='a')
#在每次序列迭代时调用
def u调用(self,x):#这里是您的自定义函数
平均值=K.平均值(x,轴=1)
返回自加总(平均值)**2
def get_config(self):#必需的类方法
返回{“a”:float(K.get_值(self.a))}
接下来,要使用.fit
,您需要一个自定义Keras回调
对象(请参见底部的备选方案):
class ActivityRegularizerScheduler(回调):
完成时,.fit会自动调用“在批处理结束时”
迭代批处理。模型及其属性由
“回调”(除了在_uinit__;处),可通过例如self.model访问“”
定义初始(自我、模型、更新):
self.update\u fn=update\u fn
self.activity\u正则化器=\u get\u activity\u正则化器(模型)
批处理端上的def(自身、批处理、日志=无):
迭代=K.get_值(self.model.optimizer.iterations)
新建活动\u reg=self.update\u fn(迭代)
#“活动正则化器”引用模型层的活动正则化器(在此
#大小写为'MyActivityRegularizer'),因此可以直接设置其属性('a')
对于self.activity\u正则化器中的activity\u正则化器:
K.设置值(活动正则化器a,新活动正则化器)
定义获取活动正则化器(模型):
活动\正则化器=[]
对于model.layers中的图层:
a_reg=getattr(层,'activity_regulazer',无)
如果某个_reg不是无:
活动\u正则化器.附加(a\u reg)
返回活动正则化器
最后,您需要在KerasCustomObjectScope
中创建您的模型-请参见下面的完整示例。
示例用法:
from keras.layers import Dense
from keras.models import Sequential
from keras.regularizers import Regularizer
from keras.callbacks import Callback
from keras.utils import CustomObjectScope
from keras.optimizers import Adam
import keras.backend as K
import numpy as np
def make_model(my_reg):
return Sequential([
Dense(20, activation='tanh', input_shape=(2,), activity_regularizer=my_reg),
Dense(2, activation='linear'),
])
要跟踪您的a
并确保它在变化,您可以通过以下方式获取其值,例如,在每个历元结束时:
for epoch in range(4):
model.fit(x,y,batch_size=32,callbacks=[activity_regularizer_scheduler],epochs=1)
print("Epoch {} activity_regularizer 'a': {}".format(epoch,
K.get_value(_get_activity_regularizers(model)[0].a)))
# My output:
# Epoch 0 activity_regularizer 'a': 0.7190816402435303
# Epoch 1 activity_regularizer 'a': 0.4982417821884155
# Epoch 2 activity_regularizer 'a': 0.2838689386844635
# Epoch 3 activity_regularizer 'a': 0.8644570708274841
关于(2),恐怕你是对的-不会使用'tanh'
输出;您需要通过activation='tanh'
。
最后,您可以通过train\u on\u batch
,无需回调即可完成此操作,但缺点是,您需要自己将数据提供给模型(并将其洗牌,等等):
非常感谢。你能回答我上面写的第二个问题吗?@Sus20200已经-而且,使用最新的代码-我再次改进了回调的运行时性能。您能告诉我如何通过激活tanh吗?@Sus20200就像我在上面的def make_model
中一样谢谢您的回答。很好。
my_reg = MyActivityRegularizer(a=1)
with CustomObjectScope({'MyActivityRegularizer':my_reg}): # required for Keras to recognize
model = make_model(my_reg)
opt = Adam(lr=1e-4)
model.compile(optimizer=opt, loss='mse')
x = np.random.randn(320,2) # dummy data
y = np.random.randn(320,2) # dummy labels
update_fn = lambda x: .5 + .4*np.cos(x) #x = number of train updates (optimizer.iterations)
activity_regularizer_scheduler = ActivityRegularizerScheduler(model, update_fn)
model.fit(x,y,batch_size=32,callbacks=[activity_regularizer_scheduler],
epochs=4,verbose=1)
for epoch in range(4):
model.fit(x,y,batch_size=32,callbacks=[activity_regularizer_scheduler],epochs=1)
print("Epoch {} activity_regularizer 'a': {}".format(epoch,
K.get_value(_get_activity_regularizers(model)[0].a)))
# My output:
# Epoch 0 activity_regularizer 'a': 0.7190816402435303
# Epoch 1 activity_regularizer 'a': 0.4982417821884155
# Epoch 2 activity_regularizer 'a': 0.2838689386844635
# Epoch 3 activity_regularizer 'a': 0.8644570708274841
activity_regularizers = _get_activity_regularizers(model)
for iteration in range(100):
x, y = get_data()
model.train_on_batch(x,y)
iteration = K.get_value(model.optimizer.iterations)
for activity_regularizer in activity_regularizers:
K.set_value(activity_regularizer, update_fn(iteration))