def _valid_step(encoder: tf.keras.Model, decoder: tf.keras.Model, dataset: tf.data.Dataset, steps_per_epoch: int): """ 验证模块 :param encoder: 模型的encoder :param decoder: 模型的decoder :param dataset: 验证数据dataset :param steps_per_epoch: 验证训练步 :return: 无返回值 """ print("验证轮次") start_time = time.time() total_loss = 0 for (batch, (audio_feature, sentence)) in enumerate(dataset.take(steps_per_epoch)): batch_start = time.time() sentence_input = sentence[:, :-1] sentence_real = sentence[:, 1:] enc_outputs, padding_mask = encoder(audio_feature) sentence_predictions = decoder( inputs=[sentence_input, enc_outputs, padding_mask]) batch_loss = loss_func_mask(sentence_real, sentence_predictions) total_loss += batch_loss print('\r{}/{} [Batch {} Loss {:.4f} {:.1f}s]'.format( (batch + 1), steps_per_epoch, batch + 1, batch_loss.numpy(), (time.time() - batch_start)), end='') print(' - {:.0f}s/step - loss: {:.4f}'.format( (time.time() - start_time) / steps_per_epoch, total_loss / steps_per_epoch))
def _train_step(model: tf.keras.Model, optimizer: tf.keras.optimizers.Adam, audio_feature: tf.Tensor, sentence: tf.Tensor, enc_hidden: tf.Tensor, dec_input: tf.Tensor): """ 训练步 :param model: 模型 :param sentence: sentence序列 :param audio_feature: 音频特征序列 :param enc_hidden: encoder初始化隐藏层 :param optimizer 优化器 :param dec_input: 解码器输入 :return: batch损失和post_net输出 """ loss = 0 with tf.GradientTape() as tape: for t in range(1, sentence.shape[1]): predictions, _ = model(audio_feature, enc_hidden, dec_input) loss += loss_func_mask(sentence[:, t], predictions) if sum(sentence[:, t]) == 0: break dec_input = tf.expand_dims(sentence[:, t], 1) batch_loss = (loss / int(sentence.shape[0])) variables = model.trainable_variables gradients = tape.gradient(loss, variables) optimizer.apply_gradients(zip(gradients, variables)) return batch_loss
def _valid_step(model: tf.keras.Model, dataset: tf.data.Dataset, steps_per_epoch: int, tokenizer: tf.keras.preprocessing.text.Tokenizer, enc_hidden: tf.Tensor, dec_input: tf.Tensor): """ 验证模块 :param model: 模型 :param dataset: 验证数据dataset :param steps_per_epoch: 验证训练步 :param tokenizer: 分词器 :param enc_hidden: encoder初始化隐藏层 :param dec_input: 解码器输入 :return: 损失、wer、ler """ print("验证轮次") start_time = time.time() total_loss = 0 aver_wers = 0 aver_norm_lers = 0 for (batch, (audio_feature, sentence, length)) in enumerate(dataset.take(steps_per_epoch)): loss = 0 batch_start = time.time() result = dec_input for t in range(1, sentence.shape[1]): dec_input = dec_input[:, -1:] predictions, _ = model(audio_feature, enc_hidden, dec_input) loss += loss_func_mask(sentence[:, t], predictions) predictions = tf.argmax(predictions, axis=-1) dec_input = tf.expand_dims(predictions, axis=-1) result = tf.concat([result, dec_input], axis=-1) batch_loss = (loss / int(sentence.shape[0])) results = tokenizer.sequences_to_texts(result.numpy()) sentence = tokenizer.sequences_to_texts(sentence.numpy()) _, aver_wer = wers(sentence, results) _, norm_aver_ler = lers(sentence, results) aver_wers += aver_wer aver_norm_lers += norm_aver_ler total_loss += batch_loss print('\r{}/{} [Batch {} Loss {:.4f} {:.1f}s]'.format( (batch + 1), steps_per_epoch, batch + 1, batch_loss.numpy(), (time.time() - batch_start)), end='') print(' - {:.0f}s/step - loss: {:.4f} - average_wer:{:.4f} - ' 'average_norm_ler:{:.4f}'.format( (time.time() - start_time) / steps_per_epoch, total_loss / steps_per_epoch, aver_wers / steps_per_epoch, aver_norm_lers / steps_per_epoch)) return total_loss / steps_per_epoch, aver_wers / steps_per_epoch, aver_norm_lers / steps_per_epoch
def _train_step(inp, tar, transformer, optimizer, train_loss, train_accuracy): tar_inp = tar[:, :-1] tar_real = tar[:, 1:] enc_padding_mask, combined_mask, dec_padding_mask = _transformer.create_masks( inp, tar_inp) with tf.GradientTape() as tape: predictions, _ = transformer(inp, tar_inp, True, enc_padding_mask, combined_mask, dec_padding_mask) loss = _optimizers.loss_func_mask(tar_real, predictions) gradients = tape.gradient(loss, transformer.trainable_variables) optimizer.apply_gradients(zip(gradients, transformer.trainable_variables)) train_loss(loss) train_accuracy(tar_real, predictions)
def _train_step(sequences, lm, optimizer, train_loss, train_accuracy): """一个训练步 @param sequences: 已编码的一个batch的数据集 shape --> (batch_size, seq_length) @param lm: 语言模型实例 @param optimizer: 优化器 """ seq_input = sequences[:, :-1] seq_real = sequences[:, 1:] with tf.GradientTape() as tape: predictions = lm(seq_input) loss = optimizers.loss_func_mask(seq_real, predictions) gradients = tape.gradient(loss, lm.trainable_variables) optimizer.apply_gradients(zip(gradients, lm.trainable_variables)) train_loss(loss) train_accuracy(seq_real, predictions)
def _train_step(self, inp: tf.Tensor, tar: tf.Tensor, weight: tf.Tensor = None): """ :param inp: 输入序列 :param tar: 目标序列 :param weight: 样本权重序列 :return: 返回训练损失和精度 """ tar_inp = tar[:, :-1] tar_real = tar[:, 1:] with tf.GradientTape() as tape: predictions = self.model(inputs=[inp, tar_inp]) loss = optimizers.loss_func_mask(tar_real, predictions, weight) gradients = tape.gradient(loss, self.model.trainable_variables) self.optimizer.apply_gradients( zip(gradients, self.model.trainable_variables)) self.train_loss(loss) self.train_accuracy(tar_real, predictions) return self.train_loss.result(), self.train_accuracy.result()
def _train_step(audio_feature, sentence, enc_hidden, tokenizer, model, las_optimizer, train_batch_size): loss = 0 dec_input = tf.expand_dims([tokenizer.word_index.get('<start>')] * train_batch_size, 1) with tf.GradientTape() as tape: # 解码器输入符号 for t in range(1, sentence.shape[1]): print(t) predictions, _ = model(audio_feature, enc_hidden, dec_input) loss += loss_func_mask(sentence[:, t], predictions) # 根据预测计算损失 print("loss===={}".format(loss)) # 使用导师驱动,下一步输入符号是训练集中对应目标符号 dec_input = sentence[:, t] dec_input = tf.expand_dims(dec_input, 1) batch_loss = (loss / int(sentence.shape[1])) print("batch_loss===={}".format(batch_loss)) variables = model.trainable_variables gradients = tape.gradient(loss, variables) # 计算损失对参数的梯度 las_optimizer.apply_gradients(zip(gradients, variables)) # 优化器反向传播更新参数 return batch_loss
def _train_step(encoder: tf.keras.Model, decoder: tf.keras.Model, optimizer, sentence_input: tf.Tensor, sentence_real: tf.Tensor, audio_feature: tf.Tensor): """ 训练步 :param encoder: 模型的encoder :param decoder: 模型的decoder :param sentence_input: sentence序列 :param audio_feature: 音频特征序列 :param sentence_real: ground-true句子序列 :param optimizer 优化器 :return: batch损失和post_net输出 """ with tf.GradientTape() as tape: enc_outputs, padding_mask = encoder(audio_feature) sentence_predictions = decoder( inputs=[sentence_input, enc_outputs, padding_mask]) loss = loss_func_mask(sentence_real, sentence_predictions) batch_loss = loss variables = encoder.trainable_variables + decoder.trainable_variables gradients = tape.gradient(loss, variables) optimizer.apply_gradients(zip(gradients, variables)) return batch_loss, sentence_predictions