In [1]:
%pylab inline
In [2]:
import numpy as np
import tensorflow as tf
from tensorflow_hmm import hmm
In [3]:
from pylab import rcParams
rcParams['figure.figsize'] = 15, 5
In [4]:
P = np.array([[0.9, 0.1], [0.1, 0.9]])
P = P**1
P = P / np.sum(P,1)
print 'P', P
hmm_tf = hmm.HMMTensorflow(P, np.array([0.0, 1.0]))
In [5]:
# observations = np.array([0, 0.0, 1.0, 1.0])
# observations = np.array([0.5] * 90)
# observations = np.random.random(60)
# observations = np.zeros(90)
# observations = np.sin(np.arange(-10, 10, 20/90.))
# observations -= 0.2
# observations[62:] = 0.2
# observations += np.arange(-1, 1, 2 / 90.)
# observations += np.random.random(90) * 0.4 - 0.2
In [6]:
# truth is off for 60 steps, then on for 30 time steps
truth = np.array([[1, 0]]*60 + [[0, 1]]*30, dtype=float)
truth = np.expand_dims(truth, axis=0)
In [7]:
observations = np.random.random((1, 90, 2)) * 4 - 2
plot(observations[0,:,:])
grid()
In [8]:
observations_variable = tf.Variable(observations)
In [9]:
posterior_graph, _, _ = hmm_tf.forward_backward(tf.sigmoid(observations_variable))
In [10]:
# build error function
sum_error_squared = tf.reduce_sum(tf.square(truth - posterior_graph))
In [11]:
# calculate d_observation/d_error
gradients_graph = tf.gradients(sum_error_squared, observations_variable)
In [12]:
session = tf.Session()
session.run(tf.initialize_all_variables())
In [ ]:
In [ ]:
In [13]:
steps = 0
In [54]:
posterior = session.run(posterior_graph)
In [55]:
print 'sum error squared: %.03f' % sum((truth[:,1] - posterior[:,1])**2)
plot(posterior[0,:,1], label='posterior')
plot(truth[0,:,1], label='truth')
grid()
legend()
Out[55]:
In [56]:
gradients = session.run(gradients_graph)[0]
In [57]:
def plot_gradients(gradients):
gradients = gradients[0]
# whiten gradients
gradients = gradients / np.std(gradients)
plot(-gradients[:,1], label='gradients')
plot(truth[0,:,1], label='truth')
# plot(sigmoid(observations[0,:,1]), label='observations')
plot(observations[0,:,1], label='observations')
ylim((-5,5))
grid()
legend()
In [58]:
plot_gradients(gradients)
In [59]:
for i in range(1):
# take 1 gradient descent step
steps += 1
observations = session.run(
observations_variable.assign_sub(gradients * 0.5 * (random.random() - 0.25))
)
In [60]:
plot(observations[0,:,1], label='observations')
sigmoid = np.vectorize(lambda(x): 1.0/(1.0+np.exp(-x)))
# plot(sigmoid(observations[0,:,1]), label='sigmoid(observations)')
legend()
grid()
In [ ]:
In [64]:
hmm_np = hmm.HMMNumpy(np.array([[0.9, 0.1], [0.1, 0.9]]), p0=np.array([0.5, 0.5]))
out, _ = hmm_np.viterbi_decode(sigmoid(observations[0,:,:]))
print 'gradient steps taken:', steps
print 'viterbi error:', sum((truth[0,:,1] - out)**2)
plot(truth[0,:,1], label='truth')
plot(out, label='out')
grid()
legend()
Out[64]:
In [ ]:
In [ ]:
In [ ]:
In [ ]: