Ejemplo n.º 1
0
def Viterbi(all_possible_hidden_states, all_possible_observed_states,
            prior_distribution, transition_model, observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """
    previous_message = rover.Distribution()
    path_map = [dict() for x in range(100)]
    for i, observation in enumerate(observations):
        current_message = rover.Distribution()

        for current_state in all_possible_hidden_states:
            if not observation:
                log_p_X_given_Z = 0
            else:
                log_p_X_given_Z = Log(
                    observation_model(current_state)[observation])

            if i == 0:
                current_message[current_state] = log_p_X_given_Z + Log(
                    prior_distribution[current_state])

            else:
                max_found = -math.inf
                max_prev_state = None
                for previous_state in all_possible_hidden_states:
                    transition_prob = Log(
                        transition_model(previous_state)
                        [current_state]) + previous_message[previous_state]
                    if transition_prob > max_found:
                        max_found = transition_prob
                        max_prev_state = previous_state
                path_map[i][current_state] = max_prev_state
                current_message[current_state] = log_p_X_given_Z + max_found

        previous_message = current_message

    # Reconstruct the Path
    current_state = max(current_message, key=lambda key: current_message[key])
    estimated_hidden_states = [current_state]
    for i in reversed(range(1, 100)):
        current_state = path_map[i][current_state]
        estimated_hidden_states.insert(0, current_state)

    return estimated_hidden_states
Ejemplo n.º 2
0
def Viterbi(all_possible_hidden_states, all_possible_observed_states,
            prior_distribution, transition_model, observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """

    # TODO: Write your code here
    w = [None] * num_time_steps
    backtrack = [None] * num_time_steps
    estimated_hidden_states = [None] * num_time_steps
    for i in range(num_time_steps):
        w[i] = rover.Distribution()
        # Initialization
        if i == 0:
            for state in prior_distribution:
                result = prior_distribution[state]
                result *= observation_model(state)[observations[0]]
                if result != 0:
                    w[i][state] = np.log(result)
        # Recursive
        else:
            backtrack[i] = {}
            for state in all_possible_hidden_states:
                p1 = 1
                if observations[i] != None:
                    p1 = observation_model(state)[observations[i]]
                if p1 == 0:
                    continue
                p2 = -np.inf
                for k in w[i - 1]:
                    if transition_model(k)[state] == 0:
                        continue
                    temp = np.log(transition_model(k)[state]) + w[i - 1][k]
                    if temp > p2:
                        p2 = temp
                        backtrack[i][state] = k
                result = np.log(p1) + p2
                if p2 != -np.inf and result != 0:
                    w[i][state] = result

    # Backtracking
    n = num_time_steps - 1
    estimated_hidden_states[n] = max(w[n], key=w[n].get)
    for i in range(1, num_time_steps):
        n = num_time_steps - 1 - i
        k = estimated_hidden_states[n + 1]
        estimated_hidden_states[n] = backtrack[n + 1][k]

    return estimated_hidden_states
def forward_backward(all_possible_hidden_states, all_possible_observed_states,
                     prior_distribution, transition_model, observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    #forward_messages[0] = prior_distribution
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps

    # TODO: Compute the forward messages
    # initialization of forward message
    forward_messages[0] = rover.Distribution({})
    initial_observed_position = observations[0]
    for z0 in all_possible_hidden_states:
        if initial_observed_position == None:
            initial_prob_position_on_state = 1
        else:
            initial_prob_position_on_state = observation_model(
                z0)[initial_observed_position]
        prior_z0 = prior_distribution[z0]
        if (initial_prob_position_on_state * prior_z0) != 0:
            forward_messages[0][z0] = initial_prob_position_on_state * prior_z0
    forward_messages[0].renormalize()

    # when i >= 1
    for i in range(1, num_time_steps):
        forward_messages[i] = rover.Distribution({})
        observed_position = observations[i]
        for zi in all_possible_hidden_states:
            if observed_position == None:
                prob_position_on_state = 1
            else:
                prob_position_on_state = observation_model(
                    zi)[observed_position]

            sum = 0
            for zi_minus_1 in forward_messages[i - 1]:
                sum = sum + forward_messages[
                    i - 1][zi_minus_1] * transition_model(zi_minus_1)[zi]
            if (prob_position_on_state *
                    sum) != 0:  # only save non-zero values
                forward_messages[i][zi] = prob_position_on_state * sum

        forward_messages[i].renormalize()  # normalize forward messages

    # TODO: Compute the backward messages
    # initialization of backward message
    backward_messages[num_time_steps - 1] = rover.Distribution({})
    for zn_minus_1 in all_possible_hidden_states:
        backward_messages[num_time_steps - 1][zn_minus_1] = 1
    # when backward message is not the last one
    for i in range(1, num_time_steps):
        backward_messages[num_time_steps - 1 - i] = rover.Distribution({})
        for zi in all_possible_hidden_states:
            sum = 0
            for zi_plus_1 in backward_messages[num_time_steps - 1 - i + 1]:
                observed_position = observations[num_time_steps - 1 - i + 1]
                if observed_position == None:
                    prob_position_on_next_state = 1
                else:
                    prob_position_on_next_state = observation_model(
                        zi_plus_1)[observed_position]
                sum = sum + backward_messages[num_time_steps - 1 - i + 1][
                    zi_plus_1] * prob_position_on_next_state * transition_model(
                        zi)[zi_plus_1]
            if sum != 0:
                backward_messages[num_time_steps - 1 - i][zi] = sum
        backward_messages[num_time_steps - 1 - i].renormalize()

    # TODO: Compute the marginals
    for i in range(0, num_time_steps):
        marginals[i] = rover.Distribution({})
        sum = 0
        for zi in all_possible_hidden_states:
            if forward_messages[i][zi] * backward_messages[i][zi] != 0:
                marginals[i][
                    zi] = forward_messages[i][zi] * backward_messages[i][zi]
                sum = sum + forward_messages[i][zi] * backward_messages[i][zi]
        for zi in marginals[i].keys():
            marginals[i][zi] = marginals[i][zi] / sum

    return marginals
def Viterbi(all_possible_hidden_states, all_possible_observed_states,
            prior_distribution, transition_model, observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """

    # TODO: Write your code here
    num_time_steps = len(observations)
    w = [None] * num_time_steps
    estimated_hidden_states = [None] * num_time_steps
    z_previous = [None] * num_time_steps

    # initialization
    w[0] = rover.Distribution({})
    initial_observed_position = observations[0]
    for z0 in all_possible_hidden_states:
        if initial_observed_position == None:
            initial_prob_position_on_state = 1
        else:
            initial_prob_position_on_state = observation_model(
                z0)[initial_observed_position]
        prior_z0 = prior_distribution[z0]
        if (initial_prob_position_on_state != 0) and (prior_z0 != 0):
            w[0][z0] = np.log(initial_prob_position_on_state) + np.log(
                prior_z0)

    # when i >= 1
    for i in range(1, num_time_steps):
        w[i] = rover.Distribution({})
        z_previous[i] = dict()
        observed_position = observations[i]
        for zi in all_possible_hidden_states:
            if observed_position == None:
                prob_position_on_state = 1
            else:
                prob_position_on_state = observation_model(
                    zi)[observed_position]
            max_term = -np.inf
            for zi_minus_1 in w[i - 1]:
                if transition_model(zi_minus_1)[zi] != 0:
                    potential_max_term = np.log(
                        transition_model(zi_minus_1)[zi]) + w[i -
                                                              1][zi_minus_1]
                    if (potential_max_term >
                            max_term) and (prob_position_on_state != 0):
                        max_term = potential_max_term
                        z_previous[i][
                            zi] = zi_minus_1  # keep track of which zi_minus_1 can maximize w[i][zi]

            if prob_position_on_state != 0:
                w[i][zi] = np.log(prob_position_on_state) + max_term

    # back track to find z0 to zn
    # first, find zn* (the last)
    max_w = -np.inf
    for zi in w[num_time_steps - 1]:
        potential_max_w = w[num_time_steps - 1][zi]
        if potential_max_w > max_w:
            max_w = potential_max_w
            estimated_hidden_states[num_time_steps - 1] = zi

    for i in range(1, num_time_steps):
        estimated_hidden_states[num_time_steps - 1 - i] = z_previous[
            num_time_steps - i][estimated_hidden_states[num_time_steps - i]]

    return estimated_hidden_states
def forward_backward(all_possible_hidden_states,
                     all_possible_observed_states,
                     prior_distribution,
                     transition_model,
                     observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    forward_messages[0] = prior_distribution
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps

    uniform = rover.Distribution()
    uniform.update(dict([(i, 1) for i in all_possible_hidden_states]))
    uniform.renormalize()


    allObs = [all_possible_observed_states if i is None else [i] for i in observations]

    # TODO: Compute the forward messages
    print("forward")
    forward_messages[0]=rover.Distribution()
    for i in prior_distribution:
        obsFactor=observation_model(i)
        for j in obsFactor:
            if j in allObs[0]:
                forward_messages[0][(i[0],i[1], 'stay')]=obsFactor[j]
    forward_messages[0].renormalize()
    # print(0, ". ", forward_messages[0])

    for i in range(num_time_steps - 1):
        forward_messages[i + 1] = rover.Distribution()
        for j in forward_messages[i]:  # states of i
            transTemp = rover.transition_model(j)
            for k in transTemp:
                # print(k, allObs[i+1])
                obsFactor=observation_model(k) #(place): chance
                for l in obsFactor:
                    if l in allObs[i+1]:
                        forward_messages[i + 1] = addValToDic(forward_messages[i + 1], k,
                                                               forward_messages[i][j] * transTemp[k]*obsFactor[l])

        forward_messages[i + 1].renormalize()
        # print(i, ". ", forward_messages[i])
        # print(i + 1, ". ", allObs[i + 1], observations[i + 1])
        # print(i + 1, ". ", forward_messages[i + 1], "\n")
    # TODO: Compute the backward messages

    backward_messages[-1] = uniform

    print("back")

    # print(-1, ". ", backward_messages[-1])
    for i in range(num_time_steps - 1, 0, -1):
        backward_messages[i - 1] = rover.Distribution()
        # revTrans=rover.Distribution()
        for j in all_possible_hidden_states: #states of i-1
            transTemp = rover.transition_model(j)
            for k in transTemp:
                if k in backward_messages[i]:
                    obsFactor=observation_model(k)
                    for l in obsFactor:
                        if l in allObs[i]:#
                            backward_messages[i-1]=addValToDic(backward_messages[i-1], j, backward_messages[i][k]*transTemp[k]*obsFactor[l])


        backward_messages[i - 1].renormalize()
        # print(i, ". ", backward_messages[i].get_mode(), backward_messages[i][backward_messages[i].get_mode()],
        #       "message", backward_messages[i])
        # print(i, ".", allObs[i], observations[i])
        # print(i - 1, ". ", backward_messages[i - 1].get_mode(),
        #       backward_messages[i - 1][backward_messages[i - 1].get_mode()], "message", backward_messages[i - 1], '\n')

    # TODO: Compute the marginals
    for i in range(num_time_steps):
        marginals[i] = rover.Distribution()
        marginals[i].update(dict(
            [(k, forward_messages[i][j] * backward_messages[i][k]) for j in forward_messages[i] for k in
             backward_messages[i] if j == k]))
        marginals[i].renormalize()
        # print(marginals[i], forward_messages[i], backward_messages[i])
    return marginals
Ejemplo n.º 6
0
def forward_backward(all_possible_hidden_states,
                     all_possible_observed_states,
                     prior_distribution,
                     transition_model,
                     observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    forward_messages[0] = prior_distribution
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps 
    
    for i in range(num_time_steps):
        # TODO: Compute the forward messages
        forward_messages[i] = rover.Distribution({})  
        if i == 0:
            for z_n in prior_distribution:
                z0 = observations[i]
                forward_messages[i][z_n] = prior_distribution[z_n] * observation_model(z_n)[z0]
            forward_messages[i].renormalize()
        else:
            xy_n = observations[i]
            for z_n in all_possible_hidden_states:
                if xy_n == None:
                    cond = 1
                else:
                    cond = observation_model(z_n)[xy_n]
                if cond != 0:
                    prob = 0
                    for prev in (forward_messages[i-1]):
                        prob += forward_messages[i-1][prev] * transition_model(prev)[z_n]
                    if prob != 0:
                        forward_messages[i][z_n] = cond * prob
            forward_messages[i].renormalize()
        #print(forward_messages[i], "for i = ",i)

        # TODO: Compute the backward messages
        last = num_time_steps - 1 - i
        backward_messages[last] = rover.Distribution({})
        if i == 0:
            for z_n in all_possible_hidden_states:
                backward_messages[last][z_n] = 1
        else:
            xy_n1 = observations[last + 1]
            for z_n in all_possible_hidden_states:
                prob = 0
                for z_n1 in backward_messages[last+1]:
                    if xy_n1 == None:
                        cond = 1
                    else:
                        cond = observation_model(z_n1)[xy_n1]
                    prob += backward_messages[last + 1][z_n1] * transition_model(z_n)[z_n1] * cond
                if prob != 0:
                    backward_messages[last][z_n] = prob
            backward_messages[last].renormalize()

    # TODO: Compute the marginals

    for i in range(num_time_steps):
        marginals[i] = rover.Distribution()
        for z_n in all_possible_hidden_states:
            alpha = forward_messages[i][z_n]
            beta = backward_messages[i][z_n]
            if alpha * beta != 0:
                marginals[i][z_n] = (alpha * beta)
        marginals[i].renormalize()
    #print("Marginal for is",marginals[1], "for i = 1")
    return marginals
Ejemplo n.º 7
0
def Viterbi(all_possible_hidden_states,
            all_possible_observed_states,
            prior_distribution,
            transition_model,
            observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """

    # TODO: Write your code here
    # Stores all Wi's
    W = [None] * len(observations)
    map_sequence = []

    # Key is Z_n+1 and value is Z_n hidden state
    links = []
    for t in range(len(observations)):
        newdict = dict()
        links.append(dict())

    # Calculate W0
    p_z0 = prior_distribution
    W0 = rover.Distribution()
    log_p_xz = rover.Distribution()
    for hidden_state in p_z0:
        likelihood = observation_model(hidden_state)
        if (observations[0] is None):
            log_p_xz[hidden_state] = 0
        else:
            log_p_xz[hidden_state] = safe_log(likelihood[observations[0]])
        W0[hidden_state] = log_p_xz[hidden_state] + safe_log(p_z0[hidden_state])
        #print(W0[hidden_state])

    #print(len(W0))
    W[0] = W0

    # Calculate Wi
    for t in range(1, len(observations)):
        W_t = rover.Distribution()
        log_p_xz = rover.Distribution()
        for hidden_state in all_possible_hidden_states:
            likelihood = observation_model(hidden_state)
            if (observations[t] is None):
                log_p_xz[hidden_state] = 0
            else:
                log_p_xz[hidden_state] = safe_log(likelihood[observations[t]])
            max_log_prob, arg_max = get_max(hidden_state, W[t - 1])
            if arg_max != None:
                '''print(t)
                print(hidden_state)
                print(links[t])

                while True:
                    pass'''



                links[t][hidden_state] = arg_max
                W_t[hidden_state] = log_p_xz[hidden_state] + max_log_prob
            # print(W_t[hidden_state])
        arg_max_debug, max_value = get_mode(W_t)
        print("t: {} | arg: {} | max: {}".format(t, arg_max_debug, max_value))
        W[t] = W_t

    final_dist = W[-1]
    max_hidden_state, max_val = get_mode(final_dist)
    map_sequence.append(max_hidden_state)
    for t in range(len(observations) - 1, 0, -1):
        prev = map_sequence[-1]
        print("T =", t)
        print("prev", prev)
        #print(prev)
        curr = links[t][prev]
        print("curr", curr)
        print("\n")
        #print(links[t])
        map_sequence.append(curr)
        # print(curr)
    estimated_hidden_states = map_sequence[::-1]

    for d in range (1, len(links)):
        if links[d] == links[d-1]:
            print("FatalError", d)

    return estimated_hidden_states
Ejemplo n.º 8
0
def Viterbi(all_possible_hidden_states, all_possible_observed_states,
            prior_distribution, transition_model, observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """

    # TODO: Write your code here

    num_time_steps = len(observations)
    forward_pass = [None] * num_time_steps
    w = [None] * num_time_steps
    max_w_zn = [None] * num_time_steps
    estimated_hidden_states = [None] * num_time_steps

    # loop through all the time_steps
    for i in range(num_time_steps):
        # create Distribution dictionaries
        w[i] = rover.Distribution()
        if i == 0:
            # TODO: initialize forward message to be ln(p(z0) * p( (x0,y0)| z0 ))
            for zn in prior_distribution:
                prior_z0 = prior_distribution[zn]
                z0 = observations[i]
                pcond_X0_z0 = observation_model(zn)[z0]
                if prior_z0 * pcond_X0_z0 != 0:
                    w[i][zn] = np.log(prior_z0 * pcond_X0_z0)
        else:
            # TODO: Compute the forward messages
            xn = observations[i]
            max_w_zn[i] = dict()
            for zn in all_possible_hidden_states:
                # Part 2: check if observation is None
                if xn == None:
                    # set conditional probability to be 1
                    pcond_Xn_zn = 1
                else:
                    pcond_Xn_zn = observation_model(zn)[xn]
                if pcond_Xn_zn != 0:
                    # set maximum value to be -inf, and find the maximum of all values
                    max_zn_prev = -np.inf
                    # iterate through all the previous zn, find the max value, and save it
                    for zn_prev in (w[i - 1]):
                        pcond_zn_zn_prev = transition_model(zn_prev)[zn]
                        # avoid log of 0 case
                        if pcond_zn_zn_prev != 0:
                            w_prev = w[i - 1][zn_prev]
                            new_zn_prev = np.log(pcond_zn_zn_prev) + w_prev
                            if new_zn_prev > max_zn_prev:
                                max_zn_prev = new_zn_prev
                                # store the maximum path to get to a certain zn from zn_prev
                                max_w_zn[i][zn] = zn_prev
                    # set the zn to be ln (p( (xn,yn)| zn )) + max {ln(p(zn,zn_prev)) +  w(zn_prev)}
                    w[i][zn] = np.log(pcond_Xn_zn) + max_zn_prev

    # loop through all the time_steps to determine optimal path
    for i in range(num_time_steps):
        end = num_time_steps - 1 - i
        if i == 0:
            # find the most probable zn at the end
            max_zn = -np.inf
            zn_star = None
            for zn in w[end]:
                zn_temp = zn
                max_zn_temp = w[end][zn_temp]
                if max_zn_temp > max_zn:
                    max_zn = max_zn_temp
                    zn_star = zn_temp
            estimated_hidden_states[end] = zn_star
        else:
            # find the path the links the old zn_star to the current time
            zn_star_prev = estimated_hidden_states[end + 1]
            estimated_hidden_states[end] = max_w_zn[end + 1][zn_star_prev]

    return estimated_hidden_states
Ejemplo n.º 9
0
def forward_backward(all_possible_hidden_states, all_possible_observed_states,
                     prior_distribution, transition_model, observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    forward_messages[0] = prior_distribution
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps
    poss_states = [None] * num_time_steps
    possible_prev_actions = ['left', 'right', 'up', 'down', 'stay']
    for i in range(0, num_time_steps):
        poss_states[i] = []
        if observations[i] == None:
            poss_states[i] = all_possible_hidden_states
        else:
            [x, y] = observations[i]
            for action in possible_prev_actions:
                poss_states[i].append((x, y, action))
                poss_states[i].append((x - 1, y, action))
                poss_states[i].append((x + 1, y, action))
                poss_states[i].append((x, y + 1, action))
                poss_states[i].append((x, y - 1, action))
    # TODO: Compute the forward messages

    for i in range(0, num_time_steps):
        forward_messages[i] = rover.Distribution()
        if observations[i] == None:
            if i == 0:
                for state in poss_states[i]:
                    forward_messages[i][state] = prior_distribution[state] * 1
            else:
                for state in poss_states[i]:
                    forward_messages[i][state] = 1*np.sum([forward_messages[i-1][zn1]*\
                                     transition_model(zn1)[state] for zn1 in poss_states[i-1]])
            forward_messages[i].renormalize()

        else:
            if i == 0:
                for state in poss_states[i]:
                    forward_messages[i][state] = prior_distribution[
                        state] * observation_model(state)[observations[0]]
            else:
                for state in poss_states[i]:
                    forward_messages[i][state] = observation_model(state)[observations[i]]*\
                        np.sum([forward_messages[i-1][zn1]*transition_model(zn1)[state] \
                             for zn1 in poss_states[i-1]])
            forward_messages[i].renormalize()
    # TODO: Compute the backward messages

    for i in range(num_time_steps - 1, -1, -1):
        backward_messages[i] = rover.Distribution()

        if i == num_time_steps - 1:
            for state in all_possible_hidden_states:
                backward_messages[i][state] = 1
        else:
            if observations[i + 1] == None:
                for state in poss_states[i]:
                    backward_messages[i][state] = np.sum([backward_messages[i+1][zn1]*\
                                  transition_model(state)[zn1] for zn1 in poss_states[i+1]])
            else:
                for state in poss_states[i]:
                    backward_messages[i][state] = np.sum([backward_messages[i+1][zn1]*\
                    observation_model(zn1)[observations[i+1]]*transition_model(state)[zn1] \
                    for zn1 in poss_states[i+1]])

            backward_messages[i].renormalize()


#     TODO: Compute the marginals
    for i in range(0, num_time_steps):
        marginals[i] = rover.Distribution()
        #        [x,y] = observations[i]
        #        possible_states = list(transition_model([x,y,'stay']).keys())
        for state in all_possible_hidden_states:

            marginals[i][state] = forward_messages[i][
                state] * backward_messages[i][state]
        marginals[i].renormalize()

    return marginals
Ejemplo n.º 10
0
def Viterbi(all_possible_hidden_states, all_possible_observed_states,
            prior_distribution, transition_model, observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """

    # TODO: Write your code here
    num_time_steps = len(observations)
    w = [None] * num_time_steps
    poss_states = [None] * num_time_steps
    phi = [None] * (num_time_steps - 1)
    possible_prev_actions = ['left', 'right', 'up', 'down', 'stay']
    estimated_hidden_states = []
    for i in range(0, num_time_steps):
        poss_states[i] = []
        if observations[i] == None:
            poss_states[i] = all_possible_hidden_states
        else:
            [x, y] = observations[i]
            for action in possible_prev_actions:
                poss_states[i].append((x, y, action))
                poss_states[i].append((x - 1, y, action))
                poss_states[i].append((x + 1, y, action))
                poss_states[i].append((x, y + 1, action))
                poss_states[i].append((x, y - 1, action))

    for i in range(0, num_time_steps):
        w[i] = rover.Distribution()
        if observations[i] == None:
            if i == 0:
                for state in poss_states[i]:
                    w[0][state] = np.log(prior_distribution[state])
            else:
                phi[i - 1] = dict()
                for state in poss_states[i]:
                    w[i][state] = np.max([
                        np.log(transition_model(zn1)[state]) + w[i - 1][zn1]
                        for zn1 in poss_states[i - 1]
                    ])
                    phi[i - 1][state] = poss_states[i - 1][np.argmax([
                        np.log(transition_model(zn1)[state]) + w[i - 1][zn1]
                        for zn1 in poss_states[i - 1]
                    ])]
        else:
            if i == 0:
                for state in poss_states[i]:
                    w[0][state] = np.log(prior_distribution[state]) + np.log(
                        observation_model(state)[observations[0]])
            else:
                phi[i - 1] = dict()
                for state in poss_states[i]:
                    w[i][state] = np.log(observation_model(state)[observations[i]]) + \
                        np.max([np.log(transition_model(zn1)[state]) + w[i-1][zn1] for zn1 in poss_states[i-1]])
                    phi[i - 1][state] = poss_states[i - 1][np.argmax([
                        np.log(transition_model(zn1)[state]) + w[i - 1][zn1]
                        for zn1 in poss_states[i - 1]
                    ])]


#        w[i].renormalize()
    max_val = -1000
    for key in w[-1].keys():
        if w[-1][key] > max_val:
            max_val = w[-1][key]
            state_max = key

    estimated_hidden_states.append(state_max)
    for i in range(num_time_steps - 2, -1, -1):
        state_max_new = phi[i][state_max]
        estimated_hidden_states.insert(0, state_max_new)
        state_max = state_max_new

    return estimated_hidden_states
Ejemplo n.º 11
0
def forward_backward(all_possible_hidden_states, all_possible_observed_states,
                     prior_distribution, transition_model, observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    forward_messages[0] = prior_distribution
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps

    for i in range(num_time_steps):
        # TODO: Compute the forward messages
        forward_messages[i] = rover.Distribution()
        # Intialization
        if i == 0:
            for state in prior_distribution:
                result = prior_distribution[state] * observation_model(state)[
                    observations[0]]
                if result != 0:
                    forward_messages[i][state] = result
        # Recursive
        else:
            for state in all_possible_hidden_states:
                result = 1
                if observations[i] != None:
                    result = observation_model(state)[observations[i]]
                subresult = 0
                for k in forward_messages[i - 1]:
                    product = transition_model(k)[state] * forward_messages[
                        i - 1][k]
                    subresult += product
                result *= subresult
                if result != 0:
                    forward_messages[i][state] = result
        forward_messages[i].renormalize()

        # TODO: Compute the backward messages
        n = num_time_steps - i - 1
        backward_messages[n] = rover.Distribution()
        # Intialization
        if i == 0:
            for state in all_possible_hidden_states:
                backward_messages[n][state] = 1
        # Recursive
        else:
            for state in all_possible_hidden_states:
                result = 0
                subresult = 1
                for k in backward_messages[n + 1]:
                    subresult = 1
                    if observations[n + 1] != None:
                        subresult = observation_model(k)[observations[n + 1]]
                    subresult *= transition_model(
                        state)[k] * backward_messages[n + 1][k]
                    result += subresult
                if result != 0:
                    backward_messages[n][state] = result
        backward_messages[n].renormalize()

    # TODO: Compute the marginals
    for i in range(num_time_steps):
        marginals[i] = rover.Distribution()
        for state in all_possible_hidden_states:
            result = forward_messages[i][state] * backward_messages[i][state]
            if result != 0:
                marginals[i][state] = result
        marginals[i].renormalize()

    return marginals
Ejemplo n.º 12
0
def forward_backward(all_possible_hidden_states,
                     all_possible_observed_states,
                     prior_distribution,
                     transition_model,
                     observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    
    
    ########################################################################
    ################ Compute the forward messages ##########################
    ########################################################################
    print("Computing forward messages")
    """ Initialization """
    forward_messages = [None] * num_time_steps
    
    forward_messages[0] = rover.Distribution()
    for state in all_possible_hidden_states:
        forward_messages[0][state] = prior_distribution[state] * ( observation_model(state) )[observations[0]]
    
    """ 
    Perform computation:
    fm[n] = p((xn, yn) | zn) * sum_over_zn-1{ fm[n-1] * p(zn | zn-1) } 
    """
    for time_step in range(1, num_time_steps):
        print("-", end = '')
        curr = rover.Distribution()
        prev = forward_messages[time_step - 1]
        
        """ Fill in the distribution """
        for curr_state in all_possible_hidden_states:
            """ Sum over previous time_step """
            for prev_state in all_possible_hidden_states:
                if(observations[time_step] != None):
                    curr[curr_state] += prev[prev_state] * ( transition_model(prev_state) )[curr_state] * ( observation_model(curr_state) )[observations[time_step]]
                else:
                    curr[curr_state] += prev[prev_state] * ( transition_model(prev_state) )[curr_state] * 1.0
        
        """ Normalize this distribution """
        curr.renormalize()
        
        """ Store distribution into forward_messages """
        forward_messages[time_step] = curr
    
    print(" ")
    
        
    ########################################################    
    ########### Compute the backward messages ##############
    ########################################################
    print("Computing backward messages")
    """ Initialization """
    backward_messages = [None] * num_time_steps    
    
    backward_messages[num_time_steps - 1] = rover.Distribution()
    for state in all_possible_hidden_states:
        backward_messages[num_time_steps - 1][state] = 1.0
    
    """ Iterate through  """
    for time_step in range(num_time_steps-2, -1, -1):
        print("-", end = '')
        prev = rover.Distribution()
        curr = backward_messages[time_step + 1]
        
        """ Iterate over zn-1 """
        for prev_state in all_possible_hidden_states:
            for curr_state in all_possible_hidden_states:
                if(observations[time_step+1] != None):
                    prev[prev_state] += curr[curr_state] * ( observation_model(curr_state) )[observations[time_step+1]] * ( transition_model(prev_state) )[curr_state] 
                else:
                    prev[prev_state] += curr[curr_state] * 1.0 * ( transition_model(prev_state) )[curr_state] 
                    
        """ Normalize new distribution """
        prev.renormalize()
        
        """ Store distribution in backward_messages """
        backward_messages[time_step] = prev
    
    print(" ")
        
    
    ##############################################
    ########### Compute the marginals ############
    ##############################################       
    print("Computing marginals")
    
    marginals = [None] * num_time_steps     
    
    """ Compute the rest of the marginals """
    for time_step in range(0, num_time_steps):
        marginals[time_step] = rover.Distribution()
        for state in all_possible_hidden_states:
            marginals[time_step][state] = forward_messages[time_step][state] * backward_messages[time_step][state]
        marginals[time_step].renormalize()
     
    return marginals
Ejemplo n.º 13
0
def Viterbi(all_possible_hidden_states,
            all_possible_observed_states,
            prior_distribution,
            transition_model,
            observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of estimated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """
    num_time_steps = len(observations)
    estimated_hidden_states = [None] * num_time_steps
    
    """ Create vector of functions. These functions will be implemented as distributions """
    W = [None] * num_time_steps
    B = [None] * num_time_steps
    
    W[0] = rover.Distribution()
    for state in all_possible_hidden_states:
        if(observations[0] != None):
            W[0][state] = log(prior_distribution[state]) + log( ( observation_model(state) )[observations[0]] )
        else:
            W[0][state] = log(prior_distribution[state]) + 0.0
    B[0] = None
    
    """ First pass through. Construct all the w equations. """
    for time_step in range(1, num_time_steps):
        print("-", end='')
        W[time_step] = rover.Distribution() 
        back_dist = rover.Distribution()
        
        for curr in all_possible_hidden_states:
            max_state = None
            max_value = -np.inf
            for prev in all_possible_hidden_states:
                new_value = log( ( transition_model(prev) )[curr] ) + W[time_step-1][prev]
                if(new_value > max_value):
                    max_value = new_value
                    max_state = prev
            
            if(observations[time_step] != None):
                W[time_step][curr] = log( (observation_model(curr))[observations[time_step]] ) + max_value
            else:
                W[time_step][curr] = max_value
            
            back_dist[curr] = max_state
        
        B[time_step] = back_dist
                
    print(" ")
    
    
    best_path_ptr = all_possible_hidden_states[0]
    for state in all_possible_hidden_states:
        if(W[num_time_steps-1][state] > W[num_time_steps-1][best_path_ptr]):
            best_path_ptr = state
            
    estimated_hidden_states[num_time_steps-1] = best_path_ptr
    
    best_path_ptr = B[num_time_steps-1][best_path_ptr]
    
    for time_step in range(num_time_steps-2, -1, -1):
        estimated_hidden_states[time_step] = best_path_ptr
        if(time_step == 0):
            break
        else:
            temp = best_path_ptr
            best_path_ptr = B[time_step][temp] 
    
    
    
#    """ Second pass through, compute and record the argmax's """
#    for time_step in range(0, num_time_steps):
#        max_state = all_possible_hidden_states[0]
#        for state in all_possible_hidden_states:
#            if(W[time_step][state] > W[time_step][max_state]):
#                max_state = state
#        estimated_hidden_states[time_step] = max_state
    
    return estimated_hidden_states
Ejemplo n.º 14
0
def Viterbi(all_possible_hidden_states, all_possible_observed_states,
            prior_distribution, transition_model, observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """
    # number of timesteps
    num_time_steps = len(observations)
    #a distribution of the hidden state that represents the log probability of transition
    #from a factor to a variable in the factor tree/HMM chain
    w_z = [None] * num_time_steps
    #a function to keep track of the most likely previous states for each current
    #timestamp in the forward pass of the algorithm. A list of dicts where the key is a given
    #hidden state for the current timestamp, and the value is a hidden state from the
    #previous timestamp that has the heighest probability to lead to the hidden state
    #denoted by the key
    phi_z = [None] * num_time_steps
    #a function to determine the most likely sequence in the backward pass of the
    #algo as we backtrack the HMM chain. A list of estimated hidden states per
    #timestamp
    zTilde_max = [None] * num_time_steps

    #Forward pass of Viterbi Algorithm. Note: this takes a minute or two to run
    #so if you want to quickly get the result after running it once, just turn
    #the preloaded flag on.
    if not PRELOADED:
        for i in range(num_time_steps):
            w_z[i] = rover.Distribution()
            phi_z[i] = {}
            for current_state in all_possible_hidden_states:
                #Define the observation distribution and the current observation
                obs_distr = observation_model(current_state)
                observation = observations[i]
                #Assume the observation is missing and assign it a unit probability
                P_obs = 1
                #If the observation exists, use the model instead to get the prob
                if observation is not None:
                    P_obs = obs_distr.get(observation)
                #if the observation distribution didn't yield a non-zero prob for
                #that observation, that means the hidden state is not really possible
                #based on that observation, so this probability should be zero, however
                #since we are working in the log domain, note that log(0) is undefined
                #so we assign it a very small probability.
                #Also note, we can't skip like we do in F/B because we are taking the
                #sum and not the product
                if P_obs is None:
                    P_obs = 1e-10
                #tackle the initialization of the recurrence
                if (i == 0):
                    #w_(z0) = log(p(z0)) + log(p(obs0 | z0))
                    prior_prob = prior_distribution[current_state]
                    #print(prior_prob)
                    if prior_prob != 0:
                        w_z[i][current_state] = np.log(prior_prob) + np.log(
                            P_obs)
                else:
                    #a hash of the previous states
                    prev_states_dict = {}
                    previous_states = w_z[i - 1]
                    #print("There are ",len(previous_states), "previous states")
                    for prev_state in previous_states:
                        #Calculate the transition probability P(zi|zi-1)
                        trans_distr = transition_model(prev_state)
                        P_trans = trans_distr.get(current_state)
                        if P_trans is None:
                            continue
                        #Calculate the max prev state transition log probability
                        prev_logprob = np.log(P_trans) + w_z[i - 1][prev_state]
                        #keep track of the probabilities of the previous states
                        prev_states_dict[prev_state] = prev_logprob
                    #store the previous state that is most likely to have gotten us to
                    #this current state
                    #print ("Prev state dict:\n", prev_states_dict)
                    max_prev_state = max(prev_states_dict,
                                         key=prev_states_dict.get)
                    phi_z[i][current_state] = max_prev_state
                    #Calculate w(zi) based on the recurrence relation
                    assert (prev_states_dict[max_prev_state] == max(
                        prev_states_dict.values()))
                    w_z[i][current_state] = np.log(P_obs) + max(
                        prev_states_dict.values())

        save_checkpoint("viterbiDict", phi_z)
        save_checkpoint("viterbiW", w_z)

    #Backward pass of Viterbi Algorithm.
    #we find the most likely state hidden within the very last timestamp.
    if PRELOADED:
        phi_z = load_checkpoint("viterbiDict")
        w_z = load_checkpoint("viterbiW")
    wLast = w_z[num_time_steps - 1]
    argmax_zLast = max(wLast, key=wLast.get)
    zTilde_max[-1] = argmax_zLast
    #Now backtrack and find the most likely state in the previous timestamp for
    #that
    for i in range(num_time_steps - 2, -1, -1):
        #the state we are backtracking from
        #print(i)
        argmax_zNext = zTilde_max[i + 1]
        #print(argmax_zNext)
        #the tagged state in the previous timestamp that is most likely to have led
        #to the next hidden state.
        max_state = phi_z[i + 1].get(argmax_zNext)
        #print ("Max leading state:\n", max_state)
        zTilde_max[i] = max_state

    #print (phi_z)
    estimated_hidden_states = zTilde_max
    #print(len(estimated_hidden_states))
    #print(estimated_hidden_states)

    return estimated_hidden_states
Ejemplo n.º 15
0
def forward_backward(all_possible_hidden_states,
                     all_possible_observed_states,
                     prior_distribution,
                     transition_model,
                     observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forwardMessages = [None] * num_time_steps
    forwardMessages[0] = prior_distribution
    backMessages = [None] * num_time_steps
    marginals = [None] * num_time_steps 
    
    # TODO: Compute the forward messages
    # initialize
    forwardMessages[0] = rover.Distribution({})
    for z0 in all_possible_hidden_states:
        initialPos = 1 if observations[0] == None else observation_model(z0)[observations[0]]
        prior_z0 = prior_distribution[z0]
        mes = initialPos * prior_distribution[z0]
        if (mes) != 0:
            forwardMessages[0][z0] = mes
    forwardMessages[0].renormalize()
    
    # for all other alpha_i's
    for i in range(1, num_time_steps):
        forwardMessages[i] = rover.Distribution({})
        observedPosition = observations[i]
        for zi in all_possible_hidden_states:
            probPosition_cur = 1 if observedPosition == None else observation_model(zi)[observedPosition]
            prob = 0
            for zi_minus_1 in forwardMessages[i-1]:
                prob += forwardMessages[i-1][zi_minus_1] * transition_model(zi_minus_1)[zi]
            if (probPosition_cur * prob) != 0: # only save non-zero values
                forwardMessages[i][zi] = probPosition_cur * prob

        forwardMessages[i].renormalize() # normalize forward messages
    
    # TODO: Compute the backward messages
    # initialization of backward message
    backMessages[num_time_steps-1] = rover.Distribution({})
    for zn_minus_1 in all_possible_hidden_states:
        backMessages[num_time_steps-1][zn_minus_1] = 1

    # fill the rest
    for i in range(1, num_time_steps):
        backMessages[num_time_steps-1-i] = rover.Distribution({})
        for zi in all_possible_hidden_states:
            prob = 0
            for zi_plus_1 in backMessages[num_time_steps-1-i+1]:
                observedPosition = observations[num_time_steps-1-i+1]
                probPosition_next = 1 if observedPosition == None else observation_model(zi_plus_1)[observedPosition]
                prob += backMessages[num_time_steps-1-i+1][zi_plus_1] * probPosition_next * transition_model(zi)[zi_plus_1]
            if prob != 0:
                backMessages[num_time_steps-1-i][zi] = prob
        backMessages[num_time_steps-1-i].renormalize()
    
    # TODO: Compute the marginals
    for i in range (0, num_time_steps): 
        marginals[i] = rover.Distribution({})    
        prob = 0
        for zi in all_possible_hidden_states:
            if forwardMessages[i][zi] * backMessages[i][zi] != 0:
                marginals[i][zi] = forwardMessages[i][zi] * backMessages[i][zi]
                prob += forwardMessages[i][zi] * backMessages[i][zi]
        for zi in marginals[i].keys():
            marginals[i][zi] /=  prob

    return marginals
Ejemplo n.º 16
0
def forward_backward(all_possible_hidden_states, all_possible_observed_states,
                     prior_distribution, transition_model, observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """
    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps

    #Compute the forward messages
    for i in range(num_time_steps):
        forward_messages[i] = rover.Distribution()
        for state in all_possible_hidden_states:
            innerSum = 0
            #The observation probability distribution
            obs_distr = observation_model(state)
            #The observation itself
            observation = observations[i]
            #The probability of observation, given a hidden state.
            #Assume the observation is missing, assigning it unit probability
            P_obs_given_hidden = 1
            #if the observation exists, get it from the distribution model
            if observation is not None:
                P_obs_given_hidden = obs_distr.get(observation)
            #If the observation didn't exist, the inferred hidden state wouldn't
            #be possible based on this and as such we ignore it
            if P_obs_given_hidden is None:
                continue
            #Handle the initialization of the recurrence relation.
            if i == 0:
                #alpha(z0) = P(z0) * P(obs|z0)
                if prior_distribution[state] is not None:
                    forward_messages[0][
                        state] = prior_distribution[state] * P_obs_given_hidden
            else:
                for previous_state in (forward_messages[i - 1]):
                    alpha_prev = (forward_messages[i - 1])[previous_state]
                    P_trans = transition_model(previous_state)[state]
                    if (P_trans == 0):
                        continue
                    innerSum = innerSum + (alpha_prev * P_trans)
                forward_messages[i][state] = P_obs_given_hidden * innerSum
        forward_messages[i].renormalize()

    #Compute the backward messages
    for i in range(num_time_steps - 1, -1, -1):
        backward_messages[i] = rover.Distribution()
        #Initialize the B(zn-1) for the recurrence relation
        if i == num_time_steps - 1:
            for state in all_possible_hidden_states:
                backward_messages[i][state] = 1
        else:
            for next_state in (backward_messages[i + 1]):
                #The observation probability distribution
                obs_distr = observation_model(next_state)
                #The observation itself
                observation = observations[i + 1]
                #The probability of observation, given a hidden state.
                #Assume the observation is missing, assigning it unit probability
                obs_prob = 1
                #if the observation exists, get it from the distribution model
                if observation is not None:
                    obs_prob = obs_distr.get(observation)
                #If the observation didn't exist, the inferred hidden state wouldn't
                #be possible based on this and as such we ignore it
                if (obs_prob is None):
                    continue
                prod = backward_messages[i + 1][next_state] * obs_prob
                for state in all_possible_hidden_states:
                    trans_prob = transition_model(state)[next_state]
                    if (trans_prob == 0):
                        continue
                    backward_messages[i][state] += (prod * trans_prob)
        backward_messages[i].renormalize()

    #Compute the marginals
    for i in range(num_time_steps):
        marginals[i] = rover.Distribution()
        for z_i in all_possible_hidden_states:
            prod = forward_messages[i][z_i] * backward_messages[i][z_i]
            if prod == 0:
                #report only non-zero probabilities in the distribution
                continue
            marginals[i][z_i] = prod
        marginals[i].renormalize()

    return marginals
Ejemplo n.º 17
0
def forward_backward(all_possible_hidden_states, all_possible_observed_states,
                     prior_distribution, transition_model, observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps

    # TODO: Compute the forward messages
    alpha_0 = rover.Distribution()  # initial forward message

    for z in prior_distribution:
        alpha_0[z] = prior_distribution[z] * observation_model(z)[
            observations[0]]  # alpha(z_0) = p(z_0)*p((x_0, y_0)|z_0)

    alpha_0.renormalize()

    forward_messages[0] = alpha_0

    # compute all the other forward messages (alphas)
    for i in range(num_time_steps - 1):
        curr_observation = observations[i + 1]
        alpha = rover.Distribution(
        )  # initialize the current forward message before filling in the values

        # go through all values for z_n to fill it in for the current forward message
        for z_n in all_possible_hidden_states:
            # account for possibilility of missing data
            if curr_observation == None:
                cond_prob = 1
            else:
                cond_prob = observation_model(z_n)[curr_observation]

            #  if the condition probability isn't 0, we need to calculate the value for alpha(z_n), otherwise we can skip it and automatically set the value to 0
            if cond_prob != 0:
                prev_sum = sum(forward_messages[i][prev_z] *
                               transition_model(prev_z)[z_n]
                               for prev_z in forward_messages[i])
                alpha[
                    z_n] = cond_prob * prev_sum  # alpha(z_n) = p((x_n, y_n)|z_n)*sum of alpha(z_{n - 1})*p(z_n|z_{n - 1}) over all possible z_{n - 1} values, calculated in previous line
            else:
                alpha[z_n] = 0

        alpha.renormalize(
        )  # renormalize the values into a probability distribution, in order to prevent integer underflow
        forward_messages[i +
                         1] = alpha  # save the alpha value for this timestep

    # TODO: Compute the backward messages
    beta_n = rover.Distribution(
    )  # initial backwards message (for final state)

    # we don't have information, so just set everything to be 1 in order not to bias the messages that build upon this
    for state in all_possible_hidden_states:
        beta_n[state] = 1
    beta_n.renormalize()

    backward_messages[num_time_steps - 1] = beta_n

    #  compute other backwards messages
    for i in reversed(range(num_time_steps - 1)):
        curr_observation = observations[i + 1]
        beta = rover.Distribution(
        )  # initialize the current backwards message before filling in its values

        # go through all values of z_{n - 1} to fill in for the current backwards message
        for prev_z in all_possible_hidden_states:
            trans_model = transition_model(
                prev_z
            )  # used to find conditional probabilities of the next state conditioned on z_{n - 1}, precomputed to reduce runtime

            # if current observation is none, we need to replace the p((x_n, y_n)|z_n) factor with 1, as we don't have information and don't want to bias the predictions
            # otherwise, we can include that factor in our calculation
            if curr_observation == None:
                # beta(z_{n - 1}) = sum of beta(z_n)*p(z_n|z_{n - 1}) over all possible z_n values from the last backwards message
                beta[prev_z] = sum(backward_messages[i + 1][z_n] *
                                   trans_model[z_n]
                                   for z_n in backward_messages[i + 1])
            else:
                # beta(z_{n - 1}) = sum of beta(z_n)*p((x_n, y_n)|z_n)*p(z_n|z_{n - 1}) over all possible z_n values from the last backwards message
                beta[prev_z] = sum(backward_messages[i + 1][z_n] *
                                   observation_model(z_n)[curr_observation] *
                                   trans_model[z_n]
                                   for z_n in backward_messages[i + 1])

        beta.renormalize(
        )  # renormalize the values into a probability distribution to prevent integer underflow
        backward_messages[i] = beta  # save the beta value for this timestep

    # TODO: Compute the marginals

    # to compute the marginals, we need to compute every gamma(z_n) and then normalize it
    for i in range(num_time_steps):
        alpha = forward_messages[i]
        beta = backward_messages[i]
        gamma = rover.Distribution()

        for state in all_possible_hidden_states:
            gamma[state] = alpha[state] * beta[
                state]  # gamma(z_n) = alpha(z_n)*beta(z_n), for each possible state

        gamma.renormalize(
        )  # renormalize to make sure it is a probability distribution
        marginals[
            i] = gamma  # save the marginal distribution for this timestep

    return marginals
Ejemplo n.º 18
0
def forward_backward(all_possible_hidden_states, all_possible_observed_states,
                     prior_distribution, transition_model, observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    # forward_messages[0] = prior_distribution
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps

    # first compute the forward and backward messages
    # loop through all the time_steps
    for i in range(num_time_steps):
        # create Distribution dictionaries
        end = num_time_steps - 1 - i
        forward_messages[i] = rover.Distribution({})
        backward_messages[end] = rover.Distribution({})
        # Initialization
        if i == 0:
            # TODO: initialize forward message to be p(z0) * p( (x0,y0)| z0 )
            for zn in prior_distribution:
                prior_z0 = prior_distribution[zn]
                z0 = observations[i]
                pcond_X0_z0 = observation_model(zn)[z0]
                if pcond_X0_z0 != 0:
                    forward_messages[i][zn] = prior_z0 * pcond_X0_z0
            # renormalize forward message
            forward_messages[i].renormalize()

            # TODO: initialize the backward message to be 1 at state all states
            for zn in all_possible_hidden_states:
                backward_messages[end][zn] = 1

        # Forward/Backward Messages
        else:
            # TODO: Compute the forward messages
            xn = observations[i]
            for zn in all_possible_hidden_states:

                # Part 2: check if observation is None
                if xn == None:
                    # set conditional probability to be 1
                    pcond_Xn_zn = 1
                else:
                    pcond_Xn_zn = observation_model(zn)[xn]

                if pcond_Xn_zn != 0:
                    sum = 0
                    for zn_prev in (forward_messages[i - 1]):
                        forward_prev = forward_messages[i - 1][zn_prev]
                        pcond_zn_zn_prev = transition_model(zn_prev)[zn]
                        sum += forward_prev * pcond_zn_zn_prev
                    if sum != 0:
                        forward_messages[i][zn] = pcond_Xn_zn * sum
            # renormalize forward message
            forward_messages[i].renormalize()

            # TODO: Compute the backward messages
            # end denotes the current state (n) while end+1 denotes the state after it (n_aft)
            xn_aft = observations[end + 1]
            for zn in all_possible_hidden_states:
                sum = 0
                for zn_aft in backward_messages[end + 1]:

                    # Part 2: check if observation is None
                    if xn_aft == None:
                        # set conditional probability to be 1 if so
                        pcond_Xn_aft_zn_aft = 1
                    else:
                        pcond_Xn_aft_zn_aft = observation_model(zn_aft)[xn_aft]

                    beta_zn_aft = backward_messages[end + 1][zn_aft]
                    pcond_zn_aft_zn = transition_model(zn)[zn_aft]
                    sum += beta_zn_aft * pcond_zn_aft_zn * pcond_Xn_aft_zn_aft
                if sum != 0:
                    backward_messages[end][zn] = sum

    # TODO: Compute the marginals
    # loop through all the time_steps
    for i in range(num_time_steps):
        # create Distribution dictionaries
        marginals[i] = rover.Distribution()
        # calculate the numerator and denominator (normalization factor)
        sum_alpha_beta = 0
        for zn in all_possible_hidden_states:
            alpha = forward_messages[i][zn]
            beta = backward_messages[i][zn]
            if alpha * beta != 0:
                marginals[i][zn] = (alpha * beta)
            sum_alpha_beta += forward_messages[i][zn] * backward_messages[i][zn]
        # check if non-zero probability (for normalization)
        if sum_alpha_beta != 0:
            # normalize each zn
            for zn in marginals[i].keys():
                marginals[i][zn] = marginals[i][zn] / sum_alpha_beta
    # print(marginals)
    return marginals
Ejemplo n.º 19
0
def Viterbi(all_possible_hidden_states, all_possible_observed_states,
            prior_distribution, transition_model, observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """

    # TODO: Write your code here

    logpxcondz = rover.Distribution()
    w1 = rover.Distribution()
    for z1 in prior_distribution:
        likelihood = observation_model(z1)
        if (observations[0] is not None):
            logpxcondz[z1] = logarithm(likelihood[observations[0]])
        w1[z1] = logpxcondz[z1] + logarithm(prior_distribution[z1])

    W = [None] * len(observations)
    W[0] = w1

    parent = []
    for i in range(len(observations)):
        parent.append({})

    print("CALCULATING W VALUES")
    for n in range(1, len(observations)):

        wn = rover.Distribution()
        logpxcondz = rover.Distribution()

        for hidden_state in all_possible_hidden_states:
            pxcondz = observation_model(hidden_state)

            if (observations[n] is not None):
                logpxcondz[hidden_state] = logarithm(pxcondz[observations[n]])

            max_log_prob, MLprev = mle_past(hidden_state, W[n - 1])

            if MLprev is not None:
                parent[n][hidden_state] = MLprev
                wn[hidden_state] = logpxcondz[hidden_state] + max_log_prob

        W[n] = wn

    end = W[-1]

    most_likely_state, max_log_prob = mlstate(end)

    state_sequence = []
    state_sequence.append(most_likely_state)
    for n in range(len(observations) - 1, 0, -1):

        past = state_sequence[-1]
        present = parent[n][past]
        state_sequence.append(present)

        print("Time step = {} | Joint(t) = {}".format(n, present))

    estimated_hidden_states = state_sequence[::-1]

    return estimated_hidden_states
Ejemplo n.º 20
0
def forward_backward(all_possible_hidden_states,
                     all_possible_observed_states,
                     prior_distribution,
                     transition_model,
                     observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """

    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    forward_messages[0] = prior_distribution
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps 
    
    # TODO: Compute the forward messages
    #forward messages are a distribution
    #update distribution based on observation and transition model
    #print(observations)
    '''copy = prior_distribution #copy is alpha distribution
    print(copy)
    print(observations)
    for state in copy:
        observed_given_hidden = observation_model(state)
        for obsstate in observed_given_hidden:
            copy[state] = copy[state]*observed_given_hidden[obsstate]'''

    alpha_z0 = prior_distribution
    for state in prior_distribution:
        likelihood_function = observation_model(state) #p(xi, yi| z0)
        p_obs_given_hidden = likelihood_function[observations[0]] #p(first observation | z0)
        alpha_z0[state] = prior_distribution[state]*p_obs_given_hidden #p(first observation|z0) * p(z0) proportional to p(z0|x0,y0)
    alpha_z0.renormalize()
    forward_messages[0] = alpha_z0

    for i in range(1,num_time_steps):

        alpha_zi_1 = forward_messages[i-1] #just want the shapes to match previous timestep distribution
        xi_yi = observations[i]
        alpha_zi = rover.Distribution()
        #print(xi_yi)

        for zi in all_possible_hidden_states:
            sum = 0
            likelihood_function = observation_model(zi) #p(xn,yn|zi)
            if xi_yi is not None:
                p_obs_given_hidden = likelihood_function[xi_yi] #p(xi,yi|zi) were xi,yi is our observation
            else:
                p_obs_given_hidden = 1
            for zi_1 in alpha_zi_1:
                nextgivenprev = transition_model(zi_1)
                sum += alpha_zi_1[zi_1]*nextgivenprev[zi]
            if p_obs_given_hidden*sum>0.0:
                alpha_zi[zi] = p_obs_given_hidden * sum

        #print(alpha_zi)
        alpha_zi.renormalize()

        sum = 0
        for key in alpha_zi:
            sum += alpha_zi[key]
        #print(sum)
        forward_messages[i] = alpha_zi


    # TODO: Compute the backward messages

    #Initialize the last beta

    beta_zN_1 = prior_distribution
    for state in all_possible_hidden_states:
        beta_zN_1[state] = 1
    beta_zN_1.renormalize()
    backward_messages[-1] =  beta_zN_1
    
    #Recursively go back for other betas
    beta_zn_1 = beta_zN_1

    print("PRINTING BETA VALUES NOW")
    for n in range(num_time_steps-2, -1, -1):
        
        beta_zn = backward_messages[n+1]
        beta_zn_1 = rover.Distribution()
        xn_yn = observations[n + 1]
        #print(xn_yn)

        for zn_1 in all_possible_hidden_states:
            sum = 0
            nextgivenprev = transition_model(zn_1)
            for zn in beta_zn:

                likelihood_function = observation_model(zn)
                if xn_yn is not None:
                    p_obs_given_hidden = likelihood_function[xn_yn]
                else:
                    p_obs_given_hidden = 1
                sum += beta_zn[zn]*p_obs_given_hidden*nextgivenprev[zn]
            if sum > 0.0:
                beta_zn_1[zn_1] = sum
        #print(beta_zn_1)
        beta_zn_1.renormalize()
        backward_messages[n] = beta_zn_1

    
    # TODO: Compute the marginals 
    print("PRINTING MARGINALS")
    for i in range(num_time_steps):
        print(i)
        alpha_zi = forward_messages[i]
        beta_zi = backward_messages[i]
        gamma_zi = rover.Distribution()
        for state in all_possible_hidden_states:
            if alpha_zi[state]*beta_zi[state] > 0:
                gamma_zi[state] = alpha_zi[state]*beta_zi[state]
        gamma_zi.renormalize()


        marginals[i] = gamma_zi

        print(marginals[i])
        #print(marginals[i].get_mode())
    return marginals
Ejemplo n.º 21
0
def forward_backward(all_possible_hidden_states, all_possible_observed_states,
                     prior_distribution, transition_model, observation_model,
                     observations):
    """
    Inputs
    ------
    all_possible_hidden_states: a list of possible hidden states
    all_possible_observed_states: a list of possible observed states
    prior_distribution: a distribution over states

    transition_model: a function that takes a hidden state and returns a
        Distribution for the next state
    observation_model: a function that takes a hidden state and returns a
        Distribution for the observation from that hidden state
    observations: a list of observations, one per hidden state
        (a missing observation is encoded as None)

    Output
    ------
    A list of marginal distributions at each time step; each distribution
    should be encoded as a Distribution (see the Distribution class in
    rover.py), and the i-th Distribution should correspond to time
    step i
    """
    num_time_steps = len(observations)
    forward_messages = [None] * num_time_steps
    backward_messages = [None] * num_time_steps
    marginals = [None] * num_time_steps

    # Compute the forward messages
    forward_prev = rover.Distribution()
    for i, observation in enumerate(observations):
        forward_curr = rover.Distribution()
        for current_state in all_possible_hidden_states:
            if i == 0:
                previous_f_sum = prior_distribution[current_state]
            else:
                previous_f_sum = sum(forward_prev[previous_state] * transition_model(previous_state)[current_state] \
                                     for previous_state in all_possible_hidden_states)

            if not observation:
                forward_curr[current_state] = previous_f_sum
            else:
                forward_curr[current_state] = observation_model(
                    current_state)[observation] * previous_f_sum

        forward_curr.renormalize()
        forward_messages[i] = forward_curr
        forward_prev = forward_curr

    # Compute the backward messages
    backward_prev = rover.Distribution()
    for i, observation_i_plus in enumerate(
            reversed(observations[1:] + [(None, )])):
        backward_curr = rover.Distribution()
        for current_state in all_possible_hidden_states:
            if i == 0:
                backward_curr[current_state] = 1
            else:
                if not observation_i_plus:
                    backward_curr[current_state] = sum(transition_model(current_state)[next_state] \
                                                      * backward_prev[next_state] for next_state in all_possible_hidden_states)
                else:
                    backward_curr[current_state] = sum(transition_model(current_state)[next_state] \
                                                      * observation_model(next_state)[observation_i_plus] \
                                                      * backward_prev[next_state] for next_state in all_possible_hidden_states)
        backward_curr.renormalize()
        backward_messages[len(backward_messages) - i - 1] = backward_curr
        backward_prev = backward_curr

    # Compute the marginals
    for i in range(len(observations)):
        marginal = rover.Distribution()
        for state in all_possible_hidden_states:
            marginal[state] = forward_messages[i][state] * backward_messages[
                i][state]
        marginal.renormalize()
        marginals[i] = marginal

    return marginals
Ejemplo n.º 22
0
def Viterbi(all_possible_hidden_states,
            all_possible_observed_states,
            prior_distribution,
            transition_model,
            observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """

    # TODO: Write your code here
    num_time_steps = len(observations)
    estimated_hidden_states = [None] * num_time_steps
    w = [None] * num_time_steps
    max_path = [None] * num_time_steps

    #Initialization
    w[0] = rover.Distribution()
    for z_n in prior_distribution:
        z0 = observations[0]
        p_z0 = prior_distribution[z_n]
        p_given_z0 = observation_model(z_n)[z0]
        if p_z0 * p_given_z0 != 0:
            w[0][z_n] = np.log(p_z0*p_given_z0)
    
    for i in range(1,num_time_steps):
        w[i] = rover.Distribution()
        xy_n = observations[i]
        max_path[i] = dict()
        for z_n in all_possible_hidden_states:
            if xy_n == None:
                p_x_given_z = 1
            else:
                p_x_given_z = observation_model(z_n)[xy_n]
            if p_x_given_z != 0:
                max_val = -100000000.00
                for prev in (w[i-1]):
                    p_z_given_prev = transition_model(prev)[z_n]
                    if p_z_given_prev != 0:
                        temp_val = np.log(p_z_given_prev) + w[i-1][prev]
                        if temp_val > max_val:
                            max_path[i][z_n] = prev
                            max_val = temp_val
                w[i][z_n] = np.log(p_x_given_z) + max_val

    #back track to find estimaded states
    for i in range(num_time_steps):
        last = num_time_steps - 1 - i
        if i == 0:
            max_z = None
            max_val = -100000000.00
            for z_n in w[last]:
                temp = w[last][z_n]
                if temp > max_val:
                    max_val = temp
                    max_z = z_n
            estimated_hidden_states[last] = max_z
        else:
            estimated_hidden_states[last] = max_path[last+1][estimated_hidden_states[last+1]]
    
    return estimated_hidden_states
def Viterbi(all_possible_hidden_states,
            all_possible_observed_states,
            prior_distribution,
            transition_model,
            observation_model,
            observations):
    """
    Inputs
    ------
    See the list inputs for the function forward_backward() above.

    Output
    ------
    A list of esitmated hidden states, each state is encoded as a tuple
    (<x>, <y>, <action>)
    """
    num_time_steps = len(observations)
    maxLastState = []
    maxLast = -100000000
    allObs = [all_possible_observed_states if i is None else [i] for i in observations]

    w = [None] * num_time_steps
    estimated_hidden_states = [rover.Distribution()] * num_time_steps

    w[0] = rover.Distribution()  # assume stay

    for i in prior_distribution:
        obsFactor=observation_model(i)
        for j in obsFactor:
            if j in allObs[0]:
                w[0][i]=["no previous", np.log(prior_distribution[i])*np.log(obsFactor[j])]


    for i in range(num_time_steps- 1):
        w[i + 1] = rover.Distribution()
        trans = rover.Distribution()

        for j in w[i]:
            tempTrans = transition_model(j)
            for k in tempTrans: #of n+1
                # print(w[i][j])

                maybeMax=np.log(tempTrans[k]) + w[i][j][1]

                if k in w[i + 1]:
                    newMax = np.maximum(maybeMax, w[i + 1][k][1])
                    if newMax != w[i + 1][k][1]:
                        trans[k] = [j, newMax] #newMax= np.maximum(np.log(tempTrans[k]) + w[i][j][1], w[i + 1][k][1])
                else:
                    trans[k] = [j, maybeMax]


        for j in trans:
            obsFactor=observation_model(j)
            for k in obsFactor:
                if k in allObs[i+1]:
                    w[i + 1][j] = [trans[j][0], trans[j][1] + np.log(obsFactor[k])]
        # print(i, w[i], "transitions")
        # print (i+1,observations[i+1],w[i+1], "\n")

    # for i in range(100):
    #     print(i, ". ", w[i])
    for i in w[-1]:
        if w[-1][i][1] > maxLast:
            maxLast = w[-1][i][1]
            maxLastState = i
    estimated_hidden_states[-1] = maxLastState
    for i in range(num_time_steps - 2, -1, -1):
        estimated_hidden_states[i] = w[i + 1][estimated_hidden_states[i + 1]][0]
    # print (estimated_hidden_states[-1])
    # TODO: Write your code here

    return estimated_hidden_states