How to Concatenate "Jagged" Tensors - python

I am trying to write an implementation of this paper in TensorFlow and I have come across a bit of a snag. In my pooling layer, I have to concatenate everything together. This is the code I use:
pooled_outputs = []
for i, filter_size in enumerate(filter_sizes):
with tf.name_scope("conv-maxpool-%s" % filter_size):
# Conv layer
filter_shape = [filter_size, embedding_size, 1, num_filters]
# W is the filter matrix
W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W")
b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b")
conv = tf.nn.conv2d(
self.embedded_chars_expanded,
W,
strides=[1, 1, 1, 1],
padding="VALID",
name="conv"
)
# Apply nonlinearity
h = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu")
# Max-pooling layer over the outputs
pooled = tf.nn.max_pool(
h,
ksize=[1, sequence_lengths[i] - filter_size + 1, 1, 1],
strides=[1, 1, 1, 1],
padding="VALID",
name="pool"
)
pooled_outputs.append(pooled)
# Combine all of the pooled features
num_filters_total = num_filters * len(filter_sizes)
print(pooled_outputs)
pooled_outputs = [tf.reshape(out, ["?", 94, 1, self.max_length]) for out in pooled_outputs] # The problem line
self.h_pool = tf.concat(3, pooled_outputs)
When I run this code, it prints out this for pooled_outputs:
[<tf.Tensor 'conv-maxpool-3/pool:0' shape=(?, 94, 1, 128) dtype=float32>, <tf.Tensor 'conv-maxpool-4/pool:0' shape=(?, 51, 1, 128) dtype=float32>, <tf.Tensor 'conv-maxpool-5/pool:0' shape=(?, 237, 1, 128) dtype=float32>]
I originally tried this code without the pooled_outputs = [tf.reshape(out, ["?", 94, 1, self.max_length]) for out in pooled_outputs] line in there and I got this error:
ValueError: Dimension 1 in both shapes must be equal, but are 51 and 237
When I added in the reshape line, I got this error:
TypeError: Expected binary or unicode string, got 94
The second error I know is because I passed a "?" for the new size, and the first error I think is because the tensors aren't the same size. How could I properly pad these Tensors so I can concatenate them with no problems?

You can pass -1 as one of the component of the shape to the tf.reshape method; it will be automatically inferred from the the shape of you tensor so the total size will be the same.
So, try to change the problem line to
pooled_outputs = [tf.reshape(out, [-1, 94, 1, self.max_length]) for out in pooled_outputs]
See the documentation for details

Related

Pytorch 3D cnn input shapes incompatible

