如何将每个时期的张量值保存在一层中并将其传递给tensorflow中的下一个时期
how to keep the values of tensors in each epoch in one layer and pass it to Next epoch in tensorflow
我有一个一般性问题。
我正在开发一个新层以合并到自动编码器中。更具体地说,该层类似于 KCompetitive
class over here。我想要的是我需要将这一层的输出保存在一个变量中,我们称之为 previous_mat_values
,然后在下一个时期也将它传递给同一层。
换句话说,我希望能够将 epoch 1
这一层的输出保存在一个变量中,然后在 epoch 2
中再次使用相同的矩阵。
所以问题出现了,这个矩阵在第一个时期的值是多少,因为它还没有那个层的输出。我们可以初始化一个与权重矩阵形状相同但值为 0
的数组,我会这样做。
previous_mat_values = tf.zeros_like(weight_tensor)
所以步骤是这样的:
在第一个epoch中,previous_mat_values
和weight_mat
会传给layer
1.a那层函数的最后,我们称之为modified_weight_mat
的最终值会存入previous_mat_values
previous_mat_values = modified_weight_mat
在第二个 epoch 中,previous_mat_values
和 weight_mat
将传递给该层,但是,previous_mat_values
具有在第一个 epoch 中保存的值。
我通过 weight_mat
并做与此相关的事情没有任何问题。这里唯一的问题是我们如何在每个 epoch 中保存 previous_mat_values
的值并将其传递给下一个 epoch。
我想在 class of that layer
中创建一个全局张量变量并将其初始化为零,但我认为将前一个时期的值保留到第二个时期没有帮助。
你知道我该如何实现吗?
如果我的解释不清楚,请告诉我。
更新 1:
这是层的实现:
class KCompetitive(Layer):
'''Applies K-Competitive layer.
# Arguments
'''
def __init__(self, topk, ctype, **kwargs):
self.topk = topk
self.ctype = ctype
self.uses_learning_phase = True
self.supports_masking = True
super(KCompetitive, self).__init__(**kwargs)
def call(self, x):
if self.ctype == 'ksparse':
return K.in_train_phase(self.kSparse(x, self.topk), x)
elif self.ctype == 'kcomp':
return K.in_train_phase(self.k_comp_tanh(x, self.topk), x)
else:
warnings.warn("Unknown ctype, using no competition.")
return x
def get_config(self):
config = {'topk': self.topk, 'ctype': self.ctype}
base_config = super(KCompetitive, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def k_comp_tanh(self, x, topk, factor=6.26):
###Some modification on x so now the x becomes
x= x+1
res = x
return res
更新 2
为了进一步说明,我将添加:
数据样本 1:
x_prev = zero
mask = tf.greate(x, x_prev) # x here related to sample 1
x_modified = x[mask]
x_prev = x_modified
数据样本2:
mask = tf.greater(x, x_prev) # x here related to sample 2 and
x_prev is from previous sample
x_modified = x[mask]
x_prev = x_modified
我不确定这是否是你的意思,但你可以在你的层中有一个变量,它在每个训练步骤中简单地使用另一个变量的先前值进行更新,大致如下:
import tensorflow as tf
class MyLayer(tf.keras.layers.Layer):
def __init__(self, units, **kwargs):
super(MyLayer, self).__init__(**kwargs)
self.units = units
def build(self, input_shape):
self.w = self.add_weight(shape=(input_shape[-1], self.units),
initializer='random_normal',
trainable=self.trainable,
name='W')
self.w_prev = self.add_weight(shape=self.w.shape,
initializer='zeros',
trainable=False,
name='W_prev')
def call(self, inputs, training=False):
# Only update value of w_prev on training steps
deps = []
if training:
deps.append(self.w_prev.assign(self.w))
with tf.control_dependencies(deps):
return tf.matmul(inputs, self.w)
这是一个用法示例:
import tensorflow as tf
import numpy as np
tf.random.set_seed(0)
np.random.seed(0)
# Make a random linear problem
x = np.random.rand(50, 3)
y = x @ np.random.rand(3, 2)
# Make model
model = tf.keras.Sequential()
my_layer = MyLayer(2, input_shape=(3,))
model.add(my_layer)
model.compile(optimizer='SGD', loss='mse')
# Train
cbk = tf.keras.callbacks.LambdaCallback(
on_batch_begin=lambda batch, logs: (tf.print('batch:', batch),
tf.print('w_prev:', my_layer.w_prev, sep='\n'),
tf.print('w:', my_layer.w, sep='\n')))
model.fit(x, y, batch_size=10, epochs=1, verbose=0, callbacks=[cbk])
输出:
batch: 0
w_prev:
[[0 0]
[0 0]
[0 0]]
w:
[[0.0755531341 0.0211461019]
[-0.0209847465 -0.0518018603]
[-0.0618413948 0.0235136505]]
batch: 1
w_prev:
[[0.0755531341 0.0211461019]
[-0.0209847465 -0.0518018603]
[-0.0618413948 0.0235136505]]
w:
[[0.0770048052 0.0292659812]
[-0.0199236758 -0.04635958]
[-0.060054455 0.0332755931]]
batch: 2
w_prev:
[[0.0770048052 0.0292659812]
[-0.0199236758 -0.04635958]
[-0.060054455 0.0332755931]]
w:
[[0.0780589 0.0353098139]
[-0.0189863108 -0.0414136574]
[-0.0590113513 0.0387929156]]
batch: 3
w_prev:
[[0.0780589 0.0353098139]
[-0.0189863108 -0.0414136574]
[-0.0590113513 0.0387929156]]
w:
[[0.0793346688 0.042034667]
[-0.0173048507 -0.0330933407]
[-0.0573575757 0.0470812619]]
batch: 4
w_prev:
[[0.0793346688 0.042034667]
[-0.0173048507 -0.0330933407]
[-0.0573575757 0.0470812619]]
w:
[[0.0805450454 0.0485667922]
[-0.0159637 -0.0261840075]
[-0.0563304275 0.052557759]]
编辑:我仍然不是 100% 确定你需要它如何工作,但这里有一些可能对你有用:
import tensorflow as tf
class KCompetitive(Layer):
'''Applies K-Competitive layer.
# Arguments
'''
def __init__(self, topk, ctype, **kwargs):
self.topk = topk
self.ctype = ctype
self.uses_learning_phase = True
self.supports_masking = True
self.x_prev = None
super(KCompetitive, self).__init__(**kwargs)
def call(self, x):
if self.ctype == 'ksparse':
return K.in_train_phase(self.kSparse(x, self.topk), x)
elif self.ctype == 'kcomp':
return K.in_train_phase(self.k_comp_tanh(x, self.topk), x)
else:
warnings.warn("Unknown ctype, using no competition.")
return x
def get_config(self):
config = {'topk': self.topk, 'ctype': self.ctype}
base_config = super(KCompetitive, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def k_comp_tanh(self, x, topk, factor=6.26):
if self.x_prev is None:
self.x_prev = self.add_weight(shape=x.shape,
initializer='zeros',
trainable=False,
name='X_prev')
###Some modification on x so now the x becomes
x_modified = self.x_prev.assign(x + 1)
return x_modified
这是一个用法示例:
import tensorflow as tf
tf.random.set_seed(0)
np.random.seed(0)
# Make model
model = tf.keras.Sequential()
model.add(tf.keras.Input(batch_shape=(3, 4)))
my_layer = KCompetitive(2, 'kcomp')
print(my_layer.x_prev)
# None
model.add(my_layer)
# The variable gets created after it is added to a model
print(my_layer.x_prev)
# <tf.Variable 'k_competitive/X_prev:0' shape=(3, 4) dtype=float32, numpy=
# array([[0., 0., 0., 0.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]], dtype=float32)>
model.compile(optimizer='SGD', loss='mse')
# "Train"
x = tf.zeros((3, 4))
cbk = tf.keras.callbacks.LambdaCallback(
on_epoch_begin=lambda batch, logs:
tf.print('initial x_prev:', my_layer.x_prev, sep='\n'),
on_epoch_end=lambda batch, logs:
tf.print('final x_prev:', my_layer.x_prev, sep='\n'),)
model.fit(x, x, epochs=1, verbose=0, callbacks=[cbk])
# initial x_prev:
# [[0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]]
# final x_prev:
# [[1 1 1 1]
# [1 1 1 1]
# [1 1 1 1]]
我有一个一般性问题。
我正在开发一个新层以合并到自动编码器中。更具体地说,该层类似于 KCompetitive
class over here。我想要的是我需要将这一层的输出保存在一个变量中,我们称之为 previous_mat_values
,然后在下一个时期也将它传递给同一层。
换句话说,我希望能够将 epoch 1
这一层的输出保存在一个变量中,然后在 epoch 2
中再次使用相同的矩阵。
所以问题出现了,这个矩阵在第一个时期的值是多少,因为它还没有那个层的输出。我们可以初始化一个与权重矩阵形状相同但值为 0
的数组,我会这样做。
previous_mat_values = tf.zeros_like(weight_tensor)
所以步骤是这样的:
在第一个epoch中,
previous_mat_values
和weight_mat
会传给layer1.a那层函数的最后,我们称之为
modified_weight_mat
的最终值会存入previous_mat_values
previous_mat_values = modified_weight_mat
在第二个 epoch 中,
previous_mat_values
和weight_mat
将传递给该层,但是,previous_mat_values
具有在第一个 epoch 中保存的值。
我通过 weight_mat
并做与此相关的事情没有任何问题。这里唯一的问题是我们如何在每个 epoch 中保存 previous_mat_values
的值并将其传递给下一个 epoch。
我想在 class of that layer
中创建一个全局张量变量并将其初始化为零,但我认为将前一个时期的值保留到第二个时期没有帮助。
你知道我该如何实现吗?
如果我的解释不清楚,请告诉我。
更新 1:
这是层的实现:
class KCompetitive(Layer):
'''Applies K-Competitive layer.
# Arguments
'''
def __init__(self, topk, ctype, **kwargs):
self.topk = topk
self.ctype = ctype
self.uses_learning_phase = True
self.supports_masking = True
super(KCompetitive, self).__init__(**kwargs)
def call(self, x):
if self.ctype == 'ksparse':
return K.in_train_phase(self.kSparse(x, self.topk), x)
elif self.ctype == 'kcomp':
return K.in_train_phase(self.k_comp_tanh(x, self.topk), x)
else:
warnings.warn("Unknown ctype, using no competition.")
return x
def get_config(self):
config = {'topk': self.topk, 'ctype': self.ctype}
base_config = super(KCompetitive, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def k_comp_tanh(self, x, topk, factor=6.26):
###Some modification on x so now the x becomes
x= x+1
res = x
return res
更新 2
为了进一步说明,我将添加:
数据样本 1:
x_prev = zero
mask = tf.greate(x, x_prev) # x here related to sample 1
x_modified = x[mask]
x_prev = x_modified
数据样本2:
mask = tf.greater(x, x_prev) # x here related to sample 2 and
x_prev is from previous sample
x_modified = x[mask]
x_prev = x_modified
我不确定这是否是你的意思,但你可以在你的层中有一个变量,它在每个训练步骤中简单地使用另一个变量的先前值进行更新,大致如下:
import tensorflow as tf
class MyLayer(tf.keras.layers.Layer):
def __init__(self, units, **kwargs):
super(MyLayer, self).__init__(**kwargs)
self.units = units
def build(self, input_shape):
self.w = self.add_weight(shape=(input_shape[-1], self.units),
initializer='random_normal',
trainable=self.trainable,
name='W')
self.w_prev = self.add_weight(shape=self.w.shape,
initializer='zeros',
trainable=False,
name='W_prev')
def call(self, inputs, training=False):
# Only update value of w_prev on training steps
deps = []
if training:
deps.append(self.w_prev.assign(self.w))
with tf.control_dependencies(deps):
return tf.matmul(inputs, self.w)
这是一个用法示例:
import tensorflow as tf
import numpy as np
tf.random.set_seed(0)
np.random.seed(0)
# Make a random linear problem
x = np.random.rand(50, 3)
y = x @ np.random.rand(3, 2)
# Make model
model = tf.keras.Sequential()
my_layer = MyLayer(2, input_shape=(3,))
model.add(my_layer)
model.compile(optimizer='SGD', loss='mse')
# Train
cbk = tf.keras.callbacks.LambdaCallback(
on_batch_begin=lambda batch, logs: (tf.print('batch:', batch),
tf.print('w_prev:', my_layer.w_prev, sep='\n'),
tf.print('w:', my_layer.w, sep='\n')))
model.fit(x, y, batch_size=10, epochs=1, verbose=0, callbacks=[cbk])
输出:
batch: 0
w_prev:
[[0 0]
[0 0]
[0 0]]
w:
[[0.0755531341 0.0211461019]
[-0.0209847465 -0.0518018603]
[-0.0618413948 0.0235136505]]
batch: 1
w_prev:
[[0.0755531341 0.0211461019]
[-0.0209847465 -0.0518018603]
[-0.0618413948 0.0235136505]]
w:
[[0.0770048052 0.0292659812]
[-0.0199236758 -0.04635958]
[-0.060054455 0.0332755931]]
batch: 2
w_prev:
[[0.0770048052 0.0292659812]
[-0.0199236758 -0.04635958]
[-0.060054455 0.0332755931]]
w:
[[0.0780589 0.0353098139]
[-0.0189863108 -0.0414136574]
[-0.0590113513 0.0387929156]]
batch: 3
w_prev:
[[0.0780589 0.0353098139]
[-0.0189863108 -0.0414136574]
[-0.0590113513 0.0387929156]]
w:
[[0.0793346688 0.042034667]
[-0.0173048507 -0.0330933407]
[-0.0573575757 0.0470812619]]
batch: 4
w_prev:
[[0.0793346688 0.042034667]
[-0.0173048507 -0.0330933407]
[-0.0573575757 0.0470812619]]
w:
[[0.0805450454 0.0485667922]
[-0.0159637 -0.0261840075]
[-0.0563304275 0.052557759]]
编辑:我仍然不是 100% 确定你需要它如何工作,但这里有一些可能对你有用:
import tensorflow as tf
class KCompetitive(Layer):
'''Applies K-Competitive layer.
# Arguments
'''
def __init__(self, topk, ctype, **kwargs):
self.topk = topk
self.ctype = ctype
self.uses_learning_phase = True
self.supports_masking = True
self.x_prev = None
super(KCompetitive, self).__init__(**kwargs)
def call(self, x):
if self.ctype == 'ksparse':
return K.in_train_phase(self.kSparse(x, self.topk), x)
elif self.ctype == 'kcomp':
return K.in_train_phase(self.k_comp_tanh(x, self.topk), x)
else:
warnings.warn("Unknown ctype, using no competition.")
return x
def get_config(self):
config = {'topk': self.topk, 'ctype': self.ctype}
base_config = super(KCompetitive, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def k_comp_tanh(self, x, topk, factor=6.26):
if self.x_prev is None:
self.x_prev = self.add_weight(shape=x.shape,
initializer='zeros',
trainable=False,
name='X_prev')
###Some modification on x so now the x becomes
x_modified = self.x_prev.assign(x + 1)
return x_modified
这是一个用法示例:
import tensorflow as tf
tf.random.set_seed(0)
np.random.seed(0)
# Make model
model = tf.keras.Sequential()
model.add(tf.keras.Input(batch_shape=(3, 4)))
my_layer = KCompetitive(2, 'kcomp')
print(my_layer.x_prev)
# None
model.add(my_layer)
# The variable gets created after it is added to a model
print(my_layer.x_prev)
# <tf.Variable 'k_competitive/X_prev:0' shape=(3, 4) dtype=float32, numpy=
# array([[0., 0., 0., 0.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]], dtype=float32)>
model.compile(optimizer='SGD', loss='mse')
# "Train"
x = tf.zeros((3, 4))
cbk = tf.keras.callbacks.LambdaCallback(
on_epoch_begin=lambda batch, logs:
tf.print('initial x_prev:', my_layer.x_prev, sep='\n'),
on_epoch_end=lambda batch, logs:
tf.print('final x_prev:', my_layer.x_prev, sep='\n'),)
model.fit(x, x, epochs=1, verbose=0, callbacks=[cbk])
# initial x_prev:
# [[0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]]
# final x_prev:
# [[1 1 1 1]
# [1 1 1 1]
# [1 1 1 1]]