AttributeError:合并模型时'顺序'没有属性'get_shape'

时间:2017-05-04 14:31:48

标签: python multiple-columns keras conv-neural-network multiclass-classification

我正在尝试创建两个顺序模型(每个模型都在不同的数据集上训练 - 不同的图像)。然后我想取其输出的平均值,并添加一个softmax图层,根据两个连续模型给出一个单独的分类输出。我的代码如下,但是我得到一个属性错误,说“顺序”对象没有属性“get_shape”。

完整的错误代码是:

Traceback (most recent call last):
  File "Mergedmodels.pyu", line 135, in <module>
   merged = average ([modelo, modelN1])
  File "G:\Anaconda\lib\site-packages\keras\layers\merge.py", line 481, in average
   return Average(**kwargs)(inputs)
  File "G:\Anaconda\lib\site-packages\keras\engine\topology.py", line 542, in _ call_input_shapes.append(K.int_sshape(x_elem))
  File "G:\Anaconda\lib\site-packages\keras\backend\tensorflow_backend.py", line 411, in int_shape
    shape = x.get_shape()
  AttributeError: 'Sequential' object has no attribute 'get_shape'

有关如何修复它的想法吗?

 import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import merge
from keras.layers import average
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras.preprocessing.image import ImageDataGenerator
from keras.datasets import mnist
import pandas as pd
from numpy import array
from PIL import Image
import matplotlib.pyplot as plt
from keras import backend as K
import glob
import os

K.set_image_dim_ordering('th')


np.random.seed(123) #set for reproducibility

size = 48, 48

#IMPORTING TRAINING IMAGES FOR FIRST MODEL (ORIGINAL)
folder = 'images'

read = lambda imname: np.asarray(Image.open(imname).convert("RGB"))

ims = [read(os.path.join(folder, filename)) for filename in os.listdir(folder)]
X_train = np.array([read(os.path.join(folder, filename)) for filename in os.listdir(folder)], dtype='uint8')
#CHECK print (X_train.shape)

X_train = X_train.reshape(X_train.shape[0],3,48,48)
#X_test = X_test.reshape(X_test.shape[0],1,28,28)
X_train = X_train.astype ('float32')
#X_test = X_test.astype ('float32')
X_train /= 255
#X_test /= 255

#IMPORTING TRAINING IMAGES FOR SECOND MODEL (NORMALIZED)
folder = 'images2'

read = lambda imname: np.asarray(Image.open(imname).convert("RGB"))

ims = [read(os.path.join(folder, filename)) for filename in os.listdir(folder)]
X_training = np.array([read(os.path.join(folder, filename)) for filename in os.listdir(folder)], dtype='uint8')
#CHECK print (X_train.shape)

X_training = X_training.reshape(X_train.shape[0],3,48,48)
#X_test = X_test.reshape(X_test.shape[0],1,28,28)
X_training = X_training.astype ('float32')
#X_test = X_test.astype ('float32')
X_training /= 255
#X_test /= 255


#IMPORTING LABELS FOR 10K TRAINING IMAGES 
saved_column = pd.read_csv('labels4.csv')

y_labels = array(saved_column)

Y_train = np_utils.to_categorical(y_labels,501)

#y_train = np.array ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1])
#(X_train, y_train),(X_test, y_test) = mnist.load_data()

#COPYING LABELS FOR SECOND MODEL TRAINING IMAGES
#Y_training = Y_train

#IMPORTING TEST IMAGES
folder2 = 'test'
read = lambda imname: np.asarray(Image.open(imname).convert("RGB"))
ims = [read(os.path.join(folder2, filename)) for filename in os.listdir(folder2)]
X_test = np.array([read(os.path.join(folder2, filename)) for filename in os.listdir(folder2)], dtype='uint8')

X_test = X_test.reshape(X_test.shape[0],3,48,48)
X_test = X_test.astype ('float32')
X_test /= 255

