I am trying to train my model to predict the next number in an integer sequence. The integer sequence that I created was generated in random.
My X_train = [[1,2,3,4,5,6], [45,45,46,47,48,49], [203,204,205,206,207,208]...]
and Y_train = [[7,8,9], [50,51,52], [209,210,211]]
The shape of X_train = (10000,6,511) and Y_train = (10000,3,511)
How should I set my input shape for my GRU/LSTM model?
def define_models(n_input = 6, n_output = 3):
# define training encoder
sequence = Input(shape=(n_input,), dtype="int32")
embedded = Embedding(13, 300, mask_zero=True)(sequence)
gru1 = GRU(1000, return_sequences=True)(embedded)
after_dp = Dropout(0.5)(gru1)
gru2 = GRU(1000, return_sequences=True)(after_dp)
after_dp = Dropout(0.5)(gru2)
output = TimeDistributed(Dense(13, activation="softmax"))(after_dp)
model = Model(input=sequence, output=output)
return model
i am getting the error :
ValueError: Error when checking input: expected input_1 to have 2 dimensions, but got array with shape (10000, 6, 511)
How should I fix it for my dataset?
You are only giving one dimension as the input_shape, while you are giving a 3d array as input.For a n-d input array, the input_shape should be last n-1 dimension values. Hence the input shape should be
(X_train.shape[1],X_train.shape[2]).
Replace this line
sequence = Input(shape=(n_input,), dtype="int32")
with this
sequence = Input(shape=(X_train.shape[1],X_train.shape[2]), dtype="int32")
Related
I am using a model trained by myself to translate braille digits into plain text. As you can see this is a classification problem with 26 classes, one for each letter in the alphabet.
This is the dataset that I used to train my model: https://www.kaggle.com/datasets/shanks0465/braille-character-dataset
This is how I am generating my training and validation set:
os.mkdir('./images/')
alpha = 'a'
for i in range(0, 26):
os.mkdir('./images/' + alpha)
alpha = chr(ord(alpha) + 1)
rootdir = "C:\\Users\\ffernandez\\Downloads\\capstoneProject\\Braille Dataset\\Braille Dataset\\"
for file in os.listdir(rootdir):
letter = file[0]
copyfile(rootdir+file, './images/' + letter + '/' + file)
The resulting folder looks like this:
folder structure
And this is how I create the train and validation split:
datagen = ImageDataGenerator(rotation_range=20,
shear_range=10,
validation_split=0.2)
train_generator = datagen.flow_from_directory('./images/',
target_size=(28,28),
subset='training')
val_generator = datagen.flow_from_directory('./images/',
target_size=(28,28),
subset='validation')
Finally this is the code corresponding to the design, compilation and training of the model:
K.clear_session()
model_ckpt = ModelCheckpoint('BrailleNet.h5',save_best_only=True)
reduce_lr = ReduceLROnPlateau(patience=8,verbose=0)
early_stop = EarlyStopping(patience=15,verbose=1)
entry = L.Input(shape=(28,28,3))
x = L.SeparableConv2D(64,(3,3),activation='relu')(entry)
x = L.MaxPooling2D((2,2))(x)
x = L.SeparableConv2D(128,(3,3),activation='relu')(x)
x = L.MaxPooling2D((2,2))(x)
x = L.SeparableConv2D(256,(2,2),activation='relu')(x)
x = L.GlobalMaxPooling2D()(x)
x = L.Dense(256)(x)
x = L.LeakyReLU()(x)
x = L.Dense(64,kernel_regularizer=l2(2e-4))(x)
x = L.LeakyReLU()(x)
x = L.Dense(26,activation='softmax')(x)
model = Model(entry,x)
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit_generator(train_generator,validation_data=val_generator,epochs=666,
callbacks=[model_ckpt,reduce_lr,early_stop],verbose=0)
Then this is the code for testing an image of the letter 'a' in braille has the same size as the training and validation set (28x28):
img_path = "./test/a1.JPG10whs.jpg"
img = plt.imread(img_path)
img_array = tf.keras.utils.img_to_array(img)
img_batch = np.expand_dims(img_array, axis=0)
img_preprocessed = tf.keras.applications.resnet50.preprocess_input(img_batch)
prediction = model.predict(img_preprocessed)
print(tf.keras.applications.imagenet_utils.decode_predictions(prediction, top=3)[0])
Just when I execute that last line of code this error appears:
ValueError: decode_predictions expects a batch of predictions (i.e. a 2D array of shape (samples, 1000)). Found array with shape: (1, 26)
A similar question I found here on stackoverflow (ValueError: `decode_predictions` expects a batch of predictions (i.e. a 2D array of shape (samples, 1000)). Found array with shape: (1, 7)).
I've seen that using "decode_predictions" only makes sense if your model outputs the ImageNet classes (1000-dimensional) but if I can't use "decode_predictions" I don't know how to get my predictions.
My desired output would be like:
prediction = model.predict(img_preprocessed)
print(prediction)
output: 'a'
Any hint or suggestion on how to solve this issue is highly appreciated.
If we take a look at what the prediction object acually is we can see that it has 26 values. These values are the propabiity for each letter that the model predicts:
So we need a way to map the prediction value to the respective letter.
A simple way to do this could to create a list of all the 26 possible letters and search the max value in the prediction array. Example:
#Create prediction labels from a-z
alpha="a"
labels=["a"]
for i in range(0, 25):
alpha = chr(ord(alpha) + 1)
labels.append(alpha)
#Search the max value in prediction
labels[np.argmax(prediction)]
The output should be the character with the highest probability:
I am trying to implement a model with the ArcFace Layer:
https://github.com/4uiiurz1/keras-arcface
to this extend I created a tf.data.dataset like so:
images= tf.data.Dataset.from_tensor_slices(train.A_image.to_numpy())
target = tf.keras.utils.to_categorical(
train.Label.to_numpy(), num_classes=n_class, dtype='float32'
)
target = tf.data.Dataset.from_tensor_slices(target)
images= images.map(transform_img)
dataset = tf.data.Dataset.zip((images, target, target))
when I call model.fit(dataset)
I get the following error:
ValueError: Layer model expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=<unknown> dtype=float32>]
But this should work according:
tf.data with multiple inputs / outputs in Keras
Can someone point out my folly?
Thanks!
Edit:
this solves some problems:
#reads in filepaths to images from dataframe train
images = tf.data.Dataset.from_tensor_slices(train.image.to_numpy())
#converts labels to one hot encoding vector
target = tf.keras.utils.to_categorical(train.Label.to_numpy(), num_classes=n_class, dtype='float32')
#reads in the image and resizes it
images= images.map(transform_img)
input_1 = tf.data.Dataset.zip((anchors, target))
dataset = tf.data.Dataset.zip((input_1, target))
And I think it's what we are trying. But I get a shape error for targets, it's (n_class, 1) instead of just (n_class,)
I.e. the fit methods throws this error
ValueError: Shapes (n_class, 1) and (n_class, n_class) are incompatible
and this warning
input expected is (None, n_class) but received an input of (n_class, 1)
I've made changes to the solution based on the arcface, you've wanted here is the code, i've managed to train it
The first one is from tensor slices as the original input and i used mnist to test it out
def map_data(inputs, outputs):
image = tf.cast(inputs['image_input'], tf.float32)
image = image / 255.
image = tf.expand_dims(image, axis=2)
labels = tf.one_hot(outputs, 10)
return {'image_input': image, 'label_input': labels}, labels
dataset = tf.data.Dataset.from_tensor_slices(({
'image_input': x_train, 'label_input': y_train
}, y_train))
dataset = dataset.map(map_data)
dataset = dataset.batch(2)
Here is the second type i have tried using a normal from tensor slices then i converted it to a multiple input, since both the normal labels are used for both the input and output
def map_data(images, annot_labels):
image = tf.cast(images, tf.float32)
image = image / 255.
image = tf.expand_dims(image, axis=2) # convert to 0 - 1 range
labels = tf.one_hot(annot_labels, 10)
return {'image_input': image, 'label_input': labels}, labels
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
dataset = dataset.map(map_data)
dataset = dataset.batch(2)
I think you should do it like this:
target = tf.keras.utils.to_categorical(train.Label.to_numpy(), num_classes=n_class, dtype='float32')
images_target = tf.data.Dataset.from_tensor_slices((train.A_image.to_numpy(), target))
images_target = images_target.map(lambda x, y: (transform_img(x), y))
target = tf.data.Dataset.from_tensor_slices(target)
dataset = tf.data.Dataset.zip((images_target, target))
I am trying to load weights and for that to work i need to perform the following:
dummy_input = tf.random.uniform(input_shape) # create a tensor of input shape
dummy_label = tf.random.uniform(label_shape) # create a tensor of label shape
hist = model.fit(dummy_input, dummy_label)
I am new to this and can't figure out what these shapes should be.
Some information about my model:
Im feeding the model images with shape (224,224,3).
In batches of 16.
I have 423 different classes and use sparse_categorical_crossentropy.
I tried this
dummy_input = tf.random.uniform([16, 224, 224, 3]) # create a tensor of input shape
dummy_label = tf.random.uniform([16, 1, 423]) # create a tensor of label shape
hist = model.fit(dummy_input, dummy_label, epochs=epochs,
steps_per_epoch=len_train // batch_size,
validation_steps=len_test // batch_size)
There may be many errors here but the one i am getting right now is
ValueError: Shape mismatch: The shape of labels (received (423,))
should equal the shape of logits except for the last dimension (received (1, 423)).
This was the solution
dummy_input = tf.random.uniform([32, 224, 224, 3]) # create a tensor of input shape
dummy_label = tf.random.uniform([32,]) # create a tensor of label shape
hist = model.fit(dummy_input, dummy_label)
# Creating a Sequential Model and adding the layers
input_img = Input(shape=(28, 28, 1))
#63 kernels - Conv of 3X3
conv_1 = Conv2D(63, kernel_size=(3,3),activation='relu', padding='same')(input_img)
#Then pooling of 2X2
encoded = MaxPooling2D((2, 2), padding='same')(conv_1)
#model.add(Dropout(0.2))
###Classification###
# Flattening the 2D arrays for fully connected layers
flatten = Flatten()(encoded)
# Adding dense layer
fc = Dense(1000, activation='relu')(flatten)
fc1 = (Dropout(0.2))(fc)
#A6 = model.add(Dropout(0.2),name = 'A6') #Combat Overfitting, drop random elements
#Softmax layer must have neurons = range of labels, 0-9 for this case
softmax = Dense(5, activation='softmax', name='classification')(fc1)
model = Model(inputs=input_img, outputs=[softmax])
when i run and model.fit the model , the follow error occurs:
ValueError: Data cardinality is ambiguous:
x sizes: 30703
y sizes: 30703, 51660
Please provide data which shares the same first dimension.
What i am trying to achieve is that , i am trying to run keras classification on mnist dataset, and i have removed some of the digits , leaving only 0,1,2,3,9, a total of 5 integers , i need to index the integers so i could output a dense layer of 5 outputs , instead of having to stick to 10 (covering integer 9). I have done the below , but error above occurs, kindly advise thanks
# Transform y_train (and similarly y_test).
uniquetrain, index = np.unique(y_train, return_inverse=True)
y_train = np.arange(len(uniquetrain))[index]
# To get back the original labels, just index into the unique values.
unique[y_train]
# Transform y_train (and similarly y_test).
uniquetest, index1 = np.unique(y_test, return_inverse=True)
y_test = np.arange(len(uniquetest))[index1]
# To get back the original labels, just index into the unique values.
unique[y_test]
You can create a mask to keep the instances of the desired labels and also create a mapping from old labels to new ones. See the code below:
X_train = ... # Tensor of shape [ELEMS, 28, 28, 1]
y_train = ... # Tensor of shape [ELEMS]
X_test = ... # Tensor of shape [TEST_ELEMS, 28, 28, 1]
y_test = ... # Tensor of shape [TEST_ELEMS]
# Labels you want to keep
keep_labels = [0, 1, 2, 3, 9]
# Map old labels to new labels, for instance the label 9 on the new set of labels,
# is going to be 4
labels_to_index = {l: i for i,l in enumerate(keep_labels)}
# Masks to keep training and test instance. Trues keeps the instances
train_keep_mask = np.zeros(y_train.shape[0], dtype=np.bool)
test_keep_mask = np.zeros(y_test.shape[0], dtype=np.bool)
for l in keep_labels:
train_keep_mask |= y_train == l
test_keep_mask |= y_test == l
# Apply masks to filter the training and test instances
X_train = X_train[train_keep_mask]
y_train = y_train[train_keep_mask]
X_test = X_test[test_keep_mask]
y_test = y_test[test_keep_mask]
# From now on X_train, y_train, X_test, y_test only contain the desired labels
# which are defined in `keep_labels`
# Map old labels to new ones
new_y_train = np.array([labels_to_index[l] for l in y_train.tolist()])
new_y_test = np.array([labels_to_index[l] for l in y_test.tolist()])
# To invert the labels use `keep_labels[new_label]`
again_old_y_train = np.array([keep_labels[l] for l in new_y_train.tolist()])
again_old_y_test = np.array([keep_labels[l] for l in new_y_test.tolist()])
I'm trying to fit RNN model on top of my data but it shows an input error : ValueError: Input arrays should have the same number of samples as target arrays. Found 8 input samples and 33984 target samples.
Attaching screenshot for reference.
https://drive.google.com/open?id=1UjO7yQjD2_52PhTLYAYoZGfQsl1bboSW
https://drive.google.com/open?id=13k2sUvEVYoJGV7bR_dxh25C-sC8Tva0L
def RNN():
inputs = Input(name='inputs',shape=[max_len])
layer = Embedding(max_words,50,input_length=max_len)(inputs)
layer = LSTM(64)(layer)
layer = Dense(256,name='FC1')(layer)
layer = Activation('relu')(layer)
layer = Dropout(0.5)(layer)
layer = Dense(1,name='out_layer')(layer)
layer = Activation('sigmoid')(layer)
model = Model(inputs=inputs,outputs=layer)
return model
model = RNN()
model.summary()
model.compile(loss='binary_crossentropy',optimizer=RMSprop(),metrics=['accuracy'])
model.fit(sequences_matrix,y_train,batch_size=128,epochs=10,
validation_split=0.2,callbacks= [EarlyStopping(monitor='val_loss',min_delta=0.0001)])
The shape of my data that i'm trying to fit into the run model:
X_train.shape = (33984, 8)
y_train.shape = (33984,)
X_test.shape = (14565, 8)
y_test.shape = (14565,)