python - 如何在keras中存储每个时代的操作结果(如TOPK)
问题描述
我在 keras 中编写了一个自定义层。在这个自定义层的一部分可以说我有一个这样的矩阵:
c = tf.cast(tf.nn.top_k(tf.nn.top_k(n, tf.shape(n)[1])[1][:, ::-1], tf.shape(n)[1])[1][:, ::-1], dtype=tf.float32)
我的问题是如何跟踪每个时代的结果值?
例如,如果我有 20 个 epoch,我需要将 20 个这个矩阵保存在一个csv
文件中。
(我知道如何保存模型的权重,但是这个是中间层操作的结果,我需要跟踪这个矩阵)。
我做了什么:
这是我的层的结构:
class my_layer(Layer):
def __init__(self, topk, ctype, **kwargs):
self.x_prev = None
self.topk_mat = None
def call(self, x):
'blah blah'
def get_config(self):
'blah blah'
def k_comp_tanh(self,x, f=6):
'blah blah'
if self.topk_mat is None:
self.topk_mat = self.add_weight(shape=(20, 25),
initializer='zeros',
trainable=False,
# dtype=tf.float32,
name='topk_mat')
c = tf.cast(tf.nn.top_k(tf.nn.top_k(n, tf.shape(n)[1])[1][:, ::-1], tf.shape(n)[1])[1][:, ::-1], dtype=tf.float32)
self.topk_mat.assign(c)
用于构建模型和拟合数据的代码:
class AutoEncoder(object):
def __init__(self, input_size, dim, comp_topk=None, ctype=None, save_model='best_model'):
self.input_size = input_size
self.dim = dim
self.comp_topk = comp_topk
self.ctype = ctype
self.save_model = save_model
self.build()
def build(self):
input_layer = Input(shape=(self.input_size,))
encoded_layer = Dense(self.dim, activation=act, kernel_initializer="glorot_normal", name="Encoded_Layer")
encoded = encoded_layer(input_layer)
encoder_model = Model(outputs=encoded, inputs=input_layer)
encoder_model.save('pathto/encoder_model')
self.encoded_instant = my_layer(self.comp_topk, self.ctype)
encoded = self.encoded_instant(encoded)
decoded = Dense_tied(self.input_size, activation='sigmoid',tied_to=encoded_layer, name='Decoded_Layer')(encoded)
# this model maps an input to its reconstruction
self.autoencoder = Model(outputs=decoded, inputs=input_layer)
# this model maps an input to its encoded representation
self.encoder = Model(outputs=encoded, inputs=input_layer)
# create a placeholder for an encoded input
encoded_input = Input(shape=(self.dim,))
# retrieve the last layer of the autoencoder model
decoder_layer = self.autoencoder.layers[-1]
# create the decoder model
self.decoder = Model(outputs=decoder_layer(encoded_input), inputs=encoded_input)
def fit(self, train_X, val_X, nb_epoch=50, batch_size=100, contractive=None):
import tensorflow as tf
optimizer = Adam(lr=0.0005)
self.autoencoder.compile(optimizer=optimizer, loss='binary_crossentropy') # kld, binary_crossentropy, mse
cbk = tf.keras.callbacks.LambdaCallback(
on_epoch_begin=lambda epoch, logs: np.savetxt("foo.csv", tf.keras.backend.eval(self.encoded_instant.topk_mat), delimiter=","))
self.autoencoder.fit(train_X[0], train_X[1],
epochs=nb_epoch,
batch_size=batch_size,
shuffle=True,
validation_data=(val_X[0], val_X[1]),
callbacks=[
ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, min_lr=0.01),
EarlyStopping(monitor='val_loss', min_delta=1e-5, patience=5, verbose=1, mode='auto'),
cbk,
save_best_only=True, mode='auto')
CustomModelCheckpoint(custom_model=self.encoder, filepath="pathtocheckpoint/{epoch}.hdf5",save_best_only=True, monitor='val_loss', mode='auto')
]
)
return self
cbk = tf.keras.callbacks.LambdaCallback(
on_epoch_begin=lambda epoch, logs: np.savetxt("mycsvtopk.csv", tf.keras.backend.eval(my_layer.topk_mat, delimiter=",")))
)
self.autoencoder.fit(train_X[0], train_X[1],
epochs=nb_epoch,
batch_size=batch_size,
shuffle=True,
validation_data=(val_X[0], val_X[1]),
callbacks=[cbk,CustomModelCheckpoint(custom_model=self.encoder, filepath="path_to_file/{epoch}.hdf5",save_best_only=True, monitor='val_loss', mode='auto')
]
)
这就是我给Autoencoder
班级打电话的地方
ae = AutoEncoder(n_vocab, args.n_dim, comp_topk=args.comp_topk, ctype=args.ctype, save_model=args.save_model)
ae.fit([X_train_noisy, X_train], [X_val_noisy, X_val], nb_epoch=args.n_epoch, \
batch_size=args.batch_size, contractive=args.contractive)
它引发错误:
tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value mylayer_1/topk_mat
[[{{node _retval_mylayer_1/topk_mat_0_0}} = _Retval[T=DT_FLOAT, index=0, _device="/job:localhost/replica:0/task:0/device:CPU:0"](mylayer_1/topk_mat)]]
Exception TypeError: TypeError("'NoneType' object is not callable",) in <bound method Session.__del__ of <tensorflow.python.client.session.Session object at 0x7f56ae01bc50>> ignored
我在 CustomCallback 中看到的所有示例都与模型已经知道的度量有关,例如损失、准确性……我上面基于@Jhadi 的想法所做的是将结果保存在一个最初用 None 初始化的变量中,并且然后在拟合部分传递此变量以将其保存为 csv 格式。尽管我收到此错误并且尝试了多种方法来修复它但没有成功,但这似乎必须起作用。在我看来,它就像一个Keras library issue
.
解决方案
我认为您可以使用列表跟踪 Checkpoint保存变量。
您需要在训练中添加代码,因此您需要编写训练循环并在每个时期结束时保存变量。
def fit_and_save_log(self, train_X, val_X, nb_epoch=50, batch_size=100, contractive=None):
import tensorflow as tf
optimizer = Adam(lr=0.0005)
self.autoencoder.compile(optimizer=optimizer, loss='binary_crossentropy') # kld, binary_crossentropy, mse
save = tf.train.Checkpoint()
save.listed = []
# Prepare dataset
X, y = train_X
train_ds = tf.data.Dataset.from_tensor_slices((x, y))
train_ds = train_ds.shuffle(10000)
train_ds = train_ds.batch(batch_size)
iterator = train_ds.make_initializable_iterator()
next_batch = iterator.get_next()
for epoch in range(nb_epoch):
sess.run(iterator.initializer)
while True:
try:
self.autoencoder.train_on_batch(next_batch[0], next_batch[1])
except tf.errors.OutOfRangeError:
break
save.listed.append(self.encoded_instant.topk_mat)
# you can compute validation results here
save_path = save.save('./topk_mat_log', session=tf.keras.backend.get_session())
return self
或者,model.fit
如果您愿意,也可以使用该功能。这样做会更容易,因为我们不需要关心创建批次。但是,重复调用model.fit
可能会导致内存泄漏。您可以试一试并检查它的行为方式。[1]
def fit_and_save_log(self, train_X, val_X, nb_epoch=50, batch_size=100, contractive=None):
import tensorflow as tf
optimizer = Adam(lr=0.0005)
self.autoencoder.compile(optimizer=optimizer, loss='binary_crossentropy') # kld, binary_crossentropy, mse
save = tf.train.Checkpoint()
save.listed = []
for epoch in range(nb_epoch):
self.autoencoder.fit(train_X[0], train_X[1],
epochs=1,
batch_size=batch_size,
shuffle=True,
validation_data=(val_X[0], val_X[1]))
save.listed.append(self.encoded_instant.topk_mat)
# you can compute validation results here
save_path = save.save('./topk_mat_log', session=tf.keras.backend.get_session())
return self
然后你可以像这样恢复保存的变量
restore = tf.train.Checkpoint()
restore.restore(save_path)
restore.listed = []
v1 = tf.Variable(0.)
restore.listed.append(v1) # Now v1 corresponds with topk_mat in the first epoch
推荐阅读
- javascript - 这个异常是如何处理的?(在 Promise 中的回调中抛出)
- laravel - Laravel 5.7 不发送验证电子邮件
- unity3d - Unity Build 安装但导致黑屏
- mysql - 常规日志不显示/记录更改
- php - Isset 检查 Array - Blade Laravel 5.8
- slider - 如何摆脱 Vuetify 滑块中的消息区域?
- azure - 来自 Salesforce 的 Azure 数据工厂管道,在接收器映射中添加时间戳
- javascript - 事件侦听器不会触发 JavaScript 上动态创建的元素
- spring - 使用 Docker 部署 Spring 和 MySQL 应用程序失败
- c# - Blazor 服务器端应用程序 api 请求问题 httpClient.PostAsync IHttpClientFactory