#IMPORTING LABELS FOR TEST IMAGES
another_column = pd.read_csv('labelstest4.csv')
test_labels = array(another_column)
Y_test = np_utils.to_categorical(test_labels,501)
#train_labels = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1])
#Y_train = np_utils.to_categorical(y_train, 2)
#Y_test = np_utils.to_categorical(y_test,10)


#BUILDING FIRST NN FOR ORIGINAL IMAGES
modelo = Sequential()

modelo.add(Convolution2D(32,3,3, activation='relu', input_shape=(3,48,48), dim_ordering='th'))
modelo.add(Convolution2D(32,3,3, activation = 'relu'))
modelo.add(MaxPooling2D(pool_size=(2,2)))
modelo.add(Dropout(0.25))

modelo.add(Flatten())
modelo.add(Dense(128,activation='relu'))
modelo.add(Dropout(0.5))
modelo.add(Dense(501, activation = 'sigmoid'))

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

modelo.fit(X_train, Y_train, 
    batch_size = 5, nb_epoch= 5, verbose = 1)

score = modelo.evaluate(X_test, Y_test, verbose=0)

#BUILDING SECOND NN FOR NORMALIZED IMAGES
modelN1 = Sequential()

modelN1.add(Convolution2D(32,3,3, activation='relu', input_shape=(3,48,48), dim_ordering='th'))
modelN1.add(Convolution2D(32,3,3, activation = 'relu'))
modelN1.add(MaxPooling2D(pool_size=(2,2)))
modelN1.add(Dropout(0.25))

modelN1.add(Flatten())
modelN1.add(Dense(128,activation='relu'))
modelN1.add(Dropout(0.5))
modelN1.add(Dense(501, activation = 'sigmoid'))

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

modelN1.fit(X_training, Y_train, 
    batch_size = 5, nb_epoch= 1, verbose = 1)

score = modelN1.evaluate(X_test, Y_test, verbose=0)

#MERGING MODELS
merged = average([modelo, modelN1])

finalmodel = Sequential ()
finalmodel.add(merged)
finalmodel.add(Dense(501, activation = 'softmax'))

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

Y_madeuplabels = np.array ([0, 1, 52, 20])  
Y_training = np_utils.to_categorical(Y_madeuplabels, 501)


finalmodel.fit([X_train], Y_training, 
    batch_size = 5, nb_epoch= 1, verbose = 1)

score = finalmodel.evaluate(X_test, Y_test, verbose=0)

print ("the code ran")

1 个答案:

答案 0 :(得分:4)

这种组合顺序模型的方式在Keras 2.0中似乎不起作用 因为average适用于张量而非图层。这就是错误消息的原因,即说顺序模型没有get_shape()方法; get_shape()仅存在于宣传书中。

以下是复制错误的示例:

mod1 = Sequential()
mod1.add(Dense(1, input_shape=(10,)))

mod2 = Sequential()
mod2.add(Dense(1, input_shape=(10,)))

avg = average([mod1, mod2]) # throws AttributeError 

解决这个问题的一种愚蠢方法是使用functional API进行组合 两个模型的输出然后做softmax层。举个例子:

X1 = np.random.rand(10, 10)
X2 = np.random.rand(10, 10)
Y  = np.random.choice(2, 10) 

mod1 = Sequential()
mod1.add(Dense(16, input_shape=(10,)))

mod2 = Sequential()
mod2.add(Dense(16, input_shape=(10,)))

# so use the outputs of the models to do the average over 
# this way we do averaging over tensor __not__ models.
avg = average([mod1.output, mod2.output])
dense = Dense(1, activation="sigmoid")(avg)

# the two inputs are the inputs to the sequential models
# and the output is the dense layer
mod3 = Model(inputs=[mod1.input, mod2.input], outputs=[dense])
mod3.compile(loss='binary_crossentropy',  optimizer='sgd')
mod3.fit([X1, X2], Y)