Keras'ta Gömme nedir?


97

Keras belgeleri bunun gerçekte ne olduğu net değil. Giriş özelliği alanını daha küçük bir alana sıkıştırmak için bunu kullanabileceğimizi anlıyorum. Ancak bu, sinirsel tasarım açısından nasıl yapılır? Otomatik tarama cihazı mı, RBM?

keras 


1
Basitçe bir ağırlık matrisi oluşturur ve indeksler; aşağıdaki ayrıntılı cevabıma bakın ( stackoverflow.com/a/53101566/9024698 ).
Outcast

3
En çok oylanan yanıt bunun bir matris çarpımı olduğunu söylese de, kaynak kodu ve diğer yanıtlar aslında bunların eğitilebilir bir matris olduklarını gösteriyor. Giriş kelimeleri sadece bu matristeki ilgili satırı seçer.
Daniel Möller

Yanıtlar:


67

Bildiğim kadarıyla Gömme katmanı, kelimeleri karşılık gelen kelime gömmelerine dönüştüren basit bir matris çarpımıdır.

Gömme katmanının ağırlıkları şekildedir (kelime_boyutu, gömme_boyutu). Her eğitim örneği için girdisi, belirli kelimeleri temsil eden tam sayılardır. Tam sayılar kelime boyutunun aralığındadır. Gömme katmanı, her i tamsayısını, gömme ağırlıkları matrisinin i. Satırına dönüştürür.

Bunu bir matris çarpımı olarak hızlı bir şekilde yapmak için, giriş tamsayıları bir tamsayı listesi olarak değil, bir sıcak matris olarak saklanır. Bu nedenle, girdi şekli (nb_words, wordabulary_size) satır başına sıfır olmayan bir değerdir. Bunu gömme ağırlıklarla çarparsanız, çıktıyı şekilde elde edersiniz.

(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)

Yani basit bir matris çarpımı ile bir örnekteki tüm kelimeleri karşılık gelen kelime düğünlerine dönüştürürsünüz.


3
Kesinlikle geçerli bir yaklaşım (bkz. Yarı Denetimli Sıralı Öğrenme ). Ayrıca, bir otomatik kodlayıcı ile yerleştirmeleri öğrenebilir ve ardından bunları, sinir ağınızın karmaşıklığını azaltmak için Gömme katmanının başlatılması olarak kullanabilirsiniz (Gömme katmanından sonra başka bir şey yaptığınızı varsayıyorum).
Lorrit

3
İşte kelime düğünleri ve avantajları hakkında güzel bir blog yazısı.
sietschie

3
Sunduğum durumda, her eğitim girdisi bir dizi kelimedir (bir cümle olabilir). Her kelime tek sıcak vektör olarak temsil edilir ve yoğun bir vektöre gömülür. Bu yaklaşımın dezavantajı, girdinin sabit uzunlukta olması gerektiğinden, tüm cümlelerinizin aynı sayıda kelimeye sahip olması gerektiğidir. Bir alternatif olacağını paragraf vektörler vektörlere cümleler, paragraflar hatta belgeleri gömebilirsiniz.
Lorrit

4
Gömme katmanı, kaybı en aza indirmek için ağırlıklarını optimize edecektir. Belki bu anlamsal benzerliği dikkate alacağı anlamına gelir, belki de olmayacaktır. Sinir ağlarını asla bilemezsiniz. Gömme işleminin belirli bir formülü takip ettiğinden emin olmak istiyorsanız (örneğin w2v), formülü kullanın. Yeterli veriye sahipseniz, Gömme katmanını kullanmak ve düğünleri eğitmek isteyebilirsiniz. Sadece deneyin ve sonuçları beğenip beğenmediğinizi kontrol edin.
Lorrit

2
User36624'e katılıyorum (aşağıdaki cevap). Onun DEĞİL basit matris çarpım.
Daniel Möller

22

Keras EmbeddingTabaka bir matris çarpımını ancak bu işlemi gerçekleştiren değildir:

1. (kelime_boyutu) x (gömme_boyutu) boyutlarından oluşan bir ağırlık matrisi oluşturur

