Convolutional Neural Network Layers - tensorflow

I want to detect certain patterns using a CNN, however, the last two layers of my CNN get an error when I try to run them. I have commented those layers in the code below.
*Every Conv2D layer is repeated before the MaxPooling layer.
inputs = tf.keras.layers.Input(shape=(256, 256, 27), name='input_layer')
lambda_layer = tf.keras.layers.Lambda(lambda value: value / 255)(inputs)
xp = tf.keras.layers.Conv2D(64, 3, padding='same', activation=tf.nn.relu)(lambda_layer)
xp = tf.keras.layers.MaxPooling2D()(xp) # by default uses 2,2
xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Conv2D(94, 3, padding='same', activation=tf.nn.relu)(xp)
xp = tf.keras.layers.MaxPooling2D()(xp)
xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Conv2D(128, 3, padding='same', activation=tf.nn.relu)(xp)
xp = tf.keras.layers.MaxPooling2D()(xp)
xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Conv2D(156, 3, padding='valid', activation=tf.nn.relu)(xp)
xp = tf.keras.layers.MaxPooling2D()(xp)
xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Conv2D(256, 3, padding='same', activation=tf.nn.relu)(xp)
xp = tf.keras.layers.MaxPooling2D()(xp)
xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Conv2D(394, 3, padding='same', activation=tf.nn.relu)(xp)
xp = tf.keras.layers.MaxPooling2D()(xp)
xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Conv2D(458, 3, padding='same', activation=tf.nn.relu)(xp)
xp = tf.keras.layers.MaxPooling2D()(xp)
xp = tf.keras.layers.BatchNormalization()(xp)
# xp = tf.keras.layers.Conv2D(516, 3, padding='same', activation=tf.nn.relu)(xp)
# xp = tf.keras.layers.Conv2D(516, 3, padding='same', activation=tf.nn.relu)(xp)
# xp = tf.keras.layers.MaxPooling2D()(xp)
# xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Dropout(0.25)(xp)
xp = tf.keras.layers.Flatten()(xp)
xp = tf.keras.layers.Dense(1024, activation=tf.nn.relu)(xp)
xp = tf.keras.layers.BatchNormalization()(xp)
xp = tf.keras.layers.Dropout(0.25)(xp)
xp = tf.keras.layers.Dense(512, activation=tf.nn.relu)(xp)
xp = tf.keras.layers.Dropout(0.25)(xp)
I get an error
Call arguments received:
• inputs=tf.Tensor(shape=(None, 2, 2, 394), dtype=float32)
Meaning I might have convolved the image too much so it's getting an error. What can I do to solve this?

Yes, the problem is your input shape is not enough to utilize pooling this much. Convolutional layers are okay since you are using padding="same" which means input shape and output shape of layer are identical. However everytime you use MaxPooling2D with a kernel of (2, 2) x and y dimensions of the input gets divided by 2. That's why after a while there is nothing to pool.
As you can see here, after a certain time you ran out of data to feed into you layers because you compressed it via pooling too much.
Possible solutions:
You can either change you input shape
Decrease the amount of MaxPooling2D layers.
You can learn to use stride and padding parameters to have more control over the output shape after pooling.

Related

Tensorflow image processing: how to predict mask

