Metrics and Loss function keras - python

Code -
def define_model():
# channel 1
inputs1 = Input(shape=(32,1))
conv1 = Conv1D(filters=256, kernel_size=2, activation='relu')(inputs1)
#bat1 = BatchNormalization(momentum=0.9)(conv1)
pool1 = MaxPooling1D(pool_size=2)(conv1)
flat1 = Flatten()(pool1)
# channel 2
inputs2 = Input(shape=(32,1))
conv2 = Conv1D(filters=256, kernel_size=4, activation='relu')(inputs2)
pool2 = MaxPooling1D(pool_size=2)(conv2)
flat2 = Flatten()(pool2)
# channel 3
inputs3 = Input(shape=(32,1))
conv3 = Conv1D(filters=256, kernel_size=4, activation='relu')(inputs3)
pool3 = MaxPooling1D(pool_size=2)(conv3)
flat3 = Flatten()(pool3)
# channel 4
inputs4 = Input(shape=(32,1))
conv4 = Conv1D(filters=256, kernel_size=6, activation='relu')(inputs4)
pool4 = MaxPooling1D(pool_size=2)(conv4)
flat4 = Flatten()(pool4)
# merge
merged = concatenate([flat1, flat2, flat3, flat4])
# interpretation
dense1 = Dense(128, activation='relu')(merged)
dense2 = Dense(96, activation='relu')(dense1)
outputs = Dense(10, activation='softmax')(dense2)
model = Model(inputs=[inputs1, inputs2, inputs3, inputs4 ], outputs=outputs)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[categorical_accuracy])
plot_model(model, show_shapes=True, to_file='/content/q.png')
return model
model_concat = define_model()
# fit model
print()
red_lr= ReduceLROnPlateau(monitor='val_loss',patience=2,verbose=2,factor=0.001,min_delta=0.01)
check=ModelCheckpoint(filepath=r'/content/drive/My Drive/Colab Notebooks/gen/concatcnn.hdf5', verbose=1, save_best_only = True)
History = model_concat.fit([X_train, X_train, X_train, X_train], y_train , epochs=20, verbose = 1 ,validation_data=([X_test, X_test, X_test, X_test], y_test), callbacks = [check, red_lr], batch_size = 32)
model_concat.summary
Unfortunately, I used binary crossentropy as loss and 'accuracy' as metrics. I got above 90% of val_accuracy.
Then, I found this link, Keras binary_crossentropy vs categorical_crossentropy performance?.
After reading the first answer, I used binary crossentropy as loss and categorical crossentropy as metrics...
Even though, I Changed this, the val_acc is not improving, it shows around 62%. what to do...
I minimised the model complexity to learn the data, but the accuracy is not improving. Am I miss anything...
Data set shape, x_train is (800,32) y_train is (200,32) y_train is (800,10) and y_test is (200, 10). Before fed into Network, I used standard scalar in x.and changed the x_train and, x_test shape to (800, 32, 1) and, (200, 32, 1).
Thanks

Related

Keras tuner Bayesian Optmization graph error

