In yolo Can I continue to training from final .weight with different class of images? - object-detection

I want to train a few products for image classification in Yolo. Let's say I have trained with 10 products (means 10 classes) and saved the best file. Now I want to add some more data of other products (means some new class names and images). So, can I call the previous trained model and then train again with only the new class of images? If not then is there any way to retrain my model not from scratch but from the last trained file with new class of images. Please, reply.
I have tried this code:
!python train.py --workers 8 --batch-size 16 --data products/data.yaml --img 640 640 --cfg cfg/training/yolov7_custom.yaml --epochs 5 --weights 'runs/train/products/weights/last.pt' --name yolov7_custom_newClass --hyp data/hyp.scratch.custom.yaml --device 0
Here, "last.pt" is the previous trained file, and "data.yaml" is the new data yaml file, whose number of classes is different as new images with new class names, after running the code, it show me this error:
RuntimeError: Error(s) in loading state_dict for Model:
size mismatch for model.105.m.0.weight: copying a param with shape torch.Size([30, 256, 1, 1]) from checkpoint, the shape in current model is torch.Size([21, 256, 1, 1]).
size mismatch for model.105.m.0.bias: copying a param with shape torch.Size([30]) from checkpoint, the shape in current model is torch.Size([21]).
size mismatch for model.105.m.1.weight: copying a param with shape torch.Size([30, 512, 1, 1]) from checkpoint, the shape in current model is torch.Size([21, 512, 1, 1]).
size mismatch for model.105.m.1.bias: copying a param with shape torch.Size([30]) from checkpoint, the shape in current model is torch.Size([21]).
size mismatch for model.105.m.2.weight: copying a param with shape torch.Size([30, 1024, 1, 1]) from checkpoint, the shape in current model is torch.Size([21, 1024, 1, 1]).
size mismatch for model.105.m.2.bias: copying a param with shape torch.Size([30]) from checkpoint, the shape in current model is torch.Size([21]).
size mismatch for model.105.im.0.implicit: copying a param with shape torch.Size([1, 30, 1, 1]) from checkpoint, the shape in current model is torch.Size([1, 21, 1, 1]).
size mismatch for model.105.im.1.implicit: copying a param with shape torch.Size([1, 30, 1, 1]) from checkpoint, the shape in current model is torch.Size([1, 21, 1, 1]).
size mismatch for model.105.im.2.implicit: copying a param with shape torch.Size([1, 30, 1, 1]) from checkpoint, the shape in current model is torch.Size([1, 21, 1, 1]).
Looks like, as the new data.yaml file's number of classes are differnet from previous models, That's why this error occured.. Any solution.

Related

Tensorflow 2 timeseries_dataset_from_array input vs target batch shapes difference

The new tf.keras.preprocessing.timeseries_dataset_from_array function is used to create sliding minibatch windows over the sequential data, for example for tasks involving rnn networks.
According to the docs it returns a minibatch of inputs and targets. However, the target minibatch this function returns does not have a sequence_length (timesteps) dimension. For example.
data = timeseries_dataset_from_array(
data=tokens,
targets=targets,
sequence_length=25,
batch_size=32,
)
for minbatch in data:
inputs, targets = minbatch
assert(inputs.shape[1] == targets.shape[1]) # error
The inputs have [32, 25, 1] shape in case you already just have word indices there and targets confusingly have [32, 1] shape.
So, my question is how am I supposed to map a tensor of inputs with a window of 25 units to a target tensor with a window of 0 units?
How I always train sequence models is by feeding the input tensor of [32, 25, 1] which is then projected into [32, 25, 100] and then you feed the target tensor to the network of size [32, 25, 1] to your loss function or if you have multi-class problem a target vector of [32, 25, num_of_classes].
That is why I am confused by the shape of the target tensor from timeseries_dataset_from_array and the intuition behind it.

Is it possible to change the input shape of a tensorflow pretrained model?

