Search code examples
pythontensorflowkerasnlplayer

Error in shape (dimention) and type of Keras model input


I am desperate to set the Input shape of this simple Keras model :( Both X and Y are numpy.narray but I don't know what's the wrong with it! I tried different X shape but the error is there! The info of the datasets (dimentions, number of samples, etc.) is available in the code. The .pkl file for X_train is got from hidden state of a pre-trained model.

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from keras.utils import np_utils
from keras import Input, Model
from keras.layers import Dense
import numpy as np

############################## X_Train ############################

X_Train_3embed1 = pd.read_pickle("XX_Train_3embeding.pkl")


X_Train_3embed = np.array(X_Train_3embed1)

print("X-Train")
print(X_Train_3embed.shape)   # (230, 1, 128)
print(type(X_Train_3embed))  # <class 'numpy.ndarray'>
print(X_Train_3embed[0].shape) # (1, 128)
print(type(X_Train_3embed[0])) # <class 'numpy.ndarray'>


############################## Y_Train ############################

Y_Train_labels_list = pd.read_pickle("lis_Y_all_Train.pkl")

print(type(Y_Train_labels_list))  #<class 'numpy.ndarray'>
print(type(Y_Train_labels_list[0])) #<class 'str'>

encoder = LabelEncoder()
encoder.fit(Y_Train_labels_list)
encoded_Y = encoder.transform(Y_Train_labels_list)
Y_my_Train = np_utils.to_categorical(encoded_Y)


print("Y-Train")
print(Y_my_Train.shape) #(230, 83)
print(type(Y_my_Train)) # <class 'numpy.ndarray'>
print(Y_my_Train[0].shape) # (83,)
print(type(Y_my_Train[0])) # <class 'numpy.ndarray'>

##################################  Model  ##################################

first_input = Input(shape=(1, 128))

first_dense = Dense(128)(first_input)

output_layer = Dense(83, activation='softmax')(first_dense)

model = Model(inputs=first_input, outputs=output_layer)

model.summary()


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


history = model.fit((X_Train_3embed, Y_my_Train), epochs=2, batch_size=32)

Here is the result:

Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 1, 128)            0         
_________________________________________________________________
dense_1 (Dense)              (None, 1, 128)            16512     
_________________________________________________________________
dense_2 (Dense)              (None, 1, 83)             10707     
=================================================================
Total params: 27,219
Trainable params: 27,219
Non-trainable params: 0
_________________________________________________________________
Traceback (most recent call last):
  File "/home/vahideh/PycharmProjects/3KArgen-master/MyTransferClassifier2.py", line 63, in <module>
    history = model.fit((X_Train_3embed, Y_my_Train), epochs=2, batch_size=32)
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training.py", line 1154, in fit
    batch_size=batch_size)
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training.py", line 579, in _standardize_user_data
    exception_prefix='input')
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training_utils.py", line 99, in standardize_input_data
    data = [standardize_single_array(x) for x in data]
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training_utils.py", line 99, in <listcomp>
    data = [standardize_single_array(x) for x in data]
  File "/home/vahideh/PycharmProjects/MyVirtualEnvs/MyKargo/lib/python3.6/site-packages/keras/engine/training_utils.py", line 34, in standardize_single_array
    elif x.ndim == 1:
AttributeError: 'tuple' object has no attribute 'ndim'

How can I feed these dataset to the model? or change the input shape of the model?


Solution

  • Your models output is of shape (None, 1, 83) i.e each samples ouptput is 1 x 83 but your ground truth for each sample is a scalar. There are two way to deal with this problem

    1. Flatten the outputs and continue using your data
    2. Remove the unnecessary dimension in your data i.e flatten each sample from 1X128 to just 128 and change the model architecture to deal with 1D data which will result in output being 1D.

    Fixed code:

    Approach 1

    from keras import Input, Model
    from keras.layers import Dense, Flatten
    import numpy as np
    
    # Dummy data
    X_Train_3embed = np.random.randn(230, 1, 128)
    Y_my_Train = np.random.randn(230, 83)
    
    #model
    first_input = Input(shape=(1, 128))
    first_dense = Dense(128)(first_input)
    output_layer = Dense(83, activation='softmax')(first_dense)
    outputs = Flatten()(output_layer)
    
    model = Model(inputs=first_input, outputs=outputs)
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
    model.summary()
    model.fit(X_Train_3embed, Y_my_Train, epochs=2, batch_size=32)
    

    Output:

    Layer (type)                 Output Shape              Param #   
    =================================================================
    input_10 (InputLayer)        [(None, 1, 128)]          0         
    _________________________________________________________________
    dense_18 (Dense)             (None, 1, 128)            16512     
    _________________________________________________________________
    dense_19 (Dense)             (None, 1, 83)             10707     
    _________________________________________________________________
    flatten_6 (Flatten)          (None, 83)                0         
    =================================================================
    Total params: 27,219
    Trainable params: 27,219
    Non-trainable params: 0
    _________________________________________________________________
    Epoch 1/2
    8/8 [==============================] - 1s 3ms/step - loss: 6.2275 - acc: 0.0162
    Epoch 2/2
    8/8 [==============================] - 0s 2ms/step - loss: 0.2639 - acc: 0.0150
    

    Approach 2

    # Dummy data
    X_Train_3embed = np.random.randn(230, 1, 128)
    Y_my_Train = np.random.randn(230, 83)
    
    #model
    first_input = Input(shape=(128))
    first_dense = Dense(128)(first_input)
    outputs = Dense(83, activation='softmax')(first_dense)
    
    model = Model(inputs=first_input, outputs=outputs)
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
    model.summary()
    model.fit(X_Train_3embed.reshape(-1,128), Y_my_Train, epochs=2, batch_size=32)
    

    Output:

    Layer (type)                 Output Shape              Param #   
    =================================================================
    input_13 (InputLayer)        [(None, 128)]             0         
    _________________________________________________________________
    dense_24 (Dense)             (None, 128)               16512     
    _________________________________________________________________
    dense_25 (Dense)             (None, 83)                10707     
    =================================================================
    Total params: 27,219
    Trainable params: 27,219
    Non-trainable params: 0
    _________________________________________________________________
    Epoch 1/2
    8/8 [==============================] - 0s 2ms/step - loss: -1.1705 - acc: 0.0100
    Epoch 2/2
    8/8 [==============================] - 0s 2ms/step - loss: -6.3587 - acc: 0.0015