Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果输入值大于输入值,keras嵌入层如何工作?_Python_Machine Learning_Keras_Keras Layer_Embedding - Fatal编程技术网

Python 如果输入值大于输入值,keras嵌入层如何工作?

Python 如果输入值大于输入值,keras嵌入层如何工作?,python,machine-learning,keras,keras-layer,embedding,Python,Machine Learning,Keras,Keras Layer,Embedding,如果输入值大于输入值,嵌入层如何工作 为什么keras没有提出例外 from keras.models import Sequential from keras.layers import Embedding model = Sequential() model.add(Embedding(1, 2, trainable=True, mask_zero=False)) input_array = [5] model.compile("rmsprop", "mse") output_arra

如果输入值大于输入值,嵌入层如何工作

为什么keras没有提出例外

from keras.models import Sequential
from keras.layers import Embedding

model = Sequential()
model.add(Embedding(1, 2, trainable=True, mask_zero=False))
input_array = [5]

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

outpur_array
#array([[[0., 0.]]], dtype=float32)

输入值=5 输入尺寸=1

文档说明输入值(5)必须小于输入值(1)。在我的示例中,它是false,但代码仍然不会引发异常


谢谢大家!

嵌入层只是一个致密层,没有什么问题。您只是对数据执行简单的线性或仿射变换。输入/输出维度是任意的,使用低输出维度在实践中更常见的原因在于,高维数据点通常在其各自的输入维度中具有低维流形,而大多数有价值的信息都位于该流形上。这是PCA或任何其他降维算法背后的几何思想


相比之下,过完备自动编码器是一个很好的实际例子,在这种情况下,更高的输出维是可取的,并且模型被迫通过其他方式学习有用的表示,而不是投影到低维子空间上,例如,通过稀疏性和套索正则化等约束。

嵌入层使用具有形状的查找矩阵(输入尺寸,输出尺寸)。其中输入要学习的嵌入向量。当我传递索引时,层通过嵌入矩阵的索引获取向量。

感谢您指出我对输入长度和输入尺寸感到困惑

首先,如果使用tensorflow.keras,则会出现错误

tensorflow

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 3, 1], [1, 2, 3]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()

但是如果我使用keras2.3.1,我不会得到任何错误

keras 2.3.1

from keras.models import Model
from keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 3, 1], [1, 2, 3]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()

那么,凯拉斯破产了吗?首先要注意的是keras和tensorflow.keras对于嵌入层有不同的实现。为了验证这一点,让我们转到keras嵌入层

现在让我们看看调用函数

    def call(self, inputs):
        if K.dtype(inputs) != 'int32':
            inputs = K.cast(inputs, 'int32')
        out = K.gather(self.embeddings, inputs)
        return out
注:如果你想要keras 2.3.1的确切源代码,请点击此处下载源代码:

但如果我们使用tensorflow实现,情况就不同了

只是为了验证,调用函数的编写方式不同

  def call(self, inputs):
    dtype = K.dtype(inputs)
    if dtype != 'int32' and dtype != 'int64':
      inputs = math_ops.cast(inputs, 'int32')
    out = embedding_ops.embedding_lookup(self.embeddings, inputs)
    return out
现在,我们可以更深入地挖掘,找到不同的行为,并找出keras没有抛出错误的源,tensorflow.keras抛出错误的源,但让我们简单地指出一点。keras嵌入层是否做错了什么

让我们像以前一样设计一个简单的网络,并观察权重矩阵

from keras.models import Model
from keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 3, 1], [1, 2, 3]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()
该模型给出以下输出

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

 [[0. 0.]
  [0. 0.]
  [0. 0.]]]
(2, 3, 2)
Model: "model_18"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_21 (InputLayer)        (None, 3)                 0         
_________________________________________________________________
embedding_33 (Embedding)     (None, 3, 2)              2         
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0
好的,我们得到了一堆零,但是默认的权重初始值设定项不是零

现在让我们观察一下权重矩阵

import keras.backend as K

w = model.layers[1].get_weights()
print(w)

事实上,它并不全是零

那么,为什么我们会得到零呢

让我们更改模型的输入

作为输入的唯一词汇表内单词索引,_dim=1为0。让我们将0作为输入之一传递

from keras.models import Model
from keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 0, 1], [1, 2, 0]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()
现在,我们得到了通过0的位置的非零向量

[[[ 0.          0.        ]
  [-0.04339869 -0.04900574]
  [ 0.          0.        ]]

 [[ 0.          0.        ]
  [ 0.          0.        ]
  [-0.04339869 -0.04900574]]]
(2, 3, 2)
Model: "model_19"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_22 (InputLayer)        (None, 3)                 0         
_________________________________________________________________
embedding_34 (Embedding)     (None, 3, 2)              2         
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0
简言之,Keras将词汇表外的单词索引映射为零向量,这是合理的,因为对于那些位置,向前传递将确保所有贡献为零(尽管偏差可能有作用)。这有点违反直觉,因为将词汇表标记传递给模型似乎是一种开销(而不仅仅是在预处理步骤中删除它们)和糟糕的做法

教训是完全避免Keras,转而使用tensorflow.Keras,因为他们清楚地提到,在2.2版本之后,支持和小错误修复会减少


keras github repo的相关问题:

你是说低投入维度和高产出维度?这有什么问题?没有。文档说明输入值(5)必须小于输入值(1)。在我的例子中,它是错误的,但代码仍然没有引起任何例外。我想你不明白嵌入层在一开始是如何工作的,另外,你能分享它确切说明的链接吗?嵌入层使用带形状的查找矩阵(输入、输出)。其中输入要学习的嵌入向量。当我传递索引时,层通过嵌入矩阵的索引获取向量。我的描述中有什么错误吗?没有。文档说明输入值(5)必须小于输入值(1)。在我的例子中,它是错误的,但代码仍然没有引起任何异常。然后给它一系列具有不同值的1D输入,如[5,4,2],也许这并不意味着嵌入层必须使用[1]的值,这是完全有意义的,为什么该值与维度相关,我猜不同值的总和很重要。如果你通过[665678787878778797979797979886785]您还将得到[0,0]*5好的,我刚才运行了您的代码,它会像预期的那样抛出一个错误:InvalidArgumentError:Indexes[0,0]=1不在[0,1)…,我省略了错误的其余部分。这可能是因为您使用的是keras,而不是tf.keras。我使用的是tensorflow keras版本,它按预期工作。我不知道为什么keras版本不能在您的系统上正常工作。请检查tf.keras是否适用于您。您认为input\u dim用于什么?您的解释不正确。
Input_dim
与词汇大小完全相同。请检查。感谢您指出,我是如何将输入_dim与输入_长度混淆的。
[[[ 0.          0.        ]
  [-0.04339869 -0.04900574]
  [ 0.          0.        ]]

 [[ 0.          0.        ]
  [ 0.          0.        ]
  [-0.04339869 -0.04900574]]]
(2, 3, 2)
Model: "model_19"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_22 (InputLayer)        (None, 3)                 0         
_________________________________________________________________
embedding_34 (Embedding)     (None, 3, 2)              2         
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0