Attention入门及其在Tensorflow中实现

翻译自Tensorflow官方教程Neural machine translation with attention
声明:

  • 本文将实现一个将西班牙语翻译成英语的seq2seq模型;
  • 需要读者对seq2seq模型有了解;
  • 需要读者对nlp中一些数据处理方式有了解;
  • 翻译并非直译,会比原文更直白和丰富。
  • 有些不重要的代码已通过(不重要)标记

我们准备训练一个seq2seq模型,将西班牙语翻译成英语。

翻译
\todavia estan en casa?
are you still at home?

在翻译中,原文本和翻译文本的词与词之间通常都有一定的对应关系。最理想的情况是:原文本的第 i i i个词对应翻译文本的第 i i i个词。当然大多数情况下不会有这么严格的对其关系。通过attention,我们可以得到如下图所示的混淆矩阵。

图中颜色鲜艳的部分表示横轴单词和纵轴单词关系密切,深蓝部分表示横轴单词和纵轴单词的关系疏远。这里的关系就是attention,显然,todavia pay more attention to you than at
attention


Note:下面的代码运行时间在10min左右,运行环境为单卡P100 GPU

code part 1: 导入需要的包(不重要)

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from sklearn.model_selection import train_test_split

import unicodedata
import re
import numpy as np
import os
import io
import time

数据准备

数据介绍: 西班牙语到英语的翻译数据。
下载地址: http://www.manythings.org/anki/
数据示例: May I borrow this book? ¿Puedo tomar prestado este libro?

code part 2:下载数据集(不重要)

# Download the file
path_to_zip = tf.keras.utils.get_file(
    'spa-eng.zip', origin='http://storage.googleapis.com/download.tensorflow.org/data/spa-eng.zip',
    extract=True)

path_to_file = os.path.dirname(path_to_zip)+"/spa-eng/spa.txt"

数据下载后,我们要做一些数据处理工作,包括一下4点:

  1. 在每句话的首尾添加开始符终止符
  2. 删除特殊符号;
  3. 将文本型的单词转化成数值型的索引(也就是建立一个字典,可以完成word->id或者id->word的映射);
  4. padding每句话,使它们长度一致

code part 3: 数据处理(不重要)

# Converts the unicode file to ascii
def unicode_to_ascii(s):
  return ''.join(c for c in unicodedata.normalize('NFD', s)
      if unicodedata.category(c) != 'Mn')


def preprocess_sentence(w):
  w = unicode_to_ascii(w.lower().strip())

  # creating a space between a word and the punctuation following it
  # eg: "he is a boy." => "he is a boy ."
  # Reference:- https://stackoverflow.com/questions/3645931/python-padding-punctuation-with-white-spaces-keeping-punctuation
  w = re.sub(r"([?.!,¿])", r" \1 ", w)
  w = re.sub(r'[" "]+', " ", w)

  # replacing everything with space except (a-z, A-Z, ".", "?", "!", ",")
  w = re.sub(r"[^a-zA-Z?.!,¿]+", " ", w)

  w = w.rstrip().strip()

  # adding a start and an end token to the sentence
  # so that the model know when to start and stop predicting.
  w = '<start> ' + w + ' <end>'
  return w
en_sentence = u"May I borrow this book?"
sp_sentence = u"¿Puedo tomar prestado este libro?"
print(preprocess_sentence(en_sentence))
print(preprocess_sentence(sp_sentence).encode('utf-8'))

输出如下所示:
  <start> may i borrow this book ? <end>
  b'<start> \xc2\xbf puedo tomar prestado este libro ? <end>'

# 1. Remove the accents
# 2. Clean the sentences
# 3. Return word pairs in the format: [ENGLISH, SPANISH]
def create_dataset(path, num_examples):
  lines = io.open(path, encoding='UTF-8').read().strip().split('\n')

  word_pairs = [[preprocess_sentence(w) for w in l.split('\t')]  for l in lines[:num_examples]]

  return zip(*word_pairs)
en, sp = create_dataset(path_to_file, None)
print(en[-1])
print(sp[-1])

输出如下所示:
  <start> if you want to sound like a native speaker , you must be willing to practice saying the same sentence over and over in the same way that banjo players practice the same phrase over and over until they can play it correctly and at the desired tempo . <end>
  <start> si quieres sonar como un hablante nativo , debes estar dispuesto a practicar diciendo la misma frase una y otra vez de la misma manera en que un musico de banjo practica el mismo fraseo una y otra vez hasta que lo puedan tocar correctamente y en el tiempo esperado . <end>

def max_length(tensor):
  return max(len(t) for t in tensor)
def tokenize(lang):
  lang_tokenizer = tf.keras.preprocessing.text.Tokenizer(
      filters='')
  lang_tokenizer.fit_on_texts(lang)

  tensor = lang_tokenizer.texts_to_sequences(lang)

  tensor = tf.keras.preprocessing.sequence.pad_sequences(tensor,
                                                         padding='post')

  return tensor, lang_tokenizer

构造一个包含30000样本的数据集

code part 4:构造一个包含3000样本的数据集(不重要)

def load_dataset(path, num_examples=None):
  # creating cleaned input, output pairs
  targ_lang, inp_lang = create_dataset(path, num_examples)

  input_tensor
  • 12
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值