Error with keras model data augmented dimensions in First epoch - python

So I have done data augmentation in a keras model. I am using Fashin_Mnist dataset. Everything goes okay but when it finished the first epoch it throws an error.
The error: ValueError: Shapes (32, 1) and (32, 10) are incompatible
My data:
img_rows = 28
img_cols = 28
batch_size = 512
img_shape = (img_rows, img_cols, 1)
x_train = x_train.reshape(x_train.shape[0], *img_shape)
x_test = x_test.reshape(x_test.shape[0], *img_shape)
x_val = x_val.reshape(x_val.shape[0], *img_shape)
label_as_binary = LabelBinarizer()
y_train_binary = label_as_binary.fit_transform(y_train)
y_test_binary = label_as_binary.fit_transform(y_test)
y_val_binary = label_as_binary.fit_transform(y_val)
My model:
model2 = Sequential([
Conv2D(filters=32, kernel_size=3, activation='relu',
input_shape=img_shape, padding="same"),
MaxPooling2D(pool_size=2),
Conv2D(filters=32, kernel_size=3, activation='relu',
padding="same"),
MaxPooling2D(pool_size=2),
Dropout(0.25),
Conv2D(filters=64, kernel_size=3, activation='relu',
padding="same"),
MaxPooling2D(pool_size=2),
Conv2D(filters=64, kernel_size=3, activation='relu',
padding="same"),
MaxPooling2D(pool_size=2),
Dropout(0.25),
Flatten(),
Dense(512, activation='relu'),
Dense(10, activation='softmax')
])
The data augmentation:
datagen = ImageDataGenerator(horizontal_flip=True, rotation_range=45,
width_shift_range=0.2, height_shift_range=0.2, zoom_range=0.1)
datagen.fit(x_train)
for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size=9):
for i in range(0, 9):
pyplot.subplot(330 + 1 + i)
pyplot.imshow(x_batch[i].reshape(28, 28),
cmap=pyplot.get_cmap('gray'))
pyplot.show()
break
model2.compile(loss='categorical_crossentropy',
optimizer=Adadelta(learning_rate=0.01), metrics=['accuracy'])
history = model2.fit_generator(datagen.flow(x_train,y_train_binary,
batch_size=batch_size),
epochs = 10, validation_data = (x_train, y_val_binary), verbose = 1)
I have seen many similar answers but none of them seem to fit mine. Help is much appreciated.

I think you should change this line:
validation_data = (x_train, y_val_binary)
to this:
validation_data = (x_val, y_val_binary)
Then, your model should run properly.

Related

binary signal data: keras ValueError: Input 0 of layer sequential is incompatible with the layer: : expected min_ndim=3, found ndim=2

I'm attempting to train models for RF fingerprinting, and have captured samples from a number of devices at a length of 1 million each. I've converted the samples into a variety of images, and have successfully trained models using that form of data by means of:
imageSize = 224
x_train = np.array(x_train) / 255
x_train.reshape(-1, imageSize, imageSize, 1)
x_val = np.array(x_val) / 255
x_val.reshape(-1, imageSize, imageSize, 1)
y_train = np.array(y_train)
y_val = np.array(y_val)
model = Sequential()
model.add(Conv2D(96, 7, padding="same", activation="relu", input_shape = (224, 224, 3)))
model.add(MaxPool2D())
model.add(Conv2D(96, 7, padding="same", activation="relu"))
model.add(MaxPool2D())
model.add(Conv2D(192, 7, padding="same", activation="relu"))
model.add(MaxPool2D())
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(384, activation="relu"))
model.add(Dense(6, activation="softmax"))
opt = Adam(learning_rate=0.000001)
model.compile(optimizer = opt, loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=["accuracy"])
model.summary()
history = model.fit(x_train, y_train, epochs = 500, validation_data = (x_val, y_val))
However, attempting to do the same to the array data (shape (60, 4000)) which was used to create the images yields the "ValueError: Input 0 of layer sequential is incompatible with the layer: : expected min_ndim=3, found ndim=2" issue listed in the title. My code for that is:
x_train = np.array(x_train)
x_train.reshape(-1, 4000, 1)
x_val = np.array(x_val)
x_val.reshape(-1, 4000, 1)
y_train = np.array(y_train)
y_val = np.array(y_val)
model = Sequential()
model.add(Conv1D(96, 7, padding="same", activation="relu", input_shape=(4000, 1)))
model.add(MaxPooling1D())
model.add(Conv1D(96, 7, padding="same", activation="relu"))
model.add(MaxPooling1D())
model.add(Conv1D(192, 7, padding="same", activation="relu"))
model.add(MaxPooling1D())
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(384, activation="relu"))
model.add(Dense(6, activation="softmax"))
opt = Adam(learning_rate=0.000001)
model.compile(optimizer = opt, loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=["accuracy"])
model.summary()
history = model.fit(x_train, y_train, epochs = 500, validation_data = (x_val, y_val))
Like many it seems, I'm unable to figure out why this input shape isn't working for the array data. Any clarifications will be helpful.
The error: expected min_ndim=3, found ndim=2 clearly explains all. The first problem, you used input shape is in three dimension (224, 224, 3), while for the second one the input shape changed to 1 dimensional array of shape (4000, 1). You should reshape the dimension of your input to the sequential model.

