簡體   English   中英

This model has not been built 錯誤在 model.summary()

[英]This model has not yet been built error on model.summary()

我將 keras 模型定義如下

class ConvLayer(Layer) :
    def __init__(self, nf, ks=3, s=2, **kwargs):
        self.nf = nf
        self.grelu = GeneralReLU(leak=0.01)
        self.conv = (Conv2D(filters     = nf,
                            kernel_size = ks,
                            strides     = s,
                            padding     = "same",
                            use_bias    = False,
                            activation  = "linear"))
        super(ConvLayer, self).__init__(**kwargs)

    def rsub(self): return -self.grelu.sub
    def set_sub(self, v): self.grelu.sub = -v
    def conv_weights(self): return self.conv.weight[0]

    def build(self, input_shape):
        # No weight to train.
        super(ConvLayer, self).build(input_shape)  # Be sure to call this at the end

    def compute_output_shape(self, input_shape):
        output_shape = (input_shape[0],
                        input_shape[1]/2,
                        input_shape[2]/2,
                        self.nf)
        return output_shape

    def call(self, x):
        return self.grelu(self.conv(x))

    def __repr__(self):
        return f'ConvLayer(nf={self.nf}, activation={self.grelu})'
class ConvModel(tf.keras.Model):
    def __init__(self, nfs, input_shape, output_shape, use_bn=False, use_dp=False):
        super(ConvModel, self).__init__(name='mlp')
        self.use_bn = use_bn
        self.use_dp = use_dp
        self.num_classes = num_classes

        # backbone layers
        self.convs = [ConvLayer(nfs[0], s=1, input_shape=input_shape)]
        self.convs += [ConvLayer(nf) for nf in nfs[1:]]
        # classification layers
        self.convs.append(AveragePooling2D())
        self.convs.append(Dense(output_shape, activation='softmax'))

    def call(self, inputs):
        for layer in self.convs: inputs = layer(inputs)
        return inputs

我能夠毫無問題地編譯這個模型

>>> model.compile(optimizer=tf.keras.optimizers.Adam(lr=lr), 
              loss='categorical_crossentropy',
              metrics=['accuracy'])

但是當我查詢這個模型的摘要時,我看到了這個錯誤

>>> model = ConvModel(nfs, input_shape=(32, 32, 3), output_shape=num_classes)
>>> model.summary()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-220-5f15418b3570> in <module>()
----> 1 model.summary()

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py in summary(self, line_length, positions, print_fn)
   1575     """
   1576     if not self.built:
-> 1577       raise ValueError('This model has not yet been built. '
   1578                        'Build the model first by calling `build()` or calling '
   1579                        '`fit()` with some data, or specify '

ValueError: This model has not yet been built. Build the model first by calling `build()` or calling `fit()` with some data, or specify an `input_shape` argument in the first layer(s) for automatic build.

我正在為模型的第一層提供input_shape ,為什么會拋出此錯誤?

錯誤說明要做什么:

該模型尚未構建。 首先通過調用build()構建模型

model.build(input_shape) # `input_shape` is the shape of the input data
                         # e.g. input_shape = (None, 32, 32, 3)
model.summary()

keras 子類模型與其他 keras 模型(順序模型和函數模型)之間存在很大差異。

順序模型和功能模型是表示層的 DAG 的數據結構。 簡而言之,功能模型或順序模型是通過像樂高積木一樣將一個層堆疊在一起構建的靜態層圖。 因此,當您向第一層提供 input_shape 時,這些(功能和順序)模型可以推斷所有其他層的形狀並構建模型。 然后您可以使用 model.summary() 打印輸入/輸出形狀。

另一方面,子類模型是通過 Python 代碼的主體(調用方法)定義的。 對於子類模型,這里沒有層圖。 我們不知道層是如何相互連接的(因為這是在調用主體中定義的,而不是作為顯式數據結構),所以我們無法推斷輸入/輸出形狀。 因此,對於子類模型,在首次使用適當的數據進行測試之前,我們不知道輸入/輸出形狀。 在 compile() 方法中,我們將進行延遲編譯並等待合適的數據。 為了讓它推斷中間層的形狀,我們需要使用適當的數據運行,然后使用 model.summary()。 如果不使用數據運行模型,它會像您注意到的那樣拋出錯誤。 請檢查GitHub 要點以獲取完整代碼。

以下是來自 Tensorflow 網站的示例。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

class ThreeLayerMLP(keras.Model):

  def __init__(self, name=None):
    super(ThreeLayerMLP, self).__init__(name=name)
    self.dense_1 = layers.Dense(64, activation='relu', name='dense_1')
    self.dense_2 = layers.Dense(64, activation='relu', name='dense_2')
    self.pred_layer = layers.Dense(10, name='predictions')

  def call(self, inputs):
    x = self.dense_1(inputs)
    x = self.dense_2(x)
    return self.pred_layer(x)

def get_model():
  return ThreeLayerMLP(name='3_layer_mlp')

model = get_model()

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(60000, 784).astype('float32') / 255
x_test = x_test.reshape(10000, 784).astype('float32') / 255

model.compile(loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              optimizer=keras.optimizers.RMSprop())

model.summary() # This will throw an error as follows
# ValueError: This model has not yet been built. Build the model first by calling `build()` or calling `fit()` with some data, or specify an `input_shape` argument in the first layer(s) for automatic build.

# Need to run with real data to infer shape of different layers
history = model.fit(x_train, y_train,
                    batch_size=64,
                    epochs=1)

model.summary()

謝謝!

另一種方法是像這樣添加屬性input_shape()

model = Sequential()
model.add(Bidirectional(LSTM(n_hidden,return_sequences=False, dropout=0.25, 
recurrent_dropout=0.1),input_shape=(n_steps,dim_input)))
# X is a train dataset with features excluding a target variable

input_shape = X.shape  
model.build(input_shape) 
model.summary()

確保正確創建模型。 像下面代碼這樣的小錯別字也可能會導致問題:

model = Model(some-input, some-output, "model-name")

而正確的代碼應該是:

model = Model(some-input, some-output, name="model-name")

如果您的 Tensorflow、Keras 版本是2.5.0 ,那么在導入 Keras 包時只需添加 Tensorflow

不是這個:

from tensorflow import keras
from keras.models import Sequential
import tensorflow as tf

像這樣:

from tensorflow import keras
from tensorflow.keras.models import Sequential
import tensorflow as tf

您的 Tensorflow、Keras 的版本問題可能是造成這種情況的原因。

我在訓練 LSTM 回歸模型時遇到了同樣的問題。

錯誤:

ValueError:此模型尚未構建。 首先通過調用build()或對一批數據調用模型來構建模型。

早些時候:

from tensorflow.keras.models import Sequential

from tensorflow.python.keras.models import Sequential

更正:

from keras.models import Sequential

我也遇到了同樣的錯誤,所以我刪除model.summary() 然后問題就解決了。 如果在構建模型之前定義了摘要模型,則會出現這種情況。

這是用於描述的鏈接,其中指出

Raises:
    ValueError: if `summary()` is called before the model is built.**

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM