Issue with Shape in Python Neural Network - python

I have the following dataframe: https://raw.githubusercontent.com/markamcgown/Projects/master/df_model.csv
At "---> 11 history = model.fit" in the last block of code below, I get the error "ValueError: Input 0 of layer sequential_8 is incompatible with the layer: : expected min_ndim=3, found ndim=2. Full shape received: [None, 26]"
Why is it expecting a minimum of 3 dimensions and how can I automate my code below to always have the right shape?
import keras
import pandas as pd
from tensorflow.keras.models import Sequential
from sklearn.model_selection import train_test_split
from keras.layers import Conv2D, MaxPooling2D, Conv1D, MaxPooling1D
from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional
from keras.layers import Dense, Dropout, Flatten, Reshape, GlobalAveragePooling1D
path = r'C:\Users\<your_local_directory>\df_model.csv'
#Import raw data file with accelerometer data
df_model = pd.read_csv(path)
df_model
y_column = 'Y_COLUMN'
x = df_model.drop(y_column, inplace=False, axis=1).values
y = df_model[y_column].values
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1, random_state=42)
def create_model(num_features, num_classes, dropout=0.3,
loss="mean_absolute_error", optimizer="rmsprop"):
model = Sequential()
model.add(Conv1D(100, 10, activation='relu', input_shape=(None,num_features)))
model.add(Conv1D(100, 10, activation='relu'))
model.add(MaxPooling1D(2))
model.add(Conv1D(160, 10, activation='relu'))
model.add(Conv1D(160, 10, activation='relu'))
model.add(LSTM(160, return_sequences=True))
model.add(LSTM(160, return_sequences=True))
model.add(GlobalAveragePooling1D())
model.add(Dropout(dropout))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=loss, metrics=["mean_absolute_error"], optimizer=optimizer)
return model
DROPOUT = 0.4
LOSS = "huber_loss"
OPTIMIZER = "adam"
num_time_periods, num_features = x_train.shape[0], x_train.shape[1]
model = create_model(num_features, num_classes=len(set(df_model[y_column])), loss=LOSS,
dropout=DROPOUT, optimizer=OPTIMIZER)
callbacks_list = [keras.callbacks.ModelCheckpoint(filepath='best_model.{epoch:02d}-{val_loss:.2f}.h5',monitor='val_loss', save_best_only=True),keras.callbacks.EarlyStopping(monitor='accuracy', patience=1)]
model.compile(loss='categorical_crossentropy',optimizer='adam', metrics=['accuracy'])
# Hyper-parameters
BATCH_SIZE = 400
EPOCHS = 1
# Enable validation to use ModelCheckpoint and EarlyStopping callbacks.
history = model.fit(x_train,y_train,batch_size=BATCH_SIZE,epochs=EPOCHS,callbacks=callbacks_list,validation_split=0.2,verbose=1)
plt.figure(figsize=(15, 4))
plt.plot(history.history['accuracy'], "g-", label="Training Accuracy")
#plt.plot(history.history['val_accuracy'], "g", label="Accuracy of validation data")
plt.plot(history.history['loss'], "r-", label="Training Loss")
#plt.plot(history.history['val_loss'], "r", label="Loss of validation data")
plt.title('Model Performance')
plt.ylabel('Accuracy & Loss')
plt.xlabel('Epoch')
plt.ylim(0)
plt.legend()
plt.show()

Related

How to solve logits and labels must have the same shape ((64, 20, 1440) vs (64, 2))

