Search code examples
kerasconv-neural-networkkeras-layer

Keras: Functional API -- Layer Datatype Error


I am trying to separate each of the outputs of a keras Conv2D layer using a for loop, and then adding another layer to it through the Functional API, but I am getting a type error. The code is:

import keras
from keras.models import Sequential, Model
from keras.layers import Flatten, Dense, Dropout, Input, Activation
from keras.layers.convolutional import Conv2D, MaxPooling2D, ZeroPadding2D
from keras.layers.merge import Add
from keras.optimizers import SGD
import cv2, numpy as np
import glob
import csv

def conv_layer:
    input = Input(shape=(3,224,224))
    k = 64
    x = np.empty(k, dtype=object)
    y = np.empty(k, dtype=object)
    z = np.empty(k, dtype=object)
    for i in range(0,k):
        x[i] = Conv2D(1, (3,3), data_format='channels_first', padding='same')(input)
        y[i] = Conv2D(1, (3,3), data_format='channels_first', padding='same')(x[i])
        z[i] = keras.layers.add([x[i], y[i]])
    out = Activation('relu')(z)
    model = Model(inputs, out, name='split-layer-model')

    return model

But, it is throwing the following error:

Traceback (most recent call last):
  File "vgg16-local-connections.py", line 352, in <module>
    model = VGG_16_local_connections()
  File "vgg16-local-connections.py", line 40, in VGG_16_local_connections
    out = Activation('relu')(z)
  File "/Users/klab/anaconda2/lib/python2.7/site-packages/keras/engine/topology.py", line 519, in __call__
    input_shapes.append(K.int_shape(x_elem))
  File "/Users/klab/anaconda2/lib/python2.7/site-packages/keras/backend/tensorflow_backend.py", line 409, in int_shape
    shape = x.get_shape()
AttributeError: 'numpy.ndarray' object has no attribute 'get_shape'

So, the datatype of z does not match the one of the Functional API. How can I fix this? Any help will be deeply appreciated!


Solution

  • Since I had defined z[i]-s as separate layers, I thought z would effectively be a stack of those z[i]-s. But, they basically had to be concatenated to make the stack I wanted,

    z = keras.layers.concatenate([z[i] for i in range (0,k)], axis=1)
    out = Activation('relu')(z)
    

    Since I was using data_format='channels_first', the concatenation was done with axis=1, but for the more common, data_format='channels_last', the concatenation has to be done with axis=3.