【问题标题】:Regarding Text Autoencoders in KERAS for topic modeling关于 KERAS 中用于主题建模的文本自动编码器
【发布时间】:2018-09-20 10:42:12
【问题描述】:

简介:我已经在 KERAS 中为 MNIST 图像训练了自动编码器(普通和变分),并观察了瓶颈层中的潜在表示在将它们聚集在一起时看起来有多好。

目标:我想对短文本做同样的事情。特地推特!我想使用 pre-trained GloVe embeddings 根据语义将它们聚集在一起。

我打算先创建一个 CNN 编码器和一个 CNN 解码器,然后再转向 LSTM/GRU。

问题: ~~~正确的损失应该是什么?如何在 Keras 中实现呢?~~~

这就是我的 KERAS 模型的样子

INPUT_TWEET(单词索引)>> EMBEDDING LAYER >> CNN_ENCODER >> BOTTLENECK >> CNN_DECODER >> OUTPUT_TWEET(单词索引)

Layer (type)                 Output Shape              Param #   
-----------------------------------------------------------------
Input_Layer (InputLayer)     (None, 64)                0         
embedding_1 (Embedding)      (None, 64, 200)           3299400   
enc_DO_0_layer (Dropout)     (None, 64, 200)           0         
enc_C_1 (Conv1D)             (None, 64, 16)            9616      
enc_MP_1 (MaxPooling1D)      (None, 32, 16)            0         
enc_C_2 (Conv1D)             (None, 32, 8)             392       
enc_MP_2 (MaxPooling1D)      (None, 16, 8)             0         
enc_C_3 (Conv1D)             (None, 16, 8)             200       
enc_MP_3 (MaxPooling1D)      (None, 8, 8)              0         
***bottleneck (Flatten)***   (None, 64)                0         
reshape_2 (Reshape)          (None, 8, 8)              0         
dec_C_1 (Conv1D)             (None, 8, 8)              200       
dec_UpS_1 (UpSampling1D)     (None, 16, 8)             0         
dec_C_2 (Conv1D)             (None, 16, 8)             200       
dec_UpS_2 (UpSampling1D)     (None, 32, 8)             0         
dec_C_3 (Conv1D)             (None, 32, 16)            400       
dec_UpS_3 (UpSampling1D)     (None, 64, 16)            0         
conv1d_2 (Conv1D)            (None, 64, 200)           9800      
dense_2 (Dense)              (None, 64, 1)             201       
flatten_2 (Flatten)          (None, 64)                0         
-----------------------------------------------------------------

这显然是错误的,因为它试图最小化输入和输出(单词索引)之间的 MSE 损失,我认为它应该在嵌入层(embedding_1 和 conv1d_2)中做到这一点。

现在我该怎么做?是否有意义?有没有办法在 Keras 中做到这一点?请检查下面的代码:

代码:

sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32',name="Input_Layer")
embedded_sequences = embedding_layer(sequence_input)
embedded_sequences1 = Dropout(0.5, name="enc_DO_0_layer")(embedded_sequences)

x = Conv1D(filters=16, kernel_size=3, activation='relu', padding='same',name="enc_C_1")(embedded_sequences1)
x = MaxPooling1D(pool_size=2, padding='same',name='enc_MP_1')(x)
x = Conv1D(filters=8, kernel_size=3, activation='relu', padding='same',name="enc_C_2")(x)
x = MaxPooling1D(pool_size=2, padding='same',name="enc_MP_2")(x)
x = Conv1D(filters=8, kernel_size=3, activation='relu', padding='same',name="enc_C_3")(x)
x = MaxPooling1D(pool_size=2, padding='same',name="enc_MP_3")(x)

encoded = Flatten(name="bottleneck")(x)
x = Reshape((8, 8))(encoded)

x = Conv1D(filters=8, kernel_size=3, activation='relu', padding='same',name="dec_C_1")(x)
x = UpSampling1D(2,name="dec_UpS_1")(x)
x = Conv1D(8, 3, activation='relu', padding='same',name="dec_C_2")(x)
x = UpSampling1D(2,name="dec_UpS_2")(x)
x = Conv1D(16, 3, activation='relu',padding='same',name="dec_C_3")(x)
x = UpSampling1D(2,name="dec_UpS_3")(x)
decoded = Conv1D(200, 3, activation='relu', padding='same')(x)
y = Dense(1)(decoded)
y = Flatten()(y)

