Keras dropping dimension in LSTM, not sure why - tensorflow

Following up to Keras LSTM Input 0 of layer sequential_10 is incompatible with the layer
I now have the following code:
def myLSTM(i_shape, o_shape):
input = keras.layers.Input(i_shape)
print(input)
model = Sequential()
x = keras.layers.LSTM(128, return_sequences = True, input_shape = [1, x_train.shape[0], x_train.shape[1]])(input)
x = keras.layers.Dropout(0.2)(x)
x = keras.layers.LSTM(128, return_sequences = True)(x)
x = keras.layers.Dropout(0.2)(x)
x = keras.layers.LSTM(64, return_sequences = True)(x)
x = keras.layers.Dropout(0.2)(x)
output = keras.layers.Dense(units = 1, activation='softmax')(x)
print('input: ', input)
print('outpput: ', output)
return keras.Model(input, output)
print(x_train.shape)
my_lstm = myLSTM(x_train.shape, y_train.shape)
my_lstm.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
my_lstm.summary()
But I get the following error:
ValueError: Input 0 is incompatible with layer model_22: expected shape=(None, 25000, 100), found shape=(None, 100)
I'm not sure why it dropped the 25000 from the dimensions. I have printed out the input variable in the first line and it is of dimension (None, 25000, 100)

Related

Input layer 0 of sequence is incompatible with the layer - CNNs

I am trying to create a CNN model using hyperparameterization for image classification. When I run the code I receive the following error:
ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 32, 32, 32, 3), found shape=(32, 32, 32, 3)
How to fix the error? Here is the whole code pasted below:
# first we create our actual code which requires the arguments, units, activation, dropout, lr:
def build_model(hp):
model = ks.Sequential([
# adding first conv2d layer
ks.layers.Conv2D(
#Let's tune the filters, kernel_size, activation function.
filters = hp.Int("conv_1_filter", min_value=1,max_value=100, step = 16),
kernel_size = hp.Choice("conv_1_kernel", values = [3,5]),
activation = hp.Choice("conv_1_activation", ["relu", "tanh", "softmax"]),
input_shape = (32,32,32,3)
),
# adding second conv2d layer
ks.layers.Conv2D(
#Let's tune the filters, kernel_size, activation function.
filters = hp.Int("conv_2_filter", min_value=1,max_value=50, step = 16),
kernel_size = hp.Choice("conv_2_kernel", values = [3,5]),
activation = hp.Choice("conv_2_activation", ["relu", "tanh", "softmax"]),
input_shape = (32,32,32,3)
)])
model.add(layers.Flatten())
# Let's tune the number of Dense layers.
for i in range(hp.Int("num_dense_layers", 1, 3)):
model.add(
layers.Dense(
# Let's tune the number of units separately
units = hp.Int(f"units_{i}", min_value=1, max_value = 100, step = 16),
activation = hp.Choice("activation", ["relu", "tanh", "softmax"])
))
if hp.Boolean("dropout"):
model.add(layers.Dropout(rate = 0.25))
model.add(layers.Dense(10, activation = "softmax"))
learning_rate = hp.Float("lr", min_value = 1e-4, max_value = 1e-2, sampling="log")
model.compile(
optimizer = ks.optimizers.Adam(learning_rate = learning_rate),
loss = "categorical_crossentropy",
metrics = ["accuracy"]
)
return model
build_model(keras_tuner.HyperParameters())
You are getting this error due the input shape mismatch.
Here i have implemented the hypermodel on the mnist fashion dataset which contains images of shape (28,282,1).
def build_model(hp):
model = tf.keras.Sequential([
tf.keras.Input(shape=(28,28,1)),
# adding first conv2d layer
tf.keras.layers.Conv2D(
#Let's tune the filters, kernel_size, activation function.
filters = hp.Int("conv_1_filter", min_value=1,max_value=100, step = 16),
kernel_size = hp.Choice("conv_1_kernel", values = [3,5]),
activation = hp.Choice("conv_1_activation", ["relu", "tanh", "softmax"]),
input_shape = (28,28,1)
),
tf.keras.layers.MaxPooling2D(
pool_size=hp.Choice('pooling_1',values=[2,3])),
# adding second conv2d layer
tf.keras.layers.Conv2D(
#Let's tune the filters, kernel_size, activation function.
filters = hp.Int("conv_2_filter", min_value=1,max_value=50, step = 16),
kernel_size = hp.Choice("conv_2_kernel", values = [3,5]),
activation = hp.Choice("conv_2_activation", ["relu", "tanh", "softmax"]),
input_shape = (28,28,1)
)])
tf.keras.layers.MaxPooling2D(
pool_size=hp.Choice('pooling_2',values=[2,3])),
model.add(tf.keras.layers.Flatten())
if hp.Boolean("dropout"):
model.add(tf.keras.layers.Dropout(rate = 0.25))
model.add(tf.keras.layers.Dense(10, activation = "softmax"))
learning_rate = hp.Float("lr", min_value = 1e-4, max_value = 1e-2, sampling="log")
model.compile(
optimizer = tf.keras.optimizers.Adam(learning_rate = learning_rate),
loss = "categorical_crossentropy",
metrics = ["accuracy"]
)
return model
By providing the correct shape you will not get any error.
For more details, Please refer to this gist and this documentation. Thank You!

