#tensorflow #tensorflow2.0 #tensorflow-lite
#tensorflow #tensorflow2.0 #tensorflow-lite
Вопрос:
Системная информация
- Платформа и дистрибутив ОС: CentOS Linux выпуска 7.7.1908 -Версия TensorFlow: 2.3.0
Я пытаюсь преобразовать официальную модель подписи к изображению tensorflow в модель TFLite
Я пытаюсь преобразовать модель tf.keras.Model
кодировщика и декодера следующим образом:
import tensorflow as tf
embedding_dim = 256
units = 512
top_k = 5000
vocab_size = top_k 1
features_shape = 2048
attention_features_shape = 64
class BahdanauAttention(tf.keras.Model):
def __init__(self, utils):
super(BahdanauAttention, self).__init__()
self.W1 = tf.keras.layers.Dense(utils)
self.W2 = tf.keras.layers.Dense(utils)
self.V = tf.keras.layers.Dense(1)
def call(self, features, hidden):
# features(CNN_encoder output) shape == (batch_size, 64, embedding_dim)
# hidden shape == (batch_size, hidden_size)
# hidden_with_time_axis shape == (batch_size, 1, hidden_size)
hidden_with_time_axis_shape = tf.expand_dims(hidden, 1)
# score shape == (batch_size, 64, hidden_size)
score = tf.nn.tanh(self.W1(features) self.W2(hidden_with_time_axis_shape))
# attention_weights shape == (batch_size, 64, 1)
# you get 1 at the last axis because you are applying score to self.V
attention_weights = tf.nn.softmax(self.V(score), axis=1)
# context_vector shape after sum == (batch_size, hidden_size)
context_vector = attention_weights * features
context_vector = tf.reduce_sum(context_vector, axis=1)
return context_vector, attention_weights
class CNN_Encoder(tf.keras.Model):
#由于您已经提取了特征并使用pickle进行了转储
#该编码器通过完全连接的层传递这些特征
def __init__(self, embedding):
super(CNN_Encoder, self).__init__()
# shape after fc == (batch_size, 64, embedding_dim)
self.fc = tf.keras.layers.Dense(embedding_dim)
# @tf.function(input_signature=[tf.TensorSpec(shape=(1, 64, features_shape),dtype=tf.float32)])
@tf.function
def call(self, x):
x = self.fc(x)
x = tf.nn.relu(x)
return x
class RNN_Decoder(tf.keras.Model):
def __init__(self, embedding_dim, units, vocab_size):
super(RNN_Decoder, self).__init__()
self.units = units
self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
self.gru = tf.keras.layers.GRU(self.units,
return_sequences=True,
return_state=True,
recurrent_initializer='glorot_uniform',
unroll = True)
self.fc1 = tf.keras.layers.Dense(self.units)
self.fc2 = tf.keras.layers.Dense(vocab_size)
self.attention = BahdanauAttention(self.units)
@tf.function(input_signature=[tf.TensorSpec(shape=[1, 1], dtype=tf.int32, name='x'),
tf.TensorSpec(shape=[1, 64, 256], dtype=tf.float32, name='feature'),
tf.TensorSpec(shape=[1, 512], dtype=tf.float32, name='hidden')])
@tf.function
def call(self, x , features, hidden):
#将注意力定义为一个单独的模型
context_vector, attention_weights = self.attention(features, hidden)
#x shape after passing through embedding == (batch_size, 1, embedding_dim)
x = self.embedding(x)
#x shape after concatenation == (batch_size, 1, embedding_dim hidden_size)
x = tf.concat([tf.expand_dims(context_vector, 1), x], axis=-1)
#将concated后的的向量传递给GRU
output, state = self.gru(x)
#shape == (batch_size, max_length, hidden_size)
x = self.fc1(output)
#x shape == (batch_size, max_length, hidden_size)
x = tf.reshape(x, (-1, x.shape[2]))
# output shape == (batch_size * max_length, vocab)
x = self.fc2(x)
return x, state, attention_weights
def reset_states(self, batch_size):
return tf.zeros((batch_size, self.units))
encoder = CNN_Encoder(embedding_dim)
decoder = RNN_Decoder(embedding_dim, units, vocab_size)`
encoder._set_inputs(tf.TensorSpec(shape=(1, 64, features_shape),dtype=tf.float32))
decoder._set_inputs([tf.TensorSpec(shape=[1, 1], dtype=tf.int32, name='x'),
tf.TensorSpec(shape=[1, 64, 256], dtype=tf.float32, name='feature'),
tf.TensorSpec(shape=[1, 512], dtype=tf.float32, name='hidden')])
encoder_converter = tf.lite.TFLiteConverter.from_keras_model(encoder)
decoder_converter = tf.lite.TFLiteConverter.from_keras_model(decoder)
encoder_model = encoder_converter.convert()
decoder_model = decoder_converter.convert()
open("encoder_model.tflite", "wb").write(encoder_model)
open("decoder_model.tflite", "wb").write(decoder_model)
Сообщение об ошибке
ValueError: Structure of Python function inputs does not match input_signature:
inputs: (
[<tf.Tensor 'x:0' shape=(1, 1) dtype=int32>, <tf.Tensor 'feature:0' shape=(1, 64, 256) dtype=float32>, <tf.Tensor 'hidden:0' shape=(1, 512) dtype=float32>])
input_signature: (
TensorSpec(shape=(1, 1), dtype=tf.int32, name='x'),
TensorSpec(shape=(1, 64, 256), dtype=tf.float32, name='feature'),
TensorSpec(shape=(1, 512), dtype=tf.float32, name='hidden'))
Я думаю, что ввод функции совпадает с входной подписью.Как я могу решить проблему?
Комментарии:
1. Похоже, эта проблема
Ответ №1:
у меня тоже была такая же проблема. найдено простое решение этой проблемы. метод вызова tf.keras.Класс модели принимает только один ввод, поэтому вам нужно упаковать все ваши входные данные в список / кортеж
https://github.com/tensorflow/tensorflow/issues/32488#issuecomment-560248754