2017-07-15 28 views
12

Tôi tò mò làm thế nào tôi có thể thêm một vector kích thước ngẫu nhiên 300 bình thường (các yếu tố type = tf.float32) bất cứ khi nào một từ không biết đến từ vựng được đào tạo trước. Tôi đang sử dụng các bản nhúng từ GloVe đã được đào tạo trước, nhưng trong một số trường hợp, tôi nhận ra tôi gặp phải những từ chưa biết, và tôi muốn tạo một vectơ từ ngẫu nhiên bình thường cho từ mới chưa được tìm thấy này.Làm thế nào để thêm nhúng mới cho các từ chưa biết trong Tensorflow (đào tạo & thiết lập trước để thử nghiệm)

Vấn đề là với thiết lập hiện tại của tôi, tôi sử dụng tf.contrib.lookup.index_table_from_tensor để chuyển đổi từ từ thành số nguyên dựa trên từ vựng đã biết. Hàm này có thể tạo mã thông báo mới và băm chúng cho một số từ được xác định trước trong số các từ vựng, nhưng embed của tôi sẽ không chứa nhúng cho giá trị băm chưa biết mới này. Tôi không chắc chắn liệu tôi có thể chỉ thêm một đoạn nhúng ngẫu nhiên vào cuối danh sách embed hay không.

Tôi cũng muốn thực hiện điều này một cách hiệu quả, vì vậy chức năng lưu lượng hoặc phương pháp tensorflow được xây dựng sẵn liên quan đến chức năng tensorflow có lẽ sẽ hiệu quả nhất. Tôi định nghĩa các thẻ đặc biệt đã biết trước như một mã thông báo kết thúc và mặc định là chuỗi trống ("" ở chỉ mục 0), nhưng điều này bị giới hạn về sức mạnh của nó để tìm hiểu các từ không xác định khác nhau. Tôi hiện đang sử dụng tf.nn.embedding_lookup() làm bước nhúng cuối cùng.

Tôi muốn có thể thêm các vectơ 300d ngẫu nhiên mới cho mỗi từ không xác định trong dữ liệu đào tạo và tôi cũng muốn thêm các vectơ từ ngẫu nhiên được tạo sẵn cho bất kỳ mã thông báo không xác định nào không được thấy trong đào tạo. trong quá trình thử nghiệm. Cách hiệu quả nhất để làm điều này là gì?

def embed_tensor(string_tensor, trainable=True): 
    """  
    Convert List of strings into list of indicies then into 300d vectors 
    """ 
    # ordered lists of vocab and corresponding (by index) 300d vector 
    vocab, embed = load_pretrained_glove() 

    # Set up tensorflow look up from string word to unique integer 
    vocab_lookup = tf.contrib.lookup.index_table_from_tensor(
     mapping=tf.constant(vocab), 
     default_value = 0) 
    string_tensor = vocab_lookup.lookup(string_tensor) 

    # define the word embedding 
    embedding_init = tf.Variable(tf.constant(np.asarray(embed), 
           dtype=tf.float32), 
           trainable=trainable, 
           name="embed_init") 

    # return the word embedded version of the sentence (300d vectors/word) 
    return tf.nn.embedding_lookup(embedding_init, string_tensor) 

Trả lời

1

Tôi chưa bao giờ thử nó nhưng tôi có thể cố gắng cung cấp một cách có thể sử dụng các máy móc tương tự của mã của bạn, nhưng tôi sẽ nghĩ về nó sau này hơn.

Phương thức index_table_from_tensor chấp nhận thông số num_oov_buckets làm xáo trộn tất cả các từ oov của bạn thành số nhóm được xác định trước.

Nếu bạn đặt thông số này thành giá trị 'đủ lớn', bạn sẽ thấy sự lây lan dữ liệu giữa các nhóm này (mỗi nhóm có ID> ID của từ trong từ vựng cuối cùng).

Vì vậy,

  • if (tại mỗi tra cứu), bạn thiết lập (tức là assign) các hàng cuối cùng (những tương ứng với thùng) của embedding_init Variable của bạn đến một giá trị ngẫu nhiên
  • nếu bạn thực hiện num_oov_buckets đủ các va chạm lớn sẽ được giảm thiểu

bạn có thể có được hành vi (gần đúng) những gì bạn đang yêu cầu một cách rất hiệu quả.

