def test_combine_sequences(self): state1 = RecurrentState([5, 10], 1) layer1_state = numpy.arange(5, dtype='int64').reshape(1, 1, 5) layer2_state = numpy.arange(10, 20, dtype='int64').reshape(1, 1, 10) state1.set([layer1_state, layer2_state]) state2 = RecurrentState([5, 10], 1) layer1_state = numpy.arange(100, 105, dtype='int64').reshape(1, 1, 5) layer2_state = numpy.arange(110, 120, dtype='int64').reshape(1, 1, 10) state2.set([layer1_state, layer2_state]) state3 = RecurrentState([5, 10], 2) layer1_state = numpy.arange(200, 210, dtype='int64').reshape(1, 2, 5) layer2_state = numpy.arange(210, 230, dtype='int64').reshape(1, 2, 10) state3.set([layer1_state, layer2_state]) combined_state = RecurrentState.combine_sequences( [state1, state2, state3]) self.assertEqual(combined_state.num_sequences, 4) self.assertEqual(len(combined_state.get()), 2) self.assertEqual(combined_state.get(0).shape, (1, 4, 5)) self.assertEqual(combined_state.get(1).shape, (1, 4, 10)) assert_equal( combined_state.get(0), numpy.asarray([[ list(range(5)), list(range(100, 105)), list(range(200, 205)), list(range(205, 210)) ]], dtype='int64')) assert_equal( combined_state.get(1), numpy.asarray([[ list(range(10, 20)), list(range(110, 120)), list(range(210, 220)), list(range(220, 230)) ]], dtype='int64')) state4 = RecurrentState([5, 11], 2) with self.assertRaises(ValueError): combined_state = RecurrentState.combine_sequences( [state1, state2, state3, state4])
def _append_word(self, tokens, target_word): """Appends a word to each of the given tokens, and updates their scores. :type tokens: list of LatticeDecoder.Tokens :param tokens: input tokens :type target_word: int or str :param target_word: word ID or word to be appended to the existing history of each input token; if not an integer, the word will be considered ``<unk>`` and this variable will be taken literally as the word that will be used in the resulting transcript """ def str_to_unk(self, word): """Returns the <unk> word ID if the argument is not a word ID. """ if isinstance(word, int): return word else: return self._unk_id input_word_ids = [[ str_to_unk(self, token.history[-1]) for token in tokens ]] input_word_ids = numpy.asarray(input_word_ids).astype('int64') input_class_ids, membership_probs = \ self._vocabulary.get_class_memberships(input_word_ids) recurrent_state = [token.state for token in tokens] recurrent_state = RecurrentState.combine_sequences(recurrent_state) target_word_id = str_to_unk(self, target_word) target_class_ids = numpy.ones(shape=(1, len(tokens))).astype('int64') target_class_ids *= self._vocabulary.word_id_to_class_id[ target_word_id] step_result = self._step_function(input_word_ids, input_class_ids, target_class_ids, *recurrent_state.get()) logprobs = step_result[0] # Add logprobs from the class membership of the predicted words. logprobs += numpy.log(membership_probs) output_state = step_result[1:] for index, token in enumerate(tokens): token.history.append(target_word) token.state = RecurrentState(self._network.recurrent_state_size) # Slice the sequence that corresponds to this token. token.state.set([ layer_state[:, index:index + 1] for layer_state in output_state ]) if target_word_id == self._unk_id: if self._ignore_unk: continue if self._unk_penalty is not None: token.nn_lm_logprob += self._unk_penalty continue # logprobs matrix contains only one time step. token.nn_lm_logprob += logprobs[0, index]
def test_combine_sequences(self): state1 = RecurrentState([5, 10], 1) layer1_state = numpy.arange(5, dtype='int64').reshape(1, 1, 5) layer2_state = numpy.arange(10, 20, dtype='int64').reshape(1, 1, 10) state1.set([layer1_state, layer2_state]) state2 = RecurrentState([5, 10], 1) layer1_state = numpy.arange(100, 105, dtype='int64').reshape(1, 1, 5) layer2_state = numpy.arange(110, 120, dtype='int64').reshape(1, 1, 10) state2.set([layer1_state, layer2_state]) state3 = RecurrentState([5, 10], 2) layer1_state = numpy.arange(200, 210, dtype='int64').reshape(1, 2, 5) layer2_state = numpy.arange(210, 230, dtype='int64').reshape(1, 2, 10) state3.set([layer1_state, layer2_state]) combined_state = RecurrentState.combine_sequences([state1, state2, state3]) self.assertEqual(combined_state.num_sequences, 4) self.assertEqual(len(combined_state.get()), 2) self.assertEqual(combined_state.get(0).shape, (1,4,5)) self.assertEqual(combined_state.get(1).shape, (1,4,10)) assert_equal(combined_state.get(0), numpy.asarray( [[list(range(5)), list(range(100, 105)), list(range(200, 205)), list(range(205, 210))]], dtype='int64')) assert_equal(combined_state.get(1), numpy.asarray( [[list(range(10, 20)), list(range(110, 120)), list(range(210, 220)), list(range(220, 230))]], dtype='int64')) state4 = RecurrentState([5, 11], 2) with self.assertRaises(ValueError): combined_state = RecurrentState.combine_sequences([state1, state2, state3, state4])
def _append_word(self, tokens, target_word_id): """Appends a word to each of the given tokens, and updates their scores. :type tokens: list of LatticeDecoder.Tokens :param tokens: input tokens :type target_word_id: int :param target_word_id: word ID to be appended to the existing history of each input token """ input_word_ids = [[token.history[-1] for token in tokens]] input_word_ids = numpy.asarray(input_word_ids).astype('int64') input_class_ids, membership_probs = \ self._vocabulary.get_class_memberships(input_word_ids) recurrent_state = [token.state for token in tokens] recurrent_state = RecurrentState.combine_sequences(recurrent_state) target_class_ids = numpy.ones(shape=(1, len(tokens))).astype('int64') target_class_ids *= self._vocabulary.word_id_to_class_id[ target_word_id] step_result = self.step_function(input_word_ids, input_class_ids, target_class_ids, *recurrent_state.get()) logprobs = step_result[0] # Add logprobs from the class membership of the predicted words. logprobs += numpy.log(membership_probs) output_state = step_result[1:] for index, token in enumerate(tokens): token.history.append(target_word_id) token.state = RecurrentState(self._network.recurrent_state_size) # Slice the sequence that corresponds to this token. token.state.set([ layer_state[:, index:index + 1] for layer_state in output_state ]) if target_word_id == self._unk_id: if self._ignore_unk: continue if not self._unk_penalty is None: token.nn_lm_logprob += self._unk_penalty continue # logprobs matrix contains only one time step. token.nn_lm_logprob += logprobs[0, index]
def _append_word(self, tokens, target_word_id): """Appends a word to each of the given tokens, and updates their scores. :type tokens: list of LatticeDecoder.Tokens :param tokens: input tokens :type target_word_id: int :param target_word_id: word ID to be appended to the existing history of each input token """ input_word_ids = [[token.history[-1] for token in tokens]] input_word_ids = numpy.asarray(input_word_ids).astype('int64') input_class_ids, membership_probs = \ self._vocabulary.get_class_memberships(input_word_ids) recurrent_state = [token.state for token in tokens] recurrent_state = RecurrentState.combine_sequences(recurrent_state) target_class_ids = numpy.ones(shape=(1, len(tokens))).astype('int64') target_class_ids *= self._vocabulary.word_id_to_class_id[target_word_id] step_result = self.step_function(input_word_ids, input_class_ids, target_class_ids, *recurrent_state.get()) logprobs = step_result[0] # Add logprobs from the class membership of the predicted words. logprobs += numpy.log(membership_probs) output_state = step_result[1:] for index, token in enumerate(tokens): token.history.append(target_word_id) token.state = RecurrentState(self._network.recurrent_state_size) # Slice the sequence that corresponds to this token. token.state.set([layer_state[:,index:index+1] for layer_state in output_state]) if target_word_id == self._unk_id: if self._ignore_unk: continue if not self._unk_penalty is None: token.nn_lm_logprob += self._unk_penalty continue # logprobs matrix contains only one time step. token.nn_lm_logprob += logprobs[0,index]
def _append_word(self, tokens, target_word, oov_logprob=None): """Appends a word to each of the given tokens, and updates their scores. :type tokens: list of LatticeDecoder.Tokens :param tokens: input tokens :type target_word: int or str :param target_word: word ID or word to be appended to the existing history of each input token; if not an integer, the word will be considered ``<unk>`` and this variable will be taken literally as the word that will be used in the resulting transcript :type oov_logprob: float :param oov_logprob: log probability to be assigned to OOV words """ def limit_to_shortlist(self, word): """Returns the ``<unk>`` word ID if the argument is not a shortlist word ID. """ if isinstance(word, int) and self._vocabulary.in_shortlist(word): return word else: return self._unk_id # Pass all/limited previous input if the net has attention if self._network.has_attention: # handle sequeces separately as the history could be varying length for index, token in enumerate(tokens): input_word_ids = [[ limit_to_shortlist(self, t) for t in token.history ]] input_word_ids = numpy.asarray(input_word_ids).astype( 'int64').transpose() #logging.debug("input shape: %s", input_word_ids.shape) input_class_ids, membership_prob = \ self._vocabulary.get_class_memberships(input_word_ids) recurrent_state = [token.state] recurrent_state = RecurrentState.combine_sequences( recurrent_state) target_word_id = limit_to_shortlist(self, target_word) target_class_ids = numpy.ones(shape=(1, 1)).astype('int64') target_class_ids *= self._vocabulary.word_id_to_class_id[ target_word_id] sub_step_result = self._step_function(input_word_ids, input_class_ids, target_class_ids, *recurrent_state.get()) #update token with the values logprobs = sub_step_result[0] #logging.debug("Logprobs shape: %s, %s", logprobs.shape, self._network.recurrent_state_size) # Add logprobs from the class membership of the predicted words. logprobs += numpy.log(membership_prob[-1, :]) output_state = sub_step_result[1:] token.history = token.history + (target_word, ) token.state = RecurrentState( self._network.recurrent_state_size) # Slice the sequence that corresponds to this token. token.state.set([layer_state for layer_state in output_state]) # logprobs matrix contains only one time step. token.nn_lm_logprob += self._handle_unk_logprob( target_word, logprobs[0, 0], oov_logprob) #logging.debug("Next time step") #for i, data in enumerate(input_word_ids): # logging.debug("Length of data: %d, %s", len(data), data) # if len(data)<max_len: #pad with zeros # input_word_ids[i] = [0] * (max_len-len(data)) + data # logging.debug("New length of data: %d, %s", len(input_word_ids[i]), input_word_ids[i]) # No attention in the network else: input_word_ids = [[ limit_to_shortlist(self, token.history[-1]) for token in tokens ]] input_word_ids = numpy.asarray(input_word_ids).astype('int64') input_class_ids, membership_probs = \ self._vocabulary.get_class_memberships(input_word_ids) recurrent_state = [token.state for token in tokens] recurrent_state = RecurrentState.combine_sequences(recurrent_state) target_word_id = limit_to_shortlist(self, target_word) target_class_ids = numpy.ones(shape=(1, len(tokens))).astype('int64') target_class_ids *= self._vocabulary.word_id_to_class_id[ target_word_id] step_result = self._step_function(input_word_ids, input_class_ids, target_class_ids, *recurrent_state.get()) logprobs = step_result[0] # Add logprobs from the class membership of the predicted words. logprobs += numpy.log(membership_probs) output_state = step_result[1:] for index, token in enumerate(tokens): token.history = token.history + (target_word, ) token.state = RecurrentState( self._network.recurrent_state_size) # Slice the sequence that corresponds to this token. token.state.set([ layer_state[:, index:index + 1] for layer_state in output_state ]) # logprobs matrix contains only one time step. token.nn_lm_logprob += self._handle_unk_logprob( target_word, logprobs[0, index], oov_logprob)