Reshape 2D numpy array into 4D array - python-3.x

I have an y_train (4D) matrix which content is (33, 224, 224, 1) where (n_images, n_pixels_y, n_pixels_x, n_bands) that needed to be transformed into a 2D vector using Flatten
now i need to do the inverse process and turn the 2D vector back to the 4D matrix with the same dimensions, what is the best way to do it?
I've been trying to use reshape but it's not being very effective
Ex:
y_pred = modelo.predict(x_test)
print(y_pred.shape) #this results in the current shape that is (33, 50176)
img = np.reshape(y_pred[1], (33,224,224,1))
plt.imshow(img, cmap='gray')
plt.show() #this results in a error 'cannot reshape array of size 50176 into shape (33,224,224,1)'

Related

Convert 3D Tensor to 4D Tensor in Pytorch

I had difficulty finding information on reshaping in PyTorch. Tensorflow is quite easy.
My tensor has shape torch.Size([3, 480, 480]).
I want to convert it to a 4D tensor with shape [1,3,480,480].
How do I do that?
You can use unsqueeze()
For example:
x = torch.zeros((4,4,4)) # Create 3D tensor
x = x.unsqueeze(0) # Add dimension as the first axis (1,4,4,4)
I've seen a few people use indexing with None to add a singular dimension as well. For example:
x = torch.zeros((4,4,4)) # Create 3D tensor
print(x[None].shape) # (1,4,4,4)
print(x[:,None,:,:].shape) # (4,1,4,4)
print(x[:,:,None,:].shape) # (4,4,1,4)
print(x[:,:,:,None].shape) # (4,4,4,1)
Personally, I prefer unsqueeze(), but it's good to be familiar with both.

Mask a 4d tensor with a 2d mask

I have a tensor which size is (batch_size, seqLength, seqLength, label_number), and a mask tensor with size (batch_size, seqLength), when I calculate loss, I need to mask out the word that I padding in. My question is how to use this 2d mask to masking out the padding samples in the 4d tensor so that I can calculate the right loss?

Conv2d wrong dimensions on Keras

I'm new to Keras and I'm trying to use convolutional autoencoders for image compression.
In particular I'm compressing images which are all of dimensions (365,929). As I'm working with numpy 2D arrays for the images, I add a dimension to make them tensors.
When feeding the network with the images with this code:
X,X_test=train_test_split(images,test_size=0.1)
# Adds 1D to each matrix, so to have a tensor.
X=np.array([np.expand_dims(i,axis=2) for i in X])
# X is (1036, 365, 929, 1) now
X_test=np.array([np.expand_dims(i,axis=2) for i in X_test])
inputs = Input(shape=(365, 929, 1))
h = Conv2D(4,(3,3),activation='relu',padding="same")(inputs)
encoded = MaxPooling2D(pool_size=2,padding="same")(h)
h = Conv2D(4,(3,3),activation='relu',padding="same")(encoded)
h = UpSampling2D((2,2))(h)
outputs = Conv2D(1,(3,3),activation='relu',padding="same")(h)
model = Model(inputs=inputs, output=outputs)
model.compile(optimizer='adam', loss='mse')
model.fit(X, X, batch_size=64, nb_epoch=5, validation_split=.33)
I get the following error:
ValueError: Error when checking target: expected conv2d_3 to have shape (366, 930, 1) but got array with shape (365, 929, 1)
How can I solve this issue? How can I modify the CNN to take images with uneven dimensions?
Your problem lies in the UpSampling2D. You can pad the image with 0s unsymetrically and then crop the image to its original size, as explained here.
To help debugging you can use print(model.Summary()) to check the dimensions of all layers.

How to use Embedding() with 3D tensor in Keras?

I have a list of stock price sequences with 20 timesteps each. That's a 2D array of shape (total_seq, 20). I can reshape it into (total_seq, 20, 1) for concatenation to other features.
I also have news title with 10 words for each timestep. So I have 3D array of shape (total_seq, 20, 10) of the news' tokens from Tokenizer.texts_to_sequences() and sequence.pad_sequences().
I want to concatenate the news embedding to the stock price and make predictions.
My idea is that the news embedding should return tensor of shape
(total_seq, 20, embed_size) so that I can concatenate it with the
stock price of shape (total_seq, 20, 1) then connect it to LSTM layers.
To do that, I should convert news embedding of shape (total_seq, 20, 10) to
(total_seq, 20, 10, embed_size) by using Embedding() function.
But in Keras, the Embedding() function takes a 2D tensor instead of 3D tensor. How do I get around with this problem?
Assume that Embedding() accepts 3D tensor, then after I get 4D tensor as output, I would remove the 3rd dimension by using LSTM to return last word's embedding only, so output of shape (total_seq, 20, 10, embed_size) would be converted to (total_seq, 20, embed_size)
But I would encounter another problem again, LSTM accepts 3D tensor not 4D so
How do I get around with Embedding and LSTM not accepting my inputs?
one workaround is to get all time stamps and news feature together
timesstaps feature = tensor(total_seq, 20)
news_feature = tensor(total_seq, 20, 10)
news_feature_reshaped = reshape(news_feature, (total_seq, 200))
final_features = concat([timestamps_feature, news_fature_reshaped], axis=1)

How to handle variable shape bias in TensorFlow?

I was just modifying some an LSTM network I had written to print out the test error. The issues, I realized, is that the model I had defined depends on the batch size.
Specifically, the input is a tensor of shape [batch_size, time_steps, features]. The input enters the LSTM cell and the output, which I turn into a list of time_steps 2D tensors, with each 2D tensor having shape [batch_size, hidden_units]. Each 2D tensor is then multiplied by a weight vector of shape [hidden_units] to yield a vector of shape [batch_size] which has added to it a bias vector of shape [batch_size].
In words, I give the model N sequences, and I expect it to output a scalar for each time step for each sequence. That is, the output is a list of N vectors, one for each time step.
For training, I give the model batches of size 13. For the test data, I feed the entire data set, which consists of over 400 examples. Thus, an error is raised, since the bias has fixed shape batch_size.
I haven't found a way to make it's shape variable without raising an error.
I can add complete code if requested. Added code anyways.
Thanks.
def basic_lstm(inputs, number_steps, number_features, number_hidden_units, batch_size):
weights = {
'out': tf.Variable(tf.random_normal([number_hidden_units, 1]))
}
biases = {
'out': tf.Variable(tf.constant(0.1, shape=[batch_size, 1]))
}
lstm_cell = rnn.BasicLSTMCell(number_hidden_units)
init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
hidden_layer_outputs, states = tf.nn.dynamic_rnn(lstm_cell, inputs,
initial_state=init_state, dtype=tf.float32)
results = tf.squeeze(tf.stack([tf.matmul(output, weights['out'])
+ biases['out'] for output
in tf.unstack(tf.transpose(hidden_layer_outputs, (1, 0, 2)))], axis=1))
return results
You want the biases to be a shape of (batch_size, )
For example (using zeros instead of tf.constant but similar problem), I was able to specify the shape as a single integer:
biases = tf.Variable(tf.zeros(10,dtype=tf.float32))
print(biases.shape)
prints:
(10,)

Resources