i'm newbie in machine learning, and i try to run lstm multi layers with keras. here's my code:
from keras.layers import Embedding
embedding_layer = Embedding(vocabulary_size, EMBEDDING_DIM, weights=[embedding_matrix], trainable=False)
from keras.layers import Input, Dense, Embedding, Dropout
from keras.layers.core import Reshape
from tensorflow.keras.optimizers import Adam
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import LSTM
X_train = pad_sequences(sequences_train)
X_test = pad_sequences(sequences_test,maxlen=X_train.shape[1])
y_train = to_categorical(np.asarray(labels[train_data.index]))
y_test = to_categorical(np.asarray(labels[test_data.index]))
embed_dim = 128
lstm_out = 128
sequence_length = X_train.shape[1]
inputs = Input(shape=(sequence_length,))
embedding = embedding_layer(inputs)
reshape = Reshape((sequence_length,EMBEDDING_DIM,1))(embedding)
adam = Adam(lr=1e-1)
model = Sequential()
model.add(Embedding(input_dim = len(word_index)+1, output_dim = EMBEDDING_DIM, input_length = sequence_length, weights=[embedding_matrix], trainable=False))
model.add(LSTM(((lstm_out)), return_sequences=True))
model.add(Dropout(0.5))
model.add(Dense(len(labels), activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics = ['accuracy'])
history = model.fit(X_train, y_train, batch_size=64, epochs=5, validation_data=(X_test, y_test), shuffle = True)
print(model.summary())
and some errors appear
File "E:\Codes\LSTM_multi_Layers.py", line 31, in <module>
history = model.fit(X_train, y_train, batch_size=64, epochs=5, validation_data=(X_test, y_test), shuffle = True)
ValueError: logits and labels must have the same shape ((64, 20, 1440) vs (64, 2))
What does it mean? and what should be changed from my code? can somebody help me, please.

Model was constructed with shape (None, 28) problem

I am getting an error. It says:
Model was constructed with shape (None, 28) for input KerasTensor(type_spec=TensorSpec(shape=(None, 28), dtype=tf.float32, name='dense_45_input'), name='dense_45_input', description="created by layer 'dense_45_input'"), but it was called on an input with incompatible shape (None, 28, 28).
Mycode is here:
from keras.utils import np_utils
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, BatchNormalization, Dropout, Activation
import seaborn as sns
from keras.initializers import RandomNormal
from keras.initializers import he_normal
import matplotlib.pyplot as plt
(train_X, train_y), (test_X, test_y) = mnist.load_data()
output_dim = 10
input_dim = train_X.shape[1]
batch_size = 128
nb_epoch = 20
model_drop = Sequential()
model_drop.add(Dense(512, activation='relu', input_shape=(input_dim,),kernel_initializer=he_normal(seed=None)))
model_drop.add(BatchNormalization())
model_drop.add(Dropout(0.5))
model_drop.add(Dense(128, activation= 'relu', kernel_initializer=he_normal(seed=None)))
model_drop.add(BatchNormalization())
model_drop.add(Dropout(0.5))
model_drop.add(Dense(output_dim, activation = 'softmax'))
model_drop.summary()
model_drop.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
history = model_drop.fit(train_X, train_y, batch_size=batch_size, epochs=nb_epoch, verbose=1)
How can I fix this? Also I am adding error photo..
Your input dimensions in building the dense layer are wrong, if the image is 28x28 you need to be able to receive all the pixels (i.e. you need 28*28=784 input connections). To really get this working you also need to one-hot encode the y variables as well as reshape the images.
(train_X, train_y), (test_X, test_y) = mnist.load_data()
output_dim = 10
input_dim = train_X.shape[1]
batch_size = 128
nb_epoch = 20
model_drop = Sequential()
# see input_dim edit here
model_drop.add(Dense(512, activation='relu', input_shape=(input_dim*input_dim,),kernel_initializer=he_normal(seed=None)))
model_drop.add(BatchNormalization())
model_drop.add(Dropout(0.5))
model_drop.add(Dense(128, activation= 'relu', kernel_initializer=he_normal(seed=None)))
model_drop.add(BatchNormalization())
model_drop.add(Dropout(0.5))
model_drop.add(Dense(output_dim, activation = 'softmax'))
model_drop.summary()
model_drop.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# encode Y_train and also shape X_train so it can feed to dense layer
Y_train = np_utils.to_categorical(train_y, num_classes=10)
X_train = train_X.reshape((-1, 28*28))
history = model_drop.fit(X_train, Y_train, batch_size=batch_size, epochs=nb_epoch, verbose=1)

SHAP ValueError: Dimension 1 in both shapes must be equal, but are 2 and 1. Shapes are [?,2] and [?,1]

Based on a previously trained feed-forward network, I tried to use SHAP to get the feature importance. I followed all the steps described in the documentation but I am still receiving the following error
ValueError: Dimension 1 in both shapes must be equal, but are 2 and 1. Shapes are [?,2] and [?,1]
The following code produces a reproduciple example that has the same error.
import pandas as pd
from numpy.random import randint
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, BatchNormalization, Dropout, Activation
from keras.optimizers import Adam
import shap
# Train_x data creation
train_x = pd.DataFrame({
'v1': randint(2, 20, 1489),
'v2': randint(50, 200, 1489),
'v3': randint(30, 90, 1489),
'v4': randint(100, 150, 1489)
})
# Train_y data creation
train_y = randint(0, 2, 1489)
# One-hot encoding as I use categorical cross-entropy
train_y = to_categorical(train_y, num_classes=2)
# Start construction of a DNN Sequential model.
model = Sequential()
# First input layer with a dropout and batch normalization layer following
model.add(Dense(256, input_dim=train_x.shape[1]))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(rate=0.2))
# Output layer
model.add(Dense(2))
model.add(Activation('softmax'))
# Use the Adam optimizer
optimizer = Adam(lr=0.001)
# Compile the model
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
model.summary()
# Fit model
hist = model.fit(train_x, train_y, epochs=100, batch_size=128, shuffle=False, verbose=2)
# SHAP calculation
explainer = shap.DeepExplainer(model, train_x)
shap_values = explainer.shap_values(train_x[:500].values)
where I have an input shape of (None, 4) and a softmax activation function at the end with 2 neurons as I use it for binary classification. The train_x data on the following code snippet are a pandas data frame of shape (1489, 4).
I tried to change the train_x shape but I had a similar error. Any help would be much appreciated.
Please see below a working example for binary classification with TF:
from numpy.random import randint
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, BatchNormalization, Dropout, Activation
from tensorflow.keras.optimizers import Adam
import shap
import tensorflow
print(shap.__version__, "\n",tensorflow.__version__)
# Train_x data creation
train_x = pd.DataFrame({
'v1': randint(2, 20, 1489),
'v2': randint(50, 200, 1489),
'v3': randint(30, 90, 1489),
'v4': randint(100, 150, 1489)
})
# Train_y data creation
train_y = randint(0, 2, 1489)
# One-hot encoding as I use categorical cross-entropy
train_y = to_categorical(train_y, num_classes=2)
# Start construction of a DNN Sequential model.
model = Sequential()
# First input layer with a dropout and batch normalization layer following
model.add(Dense(256, input_dim=train_x.shape[1]))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(rate=0.2))
# Output layer
model.add(Dense(2))
model.add(Activation('softmax'))
# Use the Adam optimizer
optimizer = Adam(lr=0.001)
# Compile the model
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
# model.summary()
# Fit model
hist = model.fit(train_x, train_y, epochs=100, batch_size=128, shuffle=False, verbose=0)
# SHAP calculation
shap.explainers._deep.deep_tf.op_handlers["AddV2"] = shap.explainers._deep.deep_tf.passthrough
explainer = shap.DeepExplainer(model, train_x)
shap_values = explainer.shap_values(train_x[:500].values)
shap.summary_plot(shap_values[1])
0.38.2
2.2.0
Note couple of things:
Package versions (tf should be below 2.4 I believe)
Addition of "AddV2" (see discussion here)

keras, invalid predict size

im quite new in keras
I have trained this with (100,8) size of input and output, i want to 1*8 output with 1*8 predict data.
for example
input that i enter 1*8.
code returns, 1*8 output data.
here is my code:
from tensorflow import keras
import numpy as np
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
import keras
from keras.layers import Input, Dense
accuracy = tf.keras.metrics.CategoricalAccuracy()
import numpy as np
xs=np.ones((100,8))
ys=np.ones((100,8))
for i in range(100):
xs[i]*=np.random.randint(30, size=8)
ys[i]=xs[i]*2
xs=xs.reshape(1,100,8)
ys=ys.reshape(1,100,8)
# model = tf.keras.Sequential([layers.Dense(units=1, input_shape=[2,4])])
model = Sequential()
model.add(Dense(10,input_shape=[100,8]))
model.add(Activation('relu'))
model.add(Dropout(0.15))
model.add(Dense(10))
model.add(Activation('relu'))
# model.add(Dropout(0.5))
model.add(Dense(8))
model.compile(optimizer='adam', loss='mean_squared_error',metrics=['accuracy'] )
model.fit(xs, ys, epochs=1000, batch_size=100)
p= np.array([[1,3,4,5,9,2,3,4]]).reshape(1,1,8)
print(model.predict(p))
you don't need to add one dimension in the first position of your data. for 2D network, you simply have to feed your model with data in the format (n_sample, n_features)
here the complete example
xs=np.ones((100,8))
ys=np.ones((100,8))
for i in range(100):
xs[i]*=np.random.randint(30, size=8)
ys[i]=xs[i]*2
xs=xs.reshape(100,8)
ys=ys.reshape(100,8)
model = Sequential()
model.add(Dense(10,input_shape=(8,)))
model.add(Activation('relu'))
model.add(Dropout(0.15))
model.add(Dense(10))
model.add(Activation('relu'))
model.add(Dense(8))
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(xs, ys, epochs=10, batch_size=100)
p = np.array([[1,3,4,5,9,2,3,4]]) # (1, 8)
pred = model.predict(p)
print(pred)
print(pred.shape) # (1, 8)