How to predict from new data set?

I have created a model to predict emotion from a voice sample, the model is made from the code below:
there are total 8 emotions:
neutral, calm, happy, sad, angry, disgust, surprised
i first extracted the features of each and every voice sample and put them in a dataframe, then loaded
them one by one to both X and (labels to Y) then split the data as shown below:
x_train, x_test, y_train, y_test = train_test_split(X, Y, random_state=0, shuffle=True)
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)
x_train = np.expand_dims(x_train, axis=2)
x_test = np.expand_dims(x_test, axis=2)
model=Sequential()
model.add(Conv1D(256, kernel_size=5, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1], 1)))
model.add(MaxPooling1D(pool_size=5, strides = 2, padding = 'same'))
model.add(Conv1D(256, kernel_size=5, strides=1, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=5, strides = 2, padding = 'same'))
model.add(Conv1D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=5, strides = 2, padding = 'same'))
model.add(Dropout(0.2))
model.add(Conv1D(64, kernel_size=5, strides=1, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=5, strides = 2, padding = 'same'))
model.add(Flatten())
model.add(Dense(units=32, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(units=8, activation='softmax'))
model.compile(optimizer = 'adam' , loss = 'categorical_crossentropy' , metrics = ['accuracy'])
model.summary()
rlrp = ReduceLROnPlateau(monitor='loss', factor=0.4, verbose=0, patience=2, min_lr=0.0000001)
history=model.fit(x_train, y_train, batch_size=64, epochs=75, validation_data=(x_test, y_test), callbacks=[rlrp])
got total 89% accuracy
Now i want to predict with a new dataset. What do i need to do?
If new_data_x_test and new_data_y_true are your new data set, then all you need to do after training the model as follows:
scaler = StandardScaler()
new_data_x_test = scaler.transform(new_data_x_test )
new_data_x_test= np.expand_dims(new_data_x_test, axis=2)
model.load_weight(h5)
new_data_y_pred = model.predict(new_data_x_test )
The thing is, you should transform it according to the model requirements. Next, evaluate on new_data_y_true and new_data_y_pred with appropriate evaluation metrics.

Image classification- Why am I getting vastly different results training on Tensorflow vs Pytorch?

I am training an image classifier for a robot that detects "blocked" vs "free" paths. Using the same data on pytorch gives >0.98 accuracy on validation data whereas tensorflow only gives around 0.50-0.60 accuracy with a mode of 52.17%.
Pytorch is using pre-trained AlexNet implementation for which there is no counterpart on tensorflow. I tried my best to mirror the implementation on tensorflow as you can see below. I have also tried other CNN models including ResNet and InceptionV3 but all give me roughly the same validation accuracy on tensorflow.
Other information:
Input images are (224, 224, 3)
Both implementations point to same training and validation directories
I've tested both models with 4 images they have not seen before and pytorch model guessed correctly whereas tensorflow model did not.
Pytorch Code:
train_loader = torch.utils.data.DataLoader(
train_dataset,
batch_size=8,
shuffle=True,
num_workers=0
)
test_loader = torch.utils.data.DataLoader(
test_dataset,
batch_size=8,
shuffle=True,
num_workers=0
)
model = models.alexnet(pretrained=True)
model.classifier[6] = torch.nn.Linear(model.classifier[6].in_features, 2)
device = torch.device('cuda')
model = model.to(device)
NUM_EPOCHS = 30
BEST_MODEL_PATH = 'best_model.pth'
best_accuracy = 0.0
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
for epoch in range(NUM_EPOCHS):
for images, labels in iter(train_loader):
images = images.to(device)
labels = labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = F.cross_entropy(outputs, labels)
loss.backward()
optimizer.step()
test_error_count = 0.0
for images, labels in iter(test_loader):
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
test_error_count += float(torch.sum(torch.abs(labels - outputs.argmax(1))))
test_accuracy = 1.0 - float(test_error_count) / float(len(test_dataset))
print('%d: %f' % (epoch, test_accuracy))
if test_accuracy > best_accuracy:
torch.save(model.state_dict(), BEST_MODEL_PATH)
best_accuracy = test_accuracy
Tensorflow code:
model = keras.models.Sequential([
keras.layers.Conv2D(filters=64, kernel_size=(11, 11), strides=(4, 4), activation='relu',
input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)),
keras.layers.BatchNormalization(),
keras.layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)),
keras.layers.Conv2D(filters=192, kernel_size=(5, 5), strides=(1, 1), activation='relu', padding="same"),
keras.layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)),
keras.layers.Conv2D(filters=384, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding="same"),
keras.layers.Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding="same"),
keras.layers.Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding="same"),
keras.layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)),
keras.layers.Dropout(0.5),
keras.layers.Flatten(),
keras.layers.Dense(4096, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(4096, activation='relu'),
keras.layers.Dense(1, activation='sigmoid')
])
train_gen = ImageDataGenerator(
rescale=1.0 / 255,
samplewise_std_normalization=True,
# rotation_range=20,
# width_shift_range=0.2,
# height_shift_range=0.1,
brightness_range=(0.0, 0.5),
# shear_range=0.2,
zoom_range=0.3,
fill_mode='nearest'
)
val_gen = ImageDataGenerator(rescale=1.0 / 255)
train_data = train_gen.flow_from_directory(
train_path,
target_size=(IMAGE_SIZE, IMAGE_SIZE),
class_mode='binary',
color_mode='rgb',
batch_size=8,
shuffle=True)
val_data = val_gen.flow_from_directory(
val_path,
target_size=(IMAGE_SIZE, IMAGE_SIZE),
class_mode='binary',
color_mode='rgb',
batch_size=8,
shuffle=True)
optimizer = tf.keras.optimizers.SGD(lr=0.001, momentum=0.9)
loss = tf.keras.losses.binary_crossentropy
model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])
num_epochs = 40
save_path = 'F:\\Documents\\Jetbot\\collision_avoidance_tf\\model_save'
model_checkpoint = tf.keras.callbacks.ModelCheckpoint(save_path, monitor='val_loss', save_best_only=True)
history = model.fit(train_data, epochs=num_epochs, validation_data=val_data, verbose=1,
callbacks=[model_checkpoint])
Any help is greatly appreciated. Thanks!

