So earlier, I trained the SNET model on images present here for the purpose of artifact removal. The hyperparameters with which I have trained the model are mentioned below:
So SNET has eight convolution-based heads that would output a certain size of patch in the image. The input would be the same patch that has jpeg artifacts artificially added into them. The predicted and the ground truth patch would be compared with one another, and then MSE loss between them is backpropagated.
The hyperparameters, that I used:
learning_rate = 0.0001, min_learning_rate = 0.000001 for exponential scheduler
optimizer = Adam
loss metric = MSE(mean squared error)
patch_size = 48 x 48
Training batch-size = 16
Evaluation metrics:
PSNR: This is used for quality measurement between the original and reconstructed image.
SSIM: A common metric is to quantify the difference in the values of each of the corresponding pixels between the sample and the reference images.
So while training the images, I was evaluating the model's performance at every step. So there are eight 48 x 48 patches of the same image, since there 8 heads in the model. The model was trained for 100 iterations. Outputs of random patches from 998 to 999 iterations are given below:
The first image is the artifact-added image, the second is the predicted one, third is the ground truth image.
After training the model, I had to test them on bigger images with a larger context(that has an object). So instead of resizing the images to 48 x 48, I divided them into patches of 48 x 48, therefore only tested on images that have width and height values that are multiples of 48. But the problem is that, though the image has high psnr and ssim values, there is a fine gap between patch to patch as shown below:
Is there a way to efficiently tackle this issue? Please suggest, open to any kind of feedback.
Below is the code for model that I used:
import tensorflow as tf
from PIL import Image
import cv2
import tensorflow as tf
import numpy as np
import os
def MSE(input,target):
#return tf.reduce_sum(tf.reduce_mean(tf.abs(input - target),axis=0))
return tf.reduce_mean(tf.abs(input - target))
initializer = tf.initializers.VarianceScaling()
def EncoderBlock(x, activation = tf.keras.layers.LeakyReLU(alpha=0.2), nf = 256):
x = tf.keras.layers.Conv2D(nf, 5, strides=1, padding='same', kernel_initializer=initializer, use_bias=True)(x)
x = activation(x)
x = tf.keras.layers.Conv2D(nf, 5, strides=1, padding='same', kernel_initializer=initializer, use_bias=True)(x)
x = activation(x)
return x
def DecoderBlock(x, activation = tf.keras.layers.LeakyReLU(alpha=0.2), nf = 256):
x = tf.keras.layers.Conv2D(nf, 5, strides=1, padding='same', kernel_initializer=initializer, use_bias=True)(x)
x = activation(x)
x = tf.keras.layers.Conv2D(3, 5, strides=1, padding='same', kernel_initializer=initializer, use_bias=True)(x)
x = activation(x)
return x
def ConvolutionalUnit(x, structure_type = 'classic', activation = tf.keras.layers.LeakyReLU(alpha=0.2), nf = 256):
residual = x
if structure_type == "classic":
x = tf.keras.layers.Conv2D(nf, 5, strides=1, padding='same', kernel_initializer=initializer, use_bias=True)(x)
x = activation(x)
x = tf.keras.layers.Add()([x, residual])
elif structure_type == "advanced":
x = tf.keras.layers.Conv2D(nf, 5, strides=1, padding='same', kernel_initializer=initializer, use_bias=True)(x)
x = activation(x)
x = tf.keras.layers.Conv2D(nf, 5, strides=1, padding='same', kernel_initializer=initializer, use_bias=True)(x)
x = tf.keras.layers.Lambda(lambda x: x * 0.1)(x)
x = tf.keras.layers.Add()([x, residual])
return x
def S_Net(channels = 3, num_metrics=8 , structure_type='advanced', nf = 256):
inputs = tf.keras.layers.Input(shape=[None, None, channels])
encoder = EncoderBlock(inputs, nf = nf)
convolution_units = []
decoders = []
for i in range(num_metrics):
convolution_units.append(ConvolutionalUnit( convolution_units[-1] if len(convolution_units)>0 else ConvolutionalUnit(encoder, nf=nf), structure_type = structure_type, nf=nf))
decoders.append(DecoderBlock(convolution_units[-1],nf=nf))
return tf.keras.Model(inputs=[inputs], outputs=decoders)
Related
I have a tensorflow implementation of a GAN that I'm trying to use to sharpen the image output from a variational autoencoder. The problem is after a few epochs (50000 generator weight updates, 200000 critic weight updates, single image batches) the network is still producing images that are almost greyscale when being trained on color images, and will typically produce very faded images with little contrast (although will produce clear images at times)
The generator gets a blurry reconstruction image as an input and tries to make a convincing fake of the real image it's based on. The discriminator gets a blurry reconstruction image and either the real image it's based on or the generators fake and ouputs a confidence value for if it is the real image or not.
This might be a case of not having trained the network enough but on every other GAN I've trained to slightly alter an image it normally learns to reproduce the input image within the first 300-400 weight updates.
One theory I have is that the gradient clipping is set quite low to facilitate stability (0.0001) and this might be causing a gradient saturation issue, but I honestly don't understand enough about the concepts involved to even know where to begin bugfixing this. This is the first time I've used wasserstein loss as well so let me know if my implementation is completely wrong.
Some additional information from my attempts to debug this -
I've tested the image inputs by adding mean absolute error loss to the generator and it is able to reproduce it's inputs and approximate the real images just fine
The loss is wasserstein and generally hangs around these values:
disc_total[0.000117] disc_real[-0.000080] disc_gen[0.000197] gen_total[-0.000062]
The input image folder is based on UTK face and contains images that look like this
The network output typically looks like this
Code:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.utils import Sequence
from tensorflow.keras import backend as K
from tensorflow.keras.constraints import Constraint
import matplotlib.pyplot as plt
import vae
import numpy as np
import random
import cv2
import os
import time
#--------------------Build Model--------------------
#Save filepath
checkpoint_dir = 'Models/GAN/WGAN-U'
#Saved models filepath
filepath = "Models/BVAE/BVAE"
#Data filepath
datapath = "Datasets/Reconstructions/UTK"
val_datapath = ""
batch_size = 1
image_save_freq = 100
model_save_freq = 1000
grad_clipping = 0.0001
vae.vae.load_weights(filepath)
for layer in vae.vae.layers:
layer.trainable = False
#Wrapper for utk face data generator
class utk_data_gen(Sequence):
def __init__(self, validation):
self.validation = validation
self.dp = val_datapath if self.validation else datapath
self.data_len = len(os.listdir(self.dp))//batch_size
def __getitem__(self, index):
X1 = np.empty(shape=(batch_size, vae.height, vae.width, vae.channels))
X2 = np.empty(shape=(batch_size, vae.height, vae.width, vae.channels))
C = np.empty(shape=(batch_size, 7))
data_dir = os.listdir(self.dp)
i=index*batch_size
for j in range(0, batch_size):
data = data_dir[i+j]
img = cv2.imread(os.path.join(self.dp,data))
img = (img / 127.5)-1.0
vae_img = img[:vae.height]
img = img[vae.height:]
labels = data.split('_')
age = float(labels[0]) / 116
gender = float(labels[1])
white = 0.0
black = 0.0
asian = 0.0
indian = 0.0
other = 0.0
if labels[2] == '0':
white = 1.0
elif labels[2] == '1':
black = 1.0
elif labels[2] == '2':
asian = 1.0
elif labels[2] == '3':
indian = 1.0
elif labels[2] == '4':
other = 1.0
img_label = (age, gender, white, black, asian, indian, other)
img_label = np.array(img_label)
X1[j]=img
X2[j]=vae_img
C[j]=img_label
Y=X1
return [X1,X2,C],Y
def __len__(self):
return self.data_len
#Wasserstein discriminator
def wasserstein_loss(y_true, y_pred):
return K.mean(y_true * y_pred)
class ClipConstraint(Constraint):
def __init__(self, clip_value):
self.clip_value = clip_value
def __call__(self, weights):
return K.clip(weights, -self.clip_value, self.clip_value)
def get_config(self):
return {'clip_value': self.clip_value}
disc_optimizer = tf.keras.optimizers.RMSprop(lr=0.00005)
def build_discriminator():
init = tf.random_normal_initializer(0.0, 0.02)
kcon = ClipConstraint(grad_clipping)
img_input = layers.Input(shape=(vae.height, vae.width, vae.channels), name='input_image')
vae_input = layers.Input(shape=(vae.height, vae.width, vae.channels), name='vae_input_image')
concat_inputs = layers.Concatenate()([img_input, vae_input])
downsamples = 4
startFilters = 32
x = layers.Conv2D(startFilters, (4,4), strides=(1,1), padding='same', kernel_constraint=kcon, kernel_initializer=init)(concat_inputs)
for i in range(downsamples):
x = layers.Conv2D(startFilters * 2**i, (4,4), strides=(2,2), padding='same', kernel_constraint=kcon, kernel_initializer=init)(x)
x = layers.BatchNormalization()(x)
x = layers.LeakyReLU(alpha=0.2)(x)
x = layers.Conv2D(startFilters * 2**downsamples, (4,4), padding='same', kernel_constraint=kcon, kernel_initializer=init)(x)
x = layers.BatchNormalization()(x)
x = layers.LeakyReLU(alpha=0.2)(x)
x = layers.Flatten()(x)
output = layers.Dense(1, activation='linear')(x)
model = keras.Model([img_input, vae_input], output, name="discriminator")
model.compile(loss=wasserstein_loss, optimizer=disc_optimizer)
return model
#Generator
def UNet_downsample(layer_input, filters):
init = tf.random_normal_initializer(0.0, 0.02)
x = layers.Conv2D(filters, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(layer_input)
x = layers.BatchNormalization()(x)
x = layers.LeakyReLU(alpha=0.2)(x)
return x
def UNet_upsample(layer_input, downsample_skip, filters, crop=False, use_dropout=False):
init = tf.random_normal_initializer(0.0, 0.02)
x = layers.Conv2DTranspose(filters, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(layer_input)
if crop:
x = x[:,:-1,:-1]
x = layers.BatchNormalization()(x)
if use_dropout:
x = layers.Dropout(0.3)(x, training=True)
x = layers.Concatenate()([x, downsample_skip])
x = layers.LeakyReLU(alpha=0.2)(x)
return x
#U-Net
def build_generator():
init = tf.random_normal_initializer(0.0, 0.02)
input_img = keras.Input(shape=(vae.height, vae.width, vae.channels), name = "gen_input_image")
x = layers.Conv2D(3, (4,4), strides=1, padding="same", kernel_initializer=init, name="input_conv")(input_img)
x1 = UNet_downsample(x, 128)
x2 = UNet_downsample(x1, 256)
x3 = UNet_downsample(x2, 512)
x4 = UNet_downsample(x3, 512)
x5 = UNet_downsample(x4, 512)
x = layers.Conv2D(512, (4,4), strides=(2,2), padding='same', activation='relu', kernel_initializer=init)(x5)
x = UNet_upsample(x, x5, 512, True)
x = UNet_upsample(x, x4, 512, True, True)
x = UNet_upsample(x, x3, 512, True, True)
x = UNet_upsample(x, x2, 256)
x = UNet_upsample(x, x1, 128)
output = layers.Conv2DTranspose(3, (4,4), strides=(2,2), activation="tanh", padding="same", name="generator_outputs")(x)
return keras.Model(inputs = [input_img], outputs=output, name="generator")
#Build GAN
gan_optimizer = tf.keras.optimizers.RMSprop(lr=0.00005)
def build_gan(disc, gen):
for layer in disc.layers:
if not isinstance(layer, layers.BatchNormalization):
layer.trainable = False
input_img = keras.Input(shape=(vae.height,vae.width,vae.channels), name = "gan_input_img")
gen_output = gen(input_img)
disc_output = disc([gen_output, input_img])
model = keras.Model(input_img, [disc_output, gen_output])
model.compile(loss=[wasserstein_loss], optimizer=gan_optimizer)
return model
discriminator = build_discriminator()
generator = build_generator()
gan = build_gan(discriminator, generator)
generator_optimizer = tf.keras.optimizers.RMSprop(lr=0.00005)
discriminator_optimizer = tf.keras.optimizers.RMSprop(lr=0.00005)
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
checkpoint = tf.train.Checkpoint(gan_optimizer=gan_optimizer,
discriminator_optimizer=discriminator_optimizer,
discriminator=discriminator,
gan=gan)
cp_num = 0
def saveImg():
labels = np.array([[0.8, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]])
im = vae.decoder.predict([np.zeros(shape=(1,20)), labels])[0]
im = tf.expand_dims(im, axis=0)
im = generator.predict([im])[0]
im = ((im+1.0)*127.5).astype(np.uint8)
cv2.imwrite("Models/GAN/Progress/GAN_"+str(cp_num)+"_"+str(time.time())+ ".jpg", im)
mean_loss_index = 0
mean_loss_losses = [[0,]*30 for i in range(5)]
def get_mean_loss(gan_loss):
global mean_loss_index
global mean_loss_losses
for i, loss in enumerate(gan_loss):
mean_loss_losses[i][mean_loss_index] = loss
mean_loss_index += 1
mean_loss_index = mean_loss_index%30
return tuple([np.mean(loss) for loss in mean_loss_losses])
real_labels = -np.ones((batch_size,1))
fake_labels = np.ones((batch_size,1))
def train(input_img, vae_img):
critic_updates = 4
disc_real_loss = 0
disc_gen_loss = 0
for i in range(critic_updates):
fake_img = generator.predict(vae_img)
disc_real_loss += discriminator.train_on_batch([input_img, vae_img], real_labels)
disc_gen_loss += discriminator.train_on_batch([fake_img, vae_img], fake_labels)
disc_real_loss /= critic_updates
disc_gen_loss /= critic_updates
disc_total_loss = disc_real_loss + disc_gen_loss
gen_loss, _ = gan.train_on_batch([vae_img], real_labels)
rec_loss = 0
print('disc_total[%.6f] disc_real[%.6f] disc_gen[%.6f] gen_total[%.6f] reconstruction[%.3f]' % get_mean_loss((disc_total_loss, disc_real_loss, disc_gen_loss, gen_loss, rec_loss)))
print()
#Main training loop
def fit(train_ds):
global cp_num
while True:
for i, (data, _) in enumerate(train_ds.__iter__()):
print("Batch " + str(i) + '.')
input_image, vae_image, labels = data
input_image = tf.cast(input_image, dtype='float32')
vae_image = tf.cast(vae_image, dtype='float32')
if (i+1) % image_save_freq == 0:
saveImg()
if (i+1) % model_save_freq == 0:
print()
checkpoint.save(file_prefix = checkpoint_prefix)
print("Model Checkpoint <" + str(cp_num) + "> Saved!")
cp_num+=1
else:
print(str(model_save_freq - i%model_save_freq) + " batches until next save")
train(input_image, vae_image)
print()
checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))
fit(utk_data_gen(False))
Any help with this would be appreciated, even just to say that I haven't made any obvious errors and this issue may resolve itself with more training. I would have waited longer to see before posting the question, but I am under a time constraint to get something visual that shows progress.
I managed to fix this somewhat by doubling the number of filters in the critic, but also, interestingly, the results don't seem to be that much better than those I obtained by just adding a small amount of mae loss to the generator during testing. If anyone else runs into this problem I'd recommend considering this as a fix.
i am doing some image segmentation whit deep learning, when i do it on fp32 i get val acc about 97% but when i try to train on fp16 i get stuck on 21% i've changed the learning rate and the epsilon and some times i get other acc but always stuck like this
this is my code
import tensorflow as tf
from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession
config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)
from tensorflow.keras import optimizers
from tensorflow_examples.models.pix2pix import pix2pix
tf.keras.mixed_precision.experimental.set_policy('mixed_float16')
from tensorflow.keras import layers
def get_model(img_size, num_classes):
inputs = keras.Input(shape=img_size + (3,))
### [First half of the network: downsampling inputs] ###
# Entry block
x = layers.Conv2D(32, 3, strides=2, padding="same")(inputs)
x = layers.BatchNormalization()(x)
x = layers.Activation("relu")(x)
previous_block_activation = x # Set aside residual
# Blocks 1, 2, 3 are identical apart from the feature depth.
for filters in [64, 128, 256]:
x = layers.Activation("relu")(x)
x = layers.SeparableConv2D(filters, 3, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.Activation("relu")(x)
x = layers.SeparableConv2D(filters, 3, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.MaxPooling2D(3, strides=2, padding="same")(x)
# Project residual
residual = layers.Conv2D(filters, 1, strides=2, padding="same")(
previous_block_activation
)
x = layers.add([x, residual]) # Add back residual
previous_block_activation = x # Set aside next residual
### [Second half of the network: upsampling inputs] ###
for filters in [256, 128, 64, 32]:
x = layers.Activation("relu")(x)
x = layers.Conv2DTranspose(filters, 3, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.Activation("relu")(x)
x = layers.Conv2DTranspose(filters, 3, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.UpSampling2D(2)(x)
# Project residual
residual = layers.UpSampling2D(2)(previous_block_activation)
residual = layers.Conv2D(filters, 1, padding="same")(residual)
x = layers.add([x, residual]) # Add back residual
previous_block_activation = x # Set aside next residual
# Add a per-pixel classification layer
outputs = layers.Conv2D(num_classes, 3, activation="softmax", padding="same")(x)
# Define the model
model = keras.Model(inputs, outputs)
return model
# Free up RAM in case the model definition cells were run multiple times
keras.backend.clear_session()
# Build model
model = get_model(img_size, num_classes)
model.compile(loss="categorical_crossentropy", optimizer=optimizers.RMSprop(lr=5e-5), metrics=['acc'])
# Train the model, doing validation at the end of each epoch.
epochs = 30
model_history= model.fit(train_gen, epochs=epochs, validation_data=val_gen)
what can be going wrong? thanks in advance
When using fp16, you need to have the final layer give fp32 output.
Change
outputs = layers.Conv2D(num_classes, 3, activation="softmax", padding="same")(x)
to
outputs = layers.Conv2D(num_classes, 3, padding="same")(x)
outputs = layers.Activation('softmax', dtype=tf.float32)(output)
Since I load my data (images) from the structured folders, I utilize the flow_from_directory function of the ImageDataGenerator class, which is provided by Keras. I've no issues while feeding this data to a CNN model. But when it comes to an LSTM model, getting the following error: ValueError: Error when checking input: expected lstm_1_input to have 3 dimensions, but got array with shape (64, 28, 28, 1). How can I reduce the dimension of the input data while reading it via ImageDataGenerator objects to be able to use an LSTM model instead of a CNN?
p.s. The shape of the input images is (28, 28) and they are grayscale.
train_valid_datagen = ImageDataGenerator(validation_split=0.2)
train_gen = train_valid_datagen.flow_from_directory(
directory=TRAIN_IMAGES_PATH,
target_size=(28, 28),
color_mode='grayscale',
batch_size=64,
class_mode='categorical',
shuffle=True,
subset='training'
)
Update: The LSTM model code:
inp = Input(shape=(28, 28, 1))
inp = Lambda(lambda x: squeeze(x, axis=-1))(inp) # from 4D to 3D
x = LSTM(num_units, dropout=dropout, recurrent_dropout=recurrent_dropout, activation=activation_fn, return_sequences=True)(inp)
x = BatchNormalization()(x)
x = Dense(128, activation=activation_fn)(x)
output = Dense(nb_classes, activation='softmax', kernel_regularizer=l2(0.001))(x)
model = Model(inputs=inp, outputs=output)
you start feeding your network with 4D data like your images in order to have the compatibility with ImageDataGenerator and then you have to reshape them in 3D format for LSTM.
These are the possibilities:
with only one channel you can simply squeeze the last dimension
inp = Input(shape=(28, 28, 1))
x = Lambda(lambda x: tf.squeeze(x, axis=-1))(inp) # from 4D to 3D
x = LSTM(32)(x)
if you have multiple channels (this is the case of RGB images or if would like to apply a RNN after a Conv2D) a solution can be this
inp = Input(shape=(28, 28, 1))
x = Conv2D(32, 3, padding='same', activation='relu')(inp)
x = Reshape((28,28*32))(x) # from 4D to 3D
x = LSTM(32)(x)
the fit can be computed as always with model.fit_generator
UPDATE: model review
inp = Input(shape=(28, 28, 1))
x = Lambda(lambda x: squeeze(x, axis=-1))(inp) # from 4D to 3D
x = LSTM(32, dropout=dropout, recurrent_dropout=recurrent_dropout, activation=activation_fn, return_sequences=False)(x)
x = BatchNormalization()(x)
x = Dense(128, activation=activation_fn)(x)
output = Dense(nb_classes, activation='softmax', kernel_regularizer=l2(0.001))(x)
model = Model(inputs=inp, outputs=output)
model.summary()
pay attention when you define inp variable (don't overwrite it)
set return_seq = False in LSTM in order to have 2D output
I am trying to convert a Keras functional model into class derived from tensorflow.keras.models.Model and I'm facing 2 issues.
1. I need to multiply 2 layers using tensorflow.keras.layers.multiply, but it returns a ValueError: A merge layer should be called on a list of inputs.
2. If I remove this layern thus working with a classical CNN, it returns a tensorflow.python.eager.core._SymbolicException:Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'patch:0' shape=(None, 64, 64, 3) dtype=float32>].
I would appreciate some guidance to convert my code. I'm using Python 3.7, TensorFlow 2.0rc2 and Keras 2.3.0. The class I have defined is the following:
class TestCNN(Model):
"""
conv1 > conv2 > fc1 > fc2 > alpha * fc2 > Sigmoid > output
"""
def __init__(self, input_dimension, n_category,**kwargs):
"""
Instanciator
:param input_dimension: tuple of int, theoretically (patch_size x patch_size x channels)
:param n_category: int, the number of categories to classify,
:param weight_decay: float, weight decay parameter for all the kernel regularizers
:return: the Keras model
"""
super(TestCNN, self).__init__(name='testcnn', **kwargs)
self.input_dimension = input_dimension
self.n_category = n_category
self.conv1 = Conv2D(36, activation='relu', name='conv1/relu')
self.conv1_maxpooling = MaxPooling2D((2, 2), name='conv1/maxpooling')
self.conv2 = Conv2D(48, activation='relu', name='conv2/relu')
self.conv2_maxpooling = MaxPooling2D((2, 2), name='conv2/maxpooling')
self.flatten1 = Flatten(name='flatten1')
self.fc1 = Dense(512, activation='relu', name='fc1/relu')
self.fc2 = Dense(512, activation='relu', name='fc2/relu')
self.alpha = TestLayer(layer_dim=128, name='alpha')
self.output1 = TestSigmoid(output_dimension=n_category, name='output_layer')
#tensorflow.function
def call(self, x):
x = self.conv1(x)
x = self.conv1_maxpooling(x)
x = self.conv2(x)
x = self.conv2_maxpooling(x)
x = self.flatten1(x)
x = self.fc1(x)
x = self.fc2(x)
alpha_times_fc2 = multiply([alpha_output, fc2_output], name='alpha_times_fc2')
return self.output1(alpha_times_fc2)
def build(self, **kwargs):
inputs = Input(shape=self.input_dimension, dtype='float32', name='patch')
outputs = self.call(inputs)
super(TestCNN, self).__init__(name="TestCNN", inputs=inputs, outputs=outputs, **kwargs)
Then, in my main loop, I'm creating the instance as following:
testcnn = TestCNN(input_dimension=input_dimension, n_category=training_set.category_count)
optimizer = tensorflow.keras.optimizers.Adam(
lr=parameter['training']['adam']['learning_rate'],
beta_1=parameter['training']['adam']['beta1'],
beta_2=parameter['training']['adam']['beta2'])
metrics_list = [tensorflow.keras.metrics.TruePositives]
loss_function = tensorflow.keras.losses.categorical_crossentropy
loss_metrics = tensorflow.keras.metrics.Mean()
testcnn.build()
testcnn.summary()
This code is raising the tensorflow.python.eager.core._SymbolicException. If I comment out some lines and return directly the results of the fc2 layer, I've got the ValueError.
I have commenter the build() function in my model and call it in my main script as following:
testcnn.build(input_dimension)
testcnn.compile(optimizer=adam_optimizer, loss=loss_function, metrics=metrics_list)
testcnn.summary()
Input dimension is a list formatted as following:
input_dimension = (batch_size, image_size, image_size, channels)
How can I create a proper size kernel by the cross product of two outputs of my net, and then matrix (tensor) will be the convolutional kernel in the later layer. i.e.
def CrossMult(inputs):
x0, x1 = inputs
#x0 = tf.keras.backend.transpose(x0)
x1 = tf.keras.backend.transpose(x1)
# you apply layer operations to layers
C = keras.layers.dot(axis=-1)(x0,x1)
return C
def Conv1d(inputs):
x, kernel = inputs
Recon = keras.backend.conv1d(x, kernel, strides=1, padding='same',
dilation_rate=1)
return Recon
input0 = input(...
x0 = ConvLayer2(x0)
x1 = ConvLayer2(x1)
layer_conv_kernel = Lambda(Conv1d)
layer_cross_prod = Lambda(CrossMult)
#kernel = keras.layers.Multiply()([x0, x1])
Kernel = layer_cross_prod([x0, x1])
#The Kernelis the cross-convolution between two output vectors and this matrix will be the convolutional kernel in the later layer.
Recon = layer_conv_kernel([input0, kKernel])
# This line raises an error!
# the size of Kernel will be (None, M,N)(error)
Recon = keras.backend.conv1d(input1, Kernel, strides=1, padding='same', dilation_rate=1)
# This line raises another error!
Recon = Conv1D(1, width, strides=1, activation='relu', padding='same')(Recon)