'Perform an fprop path and beam search on a given set of network inputs.
Arguments:
inputs (Tensor): Minibatch of network inputs
num_beams (Int): Number of beams (hypothesis) to search over
steps (Int): Length of desired output in number of time steps'

def beamsearch(self, inputs, num_beams=5, steps=None):

    self.num_beams = num_beams
    self.num_live = 1
    self.num_dead = 0
    if (steps is None):
        steps = self.layers.in_shape[1]
    bsz = self.be.bsz
    self.z_list = [self.be.iobuf(self.z_shape) for _ in range(num_beams)]
    for i in range(num_beams):
        if (getattr(self.layers.decoder, 'start_index', None) is not None):
            self.z_list[i][self.layers.decoder.start_index] = 1
    self.candidates = [np.zeros((steps, bsz)) for _ in range(num_beams)]
    self.scores = [np.zeros(bsz) for _ in range(num_beams)]
    z = self.be.iobuf(self.z_shape)
    self.layers.encoder.fprop(inputs, inference=True, beta=0.0)
    final_states = self.layers.encoder.get_final_states(self.layers.decoder_connections)
    if (len(final_states) != len(self.layers.decoder._recurrent)):
        raise ValueError('number    of    decoder    layers    ({num_layers})    does    not    match    the    number    of    decoder    connections    ({num_decoder_connections}).'.format(num_layers=len(self.layers.decoder._recurrent), num_decoder_connections=len(final_states)))
    else:
        init_state_list = final_states
    self.init_state_lists = [[self.be.zeros_like(rec.h[(-1)]) for rec in self.layers.decoder._recurrent] for _ in range(num_beams)]
    self.init_state_lists[0] = init_state_list
    if self.hasLUT:
        z_beams = [self.be.iobuf(self.layers.decoder.out_shape) for _ in range(self.num_beams)]
    else:
        z_beams = [self.be.iobuf(self.z_shape) for _ in range(self.num_beams)]
    hidden_state_beams = [[self.be.zeros_like(l.final_state()) for l in self.layers.decoder._recurrent] for _ in range(self.num_beams)]
    for t in range(steps):
        for bb in range(self.num_live):
            z = self.layers.decoder.fprop(self.z_list[bb], inference=True, init_state_list=self.init_state_lists[bb])
            z_beams[bb][:] = z
            for (i, l) in enumerate(self.layers.decoder._recurrent):
                hidden_state_beams[bb][i][:] = l.final_state()
        self._beamsearch_step(t, z_beams, hidden_state_beams)
    return self.be.array(self.candidates[(-1)])
