打包 keras tokenizer/word 索引用于 google-cloud-ml-engine
Packaging keras tokenizer/word index for use in google-cloud-ml-engine
我已经在 Keras 中创建了一个文本分类器,我可以在 Cloud ML 上很好地训练 Keras 模型:该模型随后部署在 Cloud ML 上。然而,当传递文本进行分类时,它 returns 错误的分类:我强烈怀疑它没有使用我在创建 keras 分类器时使用的相同 tokenizer/word 索引,该索引用于标记化新文本。
我不确定如何在训练时将 tokeniser/word 索引传递给 Cloud ML:之前有一个 ,但
gcloud ml-engine jobs submit training
拿起一个泡菜或包含单词索引映射的文本文件?如果是这样,我应该如何配置 setup.py 文件?
编辑:
所以,我正在使用 Keras 来标记输入文本,如下所示:
tokenizer = Tokenizer(num_words=MAX_NB_WORDS)
tokenizer.fit_on_texts(X_train)
sequences = tokenizer.texts_to_sequences(X_train)
word_index = tokenizer.word_index
如果我只是在本地加载 Keras 模型,我会像这样保存模型:
model.save('model_embeddings_20epochs_v2.h5')
我还保存了分词器,以便我可以用它来分词新数据:
with open("../saved_models/keras_tokenizer_embeddings_002.pickle", "wb") as f:
pickle.dump(tokenizer, f)
在新数据上,我恢复了模型和分词器。
model = load_model('../../saved_models/model_embeddings_20epochs_v2.h5')
with open("../../saved_models/keras_tokenizer_embeddings_002.pickle", "rb") as f:
tokenizer = pickle.load(f)
然后我使用分词器将文本转换为新数据的序列、分类等
Cloud ML 作业的脚本不保存分词器 - 我推测 Keras 脚本基本上使用相同的单词索引。
....
X_train = [x.encode('UTF8') for x in X_train]
X_test = [x.encode('UTF8') for x in X_test]
# finally, vectorize the text samples into a 2D integer tensor
tokenizer = Tokenizer(num_words=MAX_NB_WORDS)
tokenizer.fit_on_texts(X_train)
sequences = tokenizer.texts_to_sequences(X_train)
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))
.....
# prepare embedding matrix
num_words = min(MAX_NB_WORDS, len(word_index))
embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
for word, i in word_index.items():
if i >= MAX_NB_WORDS:
continue
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
# words not found in embedding index will be all-zeros.
embedding_matrix[i] = embedding_vector
# load pre-trained word embeddings into an Embedding layer
# note that we set trainable = False so as to keep the embeddings fixed
embedding_layer = Embedding(num_words,
EMBEDDING_DIM,
weights=[embedding_matrix],
input_length=MAX_SEQUENCE_LENGTH,
trainable=False)
目前,我只是在本地训练它。
gcloud ml-engine local train \
--job-dir $JOB_DIR \
--module-name trainer.multiclass_glove_embeddings_v1 \
--package-path ./trainer \
-- \
--train-file ./data/corpus.pkl
从 source code 中我可以看出,似乎即使是 TensorFlow 的 Keras 兼容库也在 Python 中进行标记化 ,即,不作为 TensorFlow 图表的一部分。
目前,CloudML Engine 仅支持为所有逻辑都编码在 TensorFlow 图中的 TensorFlow 模型提供服务。这意味着您必须在客户端进行标记化并将结果传递到服务器以进行预测。这将涉及对 客户端 进行编码以反序列化 Tokenizer
并为需要预测的输入调用 tokenizer.texts_to_sequences
。
我们认识到这并不总是理想的(对于非 Python 客户来说是行不通的,而且不方便,至少,即使对于 Python 客户也是如此)并且正在积极研究允许任意的解决方案Python 代码将 运行 作为预测的一部分。
我已经在 Keras 中创建了一个文本分类器,我可以在 Cloud ML 上很好地训练 Keras 模型:该模型随后部署在 Cloud ML 上。然而,当传递文本进行分类时,它 returns 错误的分类:我强烈怀疑它没有使用我在创建 keras 分类器时使用的相同 tokenizer/word 索引,该索引用于标记化新文本。
我不确定如何在训练时将 tokeniser/word 索引传递给 Cloud ML:之前有一个
gcloud ml-engine jobs submit training
拿起一个泡菜或包含单词索引映射的文本文件?如果是这样,我应该如何配置 setup.py 文件?
编辑:
所以,我正在使用 Keras 来标记输入文本,如下所示:
tokenizer = Tokenizer(num_words=MAX_NB_WORDS)
tokenizer.fit_on_texts(X_train)
sequences = tokenizer.texts_to_sequences(X_train)
word_index = tokenizer.word_index
如果我只是在本地加载 Keras 模型,我会像这样保存模型:
model.save('model_embeddings_20epochs_v2.h5')
我还保存了分词器,以便我可以用它来分词新数据:
with open("../saved_models/keras_tokenizer_embeddings_002.pickle", "wb") as f:
pickle.dump(tokenizer, f)
在新数据上,我恢复了模型和分词器。
model = load_model('../../saved_models/model_embeddings_20epochs_v2.h5')
with open("../../saved_models/keras_tokenizer_embeddings_002.pickle", "rb") as f:
tokenizer = pickle.load(f)
然后我使用分词器将文本转换为新数据的序列、分类等
Cloud ML 作业的脚本不保存分词器 - 我推测 Keras 脚本基本上使用相同的单词索引。
....
X_train = [x.encode('UTF8') for x in X_train]
X_test = [x.encode('UTF8') for x in X_test]
# finally, vectorize the text samples into a 2D integer tensor
tokenizer = Tokenizer(num_words=MAX_NB_WORDS)
tokenizer.fit_on_texts(X_train)
sequences = tokenizer.texts_to_sequences(X_train)
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))
.....
# prepare embedding matrix
num_words = min(MAX_NB_WORDS, len(word_index))
embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
for word, i in word_index.items():
if i >= MAX_NB_WORDS:
continue
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
# words not found in embedding index will be all-zeros.
embedding_matrix[i] = embedding_vector
# load pre-trained word embeddings into an Embedding layer
# note that we set trainable = False so as to keep the embeddings fixed
embedding_layer = Embedding(num_words,
EMBEDDING_DIM,
weights=[embedding_matrix],
input_length=MAX_SEQUENCE_LENGTH,
trainable=False)
目前,我只是在本地训练它。
gcloud ml-engine local train \
--job-dir $JOB_DIR \
--module-name trainer.multiclass_glove_embeddings_v1 \
--package-path ./trainer \
-- \
--train-file ./data/corpus.pkl
从 source code 中我可以看出,似乎即使是 TensorFlow 的 Keras 兼容库也在 Python 中进行标记化 ,即,不作为 TensorFlow 图表的一部分。
目前,CloudML Engine 仅支持为所有逻辑都编码在 TensorFlow 图中的 TensorFlow 模型提供服务。这意味着您必须在客户端进行标记化并将结果传递到服务器以进行预测。这将涉及对 客户端 进行编码以反序列化 Tokenizer
并为需要预测的输入调用 tokenizer.texts_to_sequences
。
我们认识到这并不总是理想的(对于非 Python 客户来说是行不通的,而且不方便,至少,即使对于 Python 客户也是如此)并且正在积极研究允许任意的解决方案Python 代码将 运行 作为预测的一部分。