How to get predict label from a CNN text classification? - python

I am new to CNN text classification. I want to classify text into one of two labels.
0 = tidak mengidap
1 = mengidap
My model only returns 0, no matter what sequence.
lstm_out = 150
model = Sequential()
model.add(embedding_layer)
model.add(Conv1D(filters=64, kernel_size=5, activation='relu', padding='causal'))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.7))
model.add(LSTM(units=lstm_out))
model.add(Dropout(0.7))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
X_sample = tokenizer.texts_to_sequences(df['stemmed'])
X_sample = pad_sequences(X_sample, maxlen=maxlentweet)
y_sample = model.predict(X_sample).flatten().tolist()
result = np.argmax(y_sample)
print(result)

Related

Training Tensorflow Model on PrefetchDataset

I have a large csv file that I want to train a tensorflow model on, so I am creating a PrefetchDataset object to read from the csv file in epochs.
dataset = tf.data.experimental.make_csv_dataset("test.csv", batch_size = 2, label_name="next_movement", shuffle = False, num_epochs=1)
But when I train to train the model
X_dim = pd.read_csv("test.csv", nrows = 1).shape[1]
optimizer = Adam(learning_rate = 1e-4)
model = Sequential()
model.add(Dense(128, activation="relu", kernel_regularizer=regularizers.l2(.0001),
input_shape=(X_dim,)))
#model.add(layers.Dropout(.5))
model.add(Dense(64, activation="relu", kernel_regularizer=regularizers.l2(.0001)))
#model.add(layers.Dropout(.5))
model.add(Dense(32, activation="relu",kernel_regularizer=regularizers.l2(.0001)))
#model.add(layers.Dropout(.5))
model.add(Dense(8, activation = "relu", kernel_regularizer=regularizers.l2(.0001)))
#model.add(layers.Dropout(.5))
model.add(Dense(1, activation="sigmoid", kernel_regularizer=regularizers.l2(.0001)))
#model = keras.Model(inputs, model(x))
model.compile(optimizer=optimizer,
loss="binary_crossentropy",
metrics = ['accuracy'])
model.fit(dataset)
I get this error
ValueError: Missing data for input "dense_7_input". You passed a data dictionary with keys ['', 'bid_prc1', 'bid_vol1', 'ask_prc1', 'ask_vol1', 'bid_prc2'... ] Expected the following keys: ['dense_7_input']

Using two autoencoders side by side and bulid model on top in Keras

