I originally tried the same approach and ran into the same error as this SO questioner. However, using the accepted (and only) answer there gave me another error: "input_dim is not a legal parameter."
I then tried to use the solution ("add an input_dim keyarg to the KerasClassifier constructor") on the original question, and got the same error again. Am I doing something wrong, or is there a new way to pass a first layer's input_dim through the sklearn wrapper KerasClassifier now?
Minimal code example below:
from keras.models import Sequential
from keras.layers import Dense
from sklearn import datasets
from keras.wrappers.scikit_learn import KerasClassifier
import numpy as np
def create_model():
# create model
model = Sequential()
model.add(Dense(12, input_dim=4, init='uniform', activation='relu'))
model.add(Dense(6, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
#Error thrown here:
model = KerasClassifier(build_fn=create_model, input_dim=5, nb_epoch=150, batch_size=10, verbose=0)
ValueError: input_dim is not a legal parameter
You need to pass the input_dim as one of the parameters to create_model()
def create_model(input_dim):
# create model
model = Sequential()
# model.add(Dense(12, input_dim=4, init='uniform', activation='relu'))
model.add(Dense(12, input_dim=input_dim, init='uniform', activation='relu'))
Though you need not use input_dim inside create_model for the sake of just removing the error.
Related
modell = Sequential()
modell.add(Dense(128, input_dim=5, activation='relu'))
modell.add(Dense(64, activation='relu'))
modell.add(Dense(64, activation='relu'))
modell.add(Dense(64, activation='relu'))
modell.add(Dense(64, activation='relu'))
#Output layer
modell.add(Dense(1, activation='linear'))
modell.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error'])
modell.summary()
modell.fit(X_train_scaled, y_train, validation_split=0.2,batch_size=5, epochs =250)
pickle.dump(modell,open('model.pkl','wb'))
model=pickle.load(open('model.pkl','rb'))
Using ann regression for final score prediction but getting the error:
TypeError: can't pickle weakref objects
Pickle cannot handle Keras model objects.
Try using Keras' save/ load instead ?
model.save('path/to/location')
model = keras.models.load_model('path/to/location')
I saved an MLP regression type algorithm with this type of code:
#define model
model = Sequential()
model.add(Dense(80, input_dim=2, kernel_initializer='normal', activation='relu'))
model.add(Dense(60, kernel_initializer='normal', activation='relu'))
model.add(Dense(40, kernel_initializer='normal', activation='relu'))
model.add(Dense(20, kernel_initializer='normal', activation='relu'))
model.add(Dense(10, kernel_initializer='normal', activation='relu'))
model.add(Dense(5, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.summary()
model.compile(loss='mse', optimizer='adam', metrics=[rmse])
# train model, test callback option
history = model.fit(X_train, Y_train, epochs=75, batch_size=1, verbose=2, callbacks=[callback])
#history = model.fit(X_train, Y_train, epochs=60, batch_size=1, verbose=2)
# plot metrics
plt.plot(history.history['rmse'])
plt.title('kW RSME Vs Epoch')
plt.show()
model.save('./saved_model/kwSummer')
But when I try to load the saved model:
model = tf.keras.models.load_model('./saved_model/kwSummer')
# Check its architecture
new_model.summary()
I get this error below when trying to load the model.. Would anyone have any ideas to try?
ValueError: Unable to restore custom object of type _tf_keras_metric currently. Please make sure that the layer implements `get_config`and `from_config` when saving. In addition, please use the `custom_objects` arg when calling `load_model()`.
I have been experimenting with using Python 3.7 to train the model and then IPython Anaconda Python 3.8 to load the model, would this have anything to do with the issue? Like 2 different versions of tensorflow?
EDIT,
This is the entire script
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras import backend
from datetime import datetime
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import seaborn as sns
import math
df = pd.read_csv('./colabData.csv', index_col='Date', parse_dates=True)
print(df.info())
# This function keeps the learning rate at 0.001
# and decreases it exponentially after that.
def scheduler(epoch):
if epoch < 1:
return 0.001
else:
return 0.001 * tf.math.exp(0.01 * (1 - epoch))
callback = tf.keras.callbacks.LearningRateScheduler(scheduler)
#function to calculate RSME
def rmse(y_true, y_pred):
return backend.sqrt(backend.mean(backend.square(y_pred - y_true), axis=-1))
dfTrain = df.copy()
# split into input (X) and output (Y) variables
X = dfTrain.drop(['kW'],1)
Y = dfTrain['kW']
#define training & testing data set
offset = int(X.shape[0] * 0.8)
X_train, Y_train = X[:offset], Y[:offset]
X_test, Y_test = X[offset:], Y[offset:]
#define model
model = Sequential()
model.add(Dense(80, input_dim=2, kernel_initializer='normal', activation='relu'))
model.add(Dense(60, kernel_initializer='normal', activation='relu'))
model.add(Dense(40, kernel_initializer='normal', activation='relu'))
model.add(Dense(20, kernel_initializer='normal', activation='relu'))
model.add(Dense(10, kernel_initializer='normal', activation='relu'))
model.add(Dense(5, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.summary()
model.compile(loss='mse', optimizer='adam', metrics=[rmse])
# train model, test callback option
history = model.fit(X_train, Y_train, epochs=75, batch_size=1, verbose=2, callbacks=[callback])
#history = model.fit(X_train, Y_train, epochs=60, batch_size=1, verbose=2)
# plot metrics
plt.plot(history.history['rmse'])
plt.title('kW RSME Vs Epoch')
plt.show()
model.save('./saved_model/kwSummer')
print('[INFO] Saved model to drive')
As you have a custom object, you have to load it with the custom_object argument. It also informed you in the error log. Src.
In addition, please use the `custom_objects` arg when calling `load_model()`.
Try as follows
new_model = tf.keras.models.load_model('./saved_model/kwSummer', ,
custom_objects={"rmse": rmse})
might I suggest running the code through google colab? this might help to see if the issue with the code or a compatibility issue. As google colab will ensure compatibility as it fixed a lot of the ML issues I had.
I am using tensorflow and keras to build a simple MNIST classification model, and I want to fine tune my model, so I choose sklearn.model_selection.GridSearchCV.
However, when I call the fit function, it said:
AttributeError: 'Sequential' object has no attribute 'loss'
I compared my code to others', but still can't figure out why. The only difference is that I use tensorflow.keras instead of keras.
Here is my code:
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Input, Dense, Activation, Dropout, BatchNormalization
from tensorflow.keras.datasets import mnist
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV
...
...
...
def get_model(dropout_rate=0.2, hidden_units=512):
model = Sequential()
model.add(Dropout(dropout_rate, input_shape=(28*28,)))
model.add(Dense(hidden_units, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(dropout_rate))
model.add(Dense(hidden_units, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(dropout_rate))
model.add(Dense(hidden_units, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(dropout_rate))
model.add(Dense(10, activation='softmax'))
return model
model = KerasClassifier(build_fn=get_model, batch_size=128, epochs=10)
para_dict = {'dropout_rate':[0.2,0.5,0.8], 'hidden_units':[128,256,512,1024]}
clf = GridSearchCV(model, para_dict, cv=5, scoring='accuracy')
clf.fit(x_train, y_train)
Thank you!
The build_model function above doesn't configure your model for training. You have added loss and other parameters.
You can compile the model by using keras sequential method compile. https://keras.io/models/sequential/
So your build_model function should be:
loss = 'binary_crossentropy' #https://keras.io/optimizers
optimizer = 'adam' #https://keras.io/losses
metrics = ['accuracy']
def get_model(dropout_rate=0.2, hidden_units=512):
model = Sequential()
model.add(Dropout(dropout_rate, input_shape=(28*28,)))
model.add(Dense(hidden_units, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(dropout_rate))
model.add(Dense(hidden_units, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(dropout_rate))
model.add(Dense(hidden_units, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(dropout_rate))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer = optimizer, loss = loss, metrics = metrics)
return model
This should be very simple Keras program. It works until the last line of code. But I have called the predict method. Granted I used the same input data as the training data, but that should not matter.
from keras.models import Sequential
import pandas as pd
url = 'https://raw.githubusercontent.com/werowe/logisticRegressionBestModel/master/KidCreative.csv'
data = pd.read_csv(url, delimiter=',')
labels=data['Buy']
features = data.iloc[:,2:16]
model = Sequential()
model.compile(optimizer='rmsprop' ,loss='binary_crossentropy',metrics=['accuracy'])
model.fit(data, labels, epochs=10, batch_size=32)
model.evaluate(labels, features, batch_size=128)
model.predict(labels)
model.summary()
But I get this error:
model.summary()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/walker/tf3/lib/python3.4/site-packages/keras/engine/network.py", line 1263, in summary
'This model has never been called, this its weights '
ValueError: This model has never been called, this its weights have not yet been created, so no summary can be displayed. Build the model first (e.g. by calling it on some test data).
The first step should be to actually build a model, which you don't do; i.e. after model = Sequential(), there should be some model.add statements, in order to build the model, before compiling it, fitting it, and use it for evaluation or getting its summary.
Instead of getting guidance from some repo of ambiguous quality, it's better to start from the official examples & tutorials - look for example at the Keras MNIST CNN example; replicating here only the model-related parts, we get:
model = Sequential()
# no model built, as in your case
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
This should already give an error:
TypeError: Sequential model cannot be built: model is empty. Add some layers first.
which I am surprised you don't report in your case.
Here is what we should do instead (again, refer to the link for the full details):
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
model.summary()
# works OK
As #desertnaut said, it is necessary to have layers in a model before calling mode.summary().
Edit: I want to add that, Even if your model has layers model.summary() may not work if it doesn't have "input_shape" in the first layer.
Because in Sequential model dimensions of input of each layer (thus the number of parameters) are calculated using output dimension of the preceding layer but to start this chain input dimension for the first layer is needed. So it is not possible to generate a summary of the model without the input dimension.
Note: If you don't explicitly specify input dimension than keras will figure it out when you call fit() for the first time. So if you don't specify input_shape, then you need to call model.fit() before the model.summary()
Thanks Matias Valdenegro, I added some input layers and changed the loss function. Now this works:
import tensorflow as tf
from keras.models import Sequential
import pandas as pd
from keras.layers import Dense
url = 'https://raw.githubusercontent.com/werowe/logisticRegressionBestModel/master/KidCreative.csv'
data = pd.read_csv(url, delimiter=',')
labels=data['Buy']
features = data.iloc[:,2:16]
model = Sequential()
model.add(Dense(units=64, activation='relu', input_dim=1))
model.add(Dense(units=14, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='sgd',
metrics=['accuracy'])
model.fit(labels, features,
batch_size=12,
epochs=10,
verbose=1,
validation_data=(labels, features))
model.evaluate(labels, features, verbose=0)
model.summary()
I have created with keras a neural network for predicting addition.
I have 2 inputs and 1 output (result of adding the 2 inputs).
I trained my neural network with tensorflow and then I tried to predict addition but the program returns 0 or 1 value not 3,4,5,etc.
This is my code :
from keras.models import Sequential
from keras.layers import Dense
import numpy
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load dataset
dataset = numpy.loadtxt("data.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:2]
Y = dataset[:,2]
# create model
model = Sequential()
model.add(Dense(12, input_dim=2, init='uniform', activation='relu'))
model.add(Dense(2, init='uniform', activation='relu'))
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, Y, epochs=150, batch_size=10, verbose=2)
# calculate predictions
predictions = model.predict(X)
# round predictions
rounded = [round(x[0]) for x in predictions]
print(rounded)
And my file data.csv:
1,2,3
3,3,6
4,5,9
10,8,18
1,3,4
5,3,8
For example:
1+2=3
3+3=6
4+5=9
...etc.
But I get this as output : 0,1,0,0,1,0,1...
Why didn't I get the output as 3,6,9...?
i updated code for use other loss function but i have same error :
from keras.models import Sequential
from keras.layers import Dense
import numpy
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load pima indians dataset
dataset = numpy.loadtxt("data.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:2]
Y = dataset[:,2]
# create model
model = Sequential()
model.add(Dense(12, input_dim=2, init='uniform', activation='relu'))
model.add(Dense(2, init='uniform', activation='relu'))
#model.add(Dense(1, init='uniform', activation='sigmoid'))
model.add(Dense(1, input_dim=2, init='uniform', activation='linear'))
# Compile model
#model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10, verbose=2)
# calculate predictions
predictions = model.predict(X)
# round predictions
rounded = [round(x[0]) for x in predictions]
print(rounded)
outout=1,1,1,3,1,1,...etc
As #ebeneditos mentioned, you need to change your activation function in the last layer to something other than sigmoid. You can try changing it to linear.
model.add(Dense(1, init='uniform', activation='linear'))
You should also change your loss function to something like mean squared error, as your problem is more of a regression problem than a classification problem (binary_crossentropy is used as a loss function for binary classification problems)
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
This is due to the Sigmoid function you have in the last layer. As it is defined:
It can only take values from 0 to 1. You should change last layer's activation function.
You can try this instead (with Dense(8) instead of Dense(2)):
# Create model
model = Sequential()
model.add(Dense(12, input_dim=2, init='uniform', activation='relu'))
model.add(Dense(8, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='linear'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10, verbose=2)