我想写一个自定义图层,我可以在运行之间在内存中保留一个变量.例如,
class MyLayer(Layer): def __init__(self, out_dim = 51, **kwargs): self.out_dim = out_dim super(MyLayer, self).__init__(**kwargs) def build(self, input_shape): a = 0.0 self.persistent_variable = K.variable(a) self.built = True def get_output_shape_for(self, input_shape): return (input_shape[0], 1) def call(self, x, mask=None): a = K.eval(self.persistent_variable) + 1 K.set_value(self.persistent_variable, a) return self.persistent_variable m = Sequential() m.add(MyLayer(input_shape=(1,)))
当我运行时m.predict
,我希望persistent_variable
更新,并打印增量值.但它看起来总是打印出来0
# Dummy input x = np.zeros(1) m.predict(x, batch_size=1)
我的问题是,如何persistent_variable
在每次运行后进行增量和保存m.predict
谢谢,Naveen
诀窍是你必须调用self.add_update(...)
你的调用函数来注册一个函数,每次你的模型被评估时都会被调用(我通过挖掘有状态rnns的源代码来找到它).如果您这样做self.stateful = True
,将为每个训练和预测呼叫调用您的自定义更新功能,否则它将仅在训练期间调用它.例如:
import keras.backend as K import numpy as np from keras.engine.topology import Layer class CounterLayer(Layer): def __init__(self, stateful=False,**kwargs): self.stateful = stateful # True means it will increment counter on predict and train, false means it will only increment counter on train super(CounterLayer, self).__init__(**kwargs) def build(self, input_shape): # Define variables in build self.count = K.variable(0, name="count") super(CounterLayer, self).build(input_shape) def call(self, x, mask=None): updates = [] # The format is (variable, value setting to) # So this says # self.pos = self.pos + 1 updates.append((self.count, self.count+1)) # You can append more updates to this list or call add_update more # times if you want # Add our custom update # We stick x here so it calls our update function every time our layer # is given a new x self.add_update(updates, x) # This will be an identity layer but keras gets mad for some reason # if you just output x so we'll multiply it by 1 so it thinks it is a # "new variable" return self.count # in newer keras versions you might need to name this compute_output_shape instead def get_output_shape_for(self, input_shape): # We will just return our count as an array ([[count]]) return (1,1) def reset_states(self): self.count.set_value(0)
用法示例:
from keras.layers import Input from keras.models import Model from keras.optimizers import RMSprop inputLayer = Input(shape=(10,)) counter = CounterLayer() # Don't update on predict # counter = CounterLayer(stateful=True) # This will update each time you call predict counterLayer = counter(inputLayer) model = Model(input=inputLayer, output=counterLayer) optimizer = RMSprop(lr=0.001) model.compile(loss="mse", optimizer=optimizer) # See the value of our counter print counter.count.get_value() # This won't actually train anything but each epoch will update our counter # Note that if you say have a batch size of 5, update will be called 5 times per epoch model.fit(np.zeros([1, 10]), np.array([0]), batch_size=1, nb_epoch=5) # The value of our counter has now changed print counter.count.get_value() model.predict(np.zeros([1, 10])) # If we did stateful=False, this didn't change, otherwise it did print counter.count.get_value()