Керас Создание модели CNN «Добавленный слой должен быть экземпляром класса Layer» - PullRequest
2 голосов
/ 18 июня 2020
from tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization
from tensorflow.keras.layers import Dropout, Flatten, Input, Dense

def create_model():

    def add_conv_block(model, num_filters):

        model.add(Conv2D(num_filters, 3, activation='relu', padding='same'))
        model.add(BatchNormalization())
        model.add(Conv2D(num_filters, 3, activation='relu', padding='valid'))
        model.add(MaxPooling2D(pool_size=2))
        model.add(Dropout(0.2))

        return model

    model = tf.keras.models.Sequential()
    model.add(Input(shape=(32, 32, 3)))

    model = add_conv_block(model, 32)
    model = add_conv_block(model, 64)
    model = add_conv_block(model, 128)

    model.add(Flatten())
    model.add(Dense(3, activation='softmax'))

    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

model = create_model()
model.summary()

введите описание изображения здесь

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Решение - использовать InputLayer вместо Input. InputLayer предназначен для использования с моделями Sequential. Вы также можете полностью опустить InputLayer и указать input_shape на первом уровне последовательной модели.

Input предназначен для использования с функциональным API TensorFlow Keras, а не с последовательным API.

from tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization
from tensorflow.keras.layers import Dropout, Flatten, InputLayer, Dense

def create_model():

    def add_conv_block(model, num_filters):

        model.add(Conv2D(num_filters, 3, activation='relu', padding='same'))
        model.add(BatchNormalization())
        model.add(Conv2D(num_filters, 3, activation='relu', padding='valid'))
        model.add(MaxPooling2D(pool_size=2))
        model.add(Dropout(0.2))

        return model

    model = tf.keras.models.Sequential()
    model.add(InputLayer((32, 32, 3)))

    model = add_conv_block(model, 32)
    model = add_conv_block(model, 64)
    model = add_conv_block(model, 128)

    model.add(Flatten())
    model.add(Dense(3, activation='softmax'))

    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

model = create_model()
model.summary()
1 голос
/ 18 июня 2020

Я думаю, что проблема связана с версией TF ... однако я предлагаю вам эту реализацию. Таким образом, вы можете указать input_shape в первом слое последовательной модели и преодолеть проблему

def create_model():

    def add_conv_block(model, num_filters, input_shape=None):

        if input_shape:
            model.add(Conv2D(num_filters, 3, activation='relu', padding='same', input_shape=input_shape))
        else:
            model.add(Conv2D(num_filters, 3, activation='relu', padding='same'))

        model.add(BatchNormalization())
        model.add(Conv2D(num_filters, 3, activation='relu', padding='valid'))
        model.add(MaxPooling2D(pool_size=2))
        model.add(Dropout(0.2))

        return model

    model = tf.keras.models.Sequential()
    model = add_conv_block(model, 32, input_shape=(32, 32, 3))
    model = add_conv_block(model, 64)
    model = add_conv_block(model, 128)

    model.add(Flatten())
    model.add(Dense(3, activation='softmax'))

    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

    return model

model = create_model()
model.summary() 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...