2016-02-28 34 views
65

Gần đây tôi đã xem xét một triển khai thú vị cho convolutional text classification. Tuy nhiên tất cả các mã TensorFlow tôi đã xem xét sử dụng một ngẫu nhiên (không pre-đào tạo) nhúng vectơ như sau:Sử dụng tính năng nhúng từ được đào tạo (word2vec hoặc Glove) trong TensorFlow

with tf.device('/cpu:0'), tf.name_scope("embedding"): 
    W = tf.Variable(
     tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0), 
     name="W") 
    self.embedded_chars = tf.nn.embedding_lookup(W, self.input_x) 
    self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1) 

Có ai biết làm thế nào để sử dụng các kết quả của Word2vec hoặc một chiếc găng tay trước được đào tạo từ nhúng thay vì ngẫu nhiên?

Trả lời

97

Có một vài cách để bạn có thể sử dụng tính năng nhúng được đào tạo trước trong TensorFlow. Giả sử bạn có nhúng trong một mảng NumPy được gọi là embedding, với vocab_size hàng và embedding_dim cột và bạn muốn tạo một tensor W có thể được sử dụng trong một cuộc gọi đến tf.nn.embedding_lookup().

  1. Đơn giản chỉ cần tạo W như một tf.constant() rằng mất embedding như giá trị của nó:

    W = tf.constant(embedding, name="W") 
    

    Đây là phương pháp đơn giản nhất, nhưng nó không phải là bộ nhớ hiệu quả vì giá trị của một tf.constant() được lưu trữ nhiều lần trong ký ức. Vì embedding có thể rất lớn, bạn chỉ nên sử dụng phương pháp này cho các ví dụ đồ chơi.

  2. Tạo W như một tf.Variable và khởi tạo nó từ mảng NumPy qua một tf.placeholder():

    W = tf.Variable(tf.constant(0.0, shape=[vocab_size, embedding_dim]), 
           trainable=False, name="W") 
    
    embedding_placeholder = tf.placeholder(tf.float32, [vocab_size, embedding_dim]) 
    embedding_init = W.assign(embedding_placeholder) 
    
    # ... 
    sess = tf.Session() 
    
    sess.run(embedding_init, feed_dict={embedding_placeholder: embedding}) 
    

    tránh điều này lưu trữ một bản sao của embedding trong biểu đồ, nhưng nó đòi hỏi đủ bộ nhớ để giữ hai bản sao của ma trận trong bộ nhớ cùng một lúc (một cho mảng NumPy, và một cho tf.Variable). Lưu ý rằng tôi đã giả định rằng bạn muốn giữ hằng số ma trận nhúng trong khi đào tạo, do đó, W được tạo với trainable=False.

  3. Nếu nhúng được đào tạo như một phần của mô hình TensorFlow khác, bạn có thể sử dụng tf.train.Saver để tải giá trị từ tệp điểm kiểm tra của mô hình khác. Điều này có nghĩa là ma trận nhúng có thể bỏ qua hoàn toàn Python. Tạo W như trong phương án 2, sau đó làm như sau:

    W = tf.Variable(...) 
    
    embedding_saver = tf.train.Saver({"name_of_variable_in_other_model": W}) 
    
    # ... 
    sess = tf.Session() 
    embedding_saver.restore(sess, "checkpoint_filename.ckpt") 
    
+0

Tôi tạo W như sau: W = np.loadtxt ("/ media/w2vTest.txt", dtype = 'string', delimiter = '') tạo thành một hàng: ['in' '0.070312 ......'- 0.0625']. Có vấn đề ở đây! tôi sẽ coi đây là W của tôi sau khi loại bỏ 'in' và chuyển đổi các số từ chuỗi thành float32? nếu đây là trường hợp, sau đó làm thế nào để kết nối 'in' với vector tương ứng của nó? HOẶC Tôi cần phải chuyển đổi số liệu thành float32 và sau đó để lại 'in' như nó; hy vọng rằng tensorflow sẽ làm tất cả các yêu cầu chế biến? Cảm ơn! – user3147590

+3

Ah, bạn có một vài lựa chọn ở đây. Bạn * có thể * sử dụng TensorFlow 'tf.decode_csv() 'op để chuyển đổi các tập tin văn bản thành một tensor, nhưng điều này có thể tốn kém (đặc biệt, nó đòi hỏi bạn phải tạo một' Tensor' cho mỗi cột, và sau đó nối các số với nhau). Có lẽ một giải pháp thay thế dễ dàng hơn là sử dụng ['pandas.read_csv()'] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) và ['pandas.DataFrame.as_matrix() '] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.as_matrix.html) để nhận đầu vào dưới dạng mảng NumPy. – mrry

+0

Sử dụng tùy chọn 2, có cách nào để vứt bỏ mảng NumPy và lưu một số bộ nhớ không? – morphe

23

tôi sử dụng phương pháp này để tải và chia sẻ nhúng.

W = tf.get_variable(name="W", shape=embedding.shape, initializer=tf.constant_initializer(embedding), trainable=False) 
6

Câu trả lời của @mrry là không đúng bởi vì nó provoques ghi đè lên các trọng embeddings mỗi mạng được chạy, vì vậy nếu bạn đang theo dõi một cách tiếp cận minibatch để đào tạo mạng, bạn được ghi đè lên các trọng của embeddings. Vì vậy, theo quan điểm của tôi, cách thích hợp để nhúng các tài liệu nhúng là:

embeddings = tf.get_variable("embeddings", shape=[dim1, dim2], initializer=tf.constant_initializer(np.array(embeddings_matrix)) 
+0

Bản sao chính xác của câu trả lời của LiuJia. – TimZaman

+3

@TimZaman .. Trong thực tế, anh ta thiếu đối số có thể đào tạo = False, và do đó sẽ kết thúc việc tinh chỉnh các nhúng của mình trong quá trình này. – Shatu

+3

Ngoài ra, tôi nghĩ lý do của Eugenio là không chính xác. Bạn chỉ cần không phải chạy "nhúng" với mỗi mini-batch, và mọi thứ sẽ ổn. Đó là, chỉ cần chạy khởi tạo nhúng chỉ một lần khi bắt đầu đào tạo. – Shatu

Các vấn đề liên quan