I am attempting to classify 3D blocks of data with H,D,W of 64,1024,64 respectively. These are done in batches of 2. However the input shapes do not seem to be loading in correctly and I get the error: Expected 4D (unbatched) or 5D (batched) input to conv3d, but got input of size: [2, 1]. However the input shape is [2, 1, 64, 1024, 64].
Please see the code below:
print('Images shape ', images.shape)
# forward + backward + optimize
outputs = Net(images)
Which calls the CNN3D class:
class CNN3D(nn.Module):
def __init__(self, input_shape, conv_layers, kernel_size, out_channel_ratio, FC_layers):
super(CNN3D, self).__init__()
self.input = input_shape
model = [
self._conv_layer_set(1, 8),
# self._conv_layer_set(8, 16),
# self._conv_layer_set(16, 32),
nn.Flatten(),
# nn.Linear((6*14*6), 256),
# nn.LeakyReLU(),
# nn.Linear(256, 128),
# nn.LeakyReLU(),
# nn.Linear(1952752, 1)
nn.LazyLinear(1)
]
self.model = nn.Sequential(*model)
def _conv_layer_set(self, in_c, out_c):
conv_layer = nn.Sequential(
nn.Conv3d(in_c, out_c, kernel_size=(3, 7, 3), padding=0),
nn.LeakyReLU(),
nn.MaxPool3d((2, 4, 2)),
)
return conv_layer
def forward(self, x):
print('Input shape ', self.input)
for layer in self.model:
x = layer(x)
print(x.size())
return self.model(x)
This gives the following output:
Images shape torch.Size([2, 1, 64, 1024, 64])
Images shape torch.Size([2, 1, 64, 1024, 64])
Input shape (1, 64, 1024, 64)
torch.Size([2, 8, 31, 254, 31])
torch.Size([2, 1952752])
torch.Size([2, 1])
return F.conv3d(
RuntimeError: Expected 4D (unbatched) or 5D (batched) input to conv3d, but got input of size: [2, 1]
The error seems inconsistent with the input shape so I am not sure what is going on.
Thanks

Input to reshape is a tensor with 497664 values, but the requested shape has 3072 [Op:Reshape]

I am creating patches of xception model, when I apply patches class and then reshape it then it generates an error of incompatibility between patches and reshape layers. I did not find any suitable documentation to study about calculation of parameters in patch layer to reshape them in proper dimensions for the next layer. That's why when I run this code it generates the error mentioned in title. How would I know the math to go from one layer to another and define proper size of patches = tf.reshape(patches, [1, 32, 32, 3]) to make patches from it's above layer patches = Patches(patch_size)(xception_input) without errors. My code is something like below
class Patches(layers.Layer):
def __init__(self, patch_size):
super(Patches, self).__init__()
self.patch_size = patch_size
def call(self, images):
batch_size = tf.shape(images)[0]
patches = tf.image.extract_patches(
images=images,
sizes=[1, self.patch_size, self.patch_size, 1],
strides=[1, self.patch_size, self.patch_size, 1],
rates=[1, 1, 1, 1],
padding="VALID",
)
patch_dims = patches.shape[-1]
patches = tf.reshape(patches, [batch_size, -1, patch_dims])
return patches
Model code
xception = keras.applications.Xception(
include_top=False, weights="imagenet", pooling="avg"
)
for layer in xception.layers:
layer.trainable = trainable
inputs = layers.Input(shape=(299, 299, 3), name="image_input")
patch_size = 72
print("patch_size shape is ", patch_size.shape)
print("inputs shape is ", inputs.shape)
xception_input = tf.keras.applications.xception.preprocess_input(inputs)
print("xception shape is ", xception_input.shape)
patches = Patches(patch_size)(xception_input)
print("patches shape is ", patches.shape)
patches = tf.reshape(patches, [1, 32, 32, 3])
print("patches reshape shape is ", patches.shape)
embeddings = xception(patches)
return keras.Model(inputs, embeddings, name="vision_encoder")
Output shape
patch_size shape is 72
inputs shape is (None, 299, 299, 3)
xception shape is (None, 299, 299, 3)
patches shape is (None, None, 15552)
patches reshape shape is (1, 32, 32, 3)
Update
When I change the patch code part like below
class Patches_en(layers.Layer):
def __init__(self, patch_size):
super(Patches_en, self).__init__()
self.patch_size = patch_size
def call(self, images):
#batch_size = tf.shape(images)[0]
patches = tf.image.extract_patches(
images=images,
sizes=[1, self.patch_size, self.patch_size, 1],
strides=[1, self.patch_size, self.patch_size, 1],
rates=[1, 1, 1, 1],
padding="VALID",
)
return patches
Output
inputs shape is (None, 299, 299, 3)
xception shape is (None, 299, 299, 3)
patches shape is (None, 4, 4, 15552)
and it generates this error
ValueError: Exception encountered when calling layer "tf.reshape" (type
TFOpLambda).
Dimension size must be evenly divisible by 248832 but is 3072 for '{{node tf.reshape/Reshape}} = Reshape[T=DT_FLOAT, Tshape=DT_INT32](Placeholder, tf.reshape/Reshape/shape)' with input shapes: [?,4,4,15552], [4] and with input tensors computed as partial shapes: input[1] = [1,32,32,3].
Call arguments received:
• tensor=tf.Tensor(shape=(None, 4, 4, 15552), dtype=float32)
• shape=['1', '32', '32', '3']
• name=None

How do I explain this TensorFlow tf.nn.conv2d() layer shape?

My Tensorflow convolutional layer has a shape I did not expect it to have and I do not see the mistake.
I am new to TensorFlow and want to use this function to create a convolutional layer:
def new_conv_layer(input, # The previous layer.
num_input_channels, # Num. channels in prev. layer.
filter_size, # Width and height of each filter.
num_filters, # Number of filters.
use_pooling=True): # Use 2x2 max-pooling.
shape = [filter_size, filter_size, num_input_channels, num_filters]
weights = new_weights(shape=shape)
biases = new_biases(length=num_filters)
layer = tf.nn.conv2d(input=input_,
filters=weights,
strides=[1, 1, 1, 1],
padding='SAME')
layer += biases
if use_pooling:
layer = tf.nn.max_pool(input=layer,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME')
layer = tf.nn.relu(layer)
return layer, weights
But when I use it with
num_channels = 1
img_size = 28
x_image = tf.reshape(x, [-1, img_size, img_size, num_channels])
# Convolutional Layer 1.
filter_size1 = 5 # Convolution filters are 5 x 5 pixels.
num_filters1 = 16 # There are 16 of these filters.
layer_conv1, weights_conv1 = new_conv_layer(input=x_image,
num_input_channels=num_channels,
filter_size=filter_size1,
num_filters=num_filters1,
use_pooling=True)
layer_conv1
I get this output:
<tf.Tensor 'Relu:0' shape=(None, 392, 392, 16) dtype=float32>
Because my images are of a square 28x28 shape and I apply 2x2 pooling, I would have expected this shape to be (None, 14, 14, 16).
Why is that not the case and how do I fix it?
in my case this line x = tf.compat.v1.placeholder(tf.float32, shape=[None, img_size_flat], name='x') was incorrect!
In particular img_size_flat was not the length of each "stretched" image, as it should have been.
img_size_flat = df.drop('label', axis=1).shape[1]

tf.layers.conv2d and tf.nn.conv2d Different outputs with same architecture

Note: I read the similar thread here, but it doesn't cover my use case.
I'm building a GAN and am converting my discriminator design from using tf.nn.conv2d (following some example code) to tf.layers.conv2d. Both designs use the same inputs, kernel sizes, strides, yet I'm getting different results between the two.
Both versions should be 28x28x1 input -> conv2d with a 5x5 kernel, 2 stride, 16 layers, leaky relu -> conv2d with a 3x3 kernel, 2 stride, 32 layers, leaky relu -> flatten to 7*7*32 -> 256 neuron dense network with leaky relu -> 1 value output.
I've checked the weight initialization. tf.layers.conv2d defaults to
xaiver init as shown here.
layers version:
def discriminator(x):
# Reshape to a 28x28 image with one layer of depth (greyscale)
x = tf.reshape(x, shape=[-1, 28, 28, 1])
with tf.variable_scope('discriminator', reuse=tf.AUTO_REUSE) as scope:
# Defaults to Xavier init for weights and Zeros for bias
disc_conv1 = tf.layers.conv2d(
inputs = x,
filters = 16,
kernel_size=5,
strides=2,
padding="same",
activation=tf.nn.leaky_relu
)
disc_conv2 = tf.layers.conv2d(
inputs = disc_conv1,
filters = 32,
kernel_size=3,
strides=2,
padding="same",
activation=tf.nn.leaky_relu
)
disc_conv2 = tf.reshape(disc_conv2, shape=[-1, 7 * 7 * 32])
disc_h1 = tf.layers.dense(disc_conv2, units=hidden1_dim, activation=tf.nn.leaky_relu)
disc_logits = tf.layers.dense(disc_h1, units=1)
disc_out = tf.nn.sigmoid(disc_logits)
return disc_logits, disc_out
nn version:
DC_D_W1 = tf.get_variable('DC_D_W1', shape=[5, 5, 1, 16], initializer=tf.contrib.layers.xavier_initializer())
DC_D_b1 = tf.get_variable('2', initializer=tf.zeros(shape=[16]))
DC_D_W2 = tf.get_variable('3', shape=[3, 3, 16, 32], initializer=tf.contrib.layers.xavier_initializer())
DC_D_b2 = tf.get_variable('4', initializer=tf.zeros(shape=[32]))
DC_D_W3 = tf.get_variable('5', shape=[7 * 7 * 32, 256], initializer=tf.contrib.layers.xavier_initializer())
DC_D_b3 = tf.get_variable('6', initializer=tf.zeros(shape=[256]))
DC_D_W4 = tf.get_variable('7', shape= [256, 1], initializer=tf.contrib.layers.xavier_initializer())
DC_D_b4 = tf.get_variable('8', initializer=tf.zeros(shape=[1]))
theta_DC_D = [DC_D_W1, DC_D_b1, DC_D_W2, DC_D_b2, DC_D_W3, DC_D_b3, DC_D_W4, DC_D_b4]
def discriminator(x):
x = tf.reshape(x, shape=[-1, 28, 28, 1])
conv1 = tf.nn.leaky_relu(tf.nn.conv2d(x, DC_D_W1, strides=[1, 2, 2, 1], padding='SAME') + DC_D_b1)
conv2 = tf.nn.leaky_relu(tf.nn.conv2d(conv1, DC_D_W2, strides=[1, 2, 2, 1], padding='SAME') + DC_D_b2)
conv2 = tf.reshape(conv2, shape=[-1, 7 * 7 * 32])
h = tf.nn.leaky_relu(tf.matmul(conv2, DC_D_W3) + DC_D_b3)
logit = tf.matmul(h, DC_D_W4) + DC_D_b4
prob = tf.nn.sigmoid(logit)
return logit, prob

Dimensionality error after applying a dense layer

I am trying to add a dense layer after applying dropout to the max pooled convolutional layer output.
I have the following TensorFlow code written in Python. Number of filters is 128 and len(filter_sizes) is 3
pooled_outputs = []
for i, filter_size in enumerate(filter_sizes):
with tf.name_scope("conv-maxpool-%s" % filter_size):
# Convolution Layer
filter_shape = [filter_size, embedding_size, 1, num_filters]
W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W")
b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b")
conv = tf.nn.conv2d(
self.embedded_chars_expanded,
W,
strides=[1, 1, 1, 1],
padding="VALID",
name="conv")
# Applying batch normalization
# h = tf.contrib.layers.batch_norm(conv, center=True, scale=True, is_training=True)
# Apply nonlinearity
h1 = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu")
# Maxpooling over the outputs
pooled = tf.nn.max_pool(
h1,
ksize=[1, sequence_length - filter_size + 1, 1, 1],
strides=[1, 1, 1, 1],
padding='VALID',
name="pool")
pooled_outputs.append(pooled)
# Combine all the pooled features
num_filters_total = num_filters * len(filter_sizes)
self.h_pool = tf.concat(pooled_outputs, 3)
self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total])
# Add dropout
with tf.name_scope("dropout"):
#self.h_drop = tf.nn.dropout(dense, self.dropout_keep_prob)
self.h_drop = tf.nn.dropout(self.h_pool_flat, self.dropout_keep_prob)
# Adding dense layer
dense = tf.layers.dense(self.h_drop, units=num_classes, activation=tf.nn.relu)
Facing issues after the application of the dense layer.
Following is the error:
Dimensions must be equal, but are 11 and 384 for 'output/scores/MatMul' (op: 'MatMul') with input shapes: [?,11], [384,11]
Could someone please help me with it?
The error was with the indices of the matrices. I was using the xw_plus_b function provided by tensorflow and using the dimensions of the matrices for multiplication wrong.

Categories