【问题标题】:Error with dimensions in KerasKeras 中的尺寸错误
【发布时间】:2018-09-01 10:49:53
【问题描述】:

我想实现一个简单的 word2vec 模型,但出现以下错误

ValueError: Error when checking target: expected dense-softmax to have 3 dimensions, but got array with shape (32, 14).

变量train_xtrain_y是表格的32行

[[0 0 0 0 0 0 0 0 0 1 0 0 0 0]
 [0 0 0 0 1 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 1 0 0 0 0 0 0 0 0 0]
                          ...]]

python代码如下

vocal_size = 14
input = Input(shape=(vocal_size, ), dtype='int32', name='input')
embeddings = Embedding(output_dim=5, input_dim= vocal_size)(input)
output = Dense(vocal_size, use_bias=False, activation='softmax')(embeddings)
model = Model(input=input, output=output)
model.compile(optimizer='adam', loss='categorical_crossentropy')
model.summary()
model.fit(train_x, train_y)



_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input (InputLayer)           (None, 14)                0         
_________________________________________________________________
embeddings (Embedding)       (None, 14, 5)             70        
_________________________________________________________________
dense_1 (Dense)              (None, 14, 14)            70        
=================================================================
Total params: 140
Trainable params: 140
Non-trainable params: 0

编辑:

(“我喜欢 stackoverflow”)上下文大小为 1,我创建以下元组,
(“我”、“喜欢”)、(“喜欢”、“我”)、(“喜欢”、“stackoverflow”)、(“stackoverflow”、“喜欢”)

然后我对它们进行一次热编码并将它们提供给模型。

train_x[0] -> 是单词“I”的一种热编码
train_y[0] -> 是上下文词“like”的一种热编码

编辑 2

对 skip-gram 使用第一种编码: 将 0 视为特殊词(即不是最常见的前 10.000 个)并从 1 开始计数。 我假设我应该输入一个数字并输出一个单热编码,即(“stack”,“overflow”),输入[3](“stack”)和输出[0,0,0,0,1,0,0,0,0,0,0](“overflow”)。

Input(shape=(1,)..) -> 
Embedding(output_dim=embedding_size, input_dim=vocab_size, mask_zero=True, ...) -> 
Dense(vocab_size+1, activation="Softmax")
model.compile(optimizer='SGD', loss='categorical_crossentropy')

即 embedding_size = 5,输入你例子中​​的句子,

https://imgur.com/a/32m4z

【问题讨论】:

  • 你能提供更多的设置/预处理吗? Keras 通常会读取带有标记词的句子(例如,[7,12,328,99] 表示“Hello world 我是 JDOE”)而不是二进制标签,因为我认为这是一个单词的存在/不存在。这会造成混淆,因为您似乎同时使用 vocal_size 来表示句子长度(应输入 shape)和词汇量(即 Embedding 中的 input_dim
  • @Pdubbs 你好,我编辑了我的帖子。我怀疑我的问题是我将单词作为单热编码向量提供给它。

标签: python neural-network nlp keras


【解决方案1】:

感谢您的编辑。你遇到麻烦有两个原因,一个是浅的,一个是深的。第一:浅层,密集层需要三维输入,但嵌入是二维的。您可以使用Flatten 解决此问题:

input = Input(shape=(vocal_size, ), dtype='int32', name='input')
embeddings = Embedding(output_dim=5, input_dim=vocal_size+1, input_length=vocal_size)(input)
flat = Flatten(embeddings)
output = Dense(vocal_size, use_bias=False, activation='softmax')(flat)

深层次是因为 one-hot 编码和嵌入是用于相同目的的两个选项,因此您不需要两者(请参阅 herehere)。

嵌入层需要一系列由表示单词(或元组)的整数和词汇量组成的“句子”,所以类似于

['Welcome to stack overflow',
'stack overflow is great',
'Hope it's helpful to you']

将被表示为

[[1,2,3,4,0],[3,4,5,6,0],[7,8,9,2,10]] 
# 0s are there to "pad" sentences 1 & 2 as they all need to be the same length

并像这样输入嵌入层:

input = Input(shape=(5, ), dtype='int32')
embeddings = Embedding(output_dim=5, input_dim=11, input_length=5)(input)
#input dim is 11 because we want 1 more than the number of words in our vocabulary
#padding can be done with the keras function pad_sequences

我确定你知道,我们句子的一种热编码应该是这样的:

[[1,1,1,1,0,0,0,0,0,0],
 [0,0,1,1,1,1,0,0,0,0],
 [0,1,0,0,0,0,1,1,1,1]]

因为句子已经被转换(一个热门已经将我们的句子“嵌入”为 10 维空间中的二进制向量),我们可以将其直接输入Dense 层,而无需进一步嵌入:

input = Input(shape=(vocal_size, ), dtype='int32', name='input')
output = Dense(vocal_size, use_bias=False, activation='softmax')(input)

这是一个使用两种方式的功能性玩具示例:

from keras.layers import Dense,Activation,Embedding,Input,Flatten
from keras import Model
import numpy as np

wrords = ['Welcome to stack overflow',
    'stack overflow is great',
    'Hope it\'s helpful to you']

a = [[1,2,3,4,0],[3,4,5,6,0],[7,8,9,2,10]]
b = [[1,1,1,1,0,0,0,0,0,0],
 [0,0,1,1,1,1,0,0,0,0],
 [0,1,0,0,0,0,1,1,1,1]]
c = [1,1,0] #hypothetical target is "references stack overflow"

input = Input(shape=(5, ), dtype='int32', name='input')
embeddings = Embedding(output_dim=5, input_dim=11, input_length=5)(input)
flat = Flatten()(embeddings)
output = Dense(1, activation='softmax')(flat)
model = Model(input=input, output=output)
model.compile(optimizer='adam', loss='binary_crossentropy')
model.summary()
model.fit(np.array(a),np.array(c))

input2 = Input(shape=(10, ), dtype='float32')
output2 = Dense(1, activation='softmax')(input2)
model2 = Model(input=input2, output=output2)
model2.compile(optimizer='adam', loss='binary_crossentropy')
model2.summary()
model2.fit(np.array(b),np.array(c))

【讨论】:

  • 感谢您的回答。我再次编辑了我的问题,你能告诉我是否有比我在原始帖子中发布的更好的方法来实现 word2vec,或者它看起来不错?
猜你喜欢
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 2018-09-18
  • 2018-02-10
相关资源
最近更新 更多