I am trying to optimize a convolutional neural network with Bayesian Optimization algorithm provided in keras tuner library.
When I perform the line: tuner_cnn.search(datagen.flow(X_trainRusReshaped,Y_trainRusHot), epochs=50, batch_size=256)
I encounter this error:
InvalidArgumentError: Graph execution error
One-Hot-Encode y_train and y_test as the following:
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
X_trainShape = X_train.shape[1]*X_train.shape[2]*X_train.shape[3]
X_testShape = X_test.shape[1]*X_test.shape[2]*X_test.shape[3]
X_trainFlat = X_train.reshape(X_train.shape[0], X_trainShape)
X_testFlat = X_test.reshape(X_test.shape[0], X_testShape)
# One-hot-encoding
Y_trainRusHot = to_categorical(Y_trainRus, num_classes = 2)
Y_testRusHot = to_categorical(Y_testRus, num_classes = 2)
I defined my model builder like that:
datagen = ImageDataGenerator(
featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=180,
horizontal_flip=True,vertical_flip = True)
def model_builder(hp):
model = Sequential()
#model.add(Input(shape=(50,50,3)))
for i in range(hp.Int('num_blocks', 1, 2)):
hp_padding=hp.Choice('padding_'+ str(i), values=['valid', 'same'])
hp_filters=hp.Choice('filters_'+ str(i), values=[32, 64])
model.add(Conv2D(hp_filters, (3, 3), padding=hp_padding, activation='relu', kernel_initializer='he_uniform', input_shape=(50, 50, 3)))
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(hp.Choice('dropout_'+ str(i), values=[0.0, 0.1, 0.2])))
model.add(Flatten())
hp_units = hp.Int('units', min_value=25, max_value=150, step=25)
model.add(Dense(hp_units, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(10,activation="softmax"))
hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3])
hp_optimizer=hp.Choice('Optimizer', values=['Adam', 'SGD'])
if hp_optimizer == 'Adam':
hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3])
elif hp_optimizer == 'SGD':
hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3])
nesterov=True
momentum=0.9
model.compile(loss=keras.losses.binary_crossentropy, optimizer=tf.keras.optimizers.Adam(learning_rate=hp_learning_rate), metrics=['accuracy'])
return model
perform the tuner search:
tuner_cnn = kt.tuners.BayesianOptimization(
model_builder,
objective='val_loss',
max_trials=100,
directory='.',
project_name='tuning-cnn')
tuner_cnn.search(datagen.flow(X_trainRusReshaped,Y_trainRusHot), epochs=50, batch_size=256)
I also tried to do:
tuner_cnn.search(X_trainRusReshaped, Y_trainRusHot, epochs=80, validation_data=(X_testRusReshaped, Y_testRusHot), callbacks=[stop_early])
But it does not work neither. Any idea?
From the full error message I was able to narrow down where the issue is coming from. The issue is that your last Dense layer has 10 units, which means you expect 10 classes (you even chose the correct activation function given the number of units). However you have Binary CrossEntropy as loss.
So you either have 10 classes and use either categorical or sparse categorical CrossEntropy or you have 2 classes and so the loss is indeed Binary CrossEntropy.

LSTM used for regression

Problem: I have S sequences of T timesteps each and each timestep contains F features so collectively, a dataset of
(S x T x F) and each s in S is described by 2 values (Target_1 and Target_2)
Goal: Model/Train an architecture using LSTMs in order to learn/achieve a function approximator model M and given a sequence s, to predict Target_1 and Target_2 ?
Something like this:
M(s) ~ (Target_1, Target_2)
I'm really struggling to find a way, below is a Keras implementation of an example that probably does not work. I made 2 models one for the first Target value and 1 for the second.
model1 = Sequential()
model1.add(Masking(mask_value=-10.0))
model1.add(LSTM(1, input_shape=(batch, timesteps, features), return_sequences = True))
model1.add(Flatten())
model1.add(Dense(hidden_units, activation = "relu"))
model1.add(Dense(1, activation = "linear"))
model1.compile(loss='mse', optimizer=Adam(learning_rate=0.0001))
model1.fit(x_train, y_train[:,0], validation_data=(x_test, y_test[:,0]), epochs=epochs, batch_size=batch, shuffle=False)
model2 = Sequential()
model2.add(Masking(mask_value=-10.0))
model2.add(LSTM(1, input_shape=(batch, timesteps, features), return_sequences=True))
model2.add(Flatten())
model2.add(Dense(hidden_units, activation = "relu"))
model2.add(Dense(1, activation = "linear"))
model2.compile(loss='mse', optimizer=Adam(learning_rate=0.0001))
model2.fit(x_train, y_train[:,1], validation_data=(x_test, y_test[:,1]), epochs=epochs, batch_size=batch, shuffle=False)
I want to make somehow good use of LSTMs time relevant memory in order to achieve good regression.
IIUC, you can start off with a simple (naive) approach by using two output layers:
import tensorflow as tf
timesteps, features = 20, 5
inputs = tf.keras.layers.Input((timesteps, features))
x = tf.keras.layers.Masking(mask_value=-10.0)(inputs)
x = tf.keras.layers.LSTM(32, return_sequences=False)(x)
x = tf.keras.layers.Dense(32, activation = "relu")(x)
output1 = Dense(1, activation = "linear", name='output1')(x)
output2 = Dense(1, activation = "linear", name='output2')(x)
model = tf.keras.Model(inputs, [output1, output2])
model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001))
x_train = tf.random.normal((500, timesteps, features))
y_train = tf.random.normal((500, 2))
model.fit(x_train, [y_train[:,0],y_train[:,1]] , epochs=5, batch_size=32, shuffle=False)

