How to Build a 2D Weights Matrix in Keras? - python

I am trying to solve the problem of:
X*transpose(X) == const matrix
Where I need to find X (which is an N by N matrix).
I cannot figure out a way to represent X as the weights in keras. The dense layer forces a 1D shape. If I use Lambda with Embedding it won't accept the Embedding layer.

Related

Training a modified fully-connected neural network

Take a simple 3 layer MLP neural network such as this. Each hidden layer implements y=xw+b where y is the output activations matrix of the layer of shape [batch_size, output_size], x is the input activations matrix of shape [batch_size, input_size], w is the trainable weights matrix of shape [input_size, output_size] and b is the trainable bias vector of shape [output_size].
Now modify the layer definition so each layer implements y = x(w mod m) + b where m is a trainable matrix similar to w and of same shape as w. Since tensorflow implements gradient of the modulo function for backprop, propagating gradients due to the added modulo shouldn't be an issue. Making this fairly trivial modification in the network breaks the MLP and the network stops learning altogether. In other words, the accuracy falls to ~10% for MNIST (10 digit classification) equivalent to random guessing.
Would anyone have any guesses as to why the network fails to learn with the added mod operator? I am able to implement y=xw + (b mod m) which works just fine. The problem seems to appear only when mod is used with the xw term.

Classification of individual values with matrix

I have a series of matrices 30x30 matrices that contain elements ranging from 0 to 75 (input matrices) and each one has a 30x30 matrix containing only 1s and 0s (output matrices). I am trying to train a classifier on the input matrices to predict the output matrices, however I am not sure how to best represent the input matrices for the classifier (ideally sk-learn). I can't abstract the matrices to another form as each element from the input matrix must map to the element in the same location of the output matrix. Has anyone tried to something similar?
Option 1: Multi label classifier
You can flatten the 30X30 matrix into a 900 element vector and feed it to a neural network for multi label classification
https://en.wikipedia.org/wiki/Multi-label_classification
Treat 30X30 matrix as a single channel image and model a CNN with proper loss function for multi label classification.
Option 2: Sequence to Sequence classifier
Flatten the 30X30 matrix into a 900 element vector and build a LSTM with 900 timesteps with ith element in the vector being input to ith timestep. The LSTM is connected to a Dense layer with sigmoid activation (2 class classification). If you use keras for implementaiton you will have to use return_sequence=True for this.

Train on transformed output

I have a recurrent neural network model that maps a (N,) sequence to a (N,3) length sequence. My target outputs are actually (N,N) matrices. However, I have a deterministic function implemented in numpy that converts (N,3) into these (N,N) matrices in a particular way that I want. How can I use this operation in training? I.e. currently my neural network is giving out (N,3) sequences, how do I perform my function to convert it to (N,N) on these before calling keras.fit?
Edit: I should also note that it is much harder to do the reverse function from (N,N) to (N,3) so it's not a viable option to just convert my target outputs to the (N,3) output representations.
You can use a Lambda layer as the last layer of your model:
def convert_to_n_times_n(x):
# transform x from shape (N, 3) to (N, N)
transformation_layer = tf.keras.layers.Lambda(convert_to_n_times_n)
You probably want to use "tf-native methods" within your function as much as possible to avoid unnecessary conversions of tensors to numpy arrays and back.
If you only want to use the layer during training, but not during inference, you can achieve that using the functional API:
# create your original model (N,) -> (N, 3)
input_ = Input(shape=(N,))
x = SomeFancyLayer(...)(input_)
x = ...
...
inference_output = OtherFancyLayer(...)(x)
inference_model = Model(inputs=input_, outputs=inference_output)
# create & fit the training model
training_output = transformation_layer(inference_output)
training_model = Model(inputs=input_, outputs=training_output)
training_model.compile(...)
training_model.fit(X, Y)
# run inference using your original model
inference_model.predict(...)

Unflattening Layer in Keras

I would like to create a simple Keras neural network that accepts an input matrix of dimension (rows, columns) = (n, m), flattens the matrix to a dimension (n*m, 1), sends the flattened matrix through a number of arbitrary layers, and in the final layer, once more unflattens the matrix to a dimension of (n, m) before releasing this final matrix as an output.
The issue I'm having is that I haven't found any documentation for an Unflatten layer at the keras.io page, and I'm wondering whether there is a reason that such a seemingly standard common use layer doesn't exist. Is there a much more natural and easy way to do what I'm proposing?
You can use the Reshape layer for this purpose. It accepts the desired output shape as its argument and would reshape the input tensor to that shape. For example:
from keras.layers import Reshape
rsh_inp = Reshape((n*m, 1))(inp) # if you don't want the last axis with dimension 1, you can also use Flatten layer
# rsh_inp goes through a number of arbitrary layers ...
# reshape back the output
out = Reshape((n,m))(out_rsh_inp)

How to calculate output dimensions in CNN if you specify number of outputs

I am having trouble figuring out what the dimensions of each CNN layer is.
Let's say my input is a vector which I then projected onto a 4x4x256 matrix using a fully-connected layer as so...
zP = slim.fully_connected(
z,
4*4*256,
normalizer_fn=slim.batch_norm,
activation_fn=tf.nn.relu,
scope='g_project',
weights_initializer=initializer
)
# Layer is reshaped to a 4x4x256 mapping.
zCon = tf.reshape(zP,[-1,4,4,256])
Where z was my original vector. I then take this 4x4x256 matrix and feed it into a CNN...
gen1 = slim.convolution2d_transpose(
zCon,
num_outputs=64,
kernel_size=[5,5],
stride=[2,2],
padding="SAME",
normalizer_fn=slim.batch_norm,
activation_fn=tf.nn.relu,
scope='g_conv1',
weights_initializer=initializer
)
As you can see I used a convolutional 2d transpose and I specified the output as 64, with a stride of 2 and a filter size of 5. This means that I know one of my dimension will be 64, however I do not know what the other 2 dimensions will be and I do not know how to calculate it.
I tried using the following formula but it is not working out for me...
How can I calculate the remaining dimensions?
The formula you have written is for the Convolution operation, since you need to calculate for the transposed convolution where the shapes are inverse of convolution, the formula can be derived from the above equation by re-arranging the terms as:
W = (Out-1)*S + F - 2P
W is your actual output and Out is your actual input to the transpose convolution.

Categories