I have a Tensorflow pre-trained model for Image Segmentation that receives 6 bands as input, I would like to change the input size of the model to receive 4 bands so I can retrain with my own dataset, but still not able to do it, no sure if this is even possible?
I tried getting the input node by name and change it using import_graph_def with no success, seems like it is asking to respect the dimensions when trying to substitute.
graph = tf.get_default_graph()
tf_new_input = tf.placeholder(shape=(4, 256, 256), dtype='float32', name='new_input')
tf.import_graph_def(graph_def, input_map={"ImageInputLayer": tf_new_input})
But I am getting the following error:
tensorflow.python.framework.errors_impl.InvalidArgumentError: Dimensions must be equal, but are 4 and 6 for 'import/ImageInputLayer_Sub' (op: 'Sub') with input shapes: [4,256,256], [6,256,256]
You have to convert your 4 channel placeholder input to 6 channel input and also the input image shape should be the same as your 6 channel model expects. You may use any operation but conv2d is an easy operation to perform before you feed it to your existing model. This is how you do it.
with tf.Graph().as_default() as old_graph:
# You have to load your 6 channel input graph here
saver.restore(tf.get_default_session(), <<save_path>>)
# Assuming that input node is named as 'input_node' and
# final node is named as 'softmax_node'
with tf.Graph().as_default() as new_graph:
tf_new_input = tf.placeholder(shape=(None, 256, 256, 4), dtype='float32')
# Map 4 channeled input to 6 channel and
# image input shape should be same as expected by old model.
new_node = tf.nn.conv2d(tf_new_input, (3, 3, 4, 6), strides=1, padding='SAME')
# If you want to obtain output node so that you can further perform operations.
softmax_node = tf.import_graph_def(old_graph, input_map={'input_node:0': new_node},
return_elements=['softmax_node:0'])
user1190882 responded this question very well. Just using this section to post the code for future reference, I had to make a small change by creating the filter in a separate variable since I was getting an error : Shape must be rank 4 but is rank 1 for 'Conv2D' . Also I made a small change since the input format of my model is "Channels First", I added data_format flag.
with tf.Graph().as_default() as new_graph:
tf_new_input = tf.placeholder(shape=(None, 4, 256, 256), dtype='float32')
# Creating separate variable for filter
filterc = tf.Variable(tf.random_normal([3, 3, 4, 6]))
new_node = tf.nn.conv2d(tf_new_input, filterc, strides=1, padding='SAME', data_format='NCHW')
tf.import_graph_def(old_graph, input_map={'ImageInputLayer': new_node})

The input dimension of the LSTM layer in Keras

I'm trying keras.layers.LSTM.
The following code works.
#!/usr/bin/python3
import tensorflow as tf
import numpy as np
from tensorflow import keras
data = np.array([1, 2, 3]).reshape((1, 3, 1))
x = keras.layers.Input(shape=(3, 1))
y = keras.layers.LSTM(10)(x)
model = keras.Model(inputs=x, outputs=y)
print (model.predict(data))
As shown above, the input data shape is (1, 3, 1), and the actual input shape in the Input layer is (3, 1). I'm a little bit confused about this inconsistency of the dimension.
If I use the following shape in the Input layer, it doesn't work:
x = keras.layers.Input(shape=(1, 3, 1))
The error message is as follows:
ValueError: Input 0 of layer lstm is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [None, 1, 3, 1]
It seems that the rank of the input must be 3, but why should we use a rank-2 shape in the Input layer?
Keras works with "batches" of "samples". Since most models use variable batch sizes that you define only when fitting, for convenience you don't need to care about the batch dimension, but only with the sample dimension.
That said, when you use shape = (3,1), this is the same as defining batch_shape = (None, 3, 1) or batch_input_shape = (None, 3, 1).
The three options mean:
A variable batch size: None
With samples of shape (3, 1).
It's important to know this distinction especially when you are going to create custom layers, losses or metrics. The actual tensors all have the batch dimension and you should take that into account when making operations with tensors.
Check out the documentation for tf.keras.Input. The syntax is as-
tf.keras.Input(
shape=None,
batch_size=None,
name=None,
dtype=None,
sparse=False,
tensor=None,
**kwargs
)
shape: defines the shape of a single sample, with variable batch size.
Notice, that it expects the first value as batch_size otherwise pass batch_size as a parameter explicitly

Changing a pretrained Keras model with fixed input to a flexible one in tensoflow?

I want to use a pre-trained BagNet (https://github.com/wielandbrendel/bag-of-local-features-models) to extract features. The net has fixed input height and width, the input is (None,3,224,224). Now, I want to build a new model with fexible input sizes. I tried approaches with model.layers.pop()[0] to remove the first layer and replace it with a flexible input but I get errors:
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input0_6:0", shape=(?, 3, 224, 224), dtype=float32) at layer "input0". The following previous layers were accessed without issue: []
keras_model = bagnets.keras.bagnet8()
keras_model.layers.pop()[0]
x = Input(batch_shape=(None, 3, None, None))
newModel = Model(x, keras_model.output)
How could I ressolve this issue or what are other options?

classify batch of images using tensorflow mobilenet retrain example

I have trained a classification net by using Tensorflow MobileNet retrain.py example file (in https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/image_retraining/retrain.py)
When I use the trained net, i managed to run only a single image at a time (the input is tensorflow 4d array shape [1, 128, 128, 3])
Don't know if it means anything, but the train process used train batch flag --train_batch_size=100
When i try to classify a batch of images (for example, tensorflow 4d array shape [2, 128, 128, 3] to 'input' layer), i get the following error:
ValueError: Cannot feed value of shape (2, 128, 128, 3) for Tensor 'input:0', which has shape '(1, 128, 128, 3)'
(before running this trained net session, i am using a preprocess tensorflow session that prepares the images for this net (resize, normalise, etc.)
Does anyone knows what should i do in order to run a batch of images over such a net or how can i configure the retrain.py file that would create a net that allows batch run?