I am very much a beginner and currently trying to get started with CNNs. I wanted to try out lane detection.
Using the tusimple dataset, I have images of roads and create masks with the lanes. It looks like this:
I was following this blog where something similar is done. However, my results look nothing like in the blog. For simplicity reasons, I only use one image as dataset. This way, the network should very easily be able to detect the lane in this one image. However, this cnn basically just adds a red filter on the input image. The output looks somewhat like this:
Maybe you can point me into the right direction / tell me what I am doing wrong.
I posted the whole notebook here: https://colab.research.google.com/drive/1igOulIU-1HA-Ecf4diQTLXM-mrnAeFXz?usp=sharing
Or the most relevant code included:
def convolutional_block(inputs=None, n_filters=32, dropout_prob=0, max_pooling=True):
conv = Conv2D(n_filters,
kernel_size = 3,
activation='relu',
padding='same',
kernel_initializer=tf.keras.initializers.HeNormal())(inputs)
conv = Conv2D(n_filters,
kernel_size = 3,
activation='relu',
padding='same',
kernel_initializer=tf.keras.initializers.HeNormal())(conv)
if dropout_prob > 0:
conv = Dropout(dropout_prob)(conv)
if max_pooling:
next_layer = MaxPooling2D(pool_size=(2,2))(conv)
else:
next_layer = conv
#conv = BatchNormalization()(conv)
skip_connection = conv
return next_layer, skip_connection
def upsampling_block(expansive_input, contractive_input, n_filters=32):
up = Conv2DTranspose(
n_filters,
kernel_size = 3,
strides=(2,2),
padding='same')(expansive_input)
merge = concatenate([up, contractive_input], axis=3)
conv = Conv2D(n_filters,
kernel_size = 3,
activation='relu',
padding='same',
kernel_initializer=tf.keras.initializers.HeNormal())(merge)
conv = Conv2D(n_filters,
kernel_size = 3,
activation='relu',
padding='same',
kernel_initializer=tf.keras.initializers.HeNormal())(conv)
return conv
def unet_model(input_size=(720, 1280,3), n_filters=32, n_classes=3):
inputs = Input(input_size)
#contracting path
cblock1 = convolutional_block(inputs, n_filters)
cblock2 = convolutional_block(cblock1[0], 2*n_filters)
cblock3 = convolutional_block(cblock2[0], 4*n_filters)
cblock4 = convolutional_block(cblock3[0], 8*n_filters, dropout_prob=0.2)
cblock5 = convolutional_block(cblock4[0],16*n_filters, dropout_prob=0.2, max_pooling=None)
#expanding path
ublock6 = upsampling_block(cblock5[0], cblock4[1], 8 * n_filters)
ublock7 = upsampling_block(ublock6, cblock3[1], n_filters*4)
ublock8 = upsampling_block(ublock7,cblock2[1] , n_filters*2)
ublock9 = upsampling_block(ublock8,cblock1[1], n_filters)
conv9 = Conv2D(n_classes,
1,
activation='relu',
padding='same',
kernel_initializer='he_normal')(ublock9)
conv10 = Activation('softmax')(conv9)
model = tf.keras.Model(inputs=inputs, outputs=conv10)
return model

How to fix 'tensorflow.keras.layers' has no attribute 'input'

Followings are the string that I am trying to get it but I don't know why I keep getting
tensorflow.keras.layers' has no attribute 'input' can anyone give advice :).
I don't know why even though I have called out the data it keep saying there is no input for keras.
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras import datasets
mnist = datasets.mnist
(train_x, train_y), (test_x, test_y) = mnist.load_data()
inputs = layers.input((28, 28, 1))
net = layers.Conv2D(32, (3, 3), padding ='SAME')(inputs)
net = layers.Activation('relu')(net)
net = layers.Conv2D(32, (3, 3), padding ='SAME')(net)
net = layers.Activation('relu')(net)
net = layers.MaxPooling2D(pool_size=(2, 2))(net)
net = layers.Dropout(0, 25)(net)
net = layers.Conv2D(64, (3, 3), padding ='SAME')(net)
net = layers.Activation('relu')(net)
net = layers.Conv2D(64, (3, 3), padding ='SAME')(net)
net = layers.Activation('relu')(net)
net = layers.MaxPooling2D(pool_size=(2, 2))(net)
net = layers.Dropout(0, 25)(net)
net = layers.Flatten()(net)
net = layers.Dense(512)(net)
net = layers.Activation('relu')(net)
net = layers.Dropout(0, 5)(net)
net = layers.Dense(10)(net)
net = layers.Activation('softmax')(net)
model = tf.keras.Model(inputs=inputs, outputs=net, name='Basic_CNN')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-23-5b0ca3669e40> in <module>
----> 1 inputs = layers.input((28, 28, 1))
2 net = layers.Conv2D(32, (3, 3), padding ='SAME')(inputs)
3 net = layers.Activation('relu')(net)
4 net = layers.Conv2D(32, (3, 3), padding ='SAME')(net)
5 net = layers.Activation('relu')(net)
AttributeError: module 'tensorflow.keras.layers' has no attribute 'input'
You must use Input Instead of input.
Also what do you mean by net = layers.Dropout(0, 25)(net)?
I think you meant net = layers.Dropout(0.25)(net).

Am I sharing Layers ? - keras network modeling

