Extending dimensions - numpy

Loading data from tensorflow returns ndarry (x_train, y_train), (x_test, y_test) where the data is of shape (num_samples, 3, 32, 32) I want to extend this shape to include another dimension to have something of [num_classes, num_samples, im_height, im_width, im_channels].
So for Cifar100, for instance, x_train.shape should be (100,50000, 32, 32, 3).
I tried reshaping as in x_train = np.reshape(x_train, (100, len(x_train), 32,32,1)) but this doesnt work. Neither does adding a new axis solve the problem.

You can't reshape because the total number of elements is different.
You need to create a new array and copy the data in whatever pattern you need. For example:
new_x_train = np.empty((100, 50000, 32, 32, 3), x_train.dtype)
new_x_train[:] = x_train # 100 copies of x_train using broadcasting
Or, equivalently:
new_x_train = np.broadcast_to(x_train, (100, 50000, 32, 32, 3))

Related

Tensorflow: Shapes (None, 1) and (None, 1, 10) are incompatible

I'm building an RNN and am having trouble passing in the data. The csv file I'm pulling data from has a sentence column, and a label column that's filled with a binary classification value (1 or 0). This is how I'm preprocessing right now:
data = pd.read_csv(r'/cybersecurity-sqlinjection/sqli.csv', encoding='utf-8')
vectorizer = TfidfVectorizer(norm = False, smooth_idf = False, analyzer='word', stop_words=stopwords.words('english'))
sentence_vectors = vectorizer.fit_transform((data['Sentence'].values.astype('U')))
df = pd.DataFrame(sentence_vectors.toarray())
X=df[df.columns]
y=data['Label']
X_train, X_test, y_train, y_test =train_test_split(X,y, train_size=0.8, test_size=0.2, random_state=42)
X.head()
Next I was passing in X_train to an LSTM model. At this point I was receiving errors about the shape of the data being passed in to the model, so I used the first response on this issue. I added this to the end of my code, before inputting the data into the model.
X_train_shape = X_train.shape #outputs (19327, 15016)
X_train = X_train.values.reshape(-1, 1, 15016)
model = keras.models.Sequential()
model.add(keras.layers.LSTM(15, input_shape=(1, 15016), return_sequences=True))
Now this error is being returned ValueError: Shapes (None, 1) and (None, 1, 10) are incompatible
I'm not sure what the issue is and would appreciate any help!

ValueError: Input 0 is incompatible with layer resnet50: expected shape=(None, 180, 180, 3), found shape=(180, 180, 3)

With TFF 0.18, I found this problem :
images, labels = next(img_gen.flow_from_directory(path0,target_size=(180, 180), batch_size = 2,class_mode=None))
sample_batch = (images,labels) # assumes images and labels are np.ndarray
input_spec = tf.nest.map_structure(tensor_spec_from_ndarray, sample_batch)
here is the output of input_spec
(TensorSpec(shape=(180, 180, 3), dtype=tf.float32, name=None), TensorSpec(shape=(180, 180, 3), dtype=tf.float32, name=None))
And here is my model:
model = tf.keras.applications.ResNet50(include_top=False, weights=None, input_tensor=tf.keras.Input(shape=(180, 180, 3)), pooling=None)
At a high level, the error message is saying the tensors are not the same rank (4 vs 3).
expected shape=(None, 180, 180, 3)
The expected shape has a leading None dimension, which is the batch dimension.
found shape=(180, 180, 3)
The found shape only has rank 3, with no batch dimension.
This is somewhat surprising from the code in the question which has the line batch_size = 2. I would dig into how that parameter is used by the img_gen.flow_from_directory() function to see if getting a batch dimension is possible.

How to Feed Batched Sequences of Images through Tensorflow conv2d

This seems like a trivial question, but I've been unable to find the answer.
I have batched sequences of images of shape:
[batch_size, number_of_frames, frame_height, frame_width, number_of_channels]
and I would like to pass each frame through a few convolutional and pooling layers. However, TensorFlow's conv2d layer accepts 4D inputs of shape:
[batch_size, frame_height, frame_width, number_of_channels]
My first attempt was to use tf.map_fn over axis=1, but I discovered that this function does not propagate gradients.
My second attempt was to use tf.unstack over the first dimension and then use tf.while_loop. However, my batch_size and number_of_frames are dynamically determined (i.e. both are None), and tf.unstack raises {ValueError} Cannot infer num from shape (?, ?, 30, 30, 3) if num is unspecified. I tried specifying num=tf.shape(self.observations)[1], but this raises {TypeError} Expected int for argument 'num' not <tf.Tensor 'A2C/infer/strided_slice:0' shape=() dtype=int32>.
Since all the images (num_of_frames) are passed to the same convolutional model, you can stack both batch and frames together and do the normal convolution. Can be achieved by just using tf.resize as shown below:
# input with size [batch_size, frame_height, frame_width, number_of_channels
x = tf.placeholder(tf.float32,[None, None,32,32,3])
# reshape for the conv input
x_reshapped = tf.reshape(x,[-1, 32, 32, 3])
x_reshapped output size will be (50, 32, 32, 3)
# define your conv network
y = tf.layers.conv2d(x_reshapped,5,kernel_size=(3,3),padding='SAME')
#(50, 32, 32, 3)
#Get back the input shape
out = tf.reshape(x,[-1, tf.shape(x)[1], 32, 32, 3])
The output size would be same as the input: (10, 5, 32, 32, 3
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(out, {x:np.random.normal(size=(10,5,32,32,3))}).shape)
#(10, 5, 32, 32, 3)

