Why does the output layer is simply zero at the end of the network? - tensorflow

I am trying to train a model that takes a 15x15 image and classify each pixel into two classes (1/0).
This is my loss function:
smooth = 1
def tversky(y_true, y_pred):
y_true_pos = K.flatten(y_true)
y_pred_pos = K.flatten(y_pred)
true_pos = K.sum(y_true_pos * y_pred_pos)
false_neg = K.sum(y_true_pos * (1-y_pred_pos))
false_pos = K.sum((1-y_true_pos)*y_pred_pos)
alpha = 0.5
return (true_pos + smooth)/(true_pos + alpha*false_neg + (1-alpha)*false_pos + smooth)
def tversky_loss2(y_true, y_pred):
return 1 - tversky(y_true,y_pred)
This is the model:
input_image = layers.Input(shape=(size, size, 1))
b2 = layers.Conv2D(128, (3,3), padding='same', activation='relu')(input_image)
b2 = layers.Conv2D(128, (3,3), padding='same', activation='relu')(b2)
b2 = layers.Conv2D(128, (3,3), padding='same', activation='relu')(b2)
output = layers.Conv2D(1, (1,1), activation='sigmoid', padding='same')(b2)
model = models.Model(input_image, output)
model.compile(optimizer='adam', loss=tversky_loss2, metrics=['accuracy'])
The model left is the input and the label is the middle column and the prediction is always zero on the right column:
The training performs really poorly:
Epoch 1/10
100/100 [==============================] - 4s 38ms/step - loss: 0.9269 - acc: 0.1825
Epoch 2/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9277 - acc: 0.0238
Epoch 3/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9276 - acc: 0.0239
Epoch 4/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9270 - acc: 0.0241
Epoch 5/10
100/100 [==============================] - 3s 30ms/step - loss: 0.9274 - acc: 0.0240
Epoch 6/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9269 - acc: 0.0242
Epoch 7/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9270 - acc: 0.0241
Epoch 8/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9271 - acc: 0.0241
Epoch 9/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9276 - acc: 0.0239
Epoch 10/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9266 - acc: 0.0242

This sounds like a very imbalanced dataset with very tiny true regions. This might be hard to train indeed.
You may want to increase alpha to penalize more false negatives than false positives. Anyway, unless alpha is big enough, it's very normal that in the beginning your model first goes to all neg because it's definitely a great way to decrease the loss.
Now, there is a conceptual mistake regarding how Keras works in that loss. You need to keep the "samples" separate. Otherwise you are calculating a loss as if all images were one image. (Thus, it's probable that images with many positives have a reasoable result, while images with few positives don't, and this will be a good solution)
Fix the loss as:
def tversky(y_true, y_pred):
y_true_pos = K.batch_flatten(y_true) #keep the batch dimension
y_pred_pos = K.batch_flatten(y_pred)
true_pos = K.sum(y_true_pos * y_pred_pos, axis=-1) #don't sum over the batch dimension
false_neg = K.sum(y_true_pos * (1-y_pred_pos), axis=-1)
false_pos = K.sum((1-y_true_pos)*y_pred_pos, axis=-1)
alpha = 0.5
return (true_pos + smooth)/(true_pos + alpha*false_neg + (1-alpha)*false_pos + smooth)
This way you have an individual loss value for each image, so the exitence of images with many positives don't affect the results of images with few positives.

Related

Training a Keras model for object location