For a chess engine I want to use two autoencoder models, which extract key-features out of a chess-position, concatenate them and build a model on top to compare two chess positions.
My code looks like this so far:
enc1 = keras.models.load_model("autoencoder.h5")
enc2 = keras.models.load_model("autoencoder.h5")
encoder1 = Model(
inputs=enc1.input,
outputs=[enc1.get_layer(index=2).output,
enc1.get_layer(index=4).output,
enc1.get_layer(index=6).output,
enc1.get_layer(index=7).output
]
)
encoder1.trainable = False
encoder2 = Model(
inputs=enc2.input,
outputs=[enc2.get_layer(index=2).output,
enc2.get_layer(index=4).output,
enc2.get_layer(index=6).output,
enc2.get_layer(index=7).output
]
)
encoder2.trainable = False
model = Sequential()
model.add(concatenate([encoder1, encoder2]))
model.add(Dense(400, activation="relu", input_shape=(2,769,)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(200, activation='relu', kernel_regularizer=l2(), bias_regularizer=l2()))
model.add(Dropout(0.2))
model.add(Dense(100, activation='relu', kernel_regularizer=l2(), bias_regularizer=l2()))
model.add(Dropout(0.2))
model.add(Dense(2, activation='softmax'))
metric = tf.keras.metrics.CategoricalAccuracy()
model.compile(optimizer=Adam(learning_rate=0.001), loss="categorical_crossentropy", metrics=metric)
This is giving errors. How do I concatenate these two autoencoder layers?
Thanks so much!

High accuracy in mode.fit but low precision and recall

I've been training a CNN with keras. A binary classificator where it says if a depth image has a manhole or not. I've manually labeled the datasets with 0 (no manhole) and 1 (it has a manhole). I have 2 datasets 1 with 45k images to train the CNN and one with 26k images to test the CNN.
Both datasets are unbalanced double of negatives images than positives.
This is the code:
# dimensions of our images.
img_width, img_height = 80, 60
n_positives_img, n_negatives_img = 17874, 26308
n_total_img = 44182
#Labeled arrays for datasets
arrayceros = np.zeros(n_negatives_img)
arrayunos = np.ones(n_positives_img)
#Reshaping of datasets to convert separate them
arraynegativos= ds_negatives.reshape(( n_negatives_img, img_height, img_width,1))
arraypositivos= ds_positives.reshape((n_positives_img, img_height, img_width,1))
#Labeling datasets with the arrays
ds_negatives_target = tf.data.Dataset.from_tensor_slices((arraynegativos, arrayceros))
ds_positives_target = tf.data.Dataset.from_tensor_slices((arraypositivos, arrayunos))
#Concatenate 2 datasets and shuffle them
ds_concatenate = ds_negatives_target.concatenate(ds_positives_target)
datasetfinal = ds_concatenate.shuffle(n_total_img)
Then I have the same for the second dataset for testing.
#Adding batch dimension to datasets 4dim
valid_ds = datasetfinal2.batch(12)
train_ds = datasetfinal.batch(12)
#Defining model
model = Sequential()
model.add(Conv2D(5, kernel_size=(5, 5),activation='relu',input_shape=(60,80,1),padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D((5, 5),padding='same'))
model.add(Dropout(0.3))
model.add(Conv2D(5, (5, 5), activation='relu',padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
model.add(Dropout(0.3))
model.add(Conv2D(5, (5, 5), activation='relu',padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
model.add(Dropout(0.3))
model.add(Conv2D(5, (5, 5), activation='relu',padding='same'))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(100, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(50, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))
#Compiling model
model.summary()
initial_learning_rate = 0.001
lr_schedule = keras.optimizers.schedules.ExponentialDecay(
initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True
)
model.compile(
loss="binary_crossentropy",
optimizer=keras.optimizers.Adam(learning_rate=lr_schedule),
metrics=["acc"],
)
# Define callbacks.
checkpoint_cb = keras.callbacks.ModelCheckpoint(
"2d_image_classification.h5", save_best_only=True
)
early_stopping_cb = keras.callbacks.EarlyStopping(monitor="val_acc", patience=15)
#Fitting the model
history= model.fit(train_ds, validation_data=valid_ds, batch_size=100, epochs=5,callbacks=[checkpoint_cb, early_stopping_cb])
This gives me 99% of acc in train dataset and 95% in test dataset.
But when i do this it gives me 60% precision for negatives images and 45% for positives:
#Get the real labels of valid dataset
valid_labels = list(valid_ds.flat_map(lambda x, y: tf.data.Dataset.from_tensor_slices((x, y))).as_numpy_iterator())
valid_labels = [y for x, y in valid_labels]
y_pred = model.predict(valid_ds)
y_pred = (y_pred > 0.5).astype(float)
from sklearn.metrics import classification_report
print(classification_report(valid_labels, y_pred))
Why this? I have printed both predicted labels and true labels and it look likes its random. It has no sense.
https://colab.research.google.com/drive/1bhrntDItqoeT0KLb-aKp0W8cV6LOQOtP?usp=sharing
If u need more information, just ask me.
Thanks!!!!

How to use Embedding layer for RNN with a categorical feature - Classification Task for RecoSys

I would like to build a model (RNN >> LSTM) with an Embedding layer for a categorical feature (Item ID), My training set looks so:
train_x = [[[184563.1], [184324.1], [187853.1], [174963.1], [181663.1]], [[…],[…],[…],[…],[…]], …]
I predict the sixth item ID:
train_y = [0,1,2, …., 12691]
I have 12692 unique item IDs, length of timesteps = 5 and this is a classification task.
This is a brief summary for what I've done so far: (Please correct me if I'm wrong)
One-hot-encoding for the categorical feature:
train_x = [[[1 0 0 … 0 0 0], [0 1 0 … 0 0 0], [0 0 1 … 0 0 0], […], […]], [[…],[…],[…],[…],[…]], …]
Build model:
model = Sequential()
model.add(Embedding(input_dim=12692 , output_dim=250, input_length=5))
model.add(LSTM(128, return_sequences=True)
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(LSTM(128, return_sequences=True))
model.add(Dropout(0.1))
model.add(BatchNormalization())
model.add(LSTM(128))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(12692, activation='softmax'))
opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
print(model.summary())
history = model.fit(
train_x, train_y,
batch_size=64,
epochs=epochs,
validation_data=(validation_x, validation_y))
score = model.evaluate(validation_x, validation_y, verbose=0)
I get this model summary:
Train on 131204 samples, validate on 107904 samples
But after that, this error appears:
ValueError: Error when checking input: expected embedding_input to have 2 dimensions, but got array with shape (131204, 5, 12692)
Where is my mistake and what would be the solution?
The embedding layer turns positive integers (indexes) into dense vectors of fixed size (Docs). So your train_x is not one-hot-encoded but the integer representing its index in the vocab. It will be the integer corresponding to the categorical feature.
train_x.shape will be (No:of sample X 5) --> Each representing the index of of the categorical feature
train_y.shape will be (No:of sample) --> Each representing the index of the sixth item in your time series.
Working sample
import numpy as np
import keras
from keras.layers import Embedding, LSTM, Dense
n_samples = 100
train_x = np.random.randint(0,12692,size=(n_samples ,5))
train_y = np.random.randint(0,12692,size=(n_samples))
model = keras.models.Sequential()
model.add(Embedding(input_dim=12692+1, output_dim=250, input_length=5))
model.add(LSTM(128, return_sequences=True))
model.add(LSTM(32))
model.add(Dense(32, activation='relu'))
model.add(Dense(12692, activation='softmax'))
opt = keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
print(model.summary())
history = model.fit(
train_x, train_y,
batch_size=64,
epochs=32)

Add hand-crafted features to Keras sequential model

I have 1D sequences which I want to use as input to a Keras VGG classification model, split in x_train and x_test. For each sequence, I also have custom features stored in feats_train and feats_test which I do not want to input to the convolutional layers, but to the first fully connected layer.
A complete sample of train or test would thus consist of a 1D sequence plus n floating point features.
What is the best way to feed the custom features first to the fully connected layer? I thought about concatenating the input sequence and the custom features, but I do not know how to make them separate inside the model. Are there any other options?
The code without the custom features:
x_train, x_test, y_train, y_test, feats_train, feats_test = load_balanced_datasets()
model = Sequential()
model.add(Conv1D(10, 5, activation='relu', input_shape=(timesteps, 1)))
model.add(Conv1D(10, 5, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.5, seed=789))
model.add(Conv1D(5, 6, activation='relu'))
model.add(Conv1D(5, 6, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.5, seed=789))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5, seed=789))
model.add(Dense(2, activation='softmax'))
model.compile(loss='logcosh', optimizer='adam', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=batch_size, epochs=20, shuffle=False, verbose=1)
y_pred = model.predict(x_test)
Sequential model is not very flexible. You should look into the functional API.
I would try something like this:
from keras.layers import (Conv1D, MaxPool1D, Dropout, Flatten, Dense,
Input, concatenate)
from keras.models import Model, Sequential
timesteps = 50
n = 5
def network():
sequence = Input(shape=(timesteps, 1), name='Sequence')
features = Input(shape=(n,), name='Features')
conv = Sequential()
conv.add(Conv1D(10, 5, activation='relu', input_shape=(timesteps, 1)))
conv.add(Conv1D(10, 5, activation='relu'))
conv.add(MaxPool1D(2))
conv.add(Dropout(0.5, seed=789))
conv.add(Conv1D(5, 6, activation='relu'))
conv.add(Conv1D(5, 6, activation='relu'))
conv.add(MaxPool1D(2))
conv.add(Dropout(0.5, seed=789))
conv.add(Flatten())
part1 = conv(sequence)
merged = concatenate([part1, features])
final = Dense(512, activation='relu')(merged)
final = Dropout(0.5, seed=789)(final)
final = Dense(2, activation='softmax')(final)
model = Model(inputs=[sequence, features], outputs=[final])
model.compile(loss='logcosh', optimizer='adam', metrics=['accuracy'])
return model
m = network()

Categories