I'm working with Google Colab and trying to train a model using VGG blocks. Like this:
METRICS = [
keras.metrics.TruePositives(name='tp'),
keras.metrics.FalsePositives(name='fp'),
keras.metrics.TrueNegatives(name='tn'),
keras.metrics.FalseNegatives(name='fn'),
keras.metrics.BinaryAccuracy(name='accuracy'),
keras.metrics.Precision(name='precision'),
keras.metrics.Recall(name='recall'),
keras.metrics.AUC(name='auc'),
]
# function for creating a vgg block
def vgg_block(layer_in, n_filters, n_conv):
# add convolutional layers
for _ in range(n_conv):
layer_in = Conv2D(n_filters, (3,3), padding='same', activation='relu')(layer_in)
# add max pooling layer
layer_in = MaxPooling2D((2,2), strides=(2,2))(layer_in)
return layer_in
# define model input
visible = Input(shape=(256, 256, 3))
# add vgg module
layer = vgg_block(visible, 64, 2)
#####################################
flat = Flatten()(layer)
hidden1 = Dense(128, activation='relu')(flat)
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
print(model.summary())
# plot model architecture
plot_model(model, show_shapes=True, to_file='vgg_block.png')
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=METRICS)
# New lines to obtain the best model in term of validation accuracy
from keras.callbacks import ModelCheckpoint
filepath="weights-improvement-{epoch:02d}-{val_accuracy:.2f}.h5"
checkpoint = ModelCheckpoint(filepath, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')
callbacks_list = [checkpoint]
But, when I try to use model.fit_generator it gives me an error. The code I'm using is:
history = model.fit_generator(
train_generator,
steps_per_epoch=2000 // batch_size,
epochs=20,
validation_data=validation_generator,
validation_steps=800 // batch_size,
callbacks=callbacks_list
)
I have tried everything and I don't know what to do. It gives me the following error:
NotFoundError: 2 root error(s) found.
(0) Not found: Resource localhost/total/N10tensorflow3VarE does not exist.
[[{{node metrics/accuracy/AssignAddVariableOp}}]]
[[metrics/precision/Mean/_87]]
(1) Not found: Resource localhost/total/N10tensorflow3VarE does not exist.
[[{{node metrics/accuracy/AssignAddVariableOp}}]]
0 successful operations.
0 derived errors ignored.
I would appreciate any help. I'm kind of new here. What could I do? Thanks!
It seems the problem arises only using the native keras but when I tried to implement your code and modified it in Tensorflow 2.x as below:
%tensorflow_version 2.x
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dense, Flatten
from tensorflow.keras.models import Model
METRICS = [
keras.metrics.TruePositives(name='tp'),
keras.metrics.FalsePositives(name='fp'),
keras.metrics.TrueNegatives(name='tn'),
keras.metrics.FalseNegatives(name='fn'),
keras.metrics.BinaryAccuracy(name='accuracy'),
keras.metrics.Precision(name='precision'),
keras.metrics.Recall(name='recall'),
keras.metrics.AUC(name='auc'),
]
# function for creating a vgg block
def vgg_block(layer_in, n_filters, n_conv):
# add convolutional layers
for _ in range(n_conv):
layer_in = Conv2D(n_filters, (3,3), padding='same', activation='relu')(layer_in)
# add max pooling layer
layer_in = MaxPooling2D((2,2), strides=(2,2))(layer_in)
return layer_in
# define model input
visible = Input(shape=(256, 256, 3))
# add vgg module
layer = vgg_block(visible, 64, 2)
#####################################
flat = Flatten()(layer)
hidden1 = Dense(128, activation='relu')(flat)
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
print(model.summary())
# # plot model architecture
# plot_model(model, show_shapes=True, to_file='vgg_block.png')
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=METRICS)
# New lines to obtain the best model in term of validation accuracy
from tensorflow.keras.callbacks import ModelCheckpoint
filepath="weights-improvement-{epoch:02d}-{val_accuracy:.2f}.h5"
checkpoint = ModelCheckpoint(filepath, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')
callbacks_list = [checkpoint]
## Synthetic Inputs
train_input = tf.random.normal((100, 256, 256, 3))
train_output = tf.random.normal((100, 1))
# Test Model.fit same as Model.fit_generator in TF 2.1.0
model.fit(train_input, train_output, epochs = 1)
The problem didn't show up and it is working properly.
You can try this in TF 2.x instead. I hope this solved your problem.
The problem is with the Keras version. Try with Keras 2.3.0 and above versions where they introduce new class-based metrics.
Keras documentation
Related
I am trying to implement a classification model with ResNet50. I know, CNN or transfer learning models extract the features themselves. How can I get the extracted feature vector from the image dataset in python?
Code Snippet of model training:
base_model = ResNet152V2(
input_shape = (height, width, 3),
include_top=False,
weights='imagenet'
)
from tensorflow.keras.layers import MaxPool2D, BatchNormalization, GlobalAveragePooling2D
top_model = base_model.output
top_model = GlobalAveragePooling2D()(top_model)
top_model = Dense(1072, activation='relu')(top_model)
top_model = Dropout(0.6)(top_model)
top_model = Dense(256, activation='relu')(top_model)
top_model = Dropout(0.6)(top_model)
prediction = Dense(len(categories), activation='softmax')(top_model)
model = Model(inputs=base_model.input, outputs=prediction)
for layer in model.layers:
layer_trainable=False
from tensorflow.keras.optimizers import Adam
model.compile(
optimizer = Adam(learning_rate=0.00001),
loss='categorical_crossentropy',
metrics=['accuracy']
)
import keras
from keras.callbacks import EarlyStopping
es_callback = keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)
datagen = ImageDataGenerator(rotation_range= 30,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.3,
horizontal_flip=True
)
resnet152v2 = model.fit(datagen.flow(X_train, y_train),
validation_data = (X_val, y_val),
epochs = 100,
callbacks=[es_callback]
)
I followed a solution from here.
Code snippet of extracting features from the trained model:
extract = Model(model.inputs, model.layers[-3].output) #top_model = Dropout(0.6)(top_model)
features = extract.predict(X_test)
The shape of X_test is (120, 224, 224, 3)
Once you have trained your model, you can save it (or just directly use it in the same file) then cut off the top layer.
model = load_model("xxx.h5") #Or use model directly
#Use functional model
from tensorflow.keras.models import Model
featuresModel = Model(inputs=model.input,outputs=model.layers[-3].output) #Get rids of dropout too
#Inference directly
featureVector = featuresModel.predict(yourBatchData, batch_size=yourBatchLength)
If inferenced in batches, you would need to separate the output results to see the result for each input in the batch.
I'm new with Keras and I'm trying to build a model for personal use/future learning. I've just started with python and I came up with this code (with help of videos and tutorials). I have a data of 16324 instances, each instance consists of 18 features and 1 dependent variable.
import pandas as pd
import os
import time
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, LSTM, BatchNormalization
from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint
EPOCHS = 10
BATCH_SIZE = 64
NAME = f"-TEST-{int(time.time())}"
df = pd.read_csv("EntryData.csv", names=['1SH5', '1SHA', '1SA5', '1SAA', '1WH5', '1WHA', '2SA5', '2SAA', '2SH5', '2SHA', '2WA5', '2WAA', '3R1', '3R2', '3R3', '3R4', '3R5', '3R6', 'Target'])
df_val = 14554
validation_df = df[df.index > df_val]
df = df[df.index <= df_val]
train_x = df.drop(columns=['Target'])
train_y = df[['Target']]
validation_x = validation_df.drop(columns=['Target'])
validation_y = validation_df[['Target']]
model = Sequential()
model.add(LSTM(128, input_shape=(train_x.shape[1:]), return_sequences=True))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(LSTM(128, return_sequences=True))
model.add(Dropout(0.1))
model.add(BatchNormalization())
model.add(LSTM(128))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(2, activation='softmax'))
opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(loss='sparse_categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
tensorboard = TensorBoard(log_dir=f'logs/{NAME}')
filepath = "RNN_Final-{epoch:02d}-{val_acc:.3f}"
checkpoint = ModelCheckpoint("models/{}.model".format(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')) # saves only the best ones
history = model.fit(
train_x, train_y,
batch_size=BATCH_SIZE,
epochs=EPOCHS,
validation_data=(validation_x, validation_y),
callbacks=[tensorboard, checkpoint],)
score = model.evaluate(validation_x, validation_y, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
model.save("models/{}".format(NAME))
In line
model.add(LSTM(128, input_shape=(train_x.shape[1:]), return_sequences=True))
is throwing an error:
ValueError: Input 0 of layer lstm is incompatible with the layer:
expected ndim=3, found ndim=2. Full shape received: [None, 18]
I was searching for solution on this site and on google for few hours now and I was not able to find proper answer for this or I was not able to implement the solution for similar problem.
Thank you for any tips.
An LSTM network expects three dimensional input of this format:
(n_samples, time_steps, features)
There are two main ways this can be a problem.
Your input is 2D
You have stacked (multiple) LSTM layers
1. Your input is 2D
You need to turn your input to 3D.
x = x.reshape(len(x), 1, x.shape[1])
# or
x = np.expand_dims(x, 1)
Then, specify the right input shape in the first layer:
LSTM(64, input_shape=(x.shape[1:]))
2. You have stacked LSTM layers
By default, LSTM layers will not return sequences, i.e., they will return 2D output. This means that the second LSTM layer will not have the 3D input it needs. To address this, you need to set the return_sequences=True:
tf.keras.layers.LSTM(8, return_sequences=True),
tf.keras.layers.LSTM(8)
Here's how to reproduce and solve the 2D input problem:
import tensorflow as tf
import numpy as np
x = np.random.rand(100, 10)
# x = np.expand_dims(x, 1) # uncomment to solve the problem
y = np.random.randint(0, 2, 100)
model = tf.keras.Sequential([
tf.keras.layers.LSTM(8),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
history = model.fit(x, y, validation_split=0.1)
Here's how to reproduce and solve the stacked LSTM layers problem:
import tensorflow as tf
import numpy as np
x = np.random.rand(100, 1, 10)
y = np.random.randint(0, 2, 100)
model = tf.keras.Sequential([
tf.keras.layers.LSTM(8), # use return_sequences=True to solve the problem
tf.keras.layers.LSTM(8),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
history = model.fit(x, y, validation_split=0.1)
I am trying to implement a GAN with Keras (Tensorflow backend) to colorize an image. My generator has a gray-scale input image whereas my discriminator has both the gray-scale and the colored image as inputs.
How can I train my generator without having the error
"InvalidArgumentError: You must feed a value for placeholder tensor
'input_2' with dtype float and shape [?,128,128,1] [[{{node
input_2}}]] [[{{node metrics/acc/Mean_2}}]]"
I have tried different ways to create the combined model (used to train the generator) without success. I am using Python 3.6.7 and Keras 2.2.4.
import numpy as np
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, AveragePooling2D, Dense, Dropout, Flatten, Lambda, MaxPool2D, Conv2DTranspose, UpSampling2D, Concatenate, Add
from tensorflow.keras import optimizers
from keras.preprocessing import image
def combine_generator(gen1, gen2):
while True:
yield(gen1.next(), gen2.next())
def generator_model(input_img):
outputs = Conv2D(3, (1, 1), activation='sigmoid') (input_img)
model = Model(inputs=[input_img], outputs=[outputs])
return model
def discriminator_model(output_img, input_img):
a1 = Concatenate()([output_img, input_img])
f1 = Flatten()(a1)
output = Dense(1, activation='sigmoid')(f1)
model = Model(inputs=[output_img, input_img], outputs=[output])
return model
def generator_containing_discriminator(input_img, generator, discriminator):
goutput = generator(input_img)
discriminator.trainable=False
doutput = discriminator([goutput, input_img])
model = Model(inputs=[input_img], outputs=[doutput])
return model
seed = 123456
input_size = 128
batch_size = 8
learning_rate = 1e-3
optimizer = optimizers.Adam(lr=learning_rate)
dir_train_img = "flowers_train"
data_gen = dict(rescale=1./255)
image_datagen = image.ImageDataGenerator(**data_gen)
color_generator_train = image_datagen.flow_from_directory(dir_train_img, batch_size=batch_size, class_mode=None, target_size=(input_size, input_size), color_mode="rgb", seed=seed)
gray_generator_train = image_datagen.flow_from_directory(dir_train_img, batch_size=batch_size, class_mode=None, target_size=(input_size, input_size), color_mode="grayscale", seed=seed)
train_generator = combine_generator(color_generator_train, gray_generator_train)
dmodel = discriminator_model(Input((input_size, input_size, 3)), Input((input_size, input_size, 1)))
dmodel.compile(optimizer=optimizer, loss="binary_crossentropy", metrics=["accuracy"])
dmodel.summary()
gmodel = generator_model(Input((input_size, input_size, 1)))
gmodel.summary()
gdmodel = generator_containing_discriminator(Input((input_size, input_size, 1)), gmodel, dmodel)
gdmodel.compile(optimizer=optimizer, loss="binary_crossentropy", metrics=["accuracy"])
gdmodel.summary()
dmodel.trainable=False
train_batch = next(train_generator)
labels2 = np.array([1]*len(train_batch[1]))
gdmodel.train_on_batch(train_batch[1], labels2)
As shown in the summary, the input_2 corresponds to the gray-scale input image of the discriminator, but I don't know where the problem comes from.
The problem disappears when I remove the parameter metrics=["accuracy"] from the line:
gdmodel.compile(optimizer=optimizer, loss="binary_crossentropy", metrics=["accuracy"])
I don't know why though.
I am trying to build an LSTM encoder decoder where my main goal is that the inital state of the decoder is the same as the encoder. I found the code below from here and tried to attach it to my case. I have a data with shape (1000,20,1). I want that the encoder decoder gives me in the output my input back. I do not know how to correct the code that it is working, even I understand the error. When I try to run this, I get the following error:
The model expects 2 input arrays, but only received one array. Found:
array with shape (10000, 20, 1)
from keras.models import Model
from keras.layers import Input
from keras.layers import LSTM
from keras.layers import Dense
from keras.models import Sequential
latent_dim = 128
encoder_inputs = Input(shape=(20,1))
encoder = LSTM(latent_dim, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
# We discard `encoder_outputs` and only keep the states.
encoder_states = [state_h, state_c]
# Set up the decoder, using `encoder_states` as initial state.
decoder_inputs = Input(shape=(20, 1))
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(1, activation='tanh')
decoder_outputs = decoder_dense(decoder_outputs)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
model.compile(optimizer='adam', loss='mse', metrics=['acc', 'mae'])
history=model.fit(xtrain, xtrain, epochs=200, verbose=2, shuffle=False)
I also have this model, but I am not sure how I can initalize here the encoder state same as the decoder state. Is the repeatvector doing this ?
#define model
model = Sequential()
model.add(LSTM(100, input_shape=(n_timesteps_in, n_features)))
model.add(RepeatVector(n_timesteps_in))
model.add(LSTM(100, return_sequences=True))
model.add(TimeDistributed(Dense(n_features, activation='tanh')))
model.compile(loss='mse', optimizer='adam', metrics=['mae'])
history=model.fit(train, train, epochs=epochs, verbose=2, shuffle=False)
You are building a model with 2 inputs, namely encoder_inputs and decoder_inputs but only giving one input .fit(xtrain, xtrain, ...) the second argument is the output. In case you need to give another argument of the form .fit([xtrain, the_inputs_for_decoder], xtrain, ...)
I am trying to implement CNN for a classification task. I want to see the how the weights are being optimized at each epoch. To do so, I need the values of penultimate layer. Also, I will hard code the last layer and backpropagation myself. Please recommend APIs also which which will be helpful.
Edit: I have added a code from keras examples. Looking forward to edit it.
This link provide some hint. I have mentioned the layer after which I require the output.
from __future__ import print_function
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalMaxPooling1D
from keras.datasets import imdb
# set parameters:
max_features = 5000
maxlen = 400
batch_size = 100
embedding_dims = 50
filters = 250
kernel_size = 3
hidden_dims = 250
epochs = 100
print('Loading data...')
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')
print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)
print('Build model...')
model = Sequential()
# we start off with an efficient embedding layer which maps
# our vocab indices into embedding_dims dimensions
model.add(Embedding(max_features,
embedding_dims,
input_length=maxlen))
model.add(Dropout(0.2))
# we add a Convolution1D, which will learn filters
# word group filters of size filter_length:
model.add(Conv1D(filters,
kernel_size,
padding='valid',
activation='relu',
strides=1))
# we use max pooling:
model.add(GlobalMaxPooling1D())
# We add a vanilla hidden layer:
model.add(Dense(hidden_dims))
model.add(Dropout(0.2))
model.add(Activation('relu'))
# We project onto a single unit output layer, and squash it with a sigmoid:
model.add(Dense(1))
model.add(Activation('sigmoid')) #<======== I need output after this.
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_data=(x_test, y_test))
You can get the individual layers of your model like this:
num_layer = 7 # Dense(1) layer
layer = model.layers[num_layer]
I want to see the how the weights are being optimized at each epoch.
To get the weights of the layer use layer.get_weights() like this:
w, b = layer.get_weights() # weights and bias of Dense(1)
I need the values of penultimate layer.
To get the value of the evaluation of the last layer use model.predict():
prediction = model.predict(x_test)
To get the evaluation of any other layer do it with tensorflow like this:
input = tf.placeholder(tf.float32) # Create input placeholder
layer_output = layer(input) # create layer output operation
init_op = tf.global_variables_initializer() # initialize variables
with tf.Session() as sess:
sess.run(init_op)
# evaluate layer output
output = sess.run(layer_output, feed_dict = {input: x_test})
print(output)