การฝังใน Keras คืออะไร?


97

เอกสาร Keras ไม่ชัดเจนว่านี่คืออะไร ฉันเข้าใจว่าเราสามารถใช้สิ่งนี้เพื่อบีบอัดพื้นที่คุณสมบัติการป้อนข้อมูลให้เล็กลง แต่สิ่งนี้ทำได้อย่างไรจากมุมมองของการออกแบบระบบประสาท? มันเป็น autoenocder, RBM หรือไม่?

keras 

7
เป็นตารางค้นหาที่ฝึกได้
gokul_uf

1
เพียงแค่สร้างและทำดัชนีเมทริกซ์น้ำหนัก ดูคำตอบโดยละเอียดของฉันด้านล่าง ( stackoverflow.com/a/53101566/9024698 )
Outcast

3
แม้ว่าคำตอบที่ได้รับการโหวตมากที่สุดจะบอกว่าเป็นการคูณเมทริกซ์ แต่ซอร์สโค้ดและคำตอบอื่น ๆ แสดงให้เห็นว่าอันที่จริงแล้วมันเป็นเพียงเมทริกซ์ที่ฝึกได้ คำป้อนเพียงแค่เลือกแถวตามลำดับในเมทริกซ์นี้
Daniel Möller

คำตอบ:


67

เท่าที่ฉันรู้เลเยอร์การฝังคือการคูณเมทริกซ์อย่างง่ายที่เปลี่ยนคำให้เป็นการฝังคำที่สอดคล้องกัน

น้ำหนักของเลเยอร์การฝังมีรูปร่าง (คำศัพท์ขนาด, ขนาดการฝังตัว) สำหรับตัวอย่างการฝึกแต่ละรายการข้อมูลที่ป้อนจะเป็นจำนวนเต็มซึ่งแสดงถึงคำบางคำ จำนวนเต็มอยู่ในช่วงของขนาดคำศัพท์ เลเยอร์การฝังจะแปลงจำนวนเต็ม i แต่ละตัวให้เป็นเส้น ith ของเมทริกซ์น้ำหนักการฝัง

เพื่อที่จะทำสิ่งนี้ได้อย่างรวดเร็วในฐานะการคูณเมทริกซ์จำนวนเต็มอินพุตจะไม่ถูกจัดเก็บเป็นรายการของจำนวนเต็ม แต่เป็นเมทริกซ์แบบฮ็อตเดียว ดังนั้นรูปทรงการป้อนข้อมูลคือ (nb_words, คำศัพท์_size) โดยมีค่าที่ไม่ใช่ศูนย์หนึ่งค่าต่อบรรทัด หากคุณคูณสิ่งนี้ด้วยน้ำหนักฝังคุณจะได้ผลลัพธ์เป็นรูปร่าง

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

ดังนั้นด้วยการคูณเมทริกซ์อย่างง่ายคุณสามารถแปลงคำทั้งหมดในตัวอย่างเป็นคำฝังที่เกี่ยวข้องได้


3
แนวทางที่ถูกต้องแน่นอน (ดูการเรียนรู้แบบลำดับกึ่งนิเทศ ) คุณยังสามารถเรียนรู้การฝังตัวด้วยตัวเข้ารหัสอัตโนมัติแล้วใช้เป็นค่าเริ่มต้นของเลเยอร์การฝังเพื่อลดความซับซ้อนของเครือข่ายประสาทเทียมของคุณ (ฉันคิดว่าคุณทำอย่างอื่นหลังจากเลเยอร์การฝัง)
Lorrit

3
นี่คือบล็อกโพสต์ที่ดีเกี่ยวกับการฝังคำและข้อดี
sietschie

3
ในกรณีที่ฉันนำเสนอข้อมูลการฝึกอบรมแต่ละชุดเป็นชุดคำ (สามารถเป็นประโยคได้) แต่ละคำจะแสดงเป็นเวกเตอร์ที่มีความร้อนสูงและฝังอยู่ในเวกเตอร์ที่หนาแน่น ข้อเสียของแนวทางนี้คือเนื่องจากข้อมูลที่ป้อนต้องมีความยาวคงที่ประโยคทั้งหมดของคุณจึงต้องมีจำนวนคำเท่ากัน อีกทางเลือกหนึ่งคือเวกเตอร์ย่อหน้าซึ่งสามารถฝังประโยคย่อหน้าหรือแม้แต่เอกสารลงในเวกเตอร์ได้
Lorrit

4
เลเยอร์การฝังจะปรับน้ำหนักให้เหมาะสมเพื่อลดการสูญเสียให้น้อยที่สุด บางทีนั่นหมายความว่ามันจะพิจารณาความคล้ายคลึงทางความหมายบางทีมันอาจจะไม่ คุณไม่มีทางรู้ด้วยโครงข่ายประสาทเทียม หากคุณต้องการให้แน่ใจว่าการฝังเป็นไปตามสูตรที่กำหนด (เช่น w2v) ให้ใช้สูตร หากคุณมีข้อมูลเพียงพอคุณอาจต้องการใช้เลเยอร์การฝังและฝึกการฝัง เพียงแค่ลองและตรวจสอบว่าคุณชอบผลลัพธ์
Lorrit

