【问题标题】:How to change Sequential model to Custom Class model如何将顺序模型更改为自定义类模型
【发布时间】:2019-08-24 12:32:41
【问题描述】:

我正在从旧版本中学习 tensorflow 2.0。 我发现 tensorflow 模型从 Class-base 更改为 Sequential-base。 但我想使用基于类的模型,因为它对我来说很容易阅读。

我想尝试翻译:https://www.tensorflow.org/beta/tutorials/keras/basic_text_classification_with_tfhub

embedding = 'https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1'
hub_layer = hub.KerasLayer(embedding,
                           input_shape=[],
                           dtype=tf.string,
                           trainable=True)
# hub_layer(train_example_batch[:3])


# model = tf.keras.Sequential()
# model.add(hub_layer)
# model.add(tf.keras.layers.Dense(16, activation='relu'))
# model.add(tf.keras.layers.Dense(1, activation='sigmoid'))


class MyModel(keras.Model):
    def __init__(self, embedding):
        super(MyModel, self).__init__()
        self.embedding = embedding
        self.d1 = keras.layers.Dense(16, activation='relu')
        self.d2 = keras.layers.Dense(1, activation='sigmoid')

    def call(self, x):
        print(x.shape)
        return reduce(lambda x, f: f(x), [x, self.embedding, self.d1, self.d2])


model = MyModel(hub_layer)

我收到以下错误消息。

InvalidArgumentError: 2 root error(s) found.
  (0) Invalid argument:  input must be a vector, got shape: [512,1]
     [[{{node my_model_48/keras_layer_7/StatefulPartitionedCall/StatefulPartitionedCall/StatefulPartitionedCall/tokenize/StringSplit}}]]
  (1) Invalid argument:  input must be a vector, got shape: [512,1]
     [[{{node my_model_48/keras_layer_7/StatefulPartitionedCall/StatefulPartitionedCall/StatefulPartitionedCall/tokenize/StringSplit}}]]
     [[my_model_48/keras_layer_7/StatefulPartitionedCall/StatefulPartitionedCall/StatefulPartitionedCall/SparseFillEmptyRows/SparseFillEmptyRows/_24]]
0 successful operations.
0 derived errors ignored. [Op:__inference_keras_scratch_graph_303077]

Function call stack:
keras_scratch_graph -> keras_scratch_graph

为什么会出现这个错误?另外,请回答我们是否需要丢弃基于类的模型?

【问题讨论】:

标签: tensorflow keras keras-layer


【解决方案1】:

这是正确的代码。

# model = tf.keras.Sequential()
# model.add(hub_layer)
# model.add(tf.keras.layers.Dense(16, activation='relu'))
# model.add(tf.keras.layers.Dense(1, activation='sigmoid'))


class MyModel(keras.Model):
    def __init__(self, embedding):
        super(MyModel, self).__init__()
        self.embedding = embedding
        self.d1 = keras.layers.Dense(16, activation='relu')
        self.d2 = keras.layers.Dense(1, activation='sigmoid')

    def call(self, x):
        # tf.sequeeze is needed! because x's dimention is [None, 1]. (1 was inserted without permission ...)
        return reduce(lambda x, f: f(x), [x, tf.squeeze, self.embedding, self.d1, self.d2])


model = MyModel(hub_layer)

# model.summary()
model.layers

是因为官方框架自己添加了额外的功能......

我不喜欢这个属性,但是我觉得喜欢tensorflow的人渴望去做...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多