Оценка модели CapsNet с проверкой K-Fold - Как получить лучшую модель и оценить

1

Я пытался реализовать CapsuleNet для классификации некоторых цифр. Все изображения представляют собой изображения RGB, преобразованные в оттенки серого и имеющие размер 32 X 32 а набор данных имеет 10 классификационных выходных данных.

X_train_all.shape: (2075, 32, 32, 1)
y_train_all.shape: (2075, 10)

Вот что я пробовал до сих пор.

Модель CapsNet

Сначала определите модель CapsNet. Ниже приведена основная архитектура Capsule Network, включая PrimaryCaps, DigitCaps и так далее.

def CapsNet(input_shape, n_class, routings):

    x = layers.Input(shape=input_shape)

    # Layer 1
    conv1 = layers.Conv2D()(x)

    # Layer 2
    primarycaps = PrimaryCap()

    # Layer 3
    digitcaps = CapsuleLayer()(primarycaps)

    # Layer 4
    out_caps = Length(name='capsnet')(digitcaps)

    # Decoder network.
    y = layers.Input()
    masked_by_y = Mask()([digitcaps, y])  
    masked = Mask()(digitcaps)  

    # Shared Decoder model in training and prediction
    decoder = models.Sequential(name='decoder')
    decoder.add(layers.Dense(512, activation='relu', input_dim=16*n_class))
    decoder.add(layers.Dense(1024, activation='relu'))
    decoder.add(layers.Dense(np.prod(input_shape), activation='sigmoid'))
    decoder.add(layers.Reshape(target_shape=input_shape, name='out_recon'))

    # Models for training and evaluation (prediction)
    train_model = models.Model([x, y], [out_caps, decoder(masked_by_y)])
    evals_model = models.Model(x, [out_caps, decoder(masked)])

    return train_model, evals_model

Актуальное обучение

Это просто возвращает train_model и eval_model. Ниже приведен фактический процесс обучения, который я реализовал.

def train_caps(model, data, epoch_size_frac=1.0):

    # unpacking the data
    (x_train, y_train), (x_val, y_val) = data

    # compile the model
    model.compile (....)

    # --------------Begin Training with data augmentation --------------
    def train_generator (...)


    # Training with data augmentation. 
    history = model.fit_generator (...)

    return model

K-Fold Cross Validation

Теперь для обучения модели и подгонки к ней данных я использовал метод перекрестной проверки K-Fold. Скажем, это K-Fold = 5. Как и в следующем коде, мы сохраняем 5-кратную модель и сохраняем вес.

cvscores = []

for train, val in kfold.split(X_train_all, y_train_all):

    print ('Fold: ', Fold)

    # define model
    model, eval_model = CapsNet ( ... )


    X_train = X_train_all[train]
    X_val = X_train_all[val]

    y_train = y_train_all[train]
    y_val = y_train_all[val]


#   train -
    train_caps( ... ) # calling actual training 


#     # Save each fold model
    model_name = 'Fold_'+ str(Fold) + '.h5'
    model.save(model_name)

    # evaluate the model
    scores = model.evaluate(X_val, y_val, verbose = 0)
    print("%s: %.2f%%" % (model.metrics_names[7], scores[3]*100))
    cvscores.append(scores[3] * 100) 

    Fold = Fold + 1

Проблема столкнулась 1

Проблема возникла в разделе оценки. scores = model.evaluate(X_val, y_val, verbose = 0) и он показал:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-36-12f206477b39> in <module>()
----> 1 scores = model.evaluate(X_val, Y_val, verbose = 0)
      2 print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))