model.predict () return an array instead of a number/label

I am trying to used a trained model to predict model.predict(data) a new testing data for classification. However, instead of a number/label, the program returns an array. How to modify my training code to get the output correctly? Thank you. Here is my code.
def make_model(input_shape):
input_layer = keras.layers.Input(input_shape)
conv1 = keras.layers.Conv1D(filters=150, kernel_size=100, padding="same")(input_layer)
conv1 = keras.layers.BatchNormalization()(conv1)
conv1 = keras.layers.ReLU()(conv1)
conv2 = keras.layers.Conv1D(filters=150, kernel_size=100, padding="same")(conv1)
conv2 = keras.layers.BatchNormalization()(conv2)
conv2 = keras.layers.ReLU()(conv2)
conv3 = keras.layers.Conv1D(filters=150, kernel_size=100, padding="same")(conv2)
conv3 = keras.layers.BatchNormalization()(conv3)
conv3 = keras.layers.ReLU()(conv3)
gap = keras.layers.GlobalAveragePooling1D()(conv3)
output_layer = keras.layers.Dense(num_classes, activation="softmax")(gap)
return keras.models.Model(inputs=input_layer, outputs=output_layer)
model = make_model(input_shape=x_train.shape[1:])
keras.utils.plot_model(model, show_shapes=True)
epochs = 400
batch_size = 16
callbacks = [
keras.callbacks.ModelCheckpoint(
"best_model.h5", save_best_only=True, monitor="val_loss"
),
keras.callbacks.ReduceLROnPlateau(
monitor="val_loss", factor=0.5, patience=20, min_lr=0.0001
),
keras.callbacks.EarlyStopping(monitor="val_loss", patience=50, verbose=1),
]
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["sparse_categorical_accuracy"],
)
history = model.fit(
x_train,
y_train,
batch_size=batch_size,
epochs=epochs,
callbacks=callbacks,
validation_split=0.2,
verbose=1,
)
Your model is performing as expected. Your last layer is calculated using softmax, and produces an array with probabilities of how "sure" it is of being each label.
If you want to get the actual predicted label, you can use argmax, along with the correct dimension, which returns the index(=label) that had the maximum probability. In any typical fit function, you can normally see that the accuracy is being calculated using argmax on the output of the model.

ValueError: Tensorflow2 wrong output dimensions

