可视化词嵌入

数据挖掘 r 喀拉斯 张量流
2022-01-23 14:07:10

我正在研究文本分类问题,并试图了解如何使用 tensorboard 投影仪在 Keras 中嵌入层。借用 Deep Learning with R 书中的一个例子,我有一个这样的模型:

library(keras)

max_features <- 2000                                     
max_len <- 500                                           

imdb <- dataset_imdb(num_words = max_features)
c(c(x_train, y_train), c(x_test, y_test)) %<-% imdb
x_train <- pad_sequences(x_train, maxlen = max_len)
x_test = pad_sequences(x_test, maxlen = max_len)

model <- keras_model_sequential() %>%
  layer_embedding(input_dim = max_features + 1, output_dim = 128,
                  input_length = max_len, name = "embed") %>%
  layer_conv_1d(filters = 32, kernel_size = 7, activation = "relu") %>%
  layer_max_pooling_1d(pool_size = 5) %>%
  layer_conv_1d(filters = 32, kernel_size = 7, activation = "relu") %>%
  layer_global_max_pooling_1d() %>%
  layer_dense(units = 1)

summary(model)

model %>% compile(
  optimizer = "rmsprop",
  loss = "binary_crossentropy",
  metrics = c("acc")
)

然而,当需要配置callback_tensorboard对象时,我有点迷茫。自本书编写以来,API 似乎发生了变化,我还没有找到一个好的工作示例。如果设置了参数,则该embeddings_data属性显然是必需的embeddings_freq,并且它需要与模型输入的形状相匹配c(?, 500)我可以通过简单地将所有单词标记作为矩阵传递来满足这一点:

tensorboard("my_log_dir")             

callbacks = list(
  callback_tensorboard(
    log_dir = "my_log_dir",
    histogram_freq = 1,
    embeddings_freq = 1,
    embeddings_data = matrix(1:max_features, nrow = 4)
  )
)

history <- model %>% fit(
  x_train, y_train,
  epochs = 5,
  batch_size = 128,
  validation_split = 0.2,
  callbacks = callbacks
)

该模型训练正常,但是当尝试在投影仪中查看结果时,似乎嵌入被处理为 64,000 维(2,000 个单词 * 128d 层输出?),每个 500 个元素向量都有一个点embeddings_data这使得 PCA 计算停滞不前。

停滞的 PCA

我希望最终结果更接近https://projector.tensorflow.org/上的示例,其中维度等于层输出维度,并且每个单词都有一个点。

我错过了什么?是否有任何使用当前版本的 Keras 和 Tensorflow 可视化标准词嵌入层的好的工作示例?

我正在使用R 3.3.4,Keras 2.2.0Tensorflow 1.11.

1个回答

这里似乎有几个问题在起作用。

首先,显然 PCA 计算并没有因为报告的荒谬维度而停止 - 更新tensorflow 1.12Keras 2.2.4消除了该问题。

其次,Keras 似乎基于层输入而不是实际层权重为 tensorboard 生成嵌入数据。也许这对于其他一些用法很重要,但是在标准的词/令牌嵌入场景中它使事情变得非常复杂。为了解决这个问题,我最终在训练期间跳过了嵌入,最后导出了嵌入权重,然后用更简单的拓扑训练了一个新的一次性模型,以生成我感兴趣的投影。给定一个model从样本训练的对象多于:

w <- model %>% get_layer(index = 1) %>% get_weights()

emodel <- model <- keras_model_sequential() %>%
  layer_embedding(input_dim = max_features, output_dim = 128, input_length = 1) %>%
  layer_global_max_pooling_1d() %>%
  layer_dense(units = 1)

emodel %>% get_layer(index = 1) %>% set_weights(w) %>% freeze_weights()

emodel %>% compile(
  optimizer = "rmsprop",
  loss = "binary_crossentropy",
  metrics = c("acc")
)

callbacks = list(
  callback_tensorboard(
    log_dir = "my_log_dir",
    embeddings_freq = 1,
    embeddings_data = c(1:max_features)
  )
)

history <- emodel %>% fit(
  1:max_features, 1:max_features,
  epochs = 1,
  batch_size = 256,
  callbacks = callbacks
)

tensorboard("my_log_dir")             

理想情况下,会有一些更简单/更清洁的方法来实现这一点,但这目前有效。

编辑

另一位用户在一个现已删除的问题中询问了有关向 Projector 添加令牌标签的问题。对于后代来说,这就像embeddings_metadatacallback_tensorboard. 这应该是log_dir带有所需标签的制表符分隔文件的路径(相对于您的 )。详细信息在这里:https ://www.tensorflow.org/guide/embedding#metadata