Input 0 of layer sequential is incompatible with the layer

I created a model and then loaded it in another script and try to perform a prediction from it however I can not understand why the shape being passed to the function is incorrect.
This is how the model is created:
batch_size = 1232
epochs = 5
IMG_HEIGHT = 400
IMG_WIDTH = 400
model1 = np.load("training_data.npy", allow_pickle=True)
model2 = np.load("training_data_1.npy", allow_pickle=True)
data = np.asarray(np.concatenate((model1, model2), axis=0)) # 1232
train_data = data[:-100]
X_train = np.asarray(np.array([i[0] for i in train_data]))
Y_train = np.asarray([i[1] for i in train_data])
validation_data = data[-100:]
X_val = np.asarray(np.array([i[0] for i in validation_data]))
Y_val = np.asarray([i[1] for i in validation_data])
model = Sequential([
Conv2D(16, 3, padding='same', activation='relu',
input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
MaxPooling2D(),
Conv2D(32, 3, padding='same', activation='relu'),
MaxPooling2D(),
Conv2D(64, 3, padding='same', activation='relu'),
MaxPooling2D(),
Flatten(),
Dense(512, activation='relu'),
Dense(1)
])
model.compile(optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
history = model.fit(X_train, Y_train, steps_per_epoch=batch_size, epochs=epochs,
validation_data=(X_val, Y_val), validation_steps=batch_size)
model.save("test")
And this is how I'm trying to make a prediction:
batch_size = 1232
epochs = 5
IMG_HEIGHT = 400
IMG_WIDTH = 400
model = tf.keras.models.load_model('test')
test_1 = cv2.imread('./Data/Images/test_no.jpg')
test_1 = cv2.resize(test_1, (IMG_HEIGHT, IMG_WIDTH))
prediction = model.predict([test_1])[0]
print(prediction)
When printing the shape of the test image the output is: (400, 400, 3)
I also tried using the numpy operation reshape when passing the test image to predict. However the error is always:
ValueError: Input 0 of layer sequential is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [None, 400, 3]
Add extra dimension to your input as [n_items,400,400,3]
import tensorflow as tf
X_train = tf.expand_dims(X_train, axis =-1)

SVM on top of an autoencoder for image classification: 100% accuracy on train and test data

I have a small image data set with 4 classes. So I've used an auto-encoder to extract features automatically.
These features are fed to an Support Vector Machine classifier in order to do the classification task.
After training the auto encoder for 10 epochs and training the SVM model on the extracted features I've got these confusion matrices:
My concern is about if the model isn't as general as possible in order to be applicable on a new data.
My question is: Is there any method to know if the model is over fitting except testing it on some other samples?
EDIT:
This is the code for the auto encoder:
encoder_input = Input(shape=(IMG_HEIGHT, IMG_WIDTH, 3), name='original_img')
x = Conv2D(filters=32, kernel_size=3, padding="same", input_shape=(IMG_HEIGHT, IMG_WIDTH, 3))(encoder_input)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(filters=64, kernel_size=3, padding="same", activation='relu')(x)
encoder_output = MaxPooling2D((2, 2))(x)
encoder = Model(encoder_input, encoder_output, name='encoder')
encoder.summary()
decoder_input = Input(shape=(32, 35, 64,), name='encoded_img')
x = Conv2D(filters=64, kernel_size=3, padding="same", activation='relu') (decoder_input)
x = UpSampling2D((2, 2))(x)
x = Conv2D(filters=32, kernel_size=3, padding="same", activation='relu')(x)
x = UpSampling2D((2, 2))(x)
decoder_output = Conv2D(filters=3, kernel_size=3, padding='same', activation='relu')(x)
decoder = Model(decoder_input, decoder_output, name='decoder')
decoder.summary()
autoencoder_input = Input(shape=(IMG_HEIGHT, IMG_WIDTH, 3), name='img')
encoded_img = encoder(autoencoder_input)
decoded_img = decoder(encoded_img)
Autoencoder = Model(autoencoder_input, decoded_img, name='autoencoder')
Autoencoder.summary()
total_train = 80
total_val = 40
Autoencoder.compile(optimizer='adam',
loss=tf.keras.losses.MeanSquaredError())
history = Autoencoder.fit_generator(
train_data_gen,
steps_per_epoch=total_train // batch_size,
epochs=epochs,
validation_data=val_data_gen,
validation_steps=total_val // batch_size
)
The code for the SVM and confusion matrices:
samples, y = next(train_data_gen_svm)
samples_val, y_val = next(val_data_gen_svm)
#Get features
X = encoder.predict(samples)
X_val = encoder.predict(samples_val)
# Reshape for the SVM input
X_reshape = X.reshape(80,32*35*64)
X_val_reshape = X_val.reshape(40,32*35*64)
clf = SVC(kernel='poly', degree=3)
print('X shape:', X_reshape.shape)
print('y shape: ', X_val_reshape.shape)
clf.fit(X_reshape, y)
y_pred_val = clf.predict(X_val_reshape)
y_pred_train = clf.predict(X_reshape)
cnf_matrix_val = confusion_matrix(y_val, y_pred_val,normalize='true')
cnf_matrix_train = confusion_matrix(y,y_pred_train,normalize='true')

Categories