如何屏蔽具有 RepeatVector() 层的 LSTM 自动编码器中的输入?

2023-12-11

我一直在尝试使用 LSTM 自动编码器获取向量序列的向量表示,以便我可以使用 SVM 或其他此类监督算法对序列进行分类。数据量阻止我使用完全连接的密集层进行分类。

我的输入的最短大小是 7 个时间步长,最长的序列是 356 个时间步长。因此,我用零填充了较短的序列,以获得形状为 (1326, 356, 8) 的最终 x_train,其中 1326 是训练样本的数量,8 是一个时间步的维度。我正在尝试使用给定的 LSTM 自动编码器将这些序列编码为单个向量。

model.add(Masking(mask_value=0.0, input_shape=(max_len, 8)))
model.add(LSTM(100, activation='relu'))
model.add(RepeatVector(max_len))
model.add(LSTM(8, activation='relu', return_sequences=True))
model.compile(optimizer='adam', loss='mse')
model.fit(x_train, x_train, batch_size=32, callbacks=[chk], epochs=1000, validation_split=0.05, shuffle=True)

我试图掩盖零填充的结果,但 RepeatVector() 层可能会阻碍该过程。因此,一段时间后,均方误差损失变成nan。谁能帮我解决如何在计算损失函数时只包含相关时间步长而忽略其他时间步长?


Keras 中的每一层都有一个input_mask and output_mask,面具在第一次之后就已经丢失了LSTM层(当return_sequence = False)在你的例子中。让我在下面的示例中对此进行解释,并展示在 LSTM 自动编码器中实现屏蔽的 2 种解决方案。

time_steps = 3
n_features = 2
input_layer = tfkl.Input(shape=(time_steps, n_features))
# I want to mask the timestep where all the feature values are 1 (usually we pad by 0)
x = tfk.layers.Masking(mask_value=1)(input_layer)
x = tfkl.LSTM(2, return_sequences=True)(x)
x = tfkl.LSTM(2, return_sequences=False)(x)
x = tfkl.RepeatVector(time_steps)(x)
x = tfkl.LSTM(2, return_sequences=True)(x)
x = tfkl.LSTM(2, return_sequences=True)(x)
x = tfk.layers.Dense(n_features)(x)
lstm_ae = tfk.models.Model(inputs=input_layer, outputs=x)
lstm_ae.compile(optimizer='adam', loss='mse')
print(lstm_ae.summary())

Model: "model_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_3 (InputLayer)         [(None, 3, 2)]            0         
_________________________________________________________________
masking_2 (Masking)          (None, 3, 2)              0         
_________________________________________________________________
lstm_8 (LSTM)                (None, 3, 2)              40        
_________________________________________________________________
lstm_9 (LSTM)                (None, 2)                 40        
_________________________________________________________________
repeat_vector_2 (RepeatVecto (None, 3, 2)              0         
_________________________________________________________________
lstm_10 (LSTM)               (None, 3, 2)              40        
_________________________________________________________________
lstm_11 (LSTM)               (None, 3, 2)              40        
_________________________________________________________________
dense_2 (Dense)              (None, 3, 2)              6         
=================================================================
Total params: 166
Trainable params: 166
Non-trainable params: 0
_________________________________________________________________


for i, l in enumerate(lstm_ae.layers):
    print(f'layer {i}: {l}')
    print(f'has input mask: {l.input_mask}')
    print(f'has output mask: {l.output_mask}')

layer 0: <tensorflow.python.keras.engine.input_layer.InputLayer object at 0x645b49cf8>
has input mask: None
has output mask: None
layer 1: <tensorflow.python.keras.layers.core.Masking object at 0x645b49c88>
has input mask: None
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
layer 2: <tensorflow.python.keras.layers.recurrent_v2.LSTM object at 0x645b4d0b8>
has input mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
layer 3: <tensorflow.python.keras.layers.recurrent_v2.LSTM object at 0x645b4dba8>
has input mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
has output mask: None
layer 4: <tensorflow.python.keras.layers.core.RepeatVector object at 0x645db0390>
has input mask: None
has output mask: None
layer 5: <tensorflow.python.keras.layers.recurrent_v2.LSTM object at 0x6470b5da0>
has input mask: None
has output mask: None
layer 6: <tensorflow.python.keras.layers.recurrent_v2.LSTM object at 0x6471410f0>
has input mask: None
has output mask: None
layer 7: <tensorflow.python.keras.layers.core.Dense object at 0x647dfdf60>
has input mask: None
has output mask: None

正如你在上面看到的,第二个LSTM layer (return_sequence=False) 返回一个None,这是有道理的,因为时间步丢失了(形状改变了)并且图层不知道如何传递掩模,您还可以检查源代码,您会看到它返回input_mask if return_sequence=True, 否则None。另一个问题当然是RepeatVector图层,该图层根本不支持显式遮罩,这又是因为形状发生了变化。除了这个瓶颈部分(第二个LSTM + RepeatVector)之外,模型的其他部分都能够通过mask,所以我们只需要处理瓶颈部分。

这里有两种可能的解决方案,我也会根据计算损失进行验证。

第一个解决方案:通过传递sample_weight显式忽略时间步长

# last timestep should be masked because all feature values are 1
x = np.array([1, 2, 1, 2, 1, 1], dtype='float32').reshape(1, 3, 2)
print(x)
array([[[1., 2.],
        [1., 2.],
        [1., 1.]]], dtype=float32)

y = lstm_ae.predict(x)
print(y)
array([[[0.00020542, 0.00011909],
        [0.0007361 , 0.00047323],
        [0.00158514, 0.00107504]]], dtype=float32)

# the expected loss should be the sum of square error between the first 2 timesteps
# (2 features each timestep) divided by 6. you might expect that this should be 
# divided by 4, but in the source code this is actually divided by 6, which doesn't 
# matter a lot because only the gradient of loss matter, but not the loss itself.

expected_loss = np.square(x[:, :2, :] - y[:, :2, :]).sum()/6
print(expected_loss)
1.665958086649577

actual_loss_with_masking = lstm_ae.evaluate(x=x, y=x)
print(actual_loss_with_masking)
1.9984053373336792

# the actual loss still includes the last timestep, which means the masking is not # effectively passed to the output layer for calculating the loss
print(np.square(x-y).sum()/6)
1.9984052975972493


# if we provide the sample_weight 0 for each timestep that we want to mask, the
# loss will be ignored correctly
lstm_ae.compile(optimizer='adam', loss='mse', sample_weight_mode='temporal')
sample_weight_array = np.array([1, 1, 0]).reshape(1, 3)  # it means to ignore the last timestep
actual_loss_with_sample_weight = lstm_ae.evaluate(x=x, y=x, sample_weight=sample_weight_array)
# the actual loss now is correct
print(actual_loss_with_sample_weight)
1.665958046913147

第二种解决方案:制作定制的瓶颈层以手动传递掩模

class lstm_bottleneck(tf.keras.layers.Layer):
    def __init__(self, lstm_units, time_steps, **kwargs):
        self.lstm_units = lstm_units
        self.time_steps = time_steps
        self.lstm_layer = tfkl.LSTM(lstm_units, return_sequences=False)
        self.repeat_layer = tfkl.RepeatVector(time_steps)
        super(lstm_bottleneck, self).__init__(**kwargs)
    
    def call(self, inputs):
        # just call the two initialized layers
        return self.repeat_layer(self.lstm_layer(inputs))
    
    def compute_mask(self, inputs, mask=None):
        # return the input_mask directly
        return mask

time_steps = 3
n_features = 2
input_layer = tfkl.Input(shape=(time_steps, n_features))
# I want to mask the timestep where all the feature values are 1 (usually we pad by 0)
x = tfk.layers.Masking(mask_value=1)(input_layer)
x = tfkl.LSTM(2, return_sequences=True)(x)
x = lstm_bottleneck(lstm_units=2, time_steps=3)(x)
# x = tfkl.LSTM(2, return_sequences=False)(x)
# x = tfkl.RepeatVector(time_steps)(x)
x = tfkl.LSTM(2, return_sequences=True)(x)
x = tfkl.LSTM(2, return_sequences=True)(x)
x = tfk.layers.Dense(n_features)(x)
lstm_ae = tfk.models.Model(inputs=input_layer, outputs=x)
lstm_ae.compile(optimizer='adam', loss='mse')
print(lstm_ae.summary())

Model: "model_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_3 (InputLayer)         [(None, 3, 2)]            0         
_________________________________________________________________
masking_2 (Masking)          (None, 3, 2)              0         
_________________________________________________________________
lstm_10 (LSTM)               (None, 3, 2)              40        
_________________________________________________________________
lstm_bottleneck_3 (lstm_bott (None, 3, 2)              40        
_________________________________________________________________
lstm_12 (LSTM)               (None, 3, 2)              40        
_________________________________________________________________
lstm_13 (LSTM)               (None, 3, 2)              40        
_________________________________________________________________
dense_2 (Dense)              (None, 3, 2)              6         
=================================================================
Total params: 166
Trainable params: 166
Non-trainable params: 0
_________________________________________________________________


for i, l in enumerate(lstm_ae.layers):
    print(f'layer {i}: {l}')
    print(f'has input mask: {l.input_mask}')
    print(f'has output mask: {l.output_mask}')

layer 0: <tensorflow.python.keras.engine.input_layer.InputLayer object at 0x64dbf98d0>
has input mask: None
has output mask: None
layer 1: <tensorflow.python.keras.layers.core.Masking object at 0x64dbf9f60>
has input mask: None
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
layer 2: <tensorflow.python.keras.layers.recurrent_v2.LSTM object at 0x64dbf9550>
has input mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
layer 3: <__main__.lstm_bottleneck object at 0x64dbf91d0>
has input mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
layer 4: <tensorflow.python.keras.layers.recurrent_v2.LSTM object at 0x64e04ca20>
has input mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
layer 5: <tensorflow.python.keras.layers.recurrent_v2.LSTM object at 0x64eeb8b00>
has input mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
layer 6: <tensorflow.python.keras.layers.core.Dense object at 0x64ef43208>
has input mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)
has output mask: Tensor("masking_2/Identity_1:0", shape=(None, 3), dtype=bool)

正如我们已经看到的,掩码现在已成功传递到输出层。我们还将验证损失不包括屏蔽时间步长。

# last timestep should be masked because all feature values are 1
x = np.array([1, 2, 1, 2, 1, 1], dtype='float32').reshape(1, 3, 2)
print(x)
array([[[1., 2.],
        [1., 2.],
        [1., 1.]]], dtype=float32)

y = lstm_ae.predict(x)
print(y)
array([[[ 0.00065455, -0.00294413],
        [ 0.00166675, -0.00742249],
        [ 0.00166675, -0.00742249]]], dtype=float32)

# the expected loss should be the square error between the first 2 timesteps divided by 6
expected_loss = np.square(x[:, :2, :] - y[:, :2, :]).sum()/6
print(expected_loss)
1.672815163930257

# now the loss is correct with a custom layer
actual_loss_with_masking = lstm_ae.evaluate(x=x, y=x)
print(actual_loss_with_masking)
1.672815203666687


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何屏蔽具有 RepeatVector() 层的 LSTM 自动编码器中的输入? 的相关文章

  • “Dense”对象没有属性“op”[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在尝试使用tensorflow keras制作一个完全连接的模型 这是我的代码 from tensorflow keras m
  • 在自定义 keras 层的调用函数中传递附加参数

    我创建了一个自定义 keras 层 目的是在推理过程中手动更改前一层的激活 以下是基本层 它只是将激活值乘以一个数字 import numpy as np from keras import backend as K from keras
  • keras 预测内存交换无限期增加

    我使用keras实现了一个分类程序 我有一大组图像 我想使用 for 循环来预测每个图像 然而 每次计算新图像时 交换内存都会增加 我尝试删除预测函数内部的所有变量 并且我确信该函数内部存在问题 但内存仍然增加 for img in ima
  • 具有高级计算功能的 Keras 自定义层

    我想写一些自定义的Keras分层并在层中进行一些高级计算 例如使用 Numpy Scikit OpenCV 我知道有一些数学函数keras backend可以对张量进行操作 但我需要一些更高级的功能 但是 我不知道如何正确实现这一点 我收到
  • 无法更改现有 Keras 模型中的激活

    我有一个普通的 VGG16 模型relu激活 即 def VGG 16 weights path None model Sequential model add ZeroPadding2D 1 1 input shape 3 224 224
  • 使用 Keras Tuner 调整模型时如何跳过有问题的超参数组合?

    使用 Keras Tuner 时 似乎没有办法允许跳过有问题的超参数组合 例如 Conv1D 层中的过滤器数量可能与后续 MaxPooling1D 层中的池大小的所有值不兼容 从而导致模型构建错误 然而 在运行调谐器之前可能不知道这一点 一
  • 如何将两个 keras 模型连接成一个模型?

    假设我有一个 ResNet50 模型 我希望将该模型的输出层连接到 VGG 模型的输入层 这是 ResNet 模型和 ResNet50 的输出张量 img shape 164 164 3 resnet50 model ResNet50 in
  • batch_size = x.shape[0] AttributeError: 'tuple' 对象没有属性 'shape'

    该代码结合图像和掩模进行图像检测 我怎样才能纠正这个错误 batch size x shape 0 AttributeError tuple 对象没有属性 shape 这是用于训练的代码 train datagen ImageDataGen
  • 神经网络 - 我的网络似乎训练得很好,但在分类报告中它是完全随机的

    我正在训练一个模型来对 3 种类型的车辆进行分类 一切看起来都很顺利 直到我尝试用我的模型预测任何事情 预测结果是完全随机的 我使用 3 个类别的 15000 张图像 每个类别 5000 个 进行训练 并使用 3 个类别的 6000 个图像
  • 交换keras中的张量轴

    我想将图像批次的张量轴从 batch size row col ch 交换为 批次大小 通道 行 列 在 numpy 中 这可以通过以下方式完成 X batch np moveaxis X batch 3 1 我该如何在 Keras 中做到
  • 如何在 py_function 之后重塑(图像,标签)数据集

    我正在尝试读取自定义映射数据集进行训练 但是在使用 py function 映射数据集后 我得到了未知的形状 例如 def process path file path label get label file path img tf io
  • 使用tensorflow获取真阳性、假阳性、假阴性和真阴性列表

    这是我的工作 我注释了 活 细胞的图像 约 8 000 和 死 细胞的图像 约 2 000 800 和 200 用于测试集 我正在使用 CNN 带有张量流和 keras 将图像分类为 活 或 死 我训练了我的模型 验证损失 0 35 召回率
  • 屏蔽字符串

    我需要将收到的字符串放入以下格式 在打字稿 javascript中 Eg 12 34 56 789 我知道有string mask以及通过 JQuery 的某种方式 有没有更简单的方法来做到这一点 您可以用所需的数据替换每个模式部分 fun
  • ValueError:形状(无,1)和(无,2)不兼容

    我正在训练面部表情 愤怒与快乐 模型 最后一个密集输出层以前为 1 但当我预测图像时 它的输出始终为 1 准确度为 64 所以我将其更改为 2 表示 2 个输出 但现在我收到这个错误 Epoch 1 15 ValueError Traceb
  • 图像分割 - Keras 中的自定义损失函数

    我正在使用 Keras 中实现的 U Net https arxiv org pdf 1505 04597 pdf https arxiv org pdf 1505 04597 pdf 在显微镜图像中分割细胞器 为了让我的网络能够识别仅由
  • Tensorflow 保存子类模型,该模型具有 call() 方法的多个参数

    我正在关注张量流神经机器翻译教程 https www tensorflow org tutorials text nmt with attention https www tensorflow org tutorials text nmt
  • Keras 均方误差损失层

    我目前正在实现一个自定义损失层 在此过程中 我偶然发现了 Objectives py 文件 1 中均方误差的实现 我知道我对这种损失计算的理解遗漏了一些东西 因为我一直认为平均值是在每个小批量 张量的轴 0 中的每个输出的样本之间单独完成的
  • 检查语言模型的困惑度

    我使用 Keras LSTM 创建了一个语言模型 现在我想评估它是否良好 因此我想计算困惑度 在 Python 中计算模型的困惑度的最佳方法是什么 我已经提出了两个版本并附上了相应的来源 请随时查看链接 def perplexity raw
  • 无法保存自定义子类模型

    灵感来自tf keras Model 子类化 https www tensorflow org guide keras model subclassing我创建了自定义模型 我可以训练它并获得成功的结果 但是我无法保存它 我使用 pytho
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent

随机推荐

  • ZedGraph 用图表线平滑移动 Y2Axis

    在回答我的问题时 ZedGraph 自定义图表 我有每秒插入数据的图表 现在我有其他问题 如何用图表线平滑地向下移动Y2轴 DateTime类型 并在图表中始终只显示最后30分钟 如何格式化 Y2Axis 标签 HH mm 以获得 10 0
  • 返回类型:If 在函数中条件调用 sys.exit()

    假设我在控制台脚本 1 中有以下函数 def example x int gt typing Union typing NoReturn int if x gt 10 something is wrong if this condition
  • 如何防止创建两个字段值相同的记录?

    我有下表 CREATE TABLE people first name VARCHAR 128 NOT NULL nick name VARCHAR 128 NULL 我想防止人们在尝试插入时将昵称与名字相同 我不想在任一列上创建索引 只是
  • Java 同步和可重入锁定

    当我们同步一个对象时 这是一个可重入锁吗 同步锁和可重入锁之间有真正的区别吗 亲切的问候 是的 锁定synchronized关键字是可重入的 但它们之间的实现可能有所不同 例如 在 JVM 的早期版本中 ReentrantLock的实现比s
  • 如果 knit root.dir 更改,knitr::include_graphics() 无法找到文件

    knitr允许您通过更改来更改评估代码块的目录root dir option r setup include FALSE knitr opts knit set root dir Project 这也可以在 RStudio 的全局选项中更改
  • 文本视图行 - 建议

  • 如何更改控制器中的 $model->attributes 值 - Yii

    用户主控制器代码 public function actionUpdate id model this gt loadModel id if isset POST UserMaster model gt attributes POST Us
  • arm-linux-androideabi-g++:-fuse-linker-plugin,但找不到 liblto_plugin.so

    我在ubuntu 12 04下编译Chrome V8时遇到一个问题是 arm linux androideabi g 致命错误 fuse linker plugin 但找不到 liblto plugin so ndk版本是r8b 我怎么解决
  • 了解使用 Photoshop 生成的 24 位 PNG

    具有透明度的 24 位 png 文件 可以使用以下命令生成Photoshop 真的有 24 位分布在每种颜色加上 alpha 上吗 或者 24 位仅指颜色并忽略 alpha RGBA 8888 有没有工具可以检查 PNG 文件并验证此类信息
  • 具有多个图像的 Pod

    创建一个名为 xyz 的 pod 其中包含一个容器 用于在其中运行以下每个映像 指定的映像可能在 1 到 4 个之间 nginx redis Memcached consul 问题不太清楚 但假设您希望一个 Pod 具有多个容器 下面是可以
  • 错误:结果不是以下位置的数据框:

    我正在尝试在相当大的数据框上运行拟合函数 该数据框由名为的变量分组 big group and small group 特别是 我试图获得每个的预测和 coefs 值small group代替big group 也就是说 我试图将这些新列添
  • 有没有什么好的方法来加密C#桌面应用程序[重复]

    这个问题在这里已经有答案了 可能的重复 保护 NET 代码免遭逆向工程 我们只是用C winforms开发一个应用程序 有什么好的加密方法可以帮助我们防止盗版吗 我看到有些软件可能需要硬件支持来保护其软件 如何实现 提前致谢 好吧 你在这里
  • 不读取模型[关闭]

    Closed 这个问题需要调试细节 目前不接受答案 我正在用Python编写一个程序 我想连接GPT4ALL 以便该程序像GPT聊天一样工作 仅在我的编程环境中本地运行 为此 我已经安装了 GPT4All 13B snoozy ggmlv3
  • 在 javascript 警报中编写 php

    我用以下方式在JS中编写PHP alert echo Error login 关联一个xml 用symfony翻译成两种语言 但现在不起作用 我该如何解决 您缺少引号alert call alert
  • Ruby on Rails - 将模型中的字段添加到另一个模型的表单上

    我有两个型号Contract and Addendum 合同has many addendums和附录belongs to contract 创建新合同时 将自动创建新的附录 但需要一些额外的元素来创建新的附录 如何添加字段value 这是
  • Pandas 中的顺序组内枚举

    假设我有以下数据框 date A B C D 0 2014 03 20 1 561714 0 979202 0 454935 0 629215 1 2014 03 20 0 390851 0 045697 1 683257 0 771027
  • 将引用(工具>引用)与 VBA 代码(宏)连接

    我想使用 VBA 代码以编程方式将一些引用连接到我的 VBA 项目 即无需使用 工具 gt 引用 手动设置引用 这可能吗 例如 Microsoft Office 12 0 对象库 您没有提到 Office 应用程序 在 MS Access
  • 使用 malloc 时出错

    I pass char input from main to processInExp 函数 然后我再次传递它processInExp 功能为getInput 函数在读取文件时动态分配它 Inside getInput 功能input检查时
  • 为什么 ASP.NET 网站没有 Designer.cs?

    如果我们在 Visual Studio 中创建 ASP NET Web 应用程序 我们可以看到每个 aspx 文件都会有一个关联的自动生成的 aspx designer cs 文件 但对于 ASP NET 网站 每个 aspx 文件只有一个
  • 如何屏蔽具有 RepeatVector() 层的 LSTM 自动编码器中的输入?

    我一直在尝试使用 LSTM 自动编码器获取向量序列的向量表示 以便我可以使用 SVM 或其他此类监督算法对序列进行分类 数据量阻止我使用完全连接的密集层进行分类 我的输入的最短大小是 7 个时间步长 最长的序列是 356 个时间步长 因此