-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
01470a1
commit 780e0eb
Showing
8 changed files
with
12,340 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 84, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import numpy as np\n", | ||
"import tensorflow as tf " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 85, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"class HMM(object):\n", | ||
" def __init__(self, initial_prob, trans_prob, obs_prob):\n", | ||
" self.N = np.size(initial_prob)\n", | ||
" self.initial_prob = initial_prob\n", | ||
" self.trans_prob = trans_prob\n", | ||
" self.emission = tf.constant(obs_prob)\n", | ||
" assert self.initial_prob.shape == (self.N, 1)\n", | ||
" assert self.trans_prob.shape == (self.N, self.N)\n", | ||
" assert obs_prob.shape[0] == self.N\n", | ||
" self.obs_idx = tf.placeholder(tf.int32)\n", | ||
" self.fwd = tf.placeholder(tf.float64)\n", | ||
" \n", | ||
" def get_emission(self, obs_idx):\n", | ||
" slice_location = [0, obs_idx]\n", | ||
" num_rows = tf.shape(self.emission)[0]\n", | ||
" slice_shape = [num_rows, 1]\n", | ||
" return tf.slice(self.emission, slice_location, slice_shape)\n", | ||
" \n", | ||
" def forward_init_op(self):\n", | ||
" obs_prob = self.get_emission(self.obs_idx)\n", | ||
" fwd = tf.multiply(self.initial_prob, obs_prob)\n", | ||
" return fwd\n", | ||
" \n", | ||
" def forward_op(self):\n", | ||
" transitions = tf.matmul(self.fwd,\n", | ||
" tf.transpose(self.get_emission(self.obs_idx)))\n", | ||
" weighted_transitions = transitions * self.trans_prob\n", | ||
" fwd = tf.reduce_sum(weighted_transitions, 0)\n", | ||
" return tf.reshape(fwd, tf.shape(self.fwd))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 86, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def forward_algorithm(sess, hmm, observations):\n", | ||
" fwd = sess.run(hmm.forward_init_op(), feed_dict={hmm.obs_idx:observations[0]})\n", | ||
" for t in range(1, len(observations)):\n", | ||
" fwd = sess.run(hmm.forward_op(), feed_dict={hmm.obs_idx:observations[t], hmm.fwd: fwd})\n", | ||
" prob = sess.run(tf.reduce_sum(fwd))\n", | ||
" return prob" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 87, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Probability of observing [0, 1, 1, 2, 1] is 0.004540300799999999\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"initial_prob = np.array([[0.6],[0.4]])\n", | ||
"trans_prob = np.array([[0.7, 0.3],\n", | ||
" [0.4, 0.6]])\n", | ||
"obs_prob = np.array([[0.1, 0.4, 0.5],\n", | ||
" [0.6, 0.3, 0.1]])\n", | ||
"hmm = HMM(initial_prob=initial_prob, trans_prob=trans_prob, obs_prob=obs_prob)\n", | ||
"observations = [0, 1, 1, 2, 1]\n", | ||
"with tf.Session() as sess:\n", | ||
" prob = forward_algorithm(sess, hmm, observations)\n", | ||
" print('Probability of observing {} is {}'.format(observations, prob))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 91, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# this walks through the loop unfolding to learn more about how the HMM is actually doing the comuptation in this \n", | ||
"# simple weather example\n", | ||
"\n", | ||
"# basically in the first iteration to initialize, the HMM takes the first observation index, 0, aka 'walk'\n", | ||
"# and multiplies the probabilities of walking when it is raining / sunny times by the initial probabilities of it being rainy\n", | ||
"# or sunny to get a composite probability for it being rainy or sunny and having walked\n", | ||
"\n", | ||
"# then the next step steps through the rest of the observations, 'shopping', 'shopping', 'cleaning', 'shopping', and does\n", | ||
"# the following\n", | ||
"\n", | ||
"# for 'shopping', it takes the emission probability of seeing shopping in each state at that point, and multiplies it by the existing\n", | ||
"# forward model, then applies the weighted transition probabilities in each actual state (Rainy or Sunny), \n", | ||
"# through multiplication, and then accumulates them (through reduce_sum) to get the cumulitative probability of being \n", | ||
"# in either state given the observations thus far ('walk', 'shopping')\n", | ||
"\n", | ||
"# it does the same thing for the next observations, 'shopping', 'cleaning' and 'shopping' to get the cumultative probability\n", | ||
"# of being in either state\n", | ||
"\n", | ||
"# the final answer is the cumultation of either probability, so the likelihood of that sequence of events happening, \n", | ||
"# but not necessarily the highest probability state you are in\n", | ||
"\n", | ||
"with tf.Session() as sess:\n", | ||
" slice_location = [0, 0]\n", | ||
" num_rows = tf.shape(tf.constant(obs_prob))[0]\n", | ||
" slice_shape = [num_rows, 1]\n", | ||
" fwd0 = tf.slice(tf.constant(obs_prob), slice_location, slice_shape)\n", | ||
" fwd0_eval = fwd0.eval()\n", | ||
" fwd0 = tf.multiply(initial_prob, fwd0)\n", | ||
" fwd0_eval = fwd0.eval()\n", | ||
" transitions1 = tf.matmul(fwd0, tf.transpose(np.array([[0.4], [0.3]])))\n", | ||
" weighted_transitions1 = transitions1 * trans_prob\n", | ||
" fwd1 = tf.reduce_sum(weighted_transitions1, 0)\n", | ||
" fwd1_prs_e = fwd1.eval()\n", | ||
" fwd1 = tf.reshape(fwd1, tf.shape(fwd0))\n", | ||
" fwd1_eval = fwd1.eval()\n", | ||
" \n", | ||
" transitions2 = tf.matmul(fwd1, tf.transpose(np.array([[0.4], [0.3]])))\n", | ||
" weighted_transitions2 = transitions2 * trans_prob\n", | ||
" fwd2 = tf.reduce_sum(weighted_transitions2, 0)\n", | ||
" fwd2_prs_e = fwd2.eval()\n", | ||
" fwd2 = tf.reshape(fwd2, tf.shape(fwd1))\n", | ||
" fwd2_eval = fwd2.eval()\n", | ||
" \n", | ||
"\n", | ||
" transitions3 = tf.matmul(fwd2, tf.transpose(np.array([[0.5], [0.1]])))\n", | ||
" weighted_transitions3 = transitions3 * trans_prob\n", | ||
" fwd3 = tf.reduce_sum(weighted_transitions3, 0)\n", | ||
" fwd3_prs_e = fwd3.eval()\n", | ||
" fwd3 = tf.reshape(fwd3, tf.shape(fwd2))\n", | ||
" fwd3_eval = fwd3.eval()\n", | ||
" \n", | ||
" transitions4 = tf.matmul(fwd3, tf.transpose(np.array([[0.4], [0.3]])))\n", | ||
" weighted_transitions4 = transitions4 * trans_prob\n", | ||
" fwd4 = tf.reduce_sum(weighted_transitions4, 0)\n", | ||
" fwd4_prs_e = fwd4.eval()\n", | ||
" fwd4 = tf.reshape(fwd4, tf.shape(fwd3))\n", | ||
" fwd4_eval = fwd4.eval()\n", | ||
" \n", | ||
" final_prob = tf.reduce_sum(fwd4)\n", | ||
" final_prob_e = final_prob.eval()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 89, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"[[0.06]\n", | ||
" [0.24]]\n", | ||
"[0.0552 0.0486]\n", | ||
"[[0.0552]\n", | ||
" [0.0486]]\n", | ||
"[0.023232 0.013716]\n", | ||
"[[0.023232]\n", | ||
" [0.013716]]\n", | ||
"[0.0108744 0.00151992]\n", | ||
"[[0.0108744 ]\n", | ||
" [0.00151992]]\n", | ||
"[0.00328802 0.00125228]\n", | ||
"[[0.00328802]\n", | ||
" [0.00125228]]\n", | ||
"0.004540300799999999\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"print(fwd0_eval)\n", | ||
"print(fwd1_prs_e)\n", | ||
"print(fwd1_eval)\n", | ||
"print(fwd2_prs_e)\n", | ||
"print(fwd2_eval)\n", | ||
"print(fwd3_prs_e)\n", | ||
"print(fwd3_eval)\n", | ||
"print(fwd4_prs_e)\n", | ||
"print(fwd4_eval)\n", | ||
"print(final_prob_e)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.7.0b1" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.