I am trying to use Keras to train a model for location a certain mountain peak in the images of a moving wide-angle camera. This is my training data, I have 329 images labeled:
The position does not change, so except for lens distortion and rotation, is always looks the same. Peace of cake for a human.
These plots are generated from my training data generator function to rule out any issues in that regard:
train_generator = traingui_generator([], frames_labeled, labels, batch_size)
im,la = next(train_generator)
fig = plt.figure(figsize=(16,10))
for n, (i,l) in enumerate(zip(im,la)):
a = plt.subplot(2,2,n+1)
plt.imshow(i)
plt.plot(l[0],l[1],'r+')
plt.xlim((1440,2880))
plt.ylim((0,1440))
a.invert_yaxis()
plt.show()
With the help of the Keras documentation examples, I came up with this model:
from keras import Input
from keras.models import Model
from keras.optimizers import Adam
from keras.layers import Cropping2D, Rescaling, Conv2D, MaxPooling2D, Flatten, Dense, AveragePooling2D,Resizing
inputs = Input(shape=input_shape)
x = Cropping2D(((0,0),(1440,0)))(inputs)
x = Rescaling(scale=1.0 / 255)(x)
x = Resizing(720,720)(x)
x = Conv2D(32, (3, 3), activation='relu')(x)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu')(x)
x = MaxPooling2D((2, 2))(x)
x = Flatten()(x)
x = Dense(64, activation='relu')(x)
location = Dense(2)(x)
# Define the model with the input and output layers
model = Model(inputs=inputs, outputs=location)
model.compile(optimizer=Adam(learning_rate=0.001),
loss='mse', metrics=['accuracy'])
batch_size = 4
num_train_samples = 329
num_epochs = 10
train_generator = traingui_generator([], frames_labeled, labels, batch_size)
model.fit(train_generator, steps_per_epoch=num_train_samples // batch_size, epochs=num_epochs)
This is my learning process:
27/27 [==============================] - 87s 3s/step - loss: 1126492.5000 - accuracy: 0.9877
Epoch 2/20
27/27 [==============================] - 87s 3s/step - loss: 750418.5000 - accuracy: 1.0000
Epoch 3/20
27/27 [==============================] - 87s 3s/step - loss: 702527.0625 - accuracy: 1.0000
Epoch 4/20
27/27 [==============================] - 87s 3s/step - loss: 651334.3125 - accuracy: 1.0000
Epoch 5/20
27/27 [==============================] - 87s 3s/step - loss: 591387.7500 - accuracy: 1.0000
Epoch 6/20
27/27 [==============================] - 88s 3s/step - loss: 495730.0625 - accuracy: 0.9722
Epoch 7/20
27/27 [==============================] - 87s 3s/step - loss: 322107.7500 - accuracy: 0.8981
Epoch 8/20
27/27 [==============================] - 87s 3s/step - loss: 213287.5312 - accuracy: 0.8981
Epoch 9/20
27/27 [==============================] - 87s 3s/step - loss: 151553.3281 - accuracy: 0.9475
Epoch 10/20
27/27 [==============================] - 87s 3s/step - loss: 114601.3828 - accuracy: 0.9506
Epoch 11/20
27/27 [==============================] - 87s 3s/step - loss: 96194.7031 - accuracy: 0.9475
Epoch 12/20
27/27 [==============================] - 88s 3s/step - loss: 69348.9922 - accuracy: 0.9321
Epoch 13/20
27/27 [==============================] - 87s 3s/step - loss: 65372.2852 - accuracy: 0.9475
Epoch 14/20
27/27 [==============================] - 88s 3s/step - loss: 58215.0547 - accuracy: 0.9043
Epoch 15/20
27/27 [==============================] - 87s 3s/step - loss: 57038.0078 - accuracy: 0.9475
Epoch 16/20
27/27 [==============================] - 87s 3s/step - loss: 47969.5234 - accuracy: 0.9660
Epoch 17/20
27/27 [==============================] - 87s 3s/step - loss: 45780.5820 - accuracy: 0.9383
Epoch 18/20
27/27 [==============================] - 88s 3s/step - loss: 39562.1836 - accuracy: 0.9660
Epoch 19/20
27/27 [==============================] - 87s 3s/step - loss: 51684.8164 - accuracy: 0.9537
Epoch 20/20
27/27 [==============================] - 88s 3s/step - loss: 45646.8398 - accuracy: 0.9815
I notice that the loss function is quite often increasing during the epochs and the accuracy isn't stable, so I already went down with the learning_rate by one order of magnitude.
Unfortunately, the result is not particularly good:
These plots are generated with the same piece of code as above, just replacing la with the output of model.predict(im).
Note that this on the training data, so I would rather rule out overfitting, if I understand correctly.
I have also tried just two convolutional layers, without success.
Now I read that I should modify the model, but I am lacking guidance in what direction.
Should I just play around randomly, each time waiting for it to finish? Where would I start to adjust? Filter number? Kernel size of convolution or pooling? Number of layers? Number pf epochs? Is the training data even enough?
Or is there something fundamentally wrong in what I am doing?
The size of the image is unfortunately not really open for discussion, I would even like to remove the resize because there will be other, smaller feature that I would like to detect, and add the other halve sphere, such that my final data would have 1440x2880 pixel..
If necessary, I would have access to quite powerful hardware, though, if RAM is an issue, and I would not have too much of a problem if the training took hours or more, if the problem REALLY requires it.
I would really appreciate if someone experienced could give me a push into the right direction for this concrete problem. I have no idea what to expect.
Edit: Given that my images are much larger than most examples and I read that the first layers are meant capture low frequency features, I increased the kernel size of the first layers
x = Conv2D(32, (15, 15), activation='relu')(x)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(64, (5, 5), activation='relu')(x)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(128, (3, 3), activation='relu')(x)
x = MaxPooling2D((2, 2))(x)
If anything, this made things worse.

Why my IoU keep decrease in training with tensorflow / keras?

I'm training an U-net like model for semantic segmentation but the IoU keep decrease epochs after epochs.
This is my IoU and IoU loss function. My input and output mask is an numpy array with dtype=np.bool so I casted it to float32 for calculate the IoU.
I don't know what is the problem? My metrics function or my model. I really need someone help me on this.
def iou(y_true, y_pred):
y_true = tf.keras.backend.flatten(y_true)
y_pred = tf.keras.backend.flatten(y_pred)
y_true_f = tf.cast(y_true, tf.float32)
y_pred_f = tf.cast(y_pred, tf.float32)
intersection = tf.keras.backend.sum(y_true_f * y_pred_f)
union = tf.keras.backend.sum(y_true_f) + tf.keras.backend.sum(y_pred_f) - intersection
return (intersection + 1e-7) / (union + 1e-7)
def iou_loss(y_true, y_pred):
return 1.0 - iou(y_true, y_pred)
# Compile model
metrics = [iou_loss, iou, 'accuracy']
model.compile(optimizer=Adam(learning_rate), loss=iou, metrics=[metrics], run_eagerly=True)
This is my training results
Epoch 2/100
34/34 [==============================] - 3s 89ms/step - loss: 0.0186 - iou_loss: 0.9814 - iou: 0.0186 - accuracy: 0.9022 - val_loss: 0.0358 - val_iou_loss: 0.9647 - val_iou: 0.0353 - val_accuracy: 0.9460
Epoch 00002: val_loss improved from 0.03619 to 0.03579, saving model to /content/gdrive/MyDrive/model_ccnet_iris.h5
Epoch 3/100
34/34 [==============================] - 3s 89ms/step - loss: 0.0158 - iou_loss: 0.9843 - iou: 0.0157 - accuracy: 0.8972 - val_loss: 0.0352 - val_iou_loss: 0.9652 - val_iou: 0.0348 - val_accuracy: 0.9071
Epoch 00003: val_loss improved from 0.03579 to 0.03525, saving model to /content/gdrive/MyDrive/model_ccnet_iris.h5
Epoch 4/100
34/34 [==============================] - 3s 88ms/step - loss: 0.0132 - iou_loss: 0.9868 - iou: 0.0132 - accuracy: 0.8910 - val_loss: 0.0348 - val_iou_loss: 0.9656 - val_iou: 0.0344 - val_accuracy: 0.8690
Epoch 00004: val_loss improved from 0.03525 to 0.03485, saving model to /content/gdrive/MyDrive/model_ccnet_iris.h5
Epoch 5/100
34/34 [==============================] - 3s 87ms/step - loss: 0.0112 - iou_loss: 0.9888 - iou: 0.0112 - accuracy: 0.8842 - val_loss: 0.0345 - val_iou_loss: 0.9659 - val_iou: 0.0341 - val_accuracy: 0.8411
Epoch 00005: val_loss improved from 0.03485 to 0.03455, saving model to /content/gdrive/MyDrive/model_ccnet_iris.h5
Epoch 6/100
34/34 [==============================] - 3s 85ms/step - loss: 0.0096 - iou_loss: 0.9904 - iou: 0.0096 - accuracy: 0.8740 - val_loss: 0.0343 - val_iou_loss: 0.9662 - val_iou: 0.0338 - val_accuracy: 0.8216
The function of an optimizer is to minimize the loss function
You set IoU as the loss function, that is why it is decreasing.

Keras : Simple 1 variable training to get the mean

I wrote a very basic model to train a single variable to approximate the mean value of a vector. But for some reason, it's not working properly.
I used this page describing a linear fit (2 variables):
https://www.tensorflow.org/guide/basic_training_loops
My code is as follow:
import tensorflow as tf
import numpy as np
class MyModel(tf.keras.Model):
def __init__(self, **kwargs):
super().__init__()
self.b = tf.Variable(1.0, trainable=True)
def call(self, x):
return x - self.b
model = MyModel()
model.compile(optimizer=tf.optimizers.Adam(learning_rate=1e-3), loss='mae')
X = np.random.random((10000,1))
Y = np.zeros(X.shape)
model.fit(X, Y, batch_size=10, epochs=10)
B should be optimized so that sum(abs(X - B)) is as close to 0 as possible (= the mean). However when I fit the model it's not training at all and always reaches to the solution B=0 (the real mean is around 0.5).
What do I do wrong?
This code is working fine. Please check below execution and it's output:
import tensorflow as tf
import numpy as np
class MyModel(tf.keras.Model):
def __init__(self, **kwargs):
super().__init__()
self.b = tf.Variable(1.0, trainable=True)
def call(self, x):
return x - self.b
model = MyModel()
model.compile(optimizer=tf.optimizers.Adam(learning_rate=1e-3), loss='mae')
X = np.random.random((10000,1))
Y = np.zeros(X.shape)
model.fit(X, Y, batch_size=10, epochs=10)
Output:
Epoch 1/10
1000/1000 [==============================] - 2s 1ms/step - loss: 0.2991
Epoch 2/10
1000/1000 [==============================] - 1s 1ms/step - loss: 0.2476
Epoch 3/10
1000/1000 [==============================] - 1s 1ms/step - loss: 0.2476
Epoch 4/10
1000/1000 [==============================] - 1s 1ms/step - loss: 0.2476
Epoch 5/10
1000/1000 [==============================] - 1s 1ms/step - loss: 0.2476
Epoch 6/10
1000/1000 [==============================] - 1s 1ms/step - loss: 0.2476
Epoch 7/10
1000/1000 [==============================] - 2s 2ms/step - loss: 0.2476
Epoch 8/10
1000/1000 [==============================] - 2s 2ms/step - loss: 0.2476
Epoch 9/10
1000/1000 [==============================] - 2s 2ms/step - loss: 0.2476
Epoch 10/10
1000/1000 [==============================] - 2s 2ms/step - loss: 0.2477

Saving and loading of Keras model not working

I've been trying to save and reupload a model and whenever I do that the accuracy always goes down.
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64, kernel_size=3, activation='relu', input_shape=(IMG_SIZE,IMG_SIZE,3)))
model.add(tf.keras.layers.Conv2D(32, kernel_size=3, activation='relu'))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(len(SURFACE_TYPES), activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['acc'])
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=EPOCHS,
validation_steps=10)
Output:
Epoch 1/3
84/84 [==============================] - 2s 19ms/step - loss: 1.9663 - acc: 0.6258 - val_loss: 0.8703 - val_acc: 0.6867
Epoch 2/3
84/84 [==============================] - 1s 18ms/step - loss: 0.2865 - acc: 0.9105 - val_loss: 0.4494 - val_acc: 0.8667
Epoch 3/3
84/84 [==============================] - 1s 18ms/step - loss: 0.1409 - acc: 0.9574 - val_loss: 0.3614 - val_acc: 0.9000
This followed by running these commands to produce outputs result in the same training loss but different training accuracies. The weights and structures of the models are also identical.
model.save("my_model2.h5")
model2 = load_model("my_model2.h5")
model2.evaluate(train_ds)
model.evaluate(train_ds)
Output:
84/84 [==============================] - 1s 9ms/step - loss: 0.0854 - acc: 0.0877
84/84 [==============================] - 1s 9ms/step - loss: 0.0854 - acc: 0.9862
[0.08536089956760406, 0.9861862063407898]
i have shared reference link click here
it has all formats to save & load your model

