I am building an image classification model using Keras, SGD, and Softmax activation. The training dataset consists of RGB images with dimensions of 512x384.
To do so, I have followed Keras "Getting Started" guide. However, when I tried to train the model, I got the error mentioned in the title. This is my code so far:
import numpy as np
import tensorflow as tf
from tensorflow import keras
FOLDER_PATH = 'dataset'
dataset = keras.utils.image_dataset_from_directory(
FOLDER_PATH,
batch_size=64,
image_size=(512, 384)
)
# None x None x 3 -> Arbitrarily sized images with 3 channels
inputs = keras.Input(shape=(None, None, 3))
x = CenterCrop(height=150, width=150)(inputs)
x = Rescaling(scale= 1.0 / 255)(x)
outputs = layers.Dense(6, activation="softmax")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
optimizer=keras.optimizers.SGD(learning_rate=0.01),
loss=keras.losses.CategoricalCrossentropy()
)
model.fit(dataset, epochs=3)
This is the model's summary:
Model: "model_6"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_8 (InputLayer) [(None, None, None, 3)] 0
center_crop_7 (CenterCrop) (None, 150, 150, 3) 0
rescaling_7 (Rescaling) (None, 150, 150, 3) 0
dense_7 (Dense) (None, 150, 150, 6) 24
=================================================================
Total params: 24
Trainable params: 24
Non-trainable params: 0
_________________________________________________________________
I have also checked the shape of my data:
for data, labels in dataset:
print(data.shape) # (64, 512, 384, 3)
print(data.dtype) # <dtype: 'float32'>
print(labels.shape) # (64,)
print(labels.dtype) # <dtype: 'int32'>
So, how can I fix this? I wonder if I have made some mistake in the data preprocessing pipeline, or if the data I am using is somehow incompatible with the SGD optimizer.
You need to change couple things.
first of all, softmax require you to use one-hot encoded labels. You can use the following lines to convert your data:
dataset = keras.utils.image_dataset_from_directory(
FOLDER_PATH,
batch_size=64,
image_size=(512, 384)
)
num_classes = len(dataset.class_names)
dataset = dataset.map(lambda x, y: (x, tf.one_hot(y, num_classes)))
after this step you also need to flatten your input before you feed it to your model. which is done by:
x = CenterCrop(height=150, width=150)(inputs)
x = Rescaling(scale= 1.0 / 255)(x)
x = layers.Flatten()(x) # add this line here to flatten
outputs = layers.Dense(6, activation="softmax")(x)
dont forget to change your fit:
model.fit(x_train, y_onehot, epochs=3)
Related
I am working on a gesture recognition problem. For that I have a train set. Train set consists of multiple folders and each folder consists of a series of 30 images. From those images the model is trained. Also I have a csv file that contains the class label of each folder. The class labels are : "Left Swipe", "Right Swipe", "Stop", "Thumbs Down" and "Thumbs Up". Those labels are present in one np.array variable train_class. Now, I have created a CNN model then feeding that in a Sequential model.
The code is available in below GIT location
https://github.com/subhrajyoti-ghosh/ML-and-Deep-Learning/blob/main/Gesture_Recognition.ipynb
But when I am trying to fit the model, I am receiving error. Can you please help me understanding the error and how to solve that?
You are trying to use a TimeDistributed layer on a 2D input (batch_size, 256), which will not work, because the layer needs at least a 3D tensor. You should try using tf.keras.layers.RepeatVector:
import tensorflow as tf
resnet = tf.keras.applications.ResNet50(include_top=False,weights='imagenet',input_shape=(224,224,3))
cnn = tf.keras.Sequential([resnet])
cnn.add(tf.keras.layers.Conv2D(64,(2,2),strides=(1,1)))
cnn.add(tf.keras.layers.Conv2D(16,(3,3),strides=(1,1)))
cnn.add(tf.keras.layers.Flatten())
inputs = tf.keras.layers.Input(shape=(224,224,3))
x = cnn(inputs)
x = tf.keras.layers.RepeatVector(n=30)(x)
x = tf.keras.layers.GRU(16,return_sequences=True)(x)
x = tf.keras.layers.GRU(8)(x)
outputs = tf.keras.layers.Dense(5,activation='softmax')(x)
model = tf.keras.Model(inputs, outputs)
dummy_x = tf.random.normal((1, 224,224,3))
print(model.summary())
print(model(dummy_x))
Model: "model_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_14 (InputLayer) [(None, 224, 224, 3)] 0
sequential_6 (Sequential) (None, 256) 24121296
repeat_vector_2 (RepeatVect (None, 30, 256) 0
or)
gru_5 (GRU) (None, 30, 16) 13152
gru_6 (GRU) (None, 8) 624
dense_7 (Dense) (None, 5) 45
=================================================================
Total params: 24,135,117
Trainable params: 24,081,997
Non-trainable params: 53,120
_________________________________________________________________
None
i'm fairly new to tensorflow and would appreciate answers a lot.
i'm trying to use a transformer model as an embedding layer and feed the data to a custom model.
from transformers import TFAutoModel
from tensorflow.keras import layers
def build_model():
transformer_model = TFAutoModel.from_pretrained(MODEL_NAME, config=config)
input_ids_in = layers.Input(shape=(MAX_LEN,), name='input_ids', dtype='int32')
input_masks_in = layers.Input(shape=(MAX_LEN,), name='attention_mask', dtype='int32')
embedding_layer = transformer_model(input_ids_in, attention_mask=input_masks_in)[0]
X = layers.Bidirectional(tf.keras.layers.LSTM(50, return_sequences=True, dropout=0.1, recurrent_dropout=0.1))(embedding_layer)
X = layers.GlobalMaxPool1D()(X)
X = layers.Dense(64, activation='relu')(X)
X = layers.Dropout(0.2)(X)
X = layers.Dense(30, activation='softmax')(X)
model = tf.keras.Model(inputs=[input_ids_in, input_masks_in], outputs = X)
for layer in model.layers[:3]:
layer.trainable = False
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
return model
model = build_model()
model.summary()
r = model.fit(
train_ds,
steps_per_epoch=train_steps,
epochs=EPOCHS,
verbose=3)
I have 30 classes and the labels are not one-hot encoded so im using sparse_categorical_crossentropy as my loss function but i keep getting the following error
ValueError: Shape mismatch: The shape of labels (received (1,)) should equal the shape of logits except for the last dimension (received (10, 30)).
how can i solve this?
and why is the (10, 30) shape required? i know 30 is because of the last Dense layer with 30 units but why the 10? is it because of the MAX_LENGTH which is 10?
my model summary:
Model: "model_16"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_ids (InputLayer) [(None, 10)] 0
__________________________________________________________________________________________________
attention_mask (InputLayer) [(None, 10)] 0
__________________________________________________________________________________________________
tf_bert_model_21 (TFBertModel) TFBaseModelOutputWit 162841344 input_ids[0][0]
attention_mask[0][0]
__________________________________________________________________________________________________
bidirectional_17 (Bidirectional (None, 10, 100) 327600 tf_bert_model_21[0][0]
__________________________________________________________________________________________________
global_max_pooling1d_15 (Global (None, 100) 0 bidirectional_17[0][0]
__________________________________________________________________________________________________
dense_32 (Dense) (None, 64) 6464 global_max_pooling1d_15[0][0]
__________________________________________________________________________________________________
dropout_867 (Dropout) (None, 64) 0 dense_32[0][0]
__________________________________________________________________________________________________
dense_33 (Dense) (None, 30) 1950 dropout_867[0][0]
==================================================================================================
Total params: 163,177,358
Trainable params: 336,014
Non-trainable params: 162,841,344
10 is a number of sequences in one batch. I suspect that it is a number of sequences in your dataset.
Your model acting as a sequence classifier. So you should have one label for every sequence.
I'm working on a first model in Keras, just to get started. I downloaded the MNIST data from Kaggle, which has preprocessed a subset of the data into a csv with a label column and 784 (28x28) greyscale pixel values.
I'm getting a ValueError: Shapes (None, 1) and (None, 10) are incompatible. I can't understand why.
Here's my code:
## load csv and partition into train/dev sets
dataframe = pd.read_csv('data/train.csv') ##load as pandas
dev_df = dataframe.sample(n=3000, random_state=1)
train_df = dataframe.drop(dev_df.index)
assert train_df.shape[1] == 785 #make sure it's not a problem with the data shape.
##Build the model
inputs = keras.Input(shape=(784))
x = layers.experimental.preprocessing.Rescaling(1./255)(inputs)
x = layers.Dense(100, activation='relu')(x)
x = layers.Dense(100, activation='relu')(x)
outputs = layers.Dense(10, activation='softmax')(x)
model = keras.Model(inputs=inputs,outputs=outputs)
model.summary()
At this point, I get the following model summary, which looks right to me (i.e., it looks a lot like what I'm seeing in the guides that I'm following.)
Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_3 (InputLayer) [(None, 784)] 0
_________________________________________________________________
rescaling_6 (Rescaling) (None, 784) 0
_________________________________________________________________
dense_3 (Dense) (None, 100) 78500
_________________________________________________________________
dense_4 (Dense) (None, 100) 10100
_________________________________________________________________
dense_5 (Dense) (None, 10) 1010
=================================================================
Total params: 89,610
Trainable params: 89,610
Non-trainable params: 0
Then
## compile and fit model.
model.compile(optimizer="adam", loss="categorical_crossentropy")
(X, y) = (train_df.drop('label', axis=1).to_numpy(), train_df['label'].to_numpy())
assert X.shape[1] == 784 ## we're really sure this is the right size.
assert X.shape[0] == y.shape[0] ## the number of labels matches the number of samples
history = model.fit(X, y, epochs=1, batch_size=64)
The last line raises the error. I would guess it emerges with the final dense layer, since it has the expected (None,10) shape, but I can't figure out where the (None, 1) shaped entity (whatever it is) comes from.
I'm trying to build Matrix factorization model with deep learning and deploy it using flask. I also use apscheduler to retrain the model from new inputs. Here is the model.
Model has 2 inputs cloth_ids, user_ids and one outputs ratings. both inputs and the output has the shape of 1D
#tensorflow version - 2.1.0
#keras version - 2.3.1
user_input = Input(shape=(1,))
cloth_input = Input(shape=(1,))
user_embedding = Embedding(self.n_users, embedding_dimR)(user_input)
cloth_embedding = Embedding(self.n_cloths, embedding_dimR)(cloth_input)
user_embedding = Flatten()(user_embedding)
cloth_embedding = Flatten()(cloth_embedding)
x = Concatenate()([user_embedding, cloth_embedding])
# x = Dense(denseR, activation='relu')(x)
x = Dense(R_hidden, activation='relu', name='dense1')(x)
x = Dense(R_hidden, activation='relu', name='dense2')(x)
x = Dense(R_hidden, activation='relu', name='dense3')(x)
x = Dense(R_out, activation='relu', name='dense_out')(x)
model = Model(
inputs=[user_input, cloth_input],
outputs=x
)
self.model = model
self.model.fit(
x=[self.train_user_ids,self.train_cloth_ids],
y=self.train_ratings,
batch_size=batch_sizeR,
epochs=num_epochsR,
validation_data=(
[self.test_user_ids,self.test_cloth_ids],
self.test_ratings
)
)
self.model.predict([[user_id],[cloth_id]])
# user_id, cloth_id are integers
1) First I used tensorflow.keras for import layer, model APIs and metrics.
Then I got following error while do predictions but apscheduler worked properly
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), for inputs
['input_11', 'input_12'] but instead got the following list of 1 arrays: [array([[23],
[ 0]], dtype=int64)]...
2) After I used keras instead of tensorflow.keras then model.predict worked properly but the apscheduler got the following error
Job "train_task (trigger: interval[0:00:20], next run at: 2020-05-08 12:22:29 +0530)" raised
an exception
AttributeError: '_thread._local' object has no attribute 'value'
Downgrading keras to 2.2.5 or using debug=False, threaded=False inside app.run() not working.
Please Help Me, Thanks
I was able to recreate your issue using the below code for a model.
Note - You can download the dataset I am using in the model from here.
Code to recreate the issue -
%tensorflow_version 1.x
import tensorflow as tf
print(tf.__version__)
# MLP for Pima Indians Dataset saved to single file
import numpy as np
from numpy import loadtxt
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Input, Concatenate
# load pima indians dataset
dataset = np.loadtxt("/content/pima-indians-diabetes.csv", delimiter=",")
input1 = Input(shape=(1,))
input2 = Input(shape=(1,))
# define model
x1 = Dense(12, input_shape = (2,), activation='relu')(input1)
x2 = Dense(12, input_shape = (2,), activation='relu')(input2)
x = Concatenate()([x1, x2])
x = Dense(8, activation='relu')(x)
x = Dense(1, activation='sigmoid')(x)
model = Model(inputs=[input1, input2], outputs=x)
# compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Model Summary
model.summary()
X1 = dataset[:,0]
X2 = dataset[:,1]
Y = dataset[:,8]
# Fit the model
model.fit(x=[X1,X2], y=Y, epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.predict([[X1,X2]], verbose=0)
Output -
1.15.2
Model: "model_23"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_38 (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
input_39 (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
dense_92 (Dense) (None, 12) 24 input_38[0][0]
__________________________________________________________________________________________________
dense_93 (Dense) (None, 12) 24 input_39[0][0]
__________________________________________________________________________________________________
concatenate_12 (Concatenate) (None, 24) 0 dense_92[0][0]
dense_93[0][0]
__________________________________________________________________________________________________
dense_94 (Dense) (None, 8) 200 concatenate_12[0][0]
__________________________________________________________________________________________________
dense_95 (Dense) (None, 1) 9 dense_94[0][0]
==================================================================================================
Total params: 257
Trainable params: 257
Non-trainable params: 0
__________________________________________________________________________________________________
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-32-d6b7d46777c6> in <module>()
38
39 # evaluate the model
---> 40 scores = model.predict([[X1,X2]], verbose=0)
3 frames
/tensorflow-1.15.2/python3.6/tensorflow_core/python/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
527 'Expected to see ' + str(len(names)) + ' array(s), '
528 'but instead got the following list of ' +
--> 529 str(len(data)) + ' arrays: ' + str(data)[:200] + '...')
530 elif len(names) > 1:
531 raise ValueError('Error when checking model ' + exception_prefix +
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([[ 6., 1., 8., ..., 5., 1., 1.],
[148., 85., 183., ..., 121., 126., 93.]])]...
Solution - The issue is in the bracket's for the data passed in model.predict(). It has to be similar way as data is passed in model.fit(). So I changed the model.predict([[X1,X2]], verbose=0) to model.predict([X1,X2], verbose=0) in my code and it worked fine. So in your case, you have to change model.predict([[user_id],[cloth_id]]) to model.predict([user_id,cloth_id]) and it should work fine.
Fixed Code -
%tensorflow_version 1.x
import tensorflow as tf
print(tf.__version__)
# MLP for Pima Indians Dataset saved to single file
import numpy as np
from numpy import loadtxt
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Input, Concatenate
# load pima indians dataset
dataset = np.loadtxt("/content/pima-indians-diabetes.csv", delimiter=",")
input1 = Input(shape=(1,))
input2 = Input(shape=(1,))
# define model
x1 = Dense(12, input_shape = (2,), activation='relu')(input1)
x2 = Dense(12, input_shape = (2,), activation='relu')(input2)
x = Concatenate()([x1, x2])
x = Dense(8, activation='relu')(x)
x = Dense(1, activation='sigmoid')(x)
model = Model(inputs=[input1, input2], outputs=x)
# compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Model Summary
model.summary()
X1 = dataset[:,0]
X2 = dataset[:,1]
Y = dataset[:,8]
# Fit the model
model.fit(x=[X1,X2], y=Y, epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.predict([X1,X2], verbose=0)
Output -
1.15.2
Model: "model_24"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_40 (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
input_41 (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
dense_96 (Dense) (None, 12) 24 input_40[0][0]
__________________________________________________________________________________________________
dense_97 (Dense) (None, 12) 24 input_41[0][0]
__________________________________________________________________________________________________
concatenate_13 (Concatenate) (None, 24) 0 dense_96[0][0]
dense_97[0][0]
__________________________________________________________________________________________________
dense_98 (Dense) (None, 8) 200 concatenate_13[0][0]
__________________________________________________________________________________________________
dense_99 (Dense) (None, 1) 9 dense_98[0][0]
==================================================================================================
Total params: 257
Trainable params: 257
Non-trainable params: 0
__________________________________________________________________________________________________
Hope this answers your question. Happy Learning.
I just reshape the user_id and cloth_id as follows and it works.
u = np.array([user_id]).reshape(-1,1)
c = np.array([cloth_id]).reshape(-1,1)
rating = float(self.model.predict([u,c]).squeeze())
I want to implement a word2vec using Keras. This is how I prepared my training data:
encoded = tokenizer.texts_to_sequences(data)
sequences = list()
for i in range(1, len(encoded)):
sent = encoded[i]
_4grams = list(nltk.ngrams(sent, n=4))
for gram in _4grams:
sequences.append(gram)
# split into X and y elements
sequences = np.array(sequences)
X, y = sequences[:, 0:3], sequences[:, 3]
X = to_categorical(X, num_classes=vocab_size)
y = to_categorical(y, num_classes=vocab_size)
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, y, test_size=0.3, random_state=42)
The following is my model in Keras:
model = Sequential()
model.add(Dense(50, input_shape=Xtrain.shape))
model.add(Dense(Ytrain.shape[1]))
model.add(Activation("softmax"))
Xtrain (6960, 3, 4048)
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_22 (Dense) (None, 6960, 3, 50) 202450
_________________________________________________________________
dense_23 (Dense) (None, 6960, 3, 4048) 206448
_________________________________________________________________
activation_10 (Activation) (None, 6960, 3, 4048) 0
=================================================================
Total params: 408,898
Trainable params: 408,898
Non-trainable params: 0
_________________________________________________________________
None
I got the error:
history = model.fit(Xtrain, Ytrain, epochs=10, verbose=1, validation_data=(Xtest, Ytest))
Error when checking input: expected dense_22_input to have 4 dimensions, but got array with shape (6960, 3, 4048)
I'm confused on how to prepare and feed my training data to a Keras neural network?
Input shape in keras does not necessary imply the shape of the input dataset. Input shape is shape of a single data point in the dataset(shape of input dataset without batch dimension). But you are are specifying the input shape to be shape of the dataset input including the batch dimension. The correct input shape in your case would be Xtrain.shape[1:].
model = Sequential()
model.add(Dense(50, input_shape=Xtrain.shape[1:]))
model.add(Dense(Ytrain.shape[1]))
model.add(Activation("softmax"))