ValueError: Input 0 of layer conv1_pad is incompatible with the layer: expected ndim=4, found ndim=2. Full shape received: (None, 1)

I'm getting this error when I try to replicate Facial Recognition using MobileNet on the VGGFace2 dataset.
ValueError: Input 0 of layer conv1_pad is incompatible with the layer: expected ndim=4, found ndim=2. Full shape received: (None, 1)
The below code is snippet of data generator where X is an dict with np array of images
# Generate data
X = {
"anchor_input":np.array(anchor_images),
"positive_input":np.array(positive_images),
"negative_input":np.array(negative_images),
}
Y = np.zeros((self.batch_size,2))
return (X, Y)
Output for X["anchor_input"].shape is (20, 224, 224, 3) where 20 is the batch size.
inpShape=(224,224,3)
model = tf.keras.applications.MobileNetV2(
input_shape=inpShape,
alpha=1.0,
include_top=False,
weights="imagenet",
input_tensor=None,
pooling=None,
classes=1000,
classifier_activation="softmax"
)
outputLayer = model.get_layer('block_14_add').output
x = tf.keras.layers.Conv2D(80,(3,1),padding="same",name="extra_conv0")(outputLayer)
x = tf.keras.layers.Conv2D(64,(3,3),padding="same",name = "extra_conv1")(x)
x = tf.keras.layers.AveragePooling2D()(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(64)(x)
baseNetwork = tf.keras.Model(inputs=model.input,outputs=x,name="basemodel")
input1 = tf.keras.layers.Input(shape=inpShape,name='anchor_input')
input2 = tf.keras.layers.Input(shape=inpShape,name='positive_input')
input3 = tf.keras.layers.Input(shape=inpShape,name='negative_input')
anchor_out = baseNetwork(input1)
positive_out = baseNetwork(input2)
negative_out = baseNetwork(input3)
output = DistanceLayer()(anchor_out,positive_out,negative_out)
inputs = (input1,input2,input3)
contrastive_model = tf.keras.Model(inputs=inputs,outputs=output)
contrastive_model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss=contrastive_loss_mutated,
metrics=[contrastive_loss_mutated,contrastive_accuracy])
history1 = contrastive_model.fit(
trainGenerator,
epochs = 25,
validation_data=testGenerator,
callbacks=my_callbacks)
Please help me out with this.

