tf.nn.sampled_softmax_loss用法简单介绍
在研究Skip-gram模型时遇到了采用方式的softmax,一时没有搞明白,下面做个小案例试一下。
tf.nn.sampled_softmax_loss函数的参数类别如下:
tf.nn.sampled_softmax_loss(
weights, # Shape (num_classes, dim) 神经网络输出层权重
biases, # Shape (num_classes) 神经网络输出层偏置
labels, # Shape (batch_size, num_true) 输出层标签,该标签与常规的softmax在使用中是有区别的,增加了num_true 维度
inputs, # Shape (batch_size, dim) 输出层的输入
num_sampled, # - int 采样个数
num_classes, # - int 分类类别
num_true=1, # - int 在负采样softmax中的实际分类(正负),默认为1即二分类
sampled_values=None,
remove_accidental_hits=True,
partition_strategy="mod",# - 采样模式(有点麻烦,有空再解释吧)
name="sampled_softmax_loss")
Negative Sampling是替代层次化softmax的一种方法方法。该方法借助于噪声,使用不属于目标词所在上下文的词创建与实际词对不相符的词对,进而可以将softmax激活函数替换为sigmoid 函数,负采样的目标可以定义为:
在文献 Distributed Representations of Words and Phrases and their Compositionality中有简单介绍。
下面我们用负采用的方法实现对MINST数据集的分类预测问题,Python代码实现如下:
import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("MNIST.data",one_hot=True)
print('输入数据:',mnist.train.images)
print('输入数据的大小:',mnist.train.images.shape)
import pylab
im=mnist.train.images[1]
im=im.reshape(-1,28)
pylab.imshow(im)
pylab.show()
tf.reset_default_graph()
inputs=tf.placeholder(tf.float32,[None,784])
Y=tf.placeholder(tf.float32,[None,10])
labels=tf.reshape(tf.argmax(Y,1),[-1,1])
W=tf.Variable(tf.random_normal([784,10]))
Weight=tf.transpose(W)
bias=tf.Variable(tf.zeros([10]))
num_sampled = 3
num_true = 1
num_classes = 10
cost=tf.reduce_mean(tf.nn.sampled_softmax_loss(
weights=Weight,
biases=bias,
labels=labels,
inputs=inputs,
num_sampled=num_sampled,
num_true=num_true,
num_classes=num_classes))
learning_rate=0.001
optimizer=tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)
training_epochs=25
batch_size=100
display_step=1
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(training_epochs):
avg_cost=0.
total_batch=int(mnist.train.num_examples/batch_size)
for i in range(batch_size):
batch_xs,bathc_ys=mnist.train.next_batch(batch_size)
_,c=sess.run([optimizer,cost],feed_dict={inputs:batch_xs,Y:bathc_ys})
avg_cost+=c/total_batch
if (epoch+1) % display_step == 0:
print("Epoch:",'%04d'%(epoch+1),"cost=","{:.9f}".format(avg_cost))
print("Finished")
我和原来普通softmax对比了一下,发现速度变慢了,没搞懂为啥,还要研究研究。