Nhúng trong Keras là gì?


97

Tài liệu của Keras không rõ đây thực sự là gì. Tôi hiểu rằng chúng ta có thể sử dụng điều này để nén không gian tính năng đầu vào thành một vùng nhỏ hơn. Nhưng điều này được thực hiện như thế nào từ quan điểm thiết kế thần kinh? Nó có phải là một mã tự động không, RBM?

keras 

7
Đó là một bảng tra cứu có thể được đào tạo
gokul_uf

1
Nó chỉ đơn giản là tạo và lập chỉ mục một ma trận trọng số; xem câu trả lời chi tiết của tôi bên dưới ( stackoverflow.com/a/53101566/9024698 ).
Outcast

3
Mặc dù câu trả lời được bình chọn nhiều nhất nói rằng đó là phép nhân ma trận, mã nguồn và các câu trả lời khác cho thấy trên thực tế chúng chỉ là một ma trận có thể huấn luyện được. Các từ đầu vào chỉ cần chọn hàng tương ứng trong ma trận này.
Daniel Möller

Câu trả lời:


66

Theo như tôi biết, lớp Nhúng là một phép nhân ma trận đơn giản để chuyển các từ thành các nhúng từ tương ứng của chúng.

Trọng lượng của lớp Nhúng có hình dạng (kích thước từ vựng, kích thước nhúng). Đối với mỗi mẫu đào tạo, đầu vào của nó là các số nguyên, đại diện cho các từ nhất định. Các số nguyên nằm trong phạm vi kích thước từ vựng. Lớp Nhúng biến đổi mỗi số nguyên i thành dòng thứ i của ma trận trọng số nhúng.

Để nhanh chóng thực hiện điều này dưới dạng phép nhân ma trận, các số nguyên đầu vào không được lưu trữ dưới dạng danh sách các số nguyên mà ở dạng ma trận một nóng. Do đó, hình dạng đầu vào là (nb_words, từ vựng_size) với một giá trị khác 0 trên mỗi dòng. Nếu bạn nhân giá trị này với trọng số nhúng, bạn sẽ có kết quả ở dạng

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

Vì vậy, với một phép nhân ma trận đơn giản, bạn chuyển đổi tất cả các từ trong một mẫu thành các từ nhúng tương ứng.


3
Chắc chắn là một cách tiếp cận hợp lệ (xem Học theo trình tự bán giám sát ). Bạn cũng có thể tìm hiểu các cách nhúng bằng bộ mã tự động và sau đó sử dụng chúng làm quá trình khởi tạo lớp Nhúng để giảm độ phức tạp của mạng nơ-ron của bạn (tôi giả sử rằng bạn làm việc gì khác sau lớp Nhúng).
Lorrit

3
Đây là một blogpost tốt đẹp về nhúng từ và lợi thế của chúng.
sietschie

3
Trong trường hợp mà tôi đã trình bày, mỗi đầu vào đào tạo là một tập hợp các từ (có thể là một câu). Mỗi từ được biểu diễn dưới dạng một vectơ nóng và được nhúng vào một vectơ dày đặc. Nhược điểm của phương pháp này là vì đầu vào cần có độ dài không đổi, tất cả các câu của bạn cần có cùng số từ. Một giải pháp thay thế sẽ là vectơ đoạn văn , có thể nhúng câu, đoạn văn hoặc thậm chí tài liệu vào vectơ.
Lorrit

4
Lớp Nhúng sẽ chỉ tối ưu hóa trọng lượng của nó để giảm thiểu sự mất mát. Có thể điều đó có nghĩa là nó sẽ xem xét sự tương đồng về ngữ nghĩa, có thể nó sẽ không. Bạn không bao giờ biết với mạng nơ-ron. Nếu bạn muốn chắc chắn rằng việc nhúng tuân theo một công thức nhất định (ví dụ: w2v), hãy sử dụng công thức. Nếu bạn có đủ dữ liệu, bạn có thể muốn sử dụng lớp Nhúng và đào tạo các lần nhúng. Chỉ cần thử nó và kiểm tra xem bạn có thích kết quả không.
Lorrit

