Keras prediction returns the same value everywhere.
I have some xyz data that I want to predict in a regular grid, using keras ML.
I am using something wrong and can't figure it out.
import numpy as np
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.optimizers import Adadelta, Adam
m=1e5
data=np.random.rand(m,3) # let's generate some random data (i do actually have real data that make sense)
dx=0.05
xmin=np.min(data[:,0])
xmax=np.max(data[:,0])
ymin=np.min(data[:,1])
ymax=np.max(data[:,1])
xs=np.arange(xmin,xmax+dx,dx)
ys=np.arange(ymin,ymax+dx,dx)
xg,yg=np.meshgrid(xs,ys)
shape = (len(ys), len(xs))
activation='sigmoid'
hidden_layer_sizes=[128, 64, 32, 16]
keras_model = Sequential()
keras_model.add(Dense(hidden_layer_sizes[0], activation=activation, input_shape=(2, )))
for hl_size in hidden_layer_sizes[1: ]:
keras_model.add(Dense(hl_size, activation=activation))
keras_model.add(Dense(1))
keras_model.compile(loss='mean_squared_error', optimizer=Adam())
keras_model.save_weights('cache.h5')
keras_model.summary()
keras_model.load_weights('cache.h5') # re-initialize Keras model weights
keras_history = keras_model.fit(data[:,:2], data[:,2], batch_size=m, epochs=20000, verbose=1)
X_test = np.vstack((xg.flatten(), yg.flatten())).T
res_keras=keras_model.predict(X_test).reshape(shape)
I am expecting some values "close" to an interpolation function.
Where is the mistake in my code?
change you activation from sigmoid to relu
set
activation='relu'
Related
I have a dataset of size 273985 x 5 that I'm training as a path prediction problem. I chose an LSTM inspired by this paper: https://ieeexplore.ieee.org/abstract/document/9225479
I have a baseline implementation as such:
# lstm autoencoder recreate sequence
from numpy import array
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import RepeatVector
from keras.callbacks import EarlyStopping
from keras.layers import TimeDistributed
from keras.utils import plot_model
# define input sequence
my_sequence = np.array(sample)
# reshape input into [samples, timesteps, features]
n_in = len(my_sequence)
my_sequence = my_sequence.reshape((1, n_in, 5))
# define model
model = Sequential()
model.add(LSTM(10, activation='sigmoid', input_shape=(n_in,5)))
model.add(RepeatVector(n_in))
model.add(LSTM(10, activation='sigmoid', return_sequences=True))
model.add(TimeDistributed(Dense(5)))
model.compile(optimizer='adam', loss='mse')
# fit model
model.fit(my_sequence, my_sequence, epochs=300, verbose=0)
# structure of the model and the layers
plot_model(model, show_shapes=True, to_file=path)
# demonstrate recreation
predicted = model.predict(my_sequence, verbose=0)
print(predicted)
print(my_sequence)
Right now, I am choosing my training sample by hand but I want to train my entire dataset much like bootstrapping where I train 1-50, predict the next 50; train 2-50, predict the next 50… until the end of the test set then compare my prediction against the actual values.
Would this be done via batching the data or k-fold validation? Also, how would one go about it or calculate the appropriate evaluation metric?
Thank you!
firstly im quiet new with this library. My code is simple there is input x and there is y(x*2). it should learsn simple int*2 but it cant. I think maybe paramaters are wrong but how can i determine true parameters?
from tensorflow import keras
import numpy as np
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
import keras
from keras.layers import Input, Dense
import numpy as np
import pandas as pd
xs = np.array([[1,3,4,5] , [9,2,3,4]]).reshape(1,2,4)
ys = np.array([[2,6,8,10] , [18,4,6,8]]).reshape(1,2,4)
# model = tf.keras.Sequential([layers.Dense(units=1, input_shape=[2,4])])
model = Sequential()
model.add(Dense(8,input_shape=[2,4]))
model.add(Activation('relu'))
model.add(Dense(6))
model.add(Activation('relu'))
model.add(Dense(4))
model.add(Activation('softmax'))
model.compile(optimizer='Adadelta', loss='mean_squared_error')
model.fit(xs, ys, epochs=5, batch_size=1)
p = np.array([[1,3,4,5] , [9,2,3,4]]).reshape(1,2,4)
print(model.predict(p))
My second try is more hard than *2 but i created 100 piece input and output value but still bad performance, how can i make it MORE accurate?
from tensorflow import keras
import numpy as np
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
import keras
from keras.layers import Input, Dense
import numpy as np
import pandas as pd
xs = np.array([[1,3,4,5,9,2,3,4]]).reshape(1,1,8)
xg=np.ones((100,8)).reshape(100,8)
yg=np.ones((100,8)).reshape(100,8)
for i in range(100):
xg[i-1]=xs*np.random.randint(500)
yg[i-1]=xg[i-1]*np.sin(20)
xs=xg
ys=yg
# model = tf.keras.Sequential([layers.Dense(units=1, input_shape=[2,4])])
model = Sequential()
model.add(Dense(8,input_shape=[100,8]))
model.add(Activation('relu'))
model.add(Dense(8))
model.add(Activation('relu'))
model.add(Dense(8))
# opt = keras.optimizers.sgd(learning_rate=0.2)
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(xs, ys, epochs=8000, batch_size=100)
model.summary()
p = np.array([[1,340,4,512,9,2,3,4]])
print(model.predict(p))
print(np.sin(p))
Your problem come from 2 places. First, you accidentally use softmax as output activation function, you can solve that by just comment it out (this is your root problem). Softmax function use for classification problem but your problem is regression problem there is no need for activation in the last layer. Second(after taking softmax out), it come from low number of epochs, you need to train the model for larger number of epochs for better performance.
I have a dummy np array:
model_input = np.array(range(10))
Which I am trying to put through a dummy neural network:
model = Sequential()
model.add(Dense(units = 50, input_shape = model_input.shape, activation = 'relu'))
model.add(Dense(units = 50, activation = 'relu'))
model.add(Dense(3))
model.compile(loss = 'mse', optimizer = Adam(lr = 0.01), metrics = ['accuracy'])
However, when I run
model.predict(model_input)
I receive an error:
Error when checking : expected dense_300_input to have shape (10,) but
got array with shape (1,)
This doesn't make much sense to me, as I have told the neural network that the shape of the input is equal to the shape of the array I am putting into it, and making no modifications to it before running the predict function. I feel that I am misunderstanding something fundamental here, but am not sure what it is.
My imports are:
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
Keras expects inputs to have a batch dimension. Your batch size can be 1, but input arrays still need to have a batch dimension, for instance like this:
model_input = np.array([model_input])
or one of several alternatives, such as
model_input = np.expand_dims(model_input, axis=0)
model_input = model_input[None,:]
Output
array([[0.759178 , 0.40589622, 2.0082092 ]], dtype=float32)
I have a built a LSTM architecture using Keras. My goal is to map length 29 time series input sequences of floats to length 29 output sequences of floats. I am trying to implement a "many-to-many" approach. I followed this post for implementing such a model.
I start by reshaping each data point into an np.array of shape `(1, 29, 1). I have multiple data points and train the model on each one separately. The following code is how I build my model:
def build_model():
# define model
model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(29, return_sequences=True, input_shape=(29, 1)))
model.add(tf.keras.layers.LeakyReLU(alpha=0.3))
model.compile(optimizer='sgd', loss='mse', metrics = ['mae'])
#cast data
for point in train_dict:
train_data = train_dict[point]
train_dataset = tf.data.Dataset.from_tensor_slices((
tf.cast(train_data[0], features_type),
tf.cast(train_data[1], target_type))
).repeat() #cast into X, Y
# fit model
model.fit(train_dataset, epochs=100,steps_per_epoch = 1,verbose=0)
print(model.summary())
return model
I am confused because when I call model.predict(test_point, steps = 1, verbose = 1) the model returns 29 length 29 sequences! I don't understand why this is happening, based on my understanding from the linked post. When I try return_state=True instead of return_sequences=True then my code raises this error: ValueError: All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API.
How do I solve the problem?
Your model has few flaws.
The last layer of your model is an LSTM. Assuming you're doing either classification / regression. This should be followed by a Dense layer (SoftMax/sigmoid - classification, linear - regression). But since this is a time-series problem, dense layer should be wrapped in a TimeDistributed wrapper.
It's odd to apply a LeakyReLU on top of the LSTM.
I've fixed the code with fixes for above issues. See if that helps.
from tensorflow.keras.layers import Embedding, Input, Bidirectional, LSTM, Dense, Concatenate, LeakyReLU, TimeDistributed
from tensorflow.keras.initializers import Constant
from tensorflow.keras.models import Model
from tensorflow.keras.models import Sequential
def build_model():
# define model
model = Sequential()
model.add(LSTM(29, return_sequences=True, input_shape=(29, 1)))
model.add(TimeDistributed(Dense(1)))
model.compile(optimizer='sgd', loss='mse', metrics = ['mae'])
print(model.summary())
return model
model = build_model()
I'm just trying to explore keras and tensorflow with the famous MNIST dataset.
I already applied some basic neural networks, but when it comes to tuning some hyperparameters, especially the number of layers, thanks to the sklearn wrapper GridSearchCV, I get the error below:
Parameter values for parameter (hidden_layers) need to be a sequence(but not a string) or np.ndarray.
So you can have a better view I post the main parts of my code.
Data preparation
# Extract label
X_train=train.drop(labels = ["label"],axis = 1,inplace=False)
Y_train=train['label']
del train
# Reshape to fit MLP
X_train = X_train.values.reshape(X_train.shape[0],784).astype('float32')
X_train = X_train / 255
# Label format
from keras.utils import np_utils
Y_train = keras.utils.to_categorical(Y_train, num_classes = 10)
num_classes = Y_train.shape[1]
Keras part
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV
# Function with hyperparameters to optimize
def create_model(optimizer='adam', activation = 'sigmoid', hidden_layers=2):
# Initialize the constructor
model = Sequential()
# Add an input layer
model.add(Dense(32, activation=activation, input_shape=784))
for i in range(hidden_layers):
# Add one hidden layer
model.add(Dense(16, activation=activation))
# Add an output layer
model.add(Dense(num_classes, activation='softmax'))
#compile model
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=
['accuracy'])
return model
# Model which will be the input for the GridSearchCV function
modelCV = KerasClassifier(build_fn=create_model, verbose=0)
GridSearchCV
from keras.activations import relu, sigmoid
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.layers import Dropout
from keras.utils import np_utils
activations = [sigmoid, relu]
param_grid = dict(hidden_layers=3,activation=activations, batch_size = [256], epochs=[30])
grid = GridSearchCV(estimator=modelCV, param_grid=param_grid, scoring='accuracy')
grid_result = grid.fit(X_train, Y_train)
I just want to let you know that the same kind of question has already been asked here Grid Search the number of hidden layers with keras but the answer is not complete at all and I can't add a comment to reply to the answerer.
Thank you!
You should add:
for i in range(int(hidden_layers)):
# Add one hidden layer
model.add(Dense(16, activation=activation))
Try to add the values of param_grid as lists :
params_grid={"hidden_layers": [3]}
When you are setting your parameter hidden layer =2 it goes as a string thus an error it throw.
Ideally it should a sequence to run the code that's what you error says