I have a shared network models to make a model that has multiple inputs. my code is :
f1 = 128
f2 = 256
f3 = 1
shared_conv1 = L.Conv2D(filters=f1, kernel_size=(5, 5), strides=1, padding='same',name='shared_conv1')
shared_conv2 = L.Conv2D(filters=f1, kernel_size=(3, 3), strides=1, padding='same',name='shared_conv2')
shared_conv3 = L.Conv2D(filters=f1, kernel_size=(3, 3), strides=1, padding='same',name='shared_conv3')
shared_batch1 = L.BatchNormalization(name='shared_batch1')
shared_batch2 = L.BatchNormalization(name='shared_batch2')
shared_batch3 = L.BatchNormalization(name='shared_batch3')
shared_relu1 = L.ReLU(name='shared_relu1')
shared_relu2 = L.ReLU(name='shared_relu2')
shared_relu3 = L.ReLU(name='shared_relu3')
for i in range(length):
x_64 = shared_conv1(input[i])
x_64 = shared_batch1(x_64)
x_64 = shared_relu1(x_64)
x_64 = shared_conv2(x_64)
x_64 = shared_batch2(x_64)
x_64 = shared_relu2(x_64)
x_64 = shared_conv3(x_64)
x_64 = shared_batch3(x_64)
x_64 = shared_relu3(x_64)
print(x_64)
I want to use 8 input, and want x_64 to be output 8 times, and I saw print result like this :
Tensor("shared_relu1_3/Relu:0", shape=(None, 64, 64, 128), dtype=float32)
Tensor("shared_relu1_3_1/Relu:0", shape=(None, 64, 64, 128), dtype=float32)
Tensor("shared_relu1_3_2/Relu:0", shape=(None, 64, 64, 128), dtype=float32)
Since I expected "shared_relu1_3/Relu:0" to be printed 3 times, I could not judge that my network is worked as shared network correctly.
Am I doint right ?
Yes, it is working correctly, what it might confuse you is that the output tensors actually represent computation, so each of them are different but it does not mean that the weights are different, they are being shared.
Sharing works by passing several tensors through the same layer instance, since layers are the ones that have the weights inside them. So it should be working as expected.
Also there is no need to share ReLU's, since they do not have weights. Only layers that have weights should be shared if needed.

Migrate Convolutional2D dim_ordering parameter to Conv2D in tf.keras

I'm newbie with Tensorflow and Keras, and I'm migrating the following code:
Convolution2D(64, 5, 5, activation='relu', border_mode='same', dim_ordering='tf', name='conv1_1')(inputs)
The interpreter suggest me this code:
Conv2D(64, (5, 5), activation="relu", name="conv1_1", padding="same", data_format="channels_last")
My question is:
Is dim_ordering='tf' the same as data_format="channels_last"?
Yes, dim_ordering='tf' is equal to data_format="channels_last", which is also the default, so most of the times you might simply ignore this parameter.
This site seems to store old Keras documentation pages where you can confirm this: http://faroit.com/keras-docs/1.0.8/layers/convolutional/#convolution2d
For the new api, you'll have to convert dim_ordering to data_format and the corresponding values are tf -> channels_last or th -> channels_first. So
# for dim_ordering = 'tf'
data_format = 'channels_last'
# for dim_ordering = 'th'
data_format = 'channels_first'

tf.multinomial outputs number other numbers than range

I am working with the OpenAI gym environment (using policy gradient). My network is outputting an action which is higher than the possible action range.
n_outputs = 9
learning_rate = 0.01
initializer = tf.variance_scaling_initializer()
X = tf.placeholder(tf.float32, shape=[None, 50, 70, 1])
network = tflearn.conv_2d(X, 32, 5, strides=2, activation='relu')
network = tflearn.max_pool_2d(network, 2)
network = tflearn.conv_2d(network, 32, 5, strides=2, activation='relu')
network = tflearn.max_pool_2d(network, 2)
network = tflearn.fully_connected(network, 256, activation='relu')
hidden = tf.layers.dense(network, 64, activation=tf.nn.relu, kernel_initializer=initializer)
logits = tf.layers.dense(hidden, n_outputs)
outputs = tf.nn.softmax(logits)
action = tf.multinomial(outputs, num_samples=1)
It outputs 9, which creates an error in the gym environment.
The full code.
tf.multinomial will sample outside of the range if it encounters numerical error, so in other words - you have NaNs in your graph.