Python, Tensorflow ValueError: No gradients provided for any variable - python

I have a class called RL_Brain:
class RL_Brain():
def __init__(self, n_features, n_action, memory_size=10, batch_size=32, gamma=0.9, fi_size=10):
self.n_features = n_features
self.n_actions = n_action
self.encoder = keras.Sequential([
Input((self.n_features,)),
Dense(16, activation='relu', kernel_initializer='glorot_normal', name='encoder_1'),
Dense(16, activation='relu', kernel_initializer='glorot_normal', name='encoder_2'),
Dense(16, activation='relu', kernel_initializer='glorot_normal', name='encoder_3'),
Dense(self.fi_size, activation='softmax', name='fi'),
])
self.decoder = keras.Sequential([
Input((self.fi_size,)),
Dense(16, activation='relu', name='decoder_1', trainable=True),
Dense(16, activation='relu', name='decoder_2', trainable=True),
Dense(16, activation='relu', name='decoder_3', trainable=True),
Dense(self.n_features, activation=None, name='decoder_output', trainable=True)
])
def learn(self, state, r, a, state_):
encoded = tf.one_hot(tf.argmax(self.encoder(state), axis=1), depth=self.fi_size)
encoded_ = tf.one_hot(tf.argmax(self.encoder(state_), axis=1), depth=self.fi_size)
decoded_state = self.decoder(encoded).numpy()
with tf.GradientTape() as tape:
loss1 = mean_squared_error(state, decoded_state)
grads = tape.gradient(loss1, self.decoder.trainable_variables)
self.opt.apply_gradients(zip(grads, self.decoder.trainable_variables))
When I run the learn function, I get the following error:
File "/Users/wangheng/app/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/optimizer_v2/utils.py", line 78, in filter_empty_gradients raise ValueError("No gradients provided for any variable: %s." % ...
ValueError: No gradients provided for any variable: ['decoder_1/kernel:0', 'decoder_1/bias:0', 'decoder_2/kernel:0', 'decoder_2/bias:0', 'decoder_3/kernel:0', 'decoder_3/bias:0', 'decoder_output/kernel:0', 'decoder_output/bias:0'].

the following line is causing that error
decoded_state = self.decoder(encoded).numpy()
Once you do that, there is no path from your loss function to your trainable variables so no gradient can be calculated.

Related

How to adjust layers of Autoencoder for a larger dataset

I got a dataset for motion blur. 29216 good images and 29216 blurry images with a 20% train test split. Initially, I was only using a dataset of 2000 total images so my autoencoder looked like this:
# Below is a custom data loader.
def load_image(file, target_size):
image = tf.keras.preprocessing.image.load_img(file, target_size=target_size)
image = tf.keras.preprocessing.image.img_to_array(image).astype('float32') / 255
return image
clean_frames = []
blurry_frames = []
extensions = ['.jpg', 'jpeg', '.png']
for file in tqdm(sorted(os.listdir(good_frames))):
if any(extension in file for extension in extensions):
file_path = os.path.join(good_frames, file)
clean_frames.append(load_image(file_path, (128,128)))
clean_frames = np.array(clean_frames)
for file in tqdm(sorted(os.listdir(bad_frames))):
if any(extension in file for extension in extensions):
file_path = os.path.join(bad_frames, file)
blurry_frames.append(load_image(file_path, (128,128)))
blurry_frames = np.array(blurry_frames)
print('number of clean frames: ', len(clean_frames))
print('number of blurry frames: ', len(blurry_frames))
# Train test split
x_train, x_test, y_train, y_test = train_test_split(clean_frames, blurry_frames, test_size=0.2, random_state=42)
# Network Parameters
input_shape = (128, 128, 3)
batch_size = 32
kernel_size = 3
latent_dim = 256
inputs = Input(shape = input_shape, name = 'encoder_input')
x = inputs
# Layers of the encoder
x = Conv2D(filters=64, kernel_size=kernel_size, strides=2, activation='relu', padding='same')(x)
x = Conv2D(filters=128, kernel_size=kernel_size, strides=2, activation='relu', padding='same')(x)
x = Conv2D(filters=256, kernel_size=kernel_size, strides=2, activation='relu', padding='same')(x)
shape = K.int_shape(x)
x = Flatten()(x)
latent = Dense(latent_dim, name='latent_vector')(x)
encoder = Model(inputs, latent, name='encoder')
encoder.summary()
# Layers of the decoder
latent_inputs = Input(shape=(latent_dim,), name='decoder_input')
x = Dense(shape[1]*shape[2]*shape[3])(latent_inputs)
x = Reshape((shape[1], shape[2], shape[3]))(x)
x = Conv2DTranspose(filters=256,kernel_size=kernel_size, strides=2, activation='relu', padding='same')(x)
x = Conv2DTranspose(filters=128,kernel_size=kernel_size, strides=2, activation='relu', padding='same')(x)
x = Conv2DTranspose(filters=64,kernel_size=kernel_size, strides=2, activation='relu', padding='same')(x)
outputs = Conv2DTranspose(filters=3, kernel_size=kernel_size, activation='sigmoid', padding='same', name='decoder_output')(x)
decoder = Model(latent_inputs, outputs, name='decoder')
autoencoder = Model(inputs, decoder(encoder(inputs)), name='autoencoder')
autoencoder.compile(loss='mse', optimizer='adam',metrics=["acc"])
# Automated Learning Rate reducer
lr_reducer = ReduceLROnPlateau(factor=np.sqrt(0.1),
cooldown=0,
patience=5,
verbose=1,
min_lr=0.5e-6)
callbacks = [lr_reducer]
# Begins training
history = autoencoder.fit(blurry_frames,
clean_frames,
validation_data=(blurry_frames, clean_frames),
epochs=100,
batch_size=batch_size,
callbacks=callbacks)
This would yield an accuracy of 82% after 100 epochs.
Now that I got more data, I believe I can get better performance. How should I adjust my layers and parameters to make the most of the data that I have?

Issue during searching for optimal parameters using optuna

I don't know how to solve it.
def create_model(time_steps, num_layer, num_filters, kernel_size, strides, dropout_rate, activation):
model = tf.keras.Sequential()
model.add(tf.keras.layers.InputLayer(input_shape=(time_steps, 1)))
for i in range(num_layer):
filters = int(num_filters / (i+1))
model.add(
tf.keras.layers.Conv1D(
filters=filters, kernel_size=kernel_size, padding="same", strides=strides, activation=activation
)
)
if i < (num_layer - 1):
model.add(tf.keras.layers.Dropout(rate=dropout_rate))
for i in reversed(range(num_layer)):
filters = int(num_filters / (i+1))
model.add(
tf.keras.layers.Conv1DTranspose(
filters=filters, kernel_size=kernel_size, padding="same", strides=strides, activation=activation
)
)
if i != 0:
model.add(tf.keras.layers.Dropout(rate=dropout_rate))
model.add(
tf.keras.layers.Conv1DTranspose(
filters=1, kernel_size=kernel_size, padding="same"
)
)
return model
def objective(trial):
num_layer = trial.suggest_int("num_layer", 1, 3)
num_filters = int(trial.suggest_categorical("num_filters", [16, 32, 64]))
kernel_size = trial.suggest_int("kernel_size", 1, 5, 2)
strides = trial.suggest_int("strides", 2, 4, 2)
dropout_rate = trial.suggest_uniform('dropout_rate', 0.0, 0.5)
activation = trial.suggest_categorical("activation", ["relu", "sigmoid", "tanh"])
optimizer = trial.suggest_categorical("optimizer", ["sgd", "adam"])
model = create_model(TIME_STEPS, num_layer, num_filters, kernel_size, strides, dropout_rate, activation)
model.compile(
optimizer=optimizer,
loss="mse"
)
model.summary()
history = model.fit(
x_train,
x_train,
epochs=50,
batch_size=128,
validation_split=0.1,
callbacks=[
tf.keras.callbacks.EarlyStopping(monitor="val_loss", patience=5, mode="min")
],
)
return history.history["val_loss"][-1]
study = optuna.create_study()
study.optimize(objective, n_trials=50)
Error Code
study.optimize(objective, n_trials=50)
Error Statement
ValueError: Dimensions must be equal, but are 32 and 20 for '{{node mean_squared_error/SquaredDifference}} = SquaredDifference[T=DT_FLOAT](mean_squared_error/remove_squeezable_dimensions/Squeeze, IteratorGetNext:1)' with input shapes: [?,32], [?,20].

dont know why is this error: Graph disconnected: cannot obtain value for tensor Tensor

i want to establish the VAE-CNN but i dont know why show this error.
train_datagen = ImageDataGenerator(rescale=1. / 255)
validation_datagen = ImageDataGenerator(rescale=1. / 255)
train_gen = train_datagen.flow_from_directory(
'./train for dataset/',
target_size=(80, 24),
color_mode='grayscale',
batch_size=32,
class_mode='input',
shuffle=True,
seed = 42
)
validation_gen = validation_datagen.flow_from_directory(
'./test/',
target_size=(80, 24),
color_mode='grayscale',
batch_size=32,
class_mode='input',
shuffle=False,
seed = 42
)
#VAE-CNN
filter1_V=64
filter2_V=88
latent_dim_V=20
original_inputs = keras.Input(shape=(80,24,1))
init = tf.keras.initializers.VarianceScaling(scale=0.3, mode='fan_in',distribution='uniform')
layer1_v = layers.Conv2D(filter1_V, kernel_size=3, activation = 'relu', kernel_initializer=init, padding='same', strides = 2)(original_inputs)
layer1_v = layers.MaxPool2D(pool_size=(2,2))(layer1_v)
# strides is 2 in default, which equals to pool_size
layer2_v = layers.Conv2D(filter2_V, kernel_size=3, activation='relu', kernel_initializer=init, padding='same', strides = 2)(layer1_v)
layer2_v = layers.MaxPool2D(pool_size=(2,2))(layer2_v)
layer3_v = layers.Flatten()(layer2_v)
# start to code the core part of mean and variance
#get mean
layer_mean = layers.Dense(latent_dim_V)(layer3_v)
# get log variance, it can get the value from negative to positive, if only use variance, the value is only positive
log_var = layers.Dense(latent_dim_V)(layer3_v)
# dur to the sample, in order to get back propogation, add one parameter which its distribution is normal(0,1)
def sampling(args):
layer_mean,log_var=args
eps = K.random_normal(shape=(K.shape(log_var)[0],latent_dim_V),mean=0.,stddev=1.0)
# reparameterize
# the standard varinace is what we want
std = K.exp(log_var)**0.5
return layer_mean + std * eps
z = layers.Lambda(sampling, output_shape=(latent_dim_V,))([layer_mean, log_var])
#decoder part
dec1_v = layers.Dense(layer3_v.shape[1], activation='relu')(z)
dec2_v = layers.Reshape((layer2_v.shape[1],layer2_v.shape[2],layer2_v.shape[3]))(dec1_v)
dec3_v = layers.Conv2DTranspose(filter2_V, kernel_size=3, output_padding=(1,2), activation = 'relu',kernel_initializer=init, padding = 'same', strides=(2,3))(dec2_v)
dec4_v = layers.Conv2DTranspose(filter1_V, kernel_size=3, activation = 'relu', kernel_initializer=init, padding = 'same', strides=2)(dec3_v)
dec5_v = layers.Conv2DTranspose(filter1_V, kernel_size=3, activation = "relu", kernel_initializer=init, padding = 'same', strides=2)(dec4_v)
dec_v_outputs = layers.Conv2DTranspose(1, kernel_size=3, activation = "relu", kernel_initializer=init, padding = 'same', strides=2)(dec5_v)
encoder_v = keras.Model(inputs=original_inputs, outputs=[z,layer_mean,log_var], name='encoder')
decoder_v = keras.Model(inputs=z, outputs=dec_v_outputs, name='decoder')
outputs = decoder_v(encoder_v(original_inputs)[0])
vae_model = keras.Model(inputs=original_inputs, outputs=outputs, name='vae_model')
vae_model.summary()
kl_loss = -0.5 * K.sum(log_var + 1 - layer_mean**2 - K.exp(log_var), axis=-1)
kl_loss = K.mean(kl_loss)/1920.
lr=1e-3
optimizer = keras.optimizers.Adam(learning_rate=lr)
vae_model.add_loss(kl_loss)
vae_model.compile(optimizer, loss="binary_crossentropy")
history=vae_model.fit(train_gen,train_gen, epochs=4, batch_size=32, validation_data=(validation_gen,validation_gen))
i want to get a VAE-CNN
and there is a error:ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_1:0", shape=(None, 80, 24, 1), dtype=float32) at layer "input_1". The following previous layers were accessed without issue: []
why is it and how to solve?

Keras Model from submodeling is not able to compile

I want to use Subclassing/inheritance of the keras Model class. When I want to compile my model it isn't.
I started with keras recently but used a lot of pytorch before.
I currently run tensorflow and keras on version 1.10 and 2.16 respectively and really dont know why I cant compile the model. I tried updating tf to version 1.13 but nothing changed.
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from keras.layers import Input,Conv2D,MaxPooling2D,UpSampling2D,BatchNormalization
from keras import Model, layers
print(tf.VERSION)
print(tf.keras.__version__)
batch_size = 128
epochs = 50
inChannel = 1
img_width, img_height = 64, 64
input_shape = (img_width, img_height, 1)
class AE_64x64(Model):
def __init__(self):
super(AE_64x64, self).__init__()
'''
data_format: channels last
'''
self.conv1 = Conv2D(filters=30, kernel_size=(7,7), activation='relu', padding='same', strides=2)(Input(shape=input_shape))
self.conv2 = Conv2D(filters=40, kernel_size=(5,5), activation='relu', padding='same', strides=2)
self.batchnorm = BatchNormalization(axis=2)
self.max_pool = MaxPooling2D((3,3),padding='same')
self.conv3 = Conv2D(filters=50, kernel_size=(3,3), activation='relu', padding='same', strides=2)
self.conv4 = Conv2D(filters=60, kernel_size=(3,3), activation='relu')
self.b1 = Conv2D(filters=80, kernel_size=(3,3), activation='relu')
self.b2 = Conv2D(filters=99, kernel_size=(3,3), activation='relu')
self.conv6 = Conv2D(filters=50, kernel_size=(3,3), activation='relu')
self.conv7 = Conv2D(filters=40, kernel_size=(3,3), activation='relu')
self.conv8 = Conv2D(filters=30, kernel_size=(3,3), activation='relu')
self.conv9 = Conv2D(filters=1, kernel_size=(3,3), activation='relu')
def call(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.batchnorm(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.max_pool(x)
x = self.batchnorm(x)
x = self.b1(x)
x = self.b2(x)
x = self.batchnorm(x)
x = self.conv5(x)
x = self.conv6(x)
x = self.batchnorm(x)
x = self.conv7(x)
x = self.conv8(x)
x = self.batchnorm(x)
x = self.conv9(x)
return x
AE_Model = AE_64x64()
AE_Model.compile(loss='mean_squared_error',optimizer=tf.train.AdamOptimizer(),metrics= ['mean_squared_error'])
AE_Model.summary()
I expected a summary output but instead I received this error message:
RuntimeError: You must compile your model before using it.
Is there a logical mistake in the code or a Hardware/Version problem?
you at least have to build your model. Or you fit your model with data.
anyway, when I run your code without data I get this result
AE_Model.compile(loss='mean_squared_error',optimizer=tf.train.AdamOptimizer(),metrics= ['mean_squared_error'])
AE_Model.build(input_shape)
AE_Model.summary()
1.13.1
2.2.4-tf
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================

How to add svm on top of cnn as final classifier?

I work on sentiment analysis task and i want to add SVM layer on top CNN as a final classifier, how can i do that without using hing-loss?
tweet_input = Input(shape=(seq_len,), dtype='int32')
tweet_encoder = Embedding(vocabulary_size, EMBEDDING_DIM,
input_length=seq_len, trainable=True)(tweet_input)
bigram_branch = Conv1D(filters=64, kernel_size=2, padding='same',
activation='relu', strides=1)(tweet_encoder)
bigram_branch = GlobalMaxPooling1D()(bigram_branch)
trigram_branch = Conv1D(filters=32, kernel_size=3, padding='same',
activation='relu', strides=1)(tweet_encoder)
trigram_branch = GlobalMaxPooling1D()(trigram_branch)
fourgram_branch = Conv1D(filters=16, kernel_size=4, padding='same',
activation='relu', strides=1)(tweet_encoder)
fourgram_branch = GlobalMaxPooling1D()(fourgram_branch)
merged = concatenate([bigram_branch, trigram_branch, fourgram_branch], axis=1)
merged = Dense(512, activation='softmax')(merged)
merged = Dropout(0.8)(merged)
merged = Dense(2)(merged)
output = Activation('sigmoid')(merged)
model = Model(inputs=[tweet_input], outputs=[output])
adam=keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
model.compile(loss='hinge',
optimizer= adam,
metrics=['accuracy'])
model.summary()

Categories

Resources