Weird accuracy metric in verbose when using Tensorflow keras loss=tf.losses.sparse_softmax_cross_entropy

While testing out training of Mnist dataset using Tensorflow's Keras api, i witness weird accuracy while specifying the loss=tf.losses.sparse_softmax_cross_entropy in complile statement. I am simply trying usage of 3 different ways of specifying loss functions viz.
loss='sparse_categorical_crossentropy'
loss=tf.losses.sparse_softmax_cross_entropy
loss=tf.losses.softmax_cross_entropy
Google Colab link to explain the point better
Here is the sample code
import tensorflow as tf
import numpy as np
from tensorflow import keras
from keras.datasets import mnist
from sklearn.metrics import f1_score
(x_train,y_train),(x_test,y_test) = mnist.load_data()
model = tf.keras.Sequential([
keras.layers.Flatten(),
keras.layers.Dense(units=128,activation=tf.nn.relu),
keras.layers.Dense(10, activation = tf.nn.softmax)
])
# loss='sparse_categorical_crossentropy'
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
hist = model.fit(x_train/255,y_train,epochs=10, verbose=0 )
y_pred1 = model.predict(x_test/255)
y_pred1 = np.argmax(y_pred1, axis=1)
results1 = (np.array([y_pred1 == y_test]).astype(int).reshape(-1,1))
acc1 = np.asscalar(sum(results1)/results1.shape[0])
print("case 1: loss='sparse_categorical_crossentropy' : "+ str(hist.history['acc'][9]))
print("calculated test acc : "+ str(acc1))
print("_________________________________________________")
# loss=tf.losses.sparse_softmax_cross_entropy
model.compile(optimizer=tf.train.AdamOptimizer(),
loss=tf.losses.sparse_softmax_cross_entropy,
metrics=['accuracy'])
hist = model.fit(x_train/255,y_train,epochs=10,verbose=1)
y_pred2 = model.predict(x_test/255)
y_pred2 = np.argmax(y_pred2, axis=1)
results2 = (np.array([y_pred2 == y_test]).astype(int).reshape(-1,1))
acc2 = np.asscalar(sum(results2)/results2.shape[0])
print("case 2: loss=tf.losses.sparse_softmax_cross_entropy : "+ str(hist.history['acc'][9]))
print("calculated test acc : "+ str(acc2))
print("_________________________________________________")
# loss=tf.losses.softmax_cross_entropy
model.compile(optimizer=tf.train.AdamOptimizer(),
loss=tf.losses.softmax_cross_entropy,
metrics=['accuracy'])
from keras.utils import to_categorical
y_train_onehot = to_categorical(y_train)
hist = model.fit(x_train/255,y_train_onehot,epochs=10,verbose=0)
y_pred3 = model.predict(x_test/255)
y_pred3 = np.argmax(y_pred3, axis=1)
results3 = (np.array([y_pred3 == y_test]).astype(int).reshape(-1,1))
acc3 = np.asscalar(sum(results3)/results3.shape[0])
print("case 3: loss=tf.losses.softmax_cross_entropy : "+ str(hist.history['acc'][9]))
print("calculated test acc : "+ str(acc3))
The output is as shown below
case 1: loss='sparse_categorical_crossentropy' : 0.99495
calculated test acc : 0.978
_________________________________________________
Epoch 1/10
60000/60000 [==============================] - 5s 79us/sample - loss: 1.4690 - acc: 0.0988
Epoch 2/10
60000/60000 [==============================] - 5s 79us/sample - loss: 1.4675 - acc: 0.0987
Epoch 3/10
60000/60000 [==============================] - 4s 75us/sample - loss: 1.4661 - acc: 0.0988
Epoch 4/10
60000/60000 [==============================] - 4s 74us/sample - loss: 1.4656 - acc: 0.0987
Epoch 5/10
60000/60000 [==============================] - 5s 77us/sample - loss: 1.4652 - acc: 0.0987
Epoch 6/10
60000/60000 [==============================] - 5s 78us/sample - loss: 1.4648 - acc: 0.0988
Epoch 7/10
60000/60000 [==============================] - 4s 75us/sample - loss: 1.4644 - acc: 0.0987
Epoch 8/10
60000/60000 [==============================] - 5s 76us/sample - loss: 1.4641 - acc: 0.0988
Epoch 9/10
60000/60000 [==============================] - 5s 79us/sample - loss: 1.4639 - acc: 0.0987
Epoch 10/10
60000/60000 [==============================] - 5s 76us/sample - loss: 1.4639 - acc: 0.0988
case 2: loss=tf.losses.sparse_softmax_cross_entropy : 0.09876667
calculated test acc : 0.9791
_________________________________________________
case 3: loss=tf.losses.softmax_cross_entropy : 0.99883336
calculated test acc : 0.9784
The accuracy appearing in verbose in second case loss=tf.losses.sparse_softmax_cross_entropy is 0.0987 which isn't making sense since evaluating the model on both training and test data is showing accuracy over 0.97