Im working with the Iris dataset using tensorflow2
after fitting my model I get this error message
ValueError: A target array with shape (135, 4, 8) was passed for an output of shape (None, 3) while using as loss `categorical_crossentropy`. This loss expects targets to have the same shape as the output.
I'm importing / splitting / one hot encoding the model with:
iris_data = datasets.load_iris()
def read_in_and_split_data(iris_data):
return model_selection.train_test_split(iris_data["data"], iris_data["data"], test_size=0.1)
train_data, test_data, train_targets, test_targets = read_in_and_split_data(iris_data)
train_data shape is (135, 4)
train_target shape is (135, 4)
train_targets = tf.keras.utils.to_categorical(np.array(train_targets))
test_targets = tf.keras.utils.to_categorical(np.array(test_targets))
loss = "categorical_crossentropy"
def get_model(input_shape):
model = Sequential([
Dense(64, activation = "relu", kernel_initializer='he_uniform', bias_initializer='ones', input_shape=input_shape),
Dense(128, activation = "relu"),
Dense(128, activation = "relu"),
Dense(128, activation = "relu"),
Dense(128, activation = "relu"),
Dense(64, activation = "relu"),
Dense(64, activation = "relu"),
Dense(64, activation = "relu"),
Dense(64, activation = "relu"),
Dense(3, activation = "softmax"),
])
return model
model = get_model(train_data[0].shape)
def train_model(model, train_data, train_targets, epochs):
return model.fit(train_data, train_targets, epochs)
history = train_model(model, train_data, train_targets, epochs=800)
thanks for the help!
solved it
in def read_in_and_split_data(iris_data): i was reading loading "data" two times instead of loading "data" and then "targets"
below is the correct code:
def read_in_and_split_data(iris_data):
return model_selection.train_test_split(iris_data["data"], iris_data["target"], test_size=0.1)

Keras model LSTM predict 2 features

I am trying to predict 2 features. This is how my model looks like:
Defining the model
def my_model():
input_x = Input(batch_shape=(batch_size, look_back, x_train.shape[2]), name='input')
drop = Dropout(0.5)
lstm_1 = LSTM(100, return_sequences=True, batch_input_shape=(batch_size, look_back, x_train.shape[2]), name='3dLSTM', stateful=True)(input_x)
lstm_1_drop = drop(lstm_1)
lstm_2 = LSTM(100, batch_input_shape=(batch_size, look_back, x_train.shape[2]), name='2dLSTM', stateful=True)(lstm_1_drop)
lstm_2_drop = drop(lstm_2)
y1 = Dense(1, activation='relu', name='op1')(lstm_2_drop)
y2 = Dense(1, activation='relu', name='op2')(lstm_2_drop)
model = Model(inputs=input_x, outputs=[y1,y2])
optimizer = Adam(lr=0.001, decay=0.00001)
model.compile(loss='mse', optimizer=optimizer,metrics=['mse'])
model.summary()
return model
model = my_model()
for j in range(50):
start = time.time()
history = model.fit(x_train, [y_11_train,y_22_train], epochs=1, batch_size=batch_size, verbose=0, shuffle=False)
model.reset_states()
print("Epoch",j, time.time()-start,"s")
p = model.predict(x_test, batch_size=batch_size)
My data set has 9 features:
x_train (31251, 6, 9)
y_11_train (31251,)
y_22_train (31251,)
x_test (13399, 6, 9)
y_11_test (13399,)
y_22_test (13399,)
I am trying to predict the first(y_11) and second(y_22) feature of my dataset. But I am getting prediction for only first feature not the second one.
Any help on how can I get both the predictions instead of one?
First of all you should remove multiple inputs of the same thing:
(batch_size, look_back, x_train.shape[2])
Also, try to concatenate your ouputs inside your model like this:
def my_model():
from keras.layers import concatenate
lstm_1 = LSTM(100, return_sequences=True, batch_input_shape=(batch_size, look_back, x_train.shape[2]), name='3dLSTM', stateful=True)
lstm_1_drop = drop(lstm_1)
lstm_2 = LSTM(100, name='2dLSTM', stateful=True)(lstm_1_drop)
lstm_2_drop = drop(lstm_2)
y1 = Dense(1, activation='linear', name='op1')(lstm_2_drop)
y2 = Dense(1, activation='linear', name='op2')(lstm_2_drop)
y= concatenate([y1,y2])
model = Model(inputs=input_x, outputs=y)
optimizer = Adam(lr=0.001, decay=0.00001)
model.compile(loss='mse', optimizer=optimizer,metrics=['mse'])
model.summary()
return model
EDIT
I think you should fit like this:
y_11_train = y_11_train.reshape(y_11_train.shape[0],1)
y_22_train = y_22_train.reshape(y_22_train.shape[0],1)
model = my_model()
model.fit(x_train,np.concatenate((y_11_train,y_22_train),axis=1),...)

Categories