Data Preprocessing - Input Shape for TimeDistributed CNN (LRCN) & ConvLSTM2D for Video Classification

I'm trying to do binary classification for labeled data for 300+ videos. The goal is to extract features using a ConvNet and feed into to an LSTM for sequencing with a binary output after evaluating all the frames in the video. I've preprocessed each video to have exactly 200 frames with each image being 256 x 256 so that it would be easier to feed into a DNN and split the dataset into two folders as labels. (e.g. dog and cat)
However, after searching stackoverflow for hours, I'm still unsure how to reshape the dataset of video frames so that the model accounts for the number of frames. I'm trying to feed the video frames into a 3D ConvNets and TimeDistributed (2DConvNets) + LSTM, (e.g. (300, 200, 256, 256, 3) ) with no luck. I'm able to perform 2D ConvNet classification (data is a 4D Tensor, need to add a time step dimension to make it a 5D Tensor
) pretty easily but now having issues wrangling with the temporal aspect.
I've been using Keras ImageDataGenerator and train_datagen.flow_from_directory to read in the images and have been running into shape mismatch errors when I attempt to feed it to a TimeDistributed ConvNet. I know hypothetically if I have a X_train dataset I can potentially do X_train = X_train.reshape(...). Any example code would be very much appreciated.
I think you could use ConvLSTM2D in Keras for your purpose. ImageDataGenerator is very good for CNN with images, but may be not convenient for CRNN with videos.
You have already transformed your 300 videos data in the same shape (200, 256, 256, 3), each video 200 frames, each frame 256x256 rgb. Next, you need to load them in a numpy array in shape (300, 200, 256, 256, 3). For reading videos in numpy arrays see this answer.
Then you can feed the data in a CRNN. Its first ConvLSTM2D layer should have input_shape = (None, 200, 256, 256, 3).
A sample according to your data: (only illustrated and not tested)
from keras.models import Sequential
from keras.layers import Dense
from keras.layers.convolutional_recurrent import ConvLSTM2D
model = Sequential()
model.add(ConvLSTM2D(filters = 32, kernel_size = (5, 5), input_shape = (None, 200, 256, 256, 3)))
### model.add(...more layers)
model.add(Dense(units = num_of_categories, # num of your vedio categories
kernel_initializer = 'Orthogonal', activation = 'softmax'))
model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
# then train it
model.fit(video_data, # shape (300, 200, 256, 256, 3)
[list of categories],
batch_size = 20,
epochs = 50,
validation_split = 0.1)
I hope this could be a little helpful.

ValueError: Cannot feed value of shape (64, 200, 75) for Tensor 'TargetsData/Y:0', which has shape '(200, 75)'

I know this is a dumb question but I cant seem to figure it out. I feed in a numpy array of (?,200,75) and get this error:
ValueError: Cannot feed value of shape (64, 200, 75) for Tensor 'TargetsData/Y:0', which has shape '(200, 75)'
Here is my code:
import numpy as np
import tflearn
print("loading features....")
features = np.load("features_xs.npy")
print("loading classes....")
classes = np.load("classes_xs.npy")
symbols = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'
,'q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U',
'V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0','.',',',
'!','?',':',';','\'','(',')','-','_',' ','"',]
num_symbols = len(symbols)
input_layer = tflearn.input_data(shape=[None, 200,num_symbols])
input_layer = tflearn.flatten(input_layer)
dense1 = tflearn.fully_connected(input_layer, 1000, activation='tanh',
regularizer='L2', weight_decay=0.001)
dense2 = tflearn.fully_connected(dense1, 2000, activation='tanh',
regularizer='L2', weight_decay=0.001)
dense2 = tflearn.fully_connected(dense2, 1000, activation='tanh',
regularizer='L2', weight_decay=0.001)
dropout2 = tflearn.dropout(dense2, 0.8)
final = tflearn.fully_connected(dropout2, (200*num_symbols), activation='tanh')
reshape = tflearn.reshape(final, [200,num_symbols], name="Reshape")
Adam = tflearn.Adam(learning_rate=0.01)
net = tflearn.regression(reshape, optimizer=Adam,
loss='categorical_crossentropy')
# Training
model = tflearn.DNN(net, tensorboard_verbose=0)
model.fit(features, classes, n_epoch=1, show_metric=True, run_id="dense_model")
model.save("model")
num_symbols is == to 75 in case you're wondering
I can't find the solution please help thanks.
Run the following code:
print(classes.shape)
You will be getting an output of (64, 200, 75). But your final layer reshape is expecting shape of (200, 75). You will have to supply values with shape of (200, 75) from your classes variable to resolve the error.