Import the relevant libraries
In [1]:
import tensorflow as tf
import numpy as np
import random
%matplotlib inline
import matplotlib.pyplot as plt
Let's fabricate some data. We'll call get_data()
to generate two datasets: data_a
and data_b
.
We'll use the convention that points in data_a
are ranked lower than those in data_b
. So we need to learn a ranking function (i.e. utility function) that scores points in data_a
lower.
In [2]:
n_features = 2
def get_data():
data_a = np.random.rand(10, n_features) + 1
data_b = np.random.rand(10, n_features)
plt.scatter(data_a[:, 0], data_a[:, 1], c='r', marker='x')
plt.scatter(data_b[:, 0], data_b[:, 1], c='g', marker='o')
plt.show()
return data_a, data_b
def get_data2():
data_a = np.asarray([[0.1, 0.9], [0.1, 0.8]])
data_b = np.asarray([[0.4,0.05], [0.45, 0.1]])
plt.scatter(data_a[:, 0], data_a[:, 1], c='r', marker='x')
plt.scatter(data_b[:, 0], data_b[:, 1], c='g', marker='o')
plt.xlim([0, 0.5])
plt.ylim([0, 1])
plt.axes().set_aspect('equal')
plt.show()
return data_a, data_b
data_a, data_b = get_data()
Now, let's define our ranking model. It'll take in two items (x1
and x2
), and return a score (s1
and s2
) for each item.
Our model introduces a hyper-parameter called n_hidden
to tweak the number of neurons in the hidden layer of the network.
In [3]:
n_hidden = 10
When defining the model, let's organize it into separate scopes. That way, the TensorBoard visualization will look very clean.
In [4]:
with tf.name_scope("input"):
x1 = tf.placeholder(tf.float32, [None, n_features], name="x1")
x2 = tf.placeholder(tf.float32, [None, n_features], name="x2")
dropout_keep_prob = tf.placeholder(tf.float32, name='dropout_prob')
with tf.name_scope("hidden_layer"):
with tf.name_scope("weights"):
w1 = tf.Variable(tf.random_normal([n_features, n_hidden]), name="w1")
tf.summary.histogram("w1", w1)
b1 = tf.Variable(tf.random_normal([n_hidden]), name="b1")
tf.summary.histogram("b1", b1)
with tf.name_scope("output"):
h1 = tf.nn.dropout(tf.nn.relu(tf.matmul(x1,w1) + b1), keep_prob=dropout_keep_prob)
tf.summary.histogram("h1", h1)
h2 = tf.nn.dropout(tf.nn.relu(tf.matmul(x2, w1) + b1), keep_prob=dropout_keep_prob)
tf.summary.histogram("h2", h2)
with tf.name_scope("output_layer"):
with tf.name_scope("weights"):
w2 = tf.Variable(tf.random_normal([n_hidden, 1]), name="w2")
tf.summary.histogram("w2", w2)
b2 = tf.Variable(tf.random_normal([1]), name="b2")
tf.summary.histogram("b2", b2)
with tf.name_scope("output"):
s1 = tf.matmul(h1, w2) + b2
s2 = tf.matmul(h2, w2) + b2
The loss function will involve comparing s1
and s2
.
Since we're trying to acheive the inequality Score(x1) < Score(x2)
, we need the loss function to insinuate s1 < s2
.
In other words, the loss function tries to guarantee that s1 - s2 < 0
.
In [5]:
with tf.name_scope("loss"):
s12 = s1 - s2
s12_flat = tf.reshape(s12, [-1])
pred = tf.sigmoid(s12)
lable_p = tf.sigmoid(-tf.ones_like(s12))
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=tf.zeros_like(s12_flat), logits=s12_flat + 1)
loss = tf.reduce_mean(cross_entropy)
tf.summary.scalar("loss", loss)
with tf.name_scope("train_op"):
train_op = tf.train.AdamOptimizer(0.001).minimize(loss)
Start the session and prepare peripheral ops.
In [6]:
sess = tf.InteractiveSession()
summary_op = tf.summary.merge_all()
writer = tf.summary.FileWriter("tb_files", sess.graph)
init = tf.global_variables_initializer()
sess.run(init)
Train the model with the training data.
In [7]:
for epoch in range(0, 10000):
loss_val, _ = sess.run([loss, train_op], feed_dict={x1:data_a, x2:data_b, dropout_keep_prob:0.5})
if epoch % 100 == 0 :
summary_result = sess.run(summary_op, feed_dict={x1:data_a, x2:data_b, dropout_keep_prob:1})
writer.add_summary(summary_result, epoch)
# print("Epoch {}: Loss {}".format(epoch, loss_val))
Visualize the results on a grid by accumulating a list of points to test.
In [8]:
grid_size = 10
data_test = []
for y in np.linspace(0., 1., num=grid_size):
for x in np.linspace(0., 1., num=grid_size):
data_test.append([x, y])
Run the model on all the test points and visualize the utility scores of each point by a color.
In [9]:
def visualize_results(data_test):
plt.figure()
scores_test = sess.run(s1, feed_dict={x1:data_test, dropout_keep_prob:1})
scores_img = np.reshape(scores_test, [grid_size, grid_size])
plt.imshow(scores_img, origin='lower')
plt.colorbar()
In [10]:
visualize_results(data_test)