Hành vi ngẫu nhiên có thể được chứng minh bằng lý thuyết tương tự như bảng băm: nếu số lượng nhóm đủ lớn, phương pháp băm của chuỗi sẽ gán mỗi từ oov cho một nhóm khác với xác suất cao (tức là giảm thiểu va chạm với cùng một nhóm). Vì, bạn đang gán một số ngẫu nhiên khác nhau cho mỗi nhóm khác nhau, bạn có thể có được một bản đồ (gần như) khác nhau của mỗi từ oov.

3

Ví dụ đoạn mã sau điều chỉnh embed_tensor chức năng của bạn như vậy mà từ được nhúng như sau:

  • Đối với những từ mà có một nhúng pretrained, nhúng được khởi tạo với nhúng pretrained. Việc nhúng có thể được giữ cố định trong khi đào tạo nếu trainableFalse.
  • Đối với các từ trong dữ liệu đào tạo không có nhúng sẵn, việc nhúng được khởi tạo ngẫu nhiên. Việc nhúng có thể được giữ cố định trong khi đào tạo nếu trainableFalse.
  • Đối với các từ trong dữ liệu thử nghiệm không xuất hiện trong dữ liệu đào tạo và không có nhúng sẵn, một vectơ nhúng được khởi tạo ngẫu nhiên duy nhất được sử dụng. Vector này không thể được đào tạo.
import tensorflow as tf 
import numpy as np 

EMB_DIM = 300 
def load_pretrained_glove(): 
    return ["a", "cat", "sat", "on", "the", "mat"], np.random.rand(6, EMB_DIM) 

def get_train_vocab(): 
    return ["a", "dog", "sat", "on", "the", "mat"] 

def embed_tensor(string_tensor, trainable=True): 
    """ 
    Convert List of strings into list of indices then into 300d vectors 
    """ 
    # ordered lists of vocab and corresponding (by index) 300d vector 
    pretrained_vocab, pretrained_embs = load_pretrained_glove() 
    train_vocab = get_train_vocab() 
    only_in_train = set(train_vocab) - set(pretrained_vocab) 
    vocab = pretrained_vocab + only_in_train 

    # Set up tensorflow look up from string word to unique integer 
    vocab_lookup = tf.contrib.lookup.index_table_from_tensor(
    mapping=tf.constant(vocab), 
    default_value=len(vocab)) 
    string_tensor = vocab_lookup.lookup(string_tensor) 

    # define the word embedding 
    pretrained_embs = tf.get_variable(
     name="embs_pretrained", 
     initializer=tf.constant_initializer(np.asarray(pretrained_embs), dtype=tf.float32), 
     shape=pretrained_embs.shape, 
     trainable=trainable) 
    train_embeddings = tf.get_variable(
     name="embs_only_in_train", 
     shape=[len(only_in_train), EMB_DIM], 
     initializer=tf.random_uniform_initializer(-0.04, 0.04), 
     trainable=trainable) 
    unk_embedding = tf.get_variable(
     name="unk_embedding", 
     shape=[1, EMB_DIM], 
     initializer=tf.random_uniform_initializer(-0.04, 0.04), 
     trainable=False) 

    embeddings = tf.concat([pretrained_embs, train_embeddings, unk_embedding], axis=0) 

    return tf.nn.embedding_lookup(embeddings, string_tensor) 

FYI, để có một hợp lý đại diện, không ngẫu nhiên cho những từ mà không xảy ra trong các dữ liệu đào tạo và không có một nhúng pretrained, bạn có thể xem xét từ bản đồ với một tần số thấp trong dữ liệu đào tạo của bạn cho một mã thông báo unk (không có trong từ vựng của bạn) và làm cho unk_embedding có thể đào tạo. Bằng cách này bạn học một nguyên mẫu cho các từ không nhìn thấy được trong dữ liệu huấn luyện.

0

Ý tưởng tôi có được là ghi lại các từ mới vào quá trình nhúng được đào tạo trước bằng cách thêm một chiều mới cho mỗi từ mới (về cơ bản duy trì bản chất nóng bỏng của chúng).

Giả sử số lượng từ mới nhỏ nhưng chúng quan trọng, bạn có thể tăng kích thước của kết quả được nhúng từ 300 lên 300 + # từ mới trong đó mỗi từ mới sẽ nhận được tất cả số không trừ 1 kích thước.

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