So I have some machine learning data split into testing and training data. The data is imported from a csv file and split into training and testing data using a numpy array.
I manage to split the data fine but when I try to use this data in the model I get an error of:
ValueError: Input 0 of layer "mobilenetv2_1.00_3998" is incompatible with the layer: expected shape=(None, 3998, 140, 1), found shape=(None, 140, 1)
I have tried to reshape the data to match the input shape of the model. This still doesn't work and not really sure how to go about doing this. The data needs to be reshaped but with the correct values.
training dataset consists of:
[[ 0.00770334 -1.4224063 -2.4392433 ... 2.1296244 1.7076529
0.2145994 ]
[-0.9572602 -2.1521447 -2.7491045 ... -3.784852 -2.7787943
-1.727039 ]
testing dataset consists of:
[1. 0. 0. ... 1. 0. 0.]
shape of data:
x_train: (3998, 140)
x_test: (1000, 140)
y_train: (3998,)
y_test: (1000,)
The size of the each testing and training set:
x_train: 559720
x_test: 140000
y_train: 3998
y_test: 1000
here is my code:
model = tf.keras.applications.MobileNetV2((3998, 140, 1), classes=10, weights = None)
model.compile("adam", "sparse_categorical_crossentropy", metrics=["accuracy"])
x_train, x_test, y_train, y_test = model_selection.train_test_split(x, y, test_size=0.2, random_state=123)
x_train = x_train.reshape(3998, 140, 1)
x_test = x_test.reshape(1000, 140, 1)
tf.keras.applications.MobileNetV2 is for images only, meaning a shape of (None, Height, Width, 3), where None is the batch size and 3 is the number of channels. But your training data seems to have a shape of (None, 140) which does not match the required input shape. So, try to use a different model which matches your data shape, and your error will be eliminated
I am sorry can't comment in the question
what is the shape of your input excluding batch
is it (3998, 140, 1) or (140, 1)
if it is (140, 1)
i think this part should be
tf.keras.applications.MobileNetV2((140, 1), classes=10, weights = None)
but if am correct mobile net input should have 3 dimension like (240, 240, 3)
link
but the 1 data shape is (3998, 140, 1) then you should add batch dimension to it before passing to the model
x_train = x_train.reshape(1, 3998, 140, 1)
Related
I am running an LSTM model on a simple stock market data.
When training the data, the y_train values are a simple array of floats64 of size (985,). But upon using the lstm.predict(X_test), the y_predicted values are of size array of float32 (246,2,1).
Basically, it is giving me two predictions per input X_test value. Ideally I would expect the output to be an array (246,)
Please help, here is the code:
def lstm_split(data,n_steps):
X,y=[],[]
for i in range(len(stock_data)-n_steps+1):
X.append(data[i:i+n_steps,:-1])
y.append(data[i+n_steps-1,-1])
return np.array(X),np.array(y)
stock_data_ft = X_ft
X1,y1 = lstm_split(stock_data_ft.values,n_steps=2)
train_split=0.8
split_idx = int(np.ceil(len(X1)*train_split))
date_index = stock_data_ft.index
X_train, X_test = X1[:split_idx] , X1[split_idx:]
y_train,y_test = y1[:split_idx] , y1[split_idx:]
X_train_date, X_test_date = date_index[:split_idx], date_index[split_idx:]
print(X1.shape , X_train.shape, X_test.shape, y_test.shape)
print(X_train)
lstm = Sequential()
lstm.add(LSTM(32,input_shape=(X_train.shape[1],X_train.shape[2]),activation='relu',return_sequences=True))
lstm.add(Dense(1))
lstm.compile(loss='mean_squared_error',optimizer='adam')
lstm.summary()
history = lstm.fit(X_train,y_train,epochs=100,batch_size=4,verbose=2,shuffle=False)
y_pred = lstm.predict(X_test)
I tried to get predicted values from the model.
y_pred = lstm.predict(X_test)
Was expecting output of array (246,) but instead got an output size array of float32 (246,2,1).
Some additional clarifications:
X_train.shape[1] is 2 and X_train.shape[2] is 3. These indicate the dimensions of the input features.
Basically the X values in training data is an array of dimension (985,2,3).
Some samples below:
[[ 1.53055021, 1.52204214, 1.53825887], [ 1.5526797 , 1.56142366, 1.56073994]],
[[ 1.5526797 , 1.56142366, 1.56073994], [ 1.58880785, 1.59418392, 1.6166433 ]]]
I am trying to create a image classification model using CNN. For that I am reading the data using the tf.keras.preprocessing.image_dataset_from_directory function.
This is the code:
train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir_train,seed=123,validation_split = 0.2,subset = 'training',image_size=(img_height, img_width),batch_size=batch_size)
Then I am trying to convert the dataset in np.array object. My code is
x_train = np.array(train_ds)
But when I print x_train, I am getting
array(<BatchDataset shapes: ((None, 180, 180, 3), (None,)), types: (tf.float32, tf.int32)>, dtype=object)
The object train_ds is of shape (2000,180,180,3). I am not sure what is wrong in my code.
When using image_dataset_from_directory:
... image_dataset_from_directory(main_directory, labels='inferred') will return a tf.data.Dataset that yields batches of images from the subdirectories ...
One option to get the data you want, is to use take to create a Dataset with at most count elements from this dataset.
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
img = np.empty((6000,180,180,3), dtype=np.float32)
label = np.empty((6000,), dtype=np.int32)
train_ds = tf.data.Dataset.from_tensor_slices((img,label)).batch(2000)
print(train_ds) # <BatchDataset shapes: ((None, 180, 180, 3), (None,)), types: (tf.float32, tf.int32)>
for imgs, labels in train_ds.take(1):
print(imgs.shape) # (2000, 180, 180, 3)
print(labels.shape) # (2000,)
for img in imgs:
plt.imshow(img.numpy().astype(np.uint8)) # print imgs in the batch
Depending on how you're structuring your code, you may not even need to convert to a numpy.array, since tf.keras.Model fit accepts tf.data datasets.
model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
I am writing a neural network to take the Mel frequency coefficients as inputs and then run the model. My dataset contains 100 samples - each sample is an array of 12 values corresponding to the coefficients. After splitting this data into train and test sets, I have created the X input corresponding to the array and the y input corresponding to the label.
Data array containing the coefficients
Here is a small sample of my data containing 5 elements in the X_train array:
['[107.59366 -14.153783 24.799461 -8.244417 20.95272\n -4.375943 12.77285 -0.92922235 3.9418116 7.3581047\n -0.30066165 5.441765 ]'
'[ 96.49664 2.0689797 21.557552 -32.827045 7.348135 -23.513977\n 7.9406714 -16.218931 10.594619 -21.4381 0.5903044 -10.569035 ]'
'[105.98041 -2.0483367 12.276348 -27.334534 6.8239 -23.019623\n 7.5176797 -21.884727 11.349695 -22.734652 3.0335162 -11.142375 ]'
'[ 7.73094559e+01 1.91073620e+00 6.72225571e+00 -2.74525508e-02\n 6.60858107e+00 5.99264860e-01 1.96265772e-01 -3.94772577e+00\n 7.46383286e+00 5.42239428e+00 1.21432066e-01 2.44894314e+00]']
When I create the Neural network, I want to use the 12 coefficients as an input for the network. In order to do this, I need to use each row of my X_train dataset that contains these arrays as the input. However, when I try to consider the array index as an input it gives me shape errors when trying to fit the model. My model is as follows:
def build_model_graph():
model = Sequential()
model.add(Input(shape=(12,)))
model.add(Dense(12))
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('relu'))
model.add(Dense(num_labels))
model.add(Activation('softmax'))
# Compile the model
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
return model
Here, I want to use every row of the X_train array as an input which would correspond to the shape(12,). When I use something like this:
num_epochs = 50
num_batch_size = 32
model.fit(x_train, y_train, batch_size=num_batch_size, epochs=num_epochs,
validation_data=(x_test, y_test), verbose=1)
I get an error for the shape which makes sense to me.
For reference, the error is as follows:
ValueError: Exception encountered when calling layer "sequential_20" (type Sequential).
Input 0 of layer "dense_54" is incompatible with the layer: expected min_ndim=2, found ndim=1. Full shape received: (None,)
But I am not exactly sure how I can extract the array of 12 coefficients present at each index of the X_train and then use it in the model input. Indexing the x_train and y_train did not work either. If anyone could point me in a relevant direction, it would be extremely helpful. Thanks!
Edit: My code for the dataframe is as follows:
clapdf = pd.read_csv("clapsdf.csv")
clapdf.drop('Unnamed: 0', inplace=True, axis=1)
clapdf.head()
nonclapdf = pd.read_csv("nonclapsdf.csv")
nonclapdf.drop('Unnamed: 0', inplace=True, axis=1)
sound_df = clapdf.append(nonclapdf)
sound_df.head()
d=sound_data.tolist()
df=pd.DataFrame(data=d)
data = df[0].to_numpy()
print("Before-->", data.shape)
dat = np.array([np.array(d) for d in data])
print('After-->', dat.shape)
Here, the shape remains the same as the values of each of the 80 samples are not in a comma separated format but instead in the form of a series.
If your data looks like this:
samples = 2
features = 12
x_train = tf.random.normal((samples, 1, features))
tf.Tensor(
[[[-2.5988803 -0.629626 -0.8306641 -0.78226614 0.88989156
-0.3851106 -0.66053045 1.0571191 -0.59061646 -1.1602987
0.69124466 -0.04354193]]
[[-0.86917496 2.2923143 -0.05498986 -0.09578358 0.85037625
-0.54679644 -1.2213608 -1.3766612 0.35416105 -0.57801914
-0.3699728 0.7884727 ]]], shape=(2, 1, 12), dtype=float32)
You will have to reshape it to (2, 12) in order to fit your model with the input shape (batch_size, 12):
import tensorflow as tf
def build_model_graph():
model = tf.keras.Sequential()
model.add(tf.keras.layers.Input(shape=(12,)))
model.add(tf.keras.layers.Dense(12))
model.add(tf.keras.layers.Activation('relu'))
model.add(tf.keras.layers.Dense(10))
model.add(tf.keras.layers.Activation('relu'))
model.add(tf.keras.layers.Dense(2))
model.add(tf.keras.layers.Activation('softmax'))
# Compile the model
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
return model
model = build_model_graph()
samples = 2
features = 12
x_train = tf.random.normal((samples, 1, features))
x_train = tf.reshape(x_train, (samples, features))
y = tf.random.uniform((samples, 1), maxval=2, dtype=tf.int32)
y_train = tf.keras.utils.to_categorical(y, 2)
model.fit(x_train, y_train, batch_size=1, epochs=2)
Also, you usually need to convert your labels to one-hot encoded vectors if you plan to use categorical_crossentropy.
y_train looks like this:
[[0. 1.]
[1. 0.]]
Update 1:
If your data is coming from a dataframe, try something like this:
import numpy as np
import pandas as pd
d = {'features': [[0.18525402, 0.92130125, 0.2296906, 0.75818471, 0.69813222, 0.47147329,
0.03560711, 0.06583931, 0.90921289, 0.76002148, 0.50413995, 0.36099004],
[0.18525402, 0.92130125, 0.2296906, 0.75818471, 0.69813222, 0.47147329,
0.03560711, 0.06583931, 0.90921289, 0.76002148, 0.50413995, 0.36099004]]}
df = pd.DataFrame(data=d)
data = df['features'].to_numpy()
print('Before -->', data.shape)
data = np.array([np.array(d) for d in data])
print('After -->', data.shape)
Before --> (2,)
After --> (2, 12)
I'm trying to adapt the Keras MNIST Siamese example to use a generator.
On the example, we have:
model.fit([tr_pairs[:, 0], tr_pairs[:, 1]], tr_y,
batch_size=128,
epochs=epochs,
validation_data=([te_pairs[:, 0], te_pairs[:, 1]], te_y))
Trying to figure out the shape needed to be returned by the generator, I did:
np.array([tr_pairs[:, 0], tr_pairs[:, 1]]).shape
and getting
(2, 108400, 28, 28)
My generator is then returning this:
(data, labels) = my_generator
data.shape
(2, 6, 300, 300, 3)
labels.shape
(6,)
So, it's two arrays (for the NN inputs), with 6 images (batch_size) of size 300x300x3 (RGB).
Below is the fit_generator() usage:
...
input_shape = (300, 300, 3)
...
model.fit_generator(kbg.generate(set='train'),
steps_per_epoch=training_steps,
epochs=1,
verbose=1,
callbacks=[],
validation_data=kbg.generate(set='test'),
validation_steps=validation_steps,
use_multiprocessing=False,
workers=0)
I guess I'm feeding the NN with the same shape, but I'm getting the following error:
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 gotthe following list of 1 arrays: [array([[[[[0.49803922, 0.48235294, 0.55686275],
[0.63137255, 0.61176471, 0.64313725],
[0.8627451 , 0.84313725, 0.84313725],
...,
[0.58823529, 0.64705882, 0.631...
What is wrong?
Since the model has two input layers, the generator should yield a list of two arrays as the input samples corresponding to the two input layers, like this:
def my_generator(args):
# ...
yield [first_pair, second_pair], labels
where first_pair and second_pair both have a shape of (n_samples, 300, 300, 3).
I'm attempting to follow along on what I'm thinking is the 5th or 6th simple introductory tutorial for keras that almost but never quite works.
Stripping everything out, I appear to come down to a problem with the format of my input. I read in an array of images, and extract two types, images of sign language ones and images of sign language zeros. I then set up an array of ones and zeros to correspond to what the images actually are, then make sure of sizes and types.
import numpy as np
from subprocess import check_output
print(check_output(["ls", "../data/keras/"]).decode("utf8"))
## load dataset of images of sign language numbers
x = np.load('../data/keras/npy_dataset/X.npy')
# Get the zeros and ones, construct a list of known values (Y)
X = np.concatenate((x[204:409], x[822:1027] ), axis=0) # from 0 to 204 is zero sign and from 205 to 410 is one sign
Y = np.concatenate((np.zeros(205), np.ones(205)), axis=0).reshape(X.shape[0],1)
# test shape and type
print("X shape: " , X.shape)
print("X class: " , type(X))
print("Y shape: " , Y.shape)
print("Y type: " , type(Y))
This gives me:
X shape: (410, 64, 64)
X class: <class 'numpy.ndarray'>
Y shape: (410, 1)
Y type: <class 'numpy.ndarray'>
which is all good. I then load the relevant bits from Keras, using Tensorflow as the backend and try to construct a classifier.
# get the relevant keras bits.
from keras.models import Sequential
from keras.layers import Convolution2D
# construct a classifier
classifier = Sequential() # initialize neural network
classifier.add(Convolution2D(32, (3, 3), input_shape=(410, 64, 64), activation="relu", data_format="channels_last"))
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
classifier.fit(X, Y, batch_size=32, epochs=10, verbose=1)
This results in:
ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (410, 64, 64)
This SO question, I think, suggests that my input shape needs to be altered to have a 4th dimension added to it - though it also says it's the output shape that needs to altered, I haven't been able to find anywhere to specify an output shape, so I'm assuming it is meant that I should alter the input shape to input_shape=(1, 64, 64, 1).
If I change my input shape however, then I immeadiately get this:
ValueError: Input 0 is incompatible with layer conv2d_1: expected ndim=4, found ndim=5
Which this github issue suggests is because I no longer need to specify the number of samples. So I'm left with the situation of using one input shape and getting one error, or changing it and getting another error.
Reading this and this made me think I might need to reshape my data to include information about the channels in X, but if I add in
X = X.reshape(X.shape[0], 64, 64, 1)
print(X.shape)
Then I get
ValueError: Error when checking target: expected conv2d_1 to have 4 dimensions, but got array with shape (410, 1)
If I change the reshape to anything else, i.e.
X = X.reshape(X.shape[0], 64, 64, 2)
Then I get a message saying it's unable to reshape the data, so I'm obviously doing something wrong with that, if that is, indeed, the problem.
I have read the suggested Conv2d docs which shed exactly zero light on the matter for me. Anyone else able to?
At first I used the following data sets (similar to your case):
import numpy as np
import keras
X = np.random.randint(256, size=(410, 64, 64))
Y = np.random.randint(10, size=(410, 1))
x_train = X[:, :, :, np.newaxis]
y_train = keras.utils.to_categorical(Y, num_classes=10)
And then modified your code as follows to work:
from keras.models import Sequential
from keras.layers import Convolution2D, Flatten, Dense
classifier = Sequential() # initialize neural network
classifier.add(Convolution2D(32, (3, 3), input_shape=(64, 64, 1), activation="relu", data_format="channels_last"))
classifier.add(Flatten())
classifier.add(Dense(10, activation='softmax'))
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
classifier.fit(x_train, y_train, batch_size=32, epochs=10, verbose=1)
Changed the shape of X from 410 x 64 x 64 to 410 x 64 x 64 x 1 (with channel 1).
input_shape be the shape of a sample data, that is, 64 x 64 x 1.
Changed the shape of Y using keras.utils.to_categorical() (one-hot encoding with num_classes=10).
Before compiling, Flatten() and Dense() were applied because you want categorical_crossentropy.