ValueError: Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 arrays: [array([[[[218.],
         [1.],
         [0.],
         ...,
         [1.],
         [1.],

Есть ли другой способ оценить производительность модели и измерить баллы?

Проблема столкнулась 2

При таком подходе как найти лучшую модель? Я думаю, мы можем загрузить верхнюю (предположим) модель 2-кратного сгиба и получить среднее значение оценки или что-то вроде метода ансамбля над ними. Ниже я кое-что попробовал.

def ensemble(models, model_input):

    Models_output = [model(model_input) for model in models]
    Avg = keras.layers.average(Models_output)

    model_Ensemble = Model(inputs = model_input, outputs = Avg, name = 'ens')
    model_Ensemble.compile( ... )

    return modelEnsemble

И загрузите взвешенное сохранение, чтобы мы получили метод перекрестной проверки K-Fold.

import keras

model_1, eval_model_1 = CapsNet(input_shape=[32, 32, 1],
                n_class=10,
                routings=3)

model_2, eval_model_2 = CapsNet()

models = []

# Load weights 
model_1.load_weights('Fold_1.h5')
model_1.name = 'model_1'
models.append(model_1)

model_2.load_weights('Fold_2.h5')
model_2.name = 'model_2'
models.append(model_2)

model_input = Input(shape=models[0].input_shape[1:])
ensemble_model = ensemble(models, model_input)

Это выдает ошибку следующего. Я знаю, я что-то здесь упускаю, но не могу понять, как справиться с этим.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-37-8cec3f452a69> in <module>()
      4 model_1, eval_model_1 = CapsNet(input_shape=[32, 32, 1],
      5                 n_class=10,
----> 6                 routings=3)
      7 
      8 model_2, eval_model_2 = CapsNet(input_shape=[32, 32, 1],

<ipython-input-31-d96b4a5e15ad> in CapsNet(input_shape, n_class, routings)
     44 
     45     # Shared Decoder model in training and prediction
---> 46     decoder = models.Sequential(name='decoder')
     47     decoder.add(layers.Dense(512, activation='relu', input_dim=16*n_class))
     48     decoder.add(layers.Dense(1024, activation='relu'))

AttributeError: 'list' object has no attribute 'Sequential'

Если я кратко изложу свой вопрос или проблему, с которой я столкнулся, то я не могу оценить производительность модели с помощью model.evaluate(...,...). И далее получение этой ошибки Атрибуции.

Любая помощь или предложение высоко ценится. Благодарю.

Теги:
tensorflow
machine-learning
keras
deep-learning

2 ответа

1
Лучший ответ

Проблема первая

Обратите внимание на параметр, train_model принимает ваш train_model. Ваша модель поезда имеет 2 входа и 2 выхода. Мы используем model.fit(X,Y) для обучения модели " один в один" и model.fit([X1,X2], [Y1,Y2]) для обучения модели "два в два". Модель Capsnet два в два, поэтому inputs=[X1,X2]=[x_train, y_train] и выходы (также цели) = [Y1,Y2]=[y_train,x_train]. Подробнее об этом.

Теперь, согласно вашей реализации, вы можете оценить производительность вашей модели следующим образом:

scores = model.evaluate([X_val, Y_val], [Y_val, X_val], 
    verbose=0, batch_size=64) 

Проблема вторая

Я думаю, что произошел конфликт имен. Название модели - ваша функция CapsNet и метод ensemble, я думаю, один и тот же.

decoder = models.Sequential(name='decoder')

Название models совпадает с CapsNet совпадает со списком моделей, которые вы определили в ensemble функции. Просто поменяйте имя на любое.

1

В следующей строке входными данными для train_model является список из двух массивов.

train_model = models.Model([x, y], [out_caps, decoder(masked_by_y)])

Но когда вы вызываете model.evaluate в разделе перекрестной проверки K-Fold, вы передаете в качестве входных данных один массив numpy (X_val).

scores = model.evaluate(X_val, y_val, verbose = 0)

Мне также интересно в этом случае, если вы хотите использовать модель обучения или модель проверки. Исходя из того, как вы вызывали метод и из намерения оценить модель, можно сделать вывод, что вы можете вызвать метод оценки eval_model.

scores = eval_model.evaluate(X_val, y_val, verbose = 0)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню