Keras ValueError: expected dense_1 to have shape (3,) but got array with shape (4,) - keras

I've been trying to figure out how to use Keras when reading data from a .csv[1]. I have the following code:
dataframe = pd.read_csv("iris.csv", header=None)
dataset = dataframe.values
X = dataset[:, 0:4].astype(float)
Y = dataset[:, 4]
# encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
# convert integers to dummy variables (i.e. one hot encoded)
one_hot_y = keras.utils.to_categorical(encoded_Y)
X_train = X[:100]
X_test = X[50:]
Y_train = one_hot_y[:100]
Y_test = one_hot_y[50:]
print(X_train.shape)
# define baseline model
def baseline_model():
# create model
model = keras.models.Sequential()
model.add(keras.layers.Dense(8, input_shape=(4, ), activation='relu'))
model.add(keras.layers.Dense(3, activation='softmax'))
# Compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
model = baseline_model()
history = model.fit(X_train, X_test, epochs=5)
test_loss, test_acc = model.evaluate(Y_train, Y_test)
print('Test accuracy:', test_acc)
However, when I run this, I get the error:
ValueError: Error when checking target: expected dense_1 to have shape (3,) but got array with shape (4,)
I find this odd as I was sure to set input_shape=(4, ). Any help with this would be appreciated.
[1] The CSV looks as follows:
5.1,3.5,1.4,0.2,Iris-setosa
...

You have only 3 output neurons, but the data you are using obviously has 4 classes, so you need to change this line:
model.add(keras.layers.Dense(3, activation='softmax'))
from 3 output classes to 4 output classes:
model.add(keras.layers.Dense(4, activation='softmax'))

Related

How to predict the class probability with an array

I have an array of data and I'm trying to predict the probability if it's 1 or 0
I have a data set with more than 3000 rows as features and output data is either 1 or 0.
I'm quite new with neural networks, so I found an example online but now I'm having difficulties how to predict with unknown data.
In my case I want to predict the probability of 1 for row variable.
Here's the code
df = pd.read_csv("data.csv")
X = df.iloc[:,10:]
Y = df['output']
scaler = StandardScaler()
scaler.fit(X)
X = scaler.transform(X)
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
# larger model
def create_larger():
# create model
model = Sequential()
model.add(Dense(60, input_shape=(25,), activation='relu'))
model.add(Dense(30, activation='relu'))
model.add(Dense(15, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasClassifier(model=create_larger, epochs=50, batch_size=5, verbose=2)))
pipeline = Pipeline(estimators)
kfold = StratifiedKFold(n_splits=5, shuffle=True)
results = cross_val_score(pipeline, X, encoded_Y, cv=kfold)
print("Larger: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
row = [[4, 0.558, 0.493, 0.954, 0.895, 0.683, 8.7, 26, 0.155, 8.3, 21.8, 0.21, 0.723, 0.548, 0.466, 0.979, 0.887, 0.464, 11.8, 25.5, 0.184, 7.5, 18, 0.217, 0.651]]
scaler = StandardScaler()
row = np.array(row)
scaled_row = pipeline.fit(row)
print(pipeline.predict(scaled_row))
If I run this code I get an error
ValueError: Expected array-like (array or non-string sequence), got None
So now I'm kinda lost what to change it.
Thanks.

dealing with sparse data on TensorFlow 2.2.0

I'm trying to make a Face Recognition app using insightface, I wrote this code on Tensorflow 2.1.0 and Keras 2.3.1 and it worked well but due to some issues I have to migrate to TensorFlow 2.2.0 and Keras 2.4.3, I understand that my problem is my embeddings. they are sparse but in a meaningful way. How can I avoid changing the meaningfulness for my embeddings and avoid the spares data? From the error, I understand (Consider casting elements to a supported type.) that TensorFlow can't convert my np.array to tensor because it is sparse.
what I tried
these arent the commands but I wrote them so you would have a notion of what I tried. np.array(data["embeddings"]).todense(),csr_matrix(data["embeddings"]), tf.convert_to_tensor(data["embeddings"]) and also tried to follow along this but couldn't get to model.fit_generator work.
>>> print(type(embeddings))
<class 'numpy.ndarray'>
>>> print(embeddings.shape)
(49, 512)
>>> print(embeddings)
[[ 0.02751185 0.0143353 0.0324492 ... -0.00347222 0.0154978
-0.01304669]
[ 0.09154768 -0.04196533 0.01197386 ... -0.08363352 0.03335601
0.01748604]
[ 0.00182035 -0.00307933 0.00386595 ... -0.04442558 0.04434329
0.06080627]
...
[-0.01564891 -0.01510727 0.0345119 ... -0.01690779 -0.00816008
0.08056415]
[-0.00543963 -0.03811216 -0.01148985 ... -0.05366111 0.07108331
-0.00186215]
[ 0.00627459 -0.04221528 0.00426272 ... 0.02838095 0.02116473
0.00491964]]
This is my code:
class SoftMax():
def __init__(self, input_shape, num_classes):
self.input_shape = input_shape
self.num_classes = num_classes
def build(self):
#create model
model = Sequential()
#add model layers
model.add(Dense(1024, activation='relu', input_shape=self.input_shape))
model.add(Dropout(0.5))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(self.num_classes, activation='softmax'))
# loss and optimizer
optimizer=Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
model.compile(loss=categorical_crossentropy,
optimizer=optimizer,
metrics=['accuracy'])
return model
def make_model(args, classifier=SoftMax):
# Load the face embeddings
data = pickle.loads(open(args.embeddings, "rb").read())
num_classes = len(np.unique(data["names"]))
ct = ColumnTransformer([('myŁ”Name', OneHotEncoder(), [0])])
labels = np.array(data["names"]).reshape(-1, 1)
labels = ct.fit_transform(labels)
embeddings = np.array(data["embeddings"])
# Initialize Softmax training model arguments
BATCH_SIZE = 32
EPOCHS = 32
input_shape = embeddings.shape[1]
# Build classifier
init_classifier = classifier(input_shape=(input_shape,), num_classes=num_classes)
model = init_classifier.build()
# Create KFold
cv = KFold(n_splits = 5, random_state = None, shuffle=True)
history = {'acc': [], 'val_acc': [], 'loss': [], 'val_loss': []}
# Train
for train_idx, valid_idx in cv.split(embeddings):
X_train, X_val, y_train, y_val = embeddings[train_idx], embeddings[valid_idx], labels[train_idx], labels[valid_idx]
his = model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS, verbose=1, validation_data=(X_val, y_val))
# write the face recognition model to output
model.save(args.mymodel)
f = open(args.le, "wb")
f.write(pickle.dumps(LabelEncoder()))
f.close()
Error
TypeError: Failed to convert object of type <class 'tensorflow.python.framework.sparse_tensor.SparseTensor'> to Tensor. Contents: SparseTensor(indices=Tensor("DeserializeSparse:0", shape=(None, 2), dtype=int64), values=Tensor("DeserializeSparse:1", shape=(None,), dtype=float32), dense_shape=Tensor("stack:0", shape=(2,), dtype=int64)). Consider casting elements to a supported type.

