Keras文档并不清楚它实际上是什么。据我所知,我们可以使用它将输入要素空间压缩为较小的一个。但是从神经设计的角度来看,这是怎么做到的?它是自动编码器,RBM吗?
答案 0 :(得分:59)
据我所知,嵌入层是一个简单的矩阵乘法,可将单词转换为相应的单词嵌入。
嵌入层的权重具有形状(vocabulary_size,embedding_dimension)。对于每个训练样本,其输入是整数,表示某些单词。整数在词汇量大小的范围内。嵌入层将每个整数i变换为嵌入权重矩阵的第i行。
为了快速将其作为矩阵乘法,输入整数不会存储为整数列表,而是存储为单热矩阵。因此,输入形状是(nb_words,vocabulary_size),每行一个非零值。如果将此乘以嵌入权重,则得到形状
的输出(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)
因此,通过简单的矩阵乘法,您可以将样本中的所有单词转换为相应的单词嵌入。
答案 1 :(得分:11)
Keras
Embedding
层不执行任何矩阵乘法,而仅执行:
1。创建一个尺寸为(vocabulary_size)x(embedding_dimension)尺寸的权重矩阵
2。索引此权重矩阵
看看源代码以了解类的作用总是很有用的。在这种情况下,我们将研究class
Embedding,它继承自称为Layer的基础层class
。
(1)-创建尺寸为(vocabulary_size)x(embedding_dimension)的权重矩阵:
这是在Embedding的build
功能处发生的:
def build(self, input_shape):
self.embeddings = self.add_weight(
shape=(self.input_dim, self.output_dim),
initializer=self.embeddings_initializer,
name='embeddings',
regularizer=self.embeddings_regularizer,
constraint=self.embeddings_constraint,
dtype=self.dtype)
self.built = True
如果您查看基类Layer,您会发现上面的函数add_weight
仅创建了可训练权重矩阵(在这种情况下,(vocabulary_size)x(embedding_dimension )尺寸):
def add_weight(self,
name,
shape,
dtype=None,
initializer=None,
regularizer=None,
trainable=True,
constraint=None):
"""Adds a weight variable to the layer.
# Arguments
name: String, the name for the weight variable.
shape: The shape tuple of the weight.
dtype: The dtype of the weight.
initializer: An Initializer instance (callable).
regularizer: An optional Regularizer instance.
trainable: A boolean, whether the weight should
be trained via backprop or not (assuming
that the layer itself is also trainable).
constraint: An optional Constraint instance.
# Returns
The created weight variable.
"""
initializer = initializers.get(initializer)
if dtype is None:
dtype = K.floatx()
weight = K.variable(initializer(shape),
dtype=dtype,
name=name,
constraint=constraint)
if regularizer is not None:
with K.name_scope('weight_regularizer'):
self.add_loss(regularizer(weight))
if trainable:
self._trainable_weights.append(weight)
else:
self._non_trainable_weights.append(weight)
return weight
(2)-索引此权重矩阵
这是在Embedding的call
功能处发生的:
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
此函数返回Embedding
层K.gather(self.embeddings, inputs)
的输出。 tf.keras.backend.gather的确切作用是根据self.embeddings
索引权重矩阵build
(请参见上面的inputs
函数),其中Keras
应该是正整数列表。
例如,如果您将文本/单词输入传递给Keras的one_hot函数,则可以检索这些列表,该函数将文本编码为大小为n的单词索引列表(这不是一种热门编码-请参阅有关更多信息,请参见以下示例:https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/)。
因此,仅此而已。没有矩阵乘法。
相反, Embedding
Keras
层仅是有用的,因为它确实避免了执行矩阵乘法,因此节省了一些计算资源。
否则,您可以仅使用Embedding
Dense层(在对输入数据进行编码之后)来获得可训练权重矩阵((vocabulary_size)x(embedding_dimension)< / em>尺寸),然后只需进行乘法运算即可得到与cf create-service p-rabbitmq standard my_rabbitmq
层的输出完全相同的输出。
答案 2 :(得分:6)
为了更好地理解任何功能,查看源代码是一个好习惯。这是Embedding 所以基本上它是一个可训练的查找表。
答案 3 :(得分:3)
在Keras中,mEnregistrer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String email = mEmail.getText().toString().trim();
String password = mMdp.getText().toString().trim();
final String pseudo =mPseudo.getText().toString().trim();
if (TextUtils.isEmpty(pseudo)) {
Toast.makeText(getApplicationContext(), "Entrer le pseudo", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(email)) {
Toast.makeText(getApplicationContext(), "Entrer une adresse mail", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(password)) {
Toast.makeText(getApplicationContext(), "Entrer un mot de passe", Toast.LENGTH_SHORT).show();
return;
}
if (password.length() < 6) {
Toast.makeText(getApplicationContext(), "mot de passe trop court, veuillez rentrer un minimum de 6 caractères", Toast.LENGTH_SHORT).show();
return;
}
//création compte
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignupActivity.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
//progressBar.setVisibility(View.GONE);
if (task.isSuccessful()) {
Toast.makeText(SignupActivity.this, "Inscription réussie " + task.isSuccessful(), Toast.LENGTH_SHORT).show();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
//changer les infos utilisateur
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(pseudo)
.build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "com.android.pfe.other.User profile updated.");
}
}
});
//the part that bug
User uti=new User(pseudo,email);
uti.addUser(user.getUid(),pseudo,email);
startActivity(new Intent(SignupActivity.this, LoginActivity.class));
finish();
//*****************************************************
} else {
Toast.makeText(SignupActivity.this, "erreur d'inscription" + task.getException().getMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
}
});
图层是 NOT 一个简单的矩阵乘法图层,但是一个查找表图层(请参阅下面的调用函数或原始的definition)。
Embedding
它的作用是将def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
中的每个已知整数n
映射到可训练的特征向量inputs
,其维度是所谓的嵌入特征长度。
答案 4 :(得分:0)
简单地说(从功能的角度来看),它是一个单热编码器和全连接层。图层权重是可训练的。