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),...)
Related
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)
I'm trying to add add conv layers to the transfer learning code mentioned below. But not sure how to proceed. I want to add
conv, max-pooling, 3x3 filter and stride 3 and activation mode ReLU or
conv, max-pooling, 3x3 filter and stride 3 and activation mode LReLU this layer in the below mentioned transfer learning code. Let me know if it's possible and if yes how?
CLASSES = 2
# setup model
base_model = MobileNet(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dropout(0.4)(x)
predictions = Dense(CLASSES, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)
# transfer learning
for layer in base_model.layers:
layer.trainable = False
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
"""##Data augmentation"""
# data prep
"""
## Transfer learning
"""
from tensorflow.keras.callbacks import ModelCheckpoint
filepath="mobilenet/my_model.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')
callbacks_list = [checkpoint]
EPOCHS = 1
BATCH_SIZE = 32
STEPS_PER_EPOCH = 5
VALIDATION_STEPS = 32
MODEL_FILE = 'mobilenet/filename.model'
history = model.fit_generator(
train_generator,
epochs=EPOCHS,
steps_per_epoch=STEPS_PER_EPOCH,
validation_data=validation_generator,
validation_steps=VALIDATION_STEPS,
callbacks=callbacks_list)
model.save(MODEL_FILE)
backup_model = model
model.summary()
You can do it several ways, one of them is:
model = Sequential([
base_model,
GlobalAveragePooling2D(name='avg_pool'),
Dropout(0.4),
Conv(...), # the layers you would like to add for the base model
MaxPool(...),
...
])
model.compile(...)
I think this is what you are after
CLASSES=2
new_filters=256 # specify the number of filter you want in the added convolutional layer
img_shape=(224,224,3)
base_model=tf.keras.applications.mobilenet.MobileNet( include_top=False, input_shape=img_shape, weights='imagenet',dropout=.4)
x=base_model.output
x= Conv2D(new_filters, 3, padding='same', strides= (3,3), activation='relu', name='added')(x)
x= GlobalAveragePooling2D(name='avg_pool')(x)
x= Dropout(0.4)(x)
predictions= Dense(CLASSES, activation='softmax', name='output')(x)
model=Model(inputs=base_model.input, outputs=predictions)
model.summary()
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)
Make Training data
import random
import numpy as np
x_train = []
x1_train = []
y_train = []
atoms = [0,1]
p = [0.6,0.4]
for i in range(1000):
x_train.append([np.random.choice(atoms, p=p),np.random.choice(atoms, p=p)])
for i in range(1000):
x1_train.append([np.random.choice(atoms, p=p),np.random.choice(atoms, p=p)])
for i in x_train:
if 1 in i:
y_train.append([1])
else:
y_train.append([0])
Convert to numpy arrays to make them usable by keras
x_train = np.array(x_train)
x1_train = np.array(x_train)
y_train = np.array(y_train)
import tensorflow as tf
Normalize the data to make it better for the model to use
x_train = tf.keras.utils.normalize(x_train, axis = 1)
x1_train = tf.keras.utils.normalize(x_train, axis = 1)
y_train = tf.keras.utils.normalize(y_train, axis = 0)
Make model with dense layers
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128 , activation = tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation = tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation = tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation = tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation = tf.nn.relu))
model.add(tf.keras.layers.Dense(1, activation = tf.nn.sigmoid))
Compile and train model on the 3 lists
model.compile(optimizer='adam',
loss='mean_absolute_percentage_error',
metrics=['accuracy'])
model.fit(x_train, x1_train, y_train, epochs = 10)
try this
from keras.layers import Input, Dense
from keras.models import Model
import keras
inputs1 = Input(shape=(784,))
inputs2 = Input(shape=(784,))
outputs_1 = Dense(64, activation='relu')(inputs1)
outputs_2 = Dense(64, activation='relu')(inputs2)
outputs = keras.layers.Concatenate([outputs_1, outputs_2])
predictions = Dense(10, activation='softmax')(outputs)
model = Model(inputs=[inputs1,inputs2], outputs=predictions)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit([data1, data2], labels)
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