How to understand and debug the error inside keras.model.fit?

I am trying to implement a keras LSTM. I am getting an error inside keras.model.fit. I am not understanding what this error means. My code is given below -
print(x_train.shape)
print(y_train.shape)
word_input = Input(shape=(mxlen,), dtype="int32", name="word_input")
x1 = Embedding(len(vocab), 100, input_length=mxlen, weights=[embeddings], trainable=False)(word_input)
x1 = LSTM(100)(x1)
y = Dense(6, activation="softmax", name="main_output")(x1)
model = Model(inputs=[word_input], outputs=[y])
adam = optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['categorical_accuracy']) # have to look into it
model.fit(x_train, y_train, epochs=30, batch_size=40, verbose=1)
x_train and y_train has the following shape - (10240, 198) and (10240,).
I am getting the following error:
Your output layer has 6 outputs (probably 6 classes are given), but the target labels in y_train are given as integers, apparently (array is flat).
You need to convert y_train to a one-hot encoded array first, otherwise, the cross-entropy loss cannot be computed. Input and output tensors must always be compatible with the inputs and outputs of the model.
Given that there are 6 classes in y_train, encoded as:
0,1,2,3,4,5
you require a conversion:
0 -> 1.,0.,0.,0.,0.,0.
1 -> 0.,1.,0.,0.,0.,0.
etc.
Try it like this:
import tf.keras.backend as K
...
num_classes = 6
y_one_hot = K.one_hot( y_train, num_classes )
....
model.fit(x_train, y_one_hot, epochs=30, batch_size=40, verbose=1)

Universal Sentence Encoder Error: Input 0 is incompatible with layer conv1d_6: expected ndim=3, found ndim=2