How to use a 1D-CNN model in Lime?

I have a numeric health record dataset. I used a 1D CNN keras model for the classification step.
I am giving a reproductible example in Python:
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import Conv1D, Activation, Flatten, Dense
import numpy as np
a = np.array([[0,1,2,9,3], [0,5,1,33,6], [1, 12,1,8,9]])
train = np.reshape(a[:,1:],(a[:,1:].shape[0], a[:,1:].shape[1],1))
y_train = keras.utils.to_categorical(a[:,:1])
model = Sequential()
model.add(Conv1D(filters=2, kernel_size=2, strides=1, activation='relu', padding="same", input_shape=(train.shape[1], 1), kernel_initializer='he_normal'))
model.add(Flatten())
model.add(Dense(2, activation='sigmoid'))
model.compile(loss=keras.losses.binary_crossentropy,
optimizer=keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False),
metrics=['accuracy'])
model.fit(train, y_train, epochs=3, verbose=1)
I am getting this error when I apply lime to my 1D CNN model
IndexError: boolean index did not match indexed array along dimension 1; dimension is 4 but corresponding boolean dimension is 1
import lime
import lime.lime_tabular
explainer = lime.lime_tabular.LimeTabularExplainer(train)
Is there a solution ?
I did some minor changes to your initial code (changed from keras to tensorflow.keras)
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv1D, Activation, Flatten, Dense
import numpy as np
a = np.array([[0,1,2,9,3], [0,5,1,33,6], [1, 12,1,8,9]])
train = np.reshape(a[:,1:],(a[:,1:].shape[0], a[:,1:].shape[1],1))
y_train = tf.keras.utils.to_categorical(a[:,:1])
model = Sequential()
model.add(Conv1D(filters=2, kernel_size=2, strides=1, activation='relu',
padding="same", input_shape=(train.shape[1], 1),
kernel_initializer='he_normal'))
model.add(Flatten())
model.add(Dense(2, activation='sigmoid'))
model.compile(loss=tf.keras.losses.binary_crossentropy,
optimizer=tf.keras.optimizers.Adam(lr=0.001, beta_1=0.9,
beta_2=0.999, amsgrad=False),
metrics=['accuracy'])
model.fit(train, y_train, epochs=3, verbose=1)
Then I added some test data because you don't want to train and test your LIME model on the same data
b = np.array([[1,4,5,3,2], [1,4,2,55,1], [7, 3,22,3,10]])
test = np.reshape(b[:,1:],(b[:,1:].shape[0], b[:,1:].shape[1],1))
Here I show how the RecurrentTabularExplainer can be trained
import lime
from lime import lime_tabular
explainer = lime_tabular.RecurrentTabularExplainer(train,training_labels=y_train, feature_names=["random clf"],
discretize_continuous=False, feature_selection='auto', class_names=['class 1','class 2'])
Then you can run your LIME model on one of the examples in your test data:
exp = explainer.explain_instance(np.expand_dims(test[0],axis=0), model.predict, num_features=10)
and finally display the predictions
exp.show_in_notebook()
or just printing the prediction
print(exp.as_list())
You should try lime_tabular.RecurrentTabularExplainer instead of LimeTabularExplainer. It is an explainer for keras-style recurrent neural networks. Check out the examples in LIME documentation for better understanding. Good luck:)

Categories