2
ฉันเห็นด้วยกับ user36624 (คำตอบด้านล่าง) มันไม่ใช่การคูณเมทริกซ์ง่ายๆ
Daniel Möller

22

Keras Embeddingชั้นไม่ได้ดำเนินการใด ๆ คูณเมทริกซ์ แต่เพียง:

1. สร้างเมทริกซ์น้ำหนักของมิติ(คำศัพท์_size) x (embedding_dimension)

2. ดัชนีเมทริกซ์น้ำหนักนี้


การดูซอร์สโค้ดจะมีประโยชน์เสมอเพื่อทำความเข้าใจว่าคลาสทำอะไร ในกรณีนี้เราจะมีลักษณะที่มีclass การฝังที่รับจากฐานชั้นclassที่เรียกว่าชั้น

(1) - การสร้างเมทริกซ์น้ำหนักของขนาด(คำศัพท์_size) x (embedding_dimension) :

สิ่งนี้เกิดขึ้นที่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

หากคุณดูที่ชั้นฐานชั้นคุณจะเห็นว่าฟังก์ชันadd_weightด้านบนสร้างเพียงแค่เมทริกซ์ของน้ำหนักที่ฝึกได้ (ในกรณีนี้คือมิติข้อมูล(คำศัพท์ขนาด) x (การฝังตัวมิติ):

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) - การสร้างดัชนีเมทริกซ์น้ำหนักนี้

สิ่งนี้เกิดขึ้นที่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ที่ควรเป็นจำนวนเต็มบวก

รายการเหล่านี้สามารถเรียกดูได้ตัวอย่างเช่นหากคุณส่งอินพุตข้อความ / คำของคุณไปยังฟังก์ชันone_hotของ Keras ซึ่งเข้ารหัสข้อความลงในรายการดัชนีคำที่มีขนาด n (นี่ไม่ใช่การเข้ารหัสแบบร้อน - ดูตัวอย่างนี้สำหรับข้อมูลเพิ่มเติม: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ )


ดังนั้นนั่นคือทั้งหมด ไม่มีการคูณเมทริกซ์

ในทางตรงกันข้ามชั้นจะเป็นประโยชน์เพียงเพราะว่าจะหลีกเลี่ยงการดำเนินการคูณเมทริกซ์และจึงประหยัดทรัพยากรการคำนวณบางKeras Embedding

มิฉะนั้นคุณสามารถใช้เลเยอร์Keras หนาแน่น (หลังจากที่คุณเข้ารหัสข้อมูลอินพุตของคุณแล้ว) เพื่อรับเมทริกซ์ของน้ำหนักที่ฝึกได้ (จาก(ขนาดคำศัพท์) x (ขนาดฝังตัว) ) จากนั้นทำการคูณเพื่อให้ได้ผลลัพธ์ที่จะเป็น เช่นเดียวกันกับเอาต์พุตของEmbeddingเลเยอร์


5

เพื่อให้เข้าใจถึงฟังก์ชันต่างๆได้ดีขึ้นควรดูที่ซอร์สโค้ดเป็นนิสัย นี่คือการฝัง ดังนั้นโดยพื้นฐานแล้วมันเป็นตารางค้นหาที่ฝึกได้


4

ใน Keras Embeddingเลเยอร์ไม่ใช่เลเยอร์การคูณเมทริกซ์ธรรมดา แต่เป็นเลเยอร์ตารางการค้นหา (ดูฟังก์ชันการโทรด้านล่างหรือคำจำกัดความดั้งเดิม)

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

สิ่งที่มันไม่สามารถที่จะ map แต่ละจำนวนเต็มที่รู้จักกันnในinputsการเวกเตอร์คุณลักษณะสุวินัยW[n]ซึ่งเป็นมิติที่เรียกว่าระยะเวลาในคุณลักษณะที่ฝังตัว


เมื่อคุณคูณเซตของเวกเตอร์ที่เป็นตัวแทนแบบฮ็อตเดียวด้วยเมทริกซ์ผลิตภัณฑ์จะกลายเป็นการค้นหา ดังนั้นEmbeddingเลเยอร์จึงเป็นการคูณเมทริกซ์
yannis

ยกเว้นว่า Keras ทำการคูณนี้ เพียงแค่กำหนด "embeddings = เมทริกซ์ที่ฝึกได้" และใช้ดัชนีอินพุตเพื่อรวบรวมคำจากเมทริกซ์
Daniel Möller

ดังนั้นการฝังนี้จึงช่วยประหยัดหน่วยความจำได้มากโดยไม่ต้องสร้างอินพุตรุ่นใดรุ่นหนึ่งที่ร้อนแรง
Daniel Möller

1

ในคำง่าย (จากจุดทำงานของมุมมอง) ก็เป็นหนึ่งร้อนเข้ารหัสและเต็มที่เชื่อมต่อชั้น น้ำหนักเลเยอร์สามารถฝึกได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.