I'm worked on sentiment analysis task using universal sentence encoder embed_size=512 with CNN but have an error says: Input 0 is incompatible with layer conv1d_6: expected ndim=3, found ndim=2.
and wanna know if this is right to add universal sentence encoder with CNN in this way or not?
pickle_in=open("X.pickle","rb")
X=pickle.load(pickle_in)
X = X.tolist() #convert x to list as The embedding code works once I
converted
the pandas.series data type to list.
X = np.array(X, dtype=object)[:, np.newaxis]
pickle_in=open("Y.pickle","rb")
Y=pickle.load(pickle_in)
Y = np.asarray(pd.get_dummies(Y), dtype = np.int8)
import tensorflow as tf
import tensorflow_hub as hub
module_url = "https://tfhub.dev/google/universal-sentence-encoder-large/3"
embed = hub.Module(module_url)
X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size = 0.15,
random_state = 42)
X_train, X_Val, Y_train, Y_Val = train_test_split(X_train,Y_train, test_size
= 0.15, random_state = 42)
print(X_train.shape,Y_train.shape)
print(X_test.shape,Y_test.shape)
print(X_Val.shape,Y_Val.shape)
type(Y_test)
embed_size = embed.get_output_info_dict()['default'].get_shape()[1].value
def UniversalEmbedding(x):
return embed(tf.squeeze(tf.cast(x, tf.string)),
signature="default", as_dict=True)["default"]
import keras
seed=7
np.random.seed(seed)
from keras.layers import Input, Dense, concatenate, Activation,
GlobalMaxPooling1D
from keras import layers
from keras.models import Model
input_text = layers.Input(shape=(1,), dtype=tf.string)
embedding = layers.Lambda(UniversalEmbedding,
output_shape=(embed_size,))(input_text)
bigram_branch = Conv1D(filters=64, kernel_size=1, padding='same',
activation='relu', strides=1)(embedding)
bigram_branch = GlobalMaxPooling1D()(bigram_branch)
trigram_branch = Conv1D(filters=64, kernel_size=2, padding='same',
activation='relu', strides=1)(embedding)
trigram_branch = GlobalMaxPooling1D()(trigram_branch)
fourgram_branch = Conv1D(filters=64, kernel_size=3, padding='same',
activation='relu', strides=1)(embedding)
fourgram_branch = GlobalMaxPooling1D()(fourgram_branch)
merged = concatenate([bigram_branch, trigram_branch, fourgram_branch],
axis=1)
merged = Dense(512, activation='relu')(merged)
merged = Dropout(0.8)(merged)
merged = Dense(2)(merged)
output = Activation('sigmoid')(merged)
model = Model(inputs=[tweet_input], outputs=[output])
adam=keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None,
decay=0.0, amsgrad=False)
model.compile(loss='mean_squared_error',
optimizer= adam,
metrics=['accuracy'])
model.summary()
You can not directly pass Universal Sentence Encoder to Conv1D because Conv1D expected a tensor with shape [batch, sequence, feature] while the output of Universal Sentence Encoder is [batch, feature]. It is also stated in tfhub.dev:
The input is variable length English text and the output is a 512
dimensional vector.
How can I fix this?
In my view, the easiest possible solution is to use ELMo on Tensorhub. With ELMo you can map each sentence to [batch, sequence, feature] and then feed into the Conv1D.

Wrong dimensions when trying to use model.predict() from Keras

I think the code will speak for itself, but i trained a model, that i now wanna use to predict on some new input data. The new input data seems to be the wrong dimensions though. Below you can see the code and error messages for both the model and the predicting (attempted)
tokenizer = Tokenizer(num_words=10000)
df = pd.read_csv('/home/paperspace/Sentiment Analysis Dataset.csv', index_col = 0,
error_bad_lines = False)
y = list(df['Sentiment'])
tokenizer.fit_on_texts(list(df['SentimentText']))
X = tokenizer.texts_to_sequences(list(df['SentimentText']))
X = pad_sequences(X)
print("Done, fitting on texts.")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, shuffle = True)
model = Sequential()
#Creates the wordembeddings.
embedding_vector_dim = 32
model.add(Embedding(10000, embedding_vector_dim, input_length=X.shape[1]))
model.add(Dropout(0.2))
model.add(LSTM(128))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.summary()
model.fit(numpy.array(X_train), numpy.array(y_train),
batch_size=128,
epochs=1,
validation_data=(numpy.array(X_test), numpy.array(y_test)))
score, acc = model.evaluate(numpy.array(X_test),numpy.array(y_test),
batch_size=128)
model.save('./sentiment_seq.h5')
print('Test score:', score)
print('Test accuracy:', acc)
Now for the trying to predict and error message.
text = "this is actually a very bad movie."
tokenizer = Tokenizer()
tokenizer.fit_on_texts(list(text))
X = tokenizer.texts_to_sequences(list(text))
X = pad_sequences(X)
X_flat = np.array([X.flatten()])
model = load_model('sentiment_test.h5')
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
print(model.predict(X, batch_size = 1, verbose = 1))
ValueError: Error when checking : expected embedding_1_input to have shape (None, 116) but got array with shape (1, 38)
So basically why am i getting this error, when preprocessing is the same when training and predicting, and how can i know what the expected input should be before seeing the error message?
If you're not working with a fixed input length, you should not define an input_length in the embedding layer.

Resources