python - Keras TensorFlow Hub:简单的 ELMO 网络入门
问题描述
我正在尝试从 TensorFlow hub 获得一个简单的 ELMO 模型,但结果证明这是一个挑战。
当我运行我的代码时,我收到错误消息:“急切执行函数的输入不能是 Keras 符号张量,但发现 [<tf.Tensor 'input_69:0' shape=(None, 10) dtype=string>] "
我想我弄乱了 sequence_length 参数或输入。谁能帮帮我吗?
import tensorflow as tf
import tensorflow_hub as hub
import re
from tensorflow import keras
import tensorflow.keras
from tensorflow.keras.layers import Input, Dense,Flatten
import numpy as np
import keras.callbacks
import io
from sklearn.model_selection import train_test_split
i = 0
max_cells = 51 #countLines()
x_data = np.zeros((max_cells, 10, 1), dtype='object')
y_data = np.zeros((max_cells, 3), dtype='float32')
seqs = np.zeros((max_cells), dtype='int32')
with io.open('./data/names-sample.txt', encoding='utf-8') as f:
content = f.readlines()
for line in content:
line = re.sub("[\n]", " ", line)
tokens = line.split()
for t in range(0, min(10,len(tokens))):
tkn = tokens[t]
x_data[i,t] = tkn
seqs[i] = len(tokens)
y_data[i,0] = 1
i = i+1
def build_model():
tokens = Input(shape=[10,], dtype=tf.string)
seq_lens = Input(shape=[], dtype=tf.int32)
elmo = hub.KerasLayer(
"https://tfhub.dev/google/elmo/3",
trainable=False,
output_key="elmo",
signature="tokens",
)
out = elmo({"tokens": tokens, "sequence_len": seqs})
model = keras.Model(inputs=[tokens, seq_lens], outputs=out)
model.compile("adam", loss="sparse_categorical_crossentropy")
model.summary()
return model
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.70, shuffle=True)
model = build_model()
model.fit(x_train, y_train,validation_data=(x_test, y_test),epochs=1,batch_size=32)
完全错误:
TypeError:函数构建代码之外的操作正在传递一个“图形”张量。通过在函数构建代码中包含 tf.init_scope ,可以使 Graph 张量从函数构建上下文中泄漏出来。例如,以下函数将失败:@tf.function def has_init_scope(): my_constant = tf.constant(1.) with tf.init_scope(): added = my_constant * 2 图张量的名称为:input_69:0
在处理上述异常的过程中,又出现了一个异常:
回溯(最近一次通话最后):
文件“C:\temp\Simon\TempElmoNames.py”,第 66 行,模型 = build_model()
文件“C:\temp\Simon\TempElmoNames.py”,第 56 行,在 build_model out = elmo({"tokens": tokens, "sequence_len": seqs})
文件“C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py”,第 891 行,调用 输出 = self.call(cast_inputs, *args, **kwargs)
文件“C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_hub\keras_layer.py”,第 229 行,调用结果 = f()
文件“C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_core\python\eager\function.py”,第 1081 行,调用 返回 self._call_impl(args, kwargs)
文件“C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_core\python\eager\function.py”,第 1121 行,在 _call_impl 中返回 self._call_flat(args,self.captured_inputs,cancellation_manager)
文件“C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_core\python\eager\function.py”,第 1224 行,在 _call_flat ctx、args、cancellation_manager=cancellation_manager)
文件“C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_core\python\eager\function.py”,第 511 行,调用 ctx=ctx)
文件“C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_core\python\eager\execute.py”,第 75 行,在 quick_execute“张量,但找到 {}”.format(keras_symbolic_tensors))
_SymbolicException: 急切执行函数的输入不能是 Keras 符号张量,但发现 [<tf.Tensor 'input_69:0' shape=(None, 10) dtype=string>]
以下是我正在使用的版本: Keras:2.3.1 TF:2.0.0 TH-hub:0.12.0
更新 1: 我升级了 Keras (2.6.0) TF (2.6.0) 和 TF Hub(0.12.0) 并更改了关于 seqs 和 seq_lens 如何传递的 build_model 方法。
def build_model():
tokens = Input(shape=[10,], dtype=tf.string)
seq_lens = Input(shape=[], dtype=tf.int32)
elmo = hub.KerasLayer(
"https://tfhub.dev/google/elmo/3",
trainable=False,
output_key="elmo",
signature="tokens",
)
out = elmo({"tokens": tokens, "sequence_len": seq_lens})
model = keras.Model(inputs=[tokens, seqs], outputs=out)
model.compile("adam", loss="sparse_categorical_crossentropy")
model.summary()
return model
现在我收到错误:
ValueError: Function 的输入张量必须来自
tf.keras.Input
. 收到: [3 3 2 2 3 3 3 5 3 3 3 2 7 2 2 2 3 2 2 3 3 3 3 3 3 2 3 2 3 2 3 3 2 3 3 2 3 2 2 2 2 3 2 2 3 3 5 3 3 3 0](缺少前一层元数据)。
解决方案
我不认为这是一个错误,而是 TF 让我们可以自由选择每种方法。虽然我们可以将图层子类与 keras 功能 api 混合匹配,但我想我们无法使模型子类与 keras 的模型 api 一起工作。在我看来,这就是急切执行和 keras 图形模式之间的区别发生冲突的地方,从而导致了这种“SymbolicException”。
让 TF 事先知道它应该执行什么模式可以解决它。
推荐阅读
- oracle - 在where子句中用or/nvl合并数据,有什么好处?
- reactjs - 如何将数据发送到具有多个嵌套数组的 api 反应
- sql - 如何将特定行选择到新表中?
- c# - Powershell vs C# EscapeUriString 不同的结果
- javascript - JQuery缓慢的图像变化
- javascript - Angular - 在组件之间共享图像
- javascript - 程序需要在点击时查找在父框中输入的所有父编号的后继者的计数
- ios - CKUserIdentity userRecordID 属性是可选的。为什么?
- javascript - Greasemonkey 禁用脚本
- sql - 获取选择查询可以返回的行数