使用tensorflow来做word2vector(2)--实际操作

        上篇文章对word2vector做了简单的描述,本篇主要是进行基础实践,

基本翻译来自:https://adventuresinmachinelearning.com/word2vec-tutorial-tensorflow/

加上我的一些理解。

基本步骤为:   

1、构建词袋,词袋的意思是你所要处理的所有词的一个set,并用唯一标识来标识某一个词,并统计每个词出现的次数。这里可以用简单的index,也可以用hash等方法。其实这也可以理解为为所有词建立一个loop-up table。

```

def build_dataset(words, n_words): 

 """Process raw inputs into a dataset.""" 

 count = [['UNK', -1]] count.extend(collections.Counter(words).most_common(n_words - 1)) dictionary = dict() 

 for word, _ in count: 

     dictionary[word] = len(dictionary) 

 data = list() 

 unk_count = 0 

 for word in words:

     if word in dictionary:

         index = dictionary[word]     

     else:

         index = 0 # dictionary['UNK'] 

         unk_count += 1 

    data.append(index) 

 count[0][1] = unk_count

 reversed_dictionary = dict(zip(dictionary.values(), dictionary.keys()))   

 return data, count, dictionary, reversed_dictionary

```


2、构建batch,作为神经网络的输入使用。batch中包括输入的词和label,这个label是随机给定的,作为该gram的需要预测的给定的label。比如,对于这句话“the cat sat on the mat”,如果gram是3个,那么就是 the cat sat, cat sat on ....,如果是5个,就为 the cat sat on the,输出词为sat,将要预测的上下文就是从剩下的 [‘the’, ‘cat’, ‘on’, ‘the’]中随机选择。上下文窗口的意思是在输入词的周围选择几个词。

    关于输入词和label,如果你的场景下,对于给定的输入词,给定了具体的label,那么直接进行构建即可。如在推荐场景下的dssm和youtube dnn模型中,输入词即为用户观看过得一系列视频,label为用户下一次观看的视频。

```

data_index = 0

# generate batch data

def generate_batch(data, batch_size, num_skips, skip_window): 

      global data_index

       assert batch_size % num_skips == 0   

        assert num_skips <= 2 * skip_window

        batch = np.ndarray(shape=(batch_size), dtype=np.int32)    

         context = np.ndarray(shape=(batch_size, 1), dtype=np.int32)    

        span = 2 * skip_window + 1  # [ skip_window input_word skip_window ]    

        buffer = collections.deque(maxlen=span)    

        for _ in range(span):        

                buffer.append(data[data_index])        

                data_index = (data_index + 1) % len(data)    

        for i in range(batch_size // num_skips):        

                target = skip_window  # input word at the center of the buffer        

                targets_to_avoid = [skip_window]        

                for j in range(num_skips):            

                    while target in targets_to_avoid:                

                        target = random.randint(0, span - 1)            

                    targets_to_avoid.append(target)            

                    batch[i * num_skips + j] = buffer[skip_window]  # this is the input word            

                    context[i * num_skips + j, 0] = buffer[target]  # these are the context words        

                    buffer.append(data[data_index])        

                    data_index = (data_index + 1) % len(data)    

            # Backtrack a little bit to avoid skipping words in the end of a batch    

    data_index = (data_index + len(data) - span) % len(data)    

     return batch, context

```

3、构建好输入后,即使用tensorflow来进行word2vector的训练。

注意:因为中间这一隐层是一个全连接层,所以会出现embeddings 的维度和weights 的维度相同的情况。

batch_size = 128

embedding_size = 128 # Dimension of the embedding vector.

skip_window = 1 # How many words to consider left and right.

num_skips = 2 # How many times to reuse an input to generate a context.

train_inputs = tf.placeholder(tf.int32, shape=[batch_size])

train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])

valid_dataset = tf.constant(valid_examples, dtype=tf.int32)

# Look up embeddings for inputs.

embeddings = tf.Variable( tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))

# vocabulary_size就是输入词袋的大小,如10000,使用的是one-hot的表达

#embedding_size就是将要embeding的维度。

embed = tf.nn.embedding_lookup(embeddings, train_inputs)

# tf.nn.embedding_lookup就是对这些embedding的词查找其所在的index。

#为输出层构建变量

# Construct the variables for the softmax

weights = tf.Variable(tf.truncated_normal([vocabulary_size, embedding_size], stddev=1.0 / math.sqrt(embedding_size)))

biases = tf.Variable(tf.zeros([vocabulary_size]))

hidden_out = tf.matmul(embed, tf.transpose(weights)) + biases

#最后使用交叉熵来训练模型变量,注意需要将输入先转为one-hot的形式。

# convert train_context to a one-hot format

train_one_hot = tf.one_hot(train_context, vocabulary_size)

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=hidden_out, labels=train_one_hot))

# Construct the SGD optimizer using a learning rate of 1.0.

optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(cross_entropy)

注意模型训练完之后,当然要进行验证,可以使用cosine夹角来验证训练的效果

# Compute the cosine similarity between minibatch examples and all embeddings.

norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=True))

normalized_embeddings = embeddings / norm

4、然而,使用以上的训练方法很慢,原因在于在最后一层softmax中,需要计算所有可能词的出现的概率,即10000。所以采用NCE(noise contrastive estimation),该方法仅随机挑选2-20个可能的词来进行概率预测。

所以在实际应用中,可以直接调用tensor的函数

```

# Construct the variables for the NCE loss

nce_weights = tf.Variable( tf.truncated_normal([vocabulary_size, embedding_size], stddev=1.0 / math.sqrt(embedding_size)))

nce_biases = tf.Variable(tf.zeros([vocabulary_size]))

nce_loss = tf.reduce_mean( 

             tf.nn.nce_loss(weights=nce_weights,     

                                        biases=nce_biases,

                                         labels=train_context, 

                                        inputs=embed, 

                                        num_sampled=num_sampled, 

                                num_classes=vocabulary_size))

optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(nce_loss)

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容