Issue retrieving value decode_predictions` expects a batch of predictions

I have a pretrained model trying to remove a layer and perform prediction on the new model. However retrieving error.
model = applications.VGG16(include_top=False, input_shape=(224, 224, 3), weights='imagenet')
layers = [l for l in model.layers]
x = layers[9].output
x = layers[11](x)
x = layers[12](x)
x = layers[13](x)
x = layers[14](x)
x = layers[15](x)
x = layers[16](x)
x = layers[17](x)
x = layers[18](x)
result_model = Model(inputs=layers[0].input, outputs=x)
img='/content/elephant.jpg'
img = image.load_img(img, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = result_model.predict(x)
print('Predicted:', decode_predictions(preds, top=3)[0])
Error
ValueError: `decode_predictions` expects a batch of predictions (i.e. a 2D array of shape (samples, 1000)). Found array with shape: (1, 14, 14, 512)
Your neural network doesn't have an output layer. decode_predictions can't decode the output of a convolutional layer, which is what you get when you do include_top=False. Do this:
model = applications.VGG16(include_top=True, input_shape=(224, 224, 3),
weights='imagenet')

keras gives error when using two loss function for two outputs

I have a network. the one before last layer is a dense layer. I want the last layer to return both the max value from the layer before, and the index of that max value.
so if the output of the dense layer is [0,4,5,120,1], the last layer should return [120, 3].
the loss I need the network to work with is calculated only based on the max value, not the index. therefore, I wrote a loss function for the second output, the index, that always returns zero - but if there is a better solution I would like to hear it, in addition to how to fix this error.
the code is:
def ignor_loss(preds, trues):
return 0
# build deep q network
inputs = Input((240,256,3))
pool0 = MaxPooling2D()(inputs)
conv1 = Conv2D(30,3,activation='relu')(pool0)
pool1 = MaxPooling2D()(conv1)
conv2 = Conv2D(40,3,activation='relu')(pool1)
pool2 = MaxPooling2D()(conv2)
conv3 = Conv2D(50,3,activation='relu')(pool2)
pool3 = MaxPooling2D()(conv3)
conv4 = Conv2D(60,3,activation='relu')(pool3)
pool4 = MaxPooling2D()(conv4)
conv5 = Conv2D(80,3,activation='relu')(pool4)
flat = Flatten()(conv5)
dense1 = Dense(70)(flat)
dense2 = Dense(40)(dense1)
values = Dense(env.action_space.n)(dense2)
max_, ind = Lambda(lambda x : [K.max(x),K.argmax(x)])(values)
m = Model(inputs, [max_, ind])
m.compile('adam', ['mse',ignor_loss])
and the error is:
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
any ideas?
EDIT:
here is my updated code:
# build deep q network
inputs = Input((240,256,3))
pool0 = MaxPooling2D()(inputs)
conv1 = Conv2D(30,3,activation='relu')(pool0)
pool1 = MaxPooling2D()(conv1)
conv2 = Conv2D(40,3,activation='relu')(pool1)
pool2 = MaxPooling2D()(conv2)
conv3 = Conv2D(50,3,activation='relu')(pool2)
pool3 = MaxPooling2D()(conv3)
conv4 = Conv2D(60,3,activation='relu')(pool3)
pool4 = MaxPooling2D()(conv4)
conv5 = Conv2D(80,3,activation='relu')(pool4)
flat = Flatten()(conv5)
dense1 = Dense(70)(flat)
dense2 = Dense(40)(dense1)
q_values = Dense(env.action_space.n)(dense2)
max_q = Lambda(lambda x : K.max(x), name='max')(q_values)
ind = Lambda(lambda x : K.argmax(x), name='ind')(q_values)
m = Model(inputs, [max_q,ind])
m.compile('adam', {'max':'mse','ind':'mse'}, loss_weights=[1., 0.0])
I still get the same error:
unsupported operand type(s) for -: 'int' and 'NoneType'
I need to know why this error heppens? any ideas?
EDIT 2:
now I added the keepdims=True to the max function and K.expand_dims to the argmax func, like this:
q_values = Dense(env.action_space.n)(dense2)
max_q = Lambda(lambda x : K.max(x, keepdims=True), name='max')(q_values)
ind = Lambda(lambda x : K.expand_dims(K.argmax(x)), name='ind')(q_values)
m = Model(inputs, [max_q,ind])
m.compile('adam', {'max':'mse','ind':'mse'}, loss_weights=[1., 0.0])
but I get a different error:
TypeError: Expected int64, got 0.0 of type 'float' instead.
I think that this is a cleaner solution
1 step: fit the model on the max
X = np.random.uniform(0,1, (2,240,256,3))
y = np.random.uniform(0,1, 2)
inputs = Input((240,256,3))
pool0 = MaxPooling2D()(inputs)
conv1 = Conv2D(30,3,activation='relu')(pool0)
pool1 = MaxPooling2D()(conv1)
conv2 = Conv2D(40,3,activation='relu')(pool1)
pool2 = MaxPooling2D()(conv2)
conv3 = Conv2D(50,3,activation='relu')(pool2)
pool3 = MaxPooling2D()(conv3)
conv4 = Conv2D(60,3,activation='relu')(pool3)
pool4 = MaxPooling2D()(conv4)
conv5 = Conv2D(80,3,activation='relu')(pool4)
flat = Flatten()(conv5)
dense1 = Dense(70)(flat)
dense2 = Dense(40)(dense1)
values = Dense(10)(dense2) # in my case env.action_space.n is 10
max_ = Lambda(lambda x: tf.reduce_max(x, axis=1, keepdims=True))(values)
m = Model(inputs, max_)
m.compile('adam', 'mse')
m.fit(X,y, epochs=3)
2 step: make inference with the fitted model returning max and argmax (this simply require to build a new model)
ind = Lambda(lambda x: tf.expand_dims(tf.argmax(x, axis=1),-1))(values)
final_model = Model(inputs, [max_, ind])
final_model.predict(X) this return max and argmax
EDIT: here a compact model which operate all the operation. if u have two outputs u need to pass to keras two targets. for this reason, the second target is generated by me as an array of 0 (it has no impact)
def ignor_loss(trues, preds):
return 0.
X = np.random.uniform(0,1, (2,240,256,3))
y = np.random.uniform(0,1, 2)
inputs = Input((240,256,3))
pool0 = MaxPooling2D()(inputs)
conv1 = Conv2D(30,3,activation='relu')(pool0)
pool1 = MaxPooling2D()(conv1)
conv2 = Conv2D(40,3,activation='relu')(pool1)
pool2 = MaxPooling2D()(conv2)
conv3 = Conv2D(50,3,activation='relu')(pool2)
pool3 = MaxPooling2D()(conv3)
conv4 = Conv2D(60,3,activation='relu')(pool3)
pool4 = MaxPooling2D()(conv4)
conv5 = Conv2D(80,3,activation='relu')(pool4)
flat = Flatten()(conv5)
dense1 = Dense(70)(flat)
dense2 = Dense(40)(dense1)
values = Dense(10)(dense2) # in my case env.action_space.n is 10
max_ = Lambda(lambda x: tf.reduce_max(x, axis=1, keepdims=True), name='max')(values)
ind = Lambda(lambda x: tf.expand_dims(tf.argmax(x, axis=1),-1), name='ind')(values)
m = Model(inputs, [max_,ind])
m.compile('adam', loss={'max':'mse', 'ind':ignor_loss},
loss_weights={'max':1., 'ind':0.})
m.fit(X, {'max':y, 'ind':np.zeros_like(y)}, epochs=3)
m.predict(X)

When trying to feed in variable sequences to keras LSTMs ValueError: Error when checking input?

My model:
model = Sequential()
model.add( LSTM(25, batch_input_shape = (None, None, 19), return_sequences = True ) )
model.add(Dense(4, activation = 'tanh'))
model.compile(loss='mean_squared_error', optimizer ='adam', metrics = ['accuracy'])
some example of input data shape:
input_list[0].shape = (7,19)
input_list[1].shape = (8,19)
input_list[2].shape = (17,19)
some example of output data shape:
output_list[0].shape = (7,4)
output_list[1].shape = (8,4)
output_list[2].shape = (17,4)
input_list.shape = (233,)
output_list.shape = (233,)
error while:
d_loss = model.fit(input_list,output_list,validation_split=0.33,nb_epoch=100,verbose=1,shuffle=True, batch_size = 1)
error: ValueError: Error when checking input: expected lstm_22_input to have 3 dimensions, but got array with shape (233, 1)
Just increase the dimensions, by np.expand_dims(x, axis= 0). It will become three dimensional.