I'm using Pretrained Model of Segmentation Models(https://github.com/qubvel/segmentation_models)
But I want to change first Conv2d layer's parameters to change image size.
I can change parameters simple code like below.
##base_model is segmentaion_models.Unet('efficientnetb2', input_size=(800,800))
base_model.layer[1].strides = (4,4) # before : (2,2)
and I can check changed value
base_model.layer[1].strides
> (4,4)
But output shape is same nevertheless change strides value
base_model.layers[1].get_out_shape_at(0)
> (None, 400, 400, 32)
I expected that outshape value is "(None, 200, 200, 32)" because strides value was changed. But isn't
My questions are these :
Why output shape's value isn't change?
Is there any action I need to change output shape?
Is there no correlation strides and output shape?
Thanks
Related
I have a keras transformer model trained with tensorflow 2.7.0 and python 3.7 with input shape: (None, 250, 3) and a 2D array input with shape: (250, 3)(not an image)
When making a prediction with:
prediction = model.predict(state)
I get ValueError: Input 0 of layer "model" is incompatible with the layer: expected shape=(None, 250, 3), found shape=(None, 3)
project code: https://github.com/MikeSifanele/TT
This is how state looks like:
state = np.array([[-0.07714844,-0.06640625,-0.140625],[-0.140625,-0.1650391,-0.2265625]...[0.6376953,0.6005859,0.6083984],[0.7714844,0.7441406,0.7578125]], np.float32)
Some explanation:
For input shape to the model i.e. (None, 250, 3), the first axis (represented by None) is the "sample" axis, while the rest i.e. 250,3 denotes the input dimension. Thus, when the input shape is (250, 3) it assumes the first axis as the "sample" axis and the rest as the input dimension i.e. just 3. So, to make it consistent we need to add a dimension at the beginning described in the following:
state = np.expand_dims(state, axis=0)
The shape of state then becomes (1, 250, 3) ~(None, 250, 3).
In this code "x" is an input to the convolutional 2D layer with 1 batch size, 256 both height & width size and 40 feature maps.
And, w is the weight for the convolutional layer, where the kernel size is (3x3), with depth of 10 and with 80 filters.
x = tf.random.uniform((1, 256, 256, 40))
w = tf.random.uniform((3, 3, 10, 80))
out = tf.nn.conv2d(x, w, strides = (1, 1), padding = 'SAME', data_format='NHWC')
output.shape
##############
OUTPUT:
TensorShape([1, 256, 256, 80])
Here, this particular code works fine, where the output shape is (1x256x256x80). But Why?
Here, the input's feature map is not same as the depth, which I think it should be.
According to me, the weight should be of shape (3x3x40x80) instead of (3x3x10x80)
where the 3rd position value (i.e; in 2nd index which is 40) should be equal to the 4th position value (i.e; in 3rd index which is 40) of the shape of input.
Otherwise, how would the convolution operation will happen?
*** It also works fine for the weights with the shape ***
(3x3x1x80)
(3x3x2x80)
(3x3x4x80)
(3x3x5x80)
(3x3x8x80)
(3x3x20x80)
It seems like, it works with all the depth which divides 40.
I am using VGG16 for transfer learning. My images are grayscale. So, I need to change the input channel shape of Vgg16 from (224, 224, 3) to (224, 224, 1). I tried the following code and got error:
TypeError: build() takes from 1 to 2 positional arguments but 4 were given
Can anyone help me where Am I doing it wrong?
vgg16_model= load_model('Fetched_VGG.h5')
vgg16_model.summary()
# transform the model to Sequential
model= Sequential()
for layer in vgg16_model.layers[1:-1]:
model.add(layer)
# Freezing the layers (Oppose weights to be updated)
for layer in model.layers:
layer.trainable = False
model.build(224,224,1)
model.add(Dense(2, activation='softmax', name='predictions'))
you can't, even if you get rid of the input layer, this model has a graph that has already been compiled and your first conv layer expects an input with 3 channels. I don't think there is really an easy work around to make it accept 1 channel if there is any at all.
you need to repeat your data in third dimension and have the same grayscale image in all 3 bands instead of RGB, that works just fine.
if your image has the shape of : (224,224,1):
import numpy as np
gray_image_3band = np.repeat(gray_img, repeats = 3, axis = -1)
if your image has the shape of : (224,224)
gray_image_3band = np.repeat(gray_img[..., np.newaxis], repeats = 3, axis = -1)
you don't need to call the model.build() anymore this way, keep the input layer. but if you ever wanted to call it you need to pass the shape as a tuple like this:
model.build( (224, 224, 1) ) # this is correct, notice the parentheses
I'm using Conv2d in Keras to do some classification for gray-scale images. Each image is stored as a 240*300 matrix, (namely a list [ A_1, A_2,..., A_240 ] and each A_k is a list of length 300
How should I specify the input_shape of the first layer of my ConvNet?
Thanks
ValueError: Input 0 of layer conv2d is incompatible with the layer:
expected ndim=4, found ndim=3. Full shape received
: [None, 240, 300]
First, you need to reshape your data, adding a dimension at the end with size of one, which represents one channel (a grayscale image). Assuming data has shape (samples, 240, 300):
data = data.reshape((-1, 240, 300, 1))
This will make data have shape (samples, 240, 300, 1). Then to your first layer you should give input_shape=(240, 300, 1)
I use Keras2 with TensorFlow as back-end and tried feed horizontal rectangle image (width:150 x height:100 x ch:3) into network.
I use cv2 for pre-processing images and cv2 & TensorFlow treats the shape of images as [height, width, ch] ordering (in my case, it's [100, 150, 3] This format is opposite of (width:150 x height:100 x ch:3), but it's not mistake.)
So I defined Keras model API input as follow code, but it occurred an error.
img = cv2.imread('input/train/{}.jpg'.format(id))
img = cv2.resize(img, (100, 150))
inputs = Input(shape=(100, 150, 3))
x = Conv2D(8, (3, 3), padding='same', kernel_initializer='he_normal')(inputs)
~~~
error message is below
ValueError: Error when checking input: expected input_4 to have shape
(None, 100, 150, 3) but got array with shape (4, 150, 100, 3)
By the way input = Input((150, 100, 3)) can be run.
I feel weird with discrepancy between Keras & TensorFlow, so I'm suspicious that it just don't occurred error, it does not worked properly.
Anybody can explain that? I couldn't locate the input shape ordering in Keras Document.
You can change the dimension ordering as you prefer.
You can print and change the dimension ordering like this:
from keras import backend as K
print(K.image_data_format()) # print current format
K.set_image_data_format('channels_last') # set format
If you want to permanently change the dimension ordering, you should edit it in the keras.json file, usually located at ~/.keras/keras.json:
"image_data_format": "channels_last"
My problem occurred from order of width&height at argument of cv2.resize().
cv2.resize() takes the argument like cv2.resize(img, (width, height)), whereas numpy treats image array order of (height, width).
Taken from https://keras.io/api/layers/convolution_layers/convolution2d/
Arguments
...
data_format: A string, one of channels_last (default) or
channels_first. The ordering of the dimensions in the inputs.
channels_last corresponds to inputs with shape (batch_size, height,
width, channels) while channels_first corresponds to inputs with shape
(batch_size, channels, height, width). It defaults to the
image_data_format value found in your Keras config file at
~/.keras/keras.json. If you never set it, then it will be
channels_last.
...
So it is: (batch_size, height, width, channels) (by default)