autoencoder = Model(sequence_input, y)
autoencoder.compile(optimizer='adam', loss='mean_squared_error')

autoencoder.fit(x = tweet_word_indexes ,y = tweet_word_indexes,
            epochs=10,
            batch_size=128,
            validation_split=0.2)

不希望它这样做:

由于损失严重,显然只是试图重建单词索引数组(填充零)。

Input  = [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1641 13 2 309 932 1 10 5 6]  
Output = [ -0.31552997 -0.53272009 -0.60824025 -1.14802313 -1.14597917 -1.08642125 -1.10040164 -1.19442761 -1.19560885 -1.19008029 -1.19456315 -1.2288748 -1.22721946 -1.20107424 -1.20624077 -1.24017036 -1.24014354 -1.2400831 -1.24004364 -1.23963416 -1.23968709 -1.24039733 -1.24027216 -1.23946059 -1.23946059 -1.23946059 -1.23946059 -1.23946059 -1.23946059 -1.23946059 -1.23946059 -1.23946059 -1.23946059 -1.14516866 -1.20557368 -1.5288837 -1.48179781 -1.05906188 -1.17691648 -1.94568193 -1.85741842 -1.30418646 -0.83358657 -1.61638248 -1.17812908 0.53077424 0.79578459 -0.40937367 0.35088596 1.29912627 -5.49394751 -27.1003418 -1.06875408 33.78763962 109.41391754 242.43798828 251.05577087 300.13430786 267.90420532 178.17596436 132.06596375 60.63394928 82.10819244 91.18526459]

问题: 这对你有意义吗?正确的损失应该是什么?如何在 Keras 中实现它?

【问题讨论】:

  • 你的输出是什么?当你说Word indexes 时,我并没有完全关注。 twitter上的词库超过2M。你能扩展一些你的预期输出表示吗?
  • 作为自动编码器,输出与输入相同。但也许选择这个输出的“格式”是问题的关键之一。
  • @DavidParks 很抱歉造成混乱。例如一条推文是“All work and no play makes jack a dull boy”,那么 word_indexes 就像 [44, 88, 43, 1, 475, 101, 11 , 26 ,465, 111]
  • 我明白什么是推文,你如何用数字形式表示“All work and no play makes jack a dull boy”这句话?这是我不清楚的部分。您的输入是一系列嵌入向量,您是否为输出提出了相同的形式?
  • @DanielMöller 是的。就像在图像中一样,您的目标是最小化逐像素错误。这里我不想最小化逐字的错误,而是在Embedding空间。例如,“IDIOT”和“STUPID”当你看文本时是完全不同的词,但在嵌入空间中彼此非常接近。

标签: python tensorflow nlp deep-learning keras


【解决方案1】:

首先,您不应该尝试在模型末尾获取索引(索引不可微且不遵循逻辑连续路径)。

您可能应该使用 one-hot 编码词来完成模型。然后将“softmax”与“categorical_crossentropy”一起使用。 (但不确定这是否是最好的解决方案)

最后一层应该是Dense(dicWordCount)
因此,您将索引转换为 one-hot 向量并将它们作为输出传递。

oneHotOutput = np.zeros((tweetCount,length,dicWordCount))
auxIndices = np.arange(length)

#inputIndices has shape (tweets,length), it's your array of indices
for i, tweet in zip(range(tweetCount),inputIndices):
    oneHotOutput[i][auxIndices,tweet] = 1

创建模型并:model.fit(inputIndices,oneHotOutput,...)

【讨论】:

    猜你喜欢
    • 2018-05-23
    • 2018-09-08
    • 2021-07-18
    • 2018-10-04
    • 1970-01-01
    • 2017-04-18
    • 2016-03-23
    • 1970-01-01
    • 2020-06-05
    相关资源
    最近更新 更多