2
Tôi đồng ý với user36624 (câu trả lời bên dưới). Nó KHÔNG PHẢI là một phép nhân ma trận đơn giản.
Daniel Möller

21

Các Keras Embeddinglớp không thực hiện bất kỳ phép nhân ma trận nhưng chỉ có nó:

1. tạo một ma trận trọng số của ( kích thước từ vựng) x ( kích thước_hấp_phí)

2. lập chỉ mục cho ma trận trọng số này


Luôn hữu ích khi xem mã nguồn để hiểu những gì một lớp làm. Trong trường hợp này, chúng ta sẽ xem xét phần class Nhúng kế thừa từ lớp cơ sở classđược gọi là Lớp .

(1) - Tạo ma trận trọng số của các thứ nguyên (từ vựng_size) x (embedding_dimension) :

Điều này đang xảy ra ở buildchức năng Nhúng :

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

Nếu bạn nhìn vào Layer lớp cơ sở, bạn sẽ thấy rằng hàm add_weighttrên chỉ đơn giản tạo ra một ma trận các trọng số có thể đào tạo (trong trường hợp này là (từ vựng_ kích thước) x (nhúng_dimension) kích thước):

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) - Lập chỉ mục ma trận trọng số này

Điều này đang xảy ra ở callchức năng Nhúng :

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

Hàm này trả về kết quả đầu ra của Embeddinglớp K.gather(self.embeddings, inputs). Những gì tf.keras.backend.gather làm chính xác là lập chỉ mục ma trận trọng số self.embeddings(xem buildhàm ở trên) theo inputsđó sẽ là danh sách các số nguyên dương.

Các danh sách này có thể được truy xuất, ví dụ: nếu bạn chuyển đầu vào văn bản / từ của mình vào hàm one_hot của Keras mã hóa văn bản thành danh sách chỉ mục từ có kích thước n (đây KHÔNG phải là một mã hóa nóng - hãy xem thêm ví dụ này để biết thêm thông tin: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).


Do đó, chỉ có vậy thôi. Không có phép nhân ma trận.

Ngược lại, các Keras Embeddinglớp chỉ hữu ích bởi vì chính xác nó tránh thực hiện một phép nhân ma trận và do đó nó economizes trên một số tài nguyên tính toán.

Nếu không, bạn chỉ có thể sử dụng lớp Keras Dense (sau khi bạn đã mã hóa dữ liệu đầu vào của mình) để nhận ma trận các trọng số có thể huấn luyện (của (từ vựng_size) x (embedding_dimension) ) và sau đó chỉ cần thực hiện phép nhân để nhận được kết quả chính xác tương tự với đầu ra của Embeddinglớp.


5

Để hiểu rõ hơn về bất kỳ chức năng nào, bạn nên xem mã nguồn. Đây là để nhúng Vì vậy, về cơ bản nó là một bảng tra cứu có thể đào tạo.


4

Trong Keras, Embeddinglớp là KHÔNG phải là lớp nhân ma trận đơn giản mà là lớp bảng tra cứu (xem hàm gọi bên dưới hoặc định nghĩa ban đầu ).

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

Những gì nó làm là ánh xạ từng số nguyên đã biết nvào inputsmột vectơ đặc trưng có thể đào tạoW[n] , có kích thước là chiều dài đối tượng được nhúng.


Khi bạn nhân một tập các vectơ đại diện một nóng với một ma trận, sản phẩm sẽ trở thành một dạng tra cứu. Vì vậy, các Embeddinglớp thực sự là một phép nhân ma trận.
yannis

Ngoại trừ việc không có nơi nào keras thực hiện phép nhân này. Nó chỉ định nghĩa "embeddings = a trainable matrix" và sử dụng các chỉ số đầu vào để thu thập các từ từ ma trận.
Daniel Möller

Do đó, việc nhúng này giải phóng rất nhiều bộ nhớ bằng cách đơn giản là không tạo ra bất kỳ phiên bản đầu vào nóng nào.
Daniel Möller

1

Nói cách đơn giản (từ quan điểm chức năng), nó là một bộ mã hóa một nónglớp kết nối đầy đủ . Trọng lượng lớp có thể đào tạo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.