Keras multi-class classification process taking a long time - python
I started learning how to use Keras. I have a raw file that encodes ASCII values of characters in a sentence with a corresponding product name. For example, abcd toothpaste cream would be classified as Toothpaste. The first two lines (out of ~150,000 lines) of the code is shown below. The file is also available for download here (this link will last two months from today).
12,15,11,31,30,15,0,26,28,15,29,30,19,17,15,0,19,24,30,15,28,24,11,30,0,18,19,17,19,15,24,15,0,35,0,12,15,22,22,15,36,11,0,12,15,22,22,15,36,11,0,16,28,11,17,11,24,13,19,11,29,0,16,15,23,15,24,19,24,11,29,0,11,36,36,15,14,19,24,15,0,11,36,36,15,14,19,24,15,11,22,11,19,11,0,26,15,28,16,31,23,15,0,16,15,23,15,24,19,24,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Body Care Other
12,15,19,15,28,29,14,25,28,16,0,30,18,11,19,22,11,24,14,0,13,25,0,22,30,14,0,29,21,19,24,13,11,28,15,0,26,28,15,26,11,28,11,30,19,25,24,29,0,16,11,13,19,11,22,0,13,22,15,11,24,29,15,28,29,0,24,19,32,15,11,0,16,11,13,19,11,22,0,13,22,15,11,24,29,15,28,29,0,26,28,25,14,31,13,30,29,0,24,19,32,15,11,0,23,11,21,15,0,31,26,0,13,22,15,11,28,0,23,19,13,15,22,22,11,28,0,33,11,30,15,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Skin Care Other
I am following a blog post where it uses a simple deep learning Keras model to do multi-class classification. I changed the configuration of the neural network to 243 inputs --> [100 hidden nodes] --> 67 outputs (because I have 67 classes to classify). The code is below:
import numpy
import pandas
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder
def baseline_model():
model = Sequential()
# I changed it to 243 inputs --> [100 hidden nodes] --> 67 outputs (because I have 67 classes to classify)
model.add(Dense(100, input_dim=X_len, activation='relu'))
model.add(Dense(Y_cnt, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
seed = 7
numpy.random.seed(seed)
# load dataset
dataframe = pandas.read_csv("./input/raw_mappings.csv", header=None)
dataset = dataframe.values
X_len = len(dataset[0,:-1])
X = dataset[:,0:X_len].astype(float)
Y = dataset[:,X_len]
Y_cnt = len(numpy.unique(Y))
# 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)
dummy_y = np_utils.to_categorical(encoded_Y)
estimator = KerasClassifier(build_fn=baseline_model, epochs=200, batch_size=5, verbose=0)
kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(estimator, X, dummy_y, cv=kfold)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
But it never seems to finish when I ran it on my desktop computer for more than 12 hours. I'm starting to think there is almost nothing going on. Is there something that I'm doing wrong with either the configuration of the neural network or the problem I'm trying to solve (meaning, maybe Sequential model is not the right way to go for classifying >60 classes?).
Any pointer or tip would be greatly appreciated. Thank you.
Related
My kernel died whenever I run model.predict_classes()
I'm using macbook pro m1 and found out that I can't use tensorflow with Anaconda so I installed it step by step by the following link: https://towardsdatascience.com/installing-tensorflow-on-the-m1-mac-410bb36b776 I can import tensorflow now and tested with the code in the following link and got a problem. https://machinelearningmastery.com/neural-network-for-cancer-survival-dataset/ It runs successfully on colab but not on my macbook. Here are the codes: # fit a simple mlp model on the haberman and review learning curves from pandas import read_csv from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from sklearn.metrics import accuracy_score from tensorflow.keras import Sequential from tensorflow.keras.layers import Dense from matplotlib import pyplot # load the dataset path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv' df = read_csv(path, header=None) # split into input and output columns X, y = df.values[:, :-1], df.values[:, -1] # ensure all data are floating point values X = X.astype('float32') # encode strings to integer y = LabelEncoder().fit_transform(y) # split into train and test datasets X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, stratify=y, random_state=3) # determine the number of input features n_features = X.shape[1] # define model model = Sequential() model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,))) model.add(Dense(1, activation='sigmoid')) # compile the model model.compile(optimizer='adam', loss='binary_crossentropy') # fit the model history = model.fit(X_train, y_train, epochs=200, batch_size=16, verbose=0, validation_data=(X_test,y_test)) When I run this one: # predict test set yhat = model.predict_classes(X_test) the kernel died. I've tried to delete miniforge3 folder and do the tensorflow installation again but the problem still exists. Versions: Python 3.8.10 tensorflow 2.4.0-rc0 There are some WARNING coming up but I don't think that matters, if it may, please ask me to post it up here.
I met the same problem, when label y is a sparse number in multi-class task. After I transform label y into one-hot vector, the problem just disappears. However, I didn't met this problem in binary-class problem. Maybe do some preprocessing on labels.
Spiral problem, why does my loss increase in this neural network using Keras?
I'm trying to solve the spiral problem using Keras with 3 spirals instead of 2 using a similar strategy that I used for 2. Problem is my loss is now growing exponentially instead of decreasing with the same parameters I used for 2 spirals (The neural network structure has 3 outputs instead of being binary). I'm not quite sure what could be happening with this issue if anyone could help? I have tried this with various epochs, learning rates, batch sizes. import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.optimizers import RMSprop from Question1.utils import create_neural_network, create_test_data EPOCHS = 250 BATCH_SIZE = 20 def main(): df = three_spirals(1000) # Set-up data x_train = df[['x-coord', 'y-coord']].values y_train = df['class'].values # Don't need y_test, can inspect visually if it worked or not x_test = create_test_data() # Scale data scaler = MinMaxScaler() scaler.fit(x_train) x_train = scaler.transform(x_train) x_test = scaler.transform(x_test) relu_model = create_neural_network(layers=3, neurons=[40, 40, 40], activation='relu', optimizer=RMSprop(learning_rate=0.001), loss='categorical_crossentropy', outputs=3) # Train networks relu_model.fit(x=x_train, y=y_train, epochs=EPOCHS, verbose=1, batch_size=BATCH_SIZE) # Predictions on test data relu_predictions = relu_model.predict_classes(x_test) models = [relu_model] test_predictions = [relu_predictions] # Plot plot_data(models, test_predictions) And here is the create_neural_network function: def create_neural_network(layers, neurons, activation, optimizer, loss, outputs=1): if layers != len(neurons): raise ValueError("Number of layers doesn't much the amount of neuron layers.") model = Sequential() for i in range(layers): model.add(Dense(neurons[i], activation=activation)) # Output if outputs == 1: model.add(Dense(outputs)) else: model.add(Dense(outputs, activation='softmax')) model.compile(optimizer=optimizer, loss=loss) return model
I have worked it out, for the output data it isn't like a binary classification where you only need one column. For multi classification you need a column for each class you want to classify...so where I had y could be 0, 1, 2 was incorrect. The correct way to do this was to have y0, y1, y2 which would be 1 if it fit that specific class and 0 if it didn't.
Keras estimator predict says that input is misshapen
I'm getting a numpy shape error when I use the predict function of a Keras estimator. I build, evaluate, and then retrain the model using the following code: import pandas as pd import sqlalchemy as sqla import numpy from keras.models import Sequential from keras.layers import Dense from keras.wrappers.scikit_learn import KerasClassifier from keras.utils import np_utils from keras.utils.np_utils import to_categorical from sklearn.model_selection import cross_val_score from sklearn.model_selection import KFold from sklearn.preprocessing import LabelEncoder from sklearn.pipeline import Pipeline # Connect to to the DB and retrieve the iris table con = sqla.create_engine('postgresql://tristan:sebens#db:5432/tristan') con.connect() table_name = "iris" schema = "public" iris = pd.read_sql_table(table_name, con, schema=schema) iris.head() iris_ds = iris.values # Convert the table to a numpy array X = iris_ds[:, 0:4].astype(float) # Slice the descriptive features into a numpy array Y = iris_ds[:, 4] # Slice the labels away as their own numpy array # The labels are encoded as strings, so we need to encode them # as numbers that can be output by an ANN encoder = LabelEncoder() encoder.fit(Y) encoded_Y = encoder.transform(Y) # convert integers to dummy variables (i.e. one hot encoded) dummy_y = to_categorical(encoded_Y) # define baseline model def baseline_model(): # create model model = Sequential() model.add(Dense(8, input_dim=4, activation='relu')) model.add(Dense(3, activation='softmax')) # Compile model model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) return model seed = 7 # Train the model: # First we define the model as a classifier. This will affect the process used to train it estimator = KerasClassifier(build_fn=baseline_model, epochs=200, batch_size=5, verbose=0) # Honestly not totally sure what this is, but it has to do with splitting the training/evaluation data in # a way that gives us a more realistic metric of the model's accuracy kfold = KFold(n_splits=10, shuffle=True, random_state=seed) # Now that we have our classifier and our data pipeline defined, we can begin the training process results = cross_val_score(estimator, X, dummy_y, cv=kfold) print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100)) # If we like our accuracy, then we can train the model for real # Evaluating the model actually evaluates a clone of the model, so now we need to train the model again estimator.fit(X, dummy_y) And this is where the trouble is. I try to make a test prediction: # Let's make a test prediction with our model x = X[0] estimator.predict(x) And I get an input shape error: ValueError: Error when checking input: expected dense_21_input to have shape (4,) but got array with shape (1,) I'm at a loss. How can the input have the wrong shape if it's literally a member of the training dataset?
Multi-class classification using keras
I am developing a neural network in order to classify with classes pre-calculated with k-means. Dataset looks like: 50,12500,2,1,5 50,8500,2,1,15 50,6000,2,1,9 50,8500,2,1,15 Where resulting row is the last row. Here is the code on Python with Keras I am trying to get working: import numpy import pandas from keras.models import Sequential from keras.layers import Dense,Dropout from keras.wrappers.scikit_learn import KerasClassifier from keras.utils import np_utils from sklearn.model_selection import cross_val_score from sklearn.model_selection import KFold from sklearn.preprocessing import LabelEncoder from sklearn.pipeline import Pipeline # fix random seed for reproducibility seed = 7 numpy.random.seed(seed) # load dataset dataset = numpy.genfromtxt ('../r-calculations/k-means/output16.csv', delimiter=",") X = dataset[:,0:4].astype(float) Y = dataset[:,4] print(Y[0]) Y = np_utils.to_categorical(Y) model = Sequential() model.add(Dense(5, activation='tanh', input_dim=4)) #model.add(Dropout(0.25)) model.add(Dense(10, activation='tanh')) #model.add(Dropout(0.25)) model.add(Dense(10, activation='relu')) #model.add(Dropout(0.25)) model.add(Dense(17, activation='softmax')) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(X,Y, epochs=10, batch_size=10) #print( model.predict(numpy.array([2,36,2,5,2384,1,2,4,3,1,1,4,33,3,1,1,2,1,1,1]).reshape((1,20))) ) #print( model.predict(numpy.array(X[0]).reshape((1,4))) ) #print( model.predict(numpy.array(X[1]).reshape((1,4))) ) #print( model.predict(numpy.array(X[2]).reshape((1,4))) ) result = model.predict(numpy.array(X[0]).reshape((1,4))) for res in result[0]: print res If I get it right, now I am getting a probability for each class as an output. How can I retrieve labels back after I have called "to_categorical" on it? Is there a way to get a class number, instead of probability for each class? For now it does not seem to be working right, big loss ~2, accuracy ~0.29 and I cannot make it to converge. What am I doing wrong? UPDATE Mar 19 So far I have solved my problem, I changed my model a lot of times and finally found working configuration.
If you want the class instead of the probability you could call numpy argmax at your predictions. Or use the convenient call predict_classes instead of predict result = model.predict_classes(numpy.array(X[0]).reshape((1,4))) As for your result, you could try running a few extra epochs, but it is hard to say what is wrong. Could be your training data quality, bad initialization, not having enough data, bad model (i'd use only relu activations).
LSTM implementation in keras Using specific dataset
I am trying to understand how LSTM RNNs work and how they can be implemented in Keras in order to be able to solve a binary classification problem. My code and the dataset i use are visible below. When i compilr the code i get an error TypeError: __init__() got multiple values for keyword argument 'input_dim', Can anybody help? from keras.models import Sequential from keras.layers import LSTM from keras.layers.embeddings import Embedding from keras.layers import Dense from sklearn.cross_validation import train_test_split import numpy from sklearn.preprocessing import StandardScaler # data normalization seed = 7 numpy.random.seed(seed) dataset = numpy.loadtxt("sorted output.csv", delimiter=",") X = dataset[:,0:4] scaler = StandardScaler(copy=True, with_mean=True, with_std=True ) #data normalization X = scaler.fit_transform(X) #data normalization Y = dataset[:4] # split into 67% for train and 33% for test X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=seed) # create model model = Sequential() model.add(Embedding(12,input_dim=4,init='uniform',activation='relu')) model.add(Dense(4, init='uniform', activation='relu')) model.add(LSTM(100)) model.add(Dense(1, init='uniform', activation='sigmoid')) # Compile model model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # Fit the model model.fit(X_train, y_train, validation_data=(X_test,y_test), nb_epoch=150, batch_size=10)
Looks like two separate questions here. Regarding how to use LSTMs / Keras, there are some good tutorials around. Try this one which also describes a binary classification problem. If you have a specific issue or area that you don't understand, let me know. Regarding the file opening issue, perhaps the whitespace in the filename is causing an issue. Check out this answer to see if it helps.
This is in fact a case where the error message you are getting is perfectly to-the-point. (I wish this would always be the case with Python and Keras...) Keras' Embedding layer constructor has this signature: keras.layers.embeddings.Embedding(input_dim, output_dim, ...) However, you are constructing it using: Embedding(12,input_dim=4,...) So figure out which is the input and output dimension, respectively, and fix your parameter order and names. Based on the table you included in the question, I'm guessing 4 is your input dimension and 12 is your output dimension; then it'd be Embedding(input_dim=4, output_dim=12, ...).