2. bu ağırlık matrisini indeksler


Bir sınıfın ne yaptığını anlamak için kaynak koduna bakmak her zaman yararlıdır. Bu durumda, Layer denilen temel katmandan miras kalan class Gömme'ye bir göz atacağız .class

(1) - (kelime_boyutu) x (gömme_boyutu) boyutlarından oluşan bir ağırlık matrisi oluşturma :

Bu, Gömmebuild işlevinde gerçekleşir :

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

Katman temel sınıfına bakarsanız, add_weightyukarıdaki fonksiyonun basitçe eğitilebilir ağırlıklardan oluşan bir matris oluşturduğunu göreceksiniz (bu durumda (kelime_boyutu) x (gömme_boyutu) boyutları):

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) - Bu ağırlık matrisinin indekslenmesi

Bu, Gömmecall işlevinde gerçekleşir :

def call(self, inputs):
    if K.dtype(inputs) != 'int32':
        inputs = K.cast(inputs, 'int32')
    out = K.gather(self.embeddings, inputs)
    return out

Bu işlev, olan Embeddingkatmanın çıktısını döndürür K.gather(self.embeddings, inputs). Ne tf.keras.backend.gather yok tam olarak ağırlıkları matrisi endeksi etmektir self.embeddings(bkz buildgöre yukarıdaki fonksiyonu) inputspozitif tamsayılar listeleri olması gereken.

Bu listeler, örneğin metin / kelime girişlerinizi, bir metni n boyutunda kelime dizinleri listesine kodlayan Keras'ın one_hot işlevine geçirirseniz alınabilir (bu, bir sıcak kodlama DEĞİLDİR - daha fazla bilgi için bu örneğe de bakın: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).


Bu nedenle, hepsi bu. Matris çarpımı yoktur.

Aksine, tam olarak bir matris çarpma yerine getirilmesinin önüne çünkü tabaka sadece yararlıdır ve dolayısıyla bazı hesaplamalı kaynaklara tasarruf etmenizi sağlar.Keras Embedding

Aksi takdirde, bir Keras Yoğun katmanı (girdi verilerinizi kodladıktan sonra) eğitilebilir ağırlıkların bir matrisini ((kelime_boyutu ) x (gömme_boyutu) boyutlarından) elde etmek için kullanabilir ve ardından tam olarak olacak çıktıyı elde etmek için çarpmayı yapabilirsiniz. Embeddingkatmanın çıktısı ile aynı .


5

Herhangi bir işlevi daha iyi anlamak için kaynak koduna bakmak iyi bir alışkanlıktır. İşte Gömme için Yani temelde eğitilebilir bir arama tablosu.


4

Keras'ta Embeddingkatman, basit bir matris çarpım katmanı DEĞİL , ancak bir arama tablosu katmanıdır (aşağıdaki çağrı işlevine veya orijinal tanıma bakın ).

def call(self, inputs):
    if K.dtype(inputs) != 'int32':
        inputs = K.cast(inputs, 'int32')
    out = K.gather(self.embeddings, inputs)
    return out

Yaptığı şey her bilinen bir tamsayı haritalarını çıkarmak niçinde inputseğitilebilir bir özellik vektörü için W[n]kimin boyut sözde gömülü özellik uzunluğudur.


Tek sıcak temsil edilen vektör kümesini bir matrisle çarptığınızda, çarpım bir arama olur. Bu yüzden Embeddingtabaka olan gerçekten bir matris çarpım.
yannis

Keras'ın hiçbir yerde bu çarpma işlemini gerçekleştirmemesi dışında. Yalnızca "gömmeler = eğitilebilir bir matris" tanımlar ve matristen kelimeleri toplamak için girdi indekslerini kullanır.
Daniel Möller

Böylelikle, bu gömme, girişlerin herhangi bir tek sıcak versiyonunu oluşturmayarak çok fazla belleği kurtarır.
Daniel Möller

1

Basit bir deyişle (işlevsellik açısından), tek sıcak kodlayıcı ve tam bağlantılı bir katmandır . Katman ağırlıkları eğitilebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.