How to improve the model's accuracy? - tensorflow

I am definitely a new beginner of tensorflow, I tried to create a simple model, but the accuracy is super low, can someone help to figure out what is wrong?
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
train_x = [[i, j] for i in range(1000) for j in range(1000)]
train_y = [[(2 * i + 3 * j) % 10] for i in range(1000) for j in range(1000)]
model = Sequential()
model.add(Dense(32, activation="relu", input_dim=2))
model.add(Dense(32, activation="relu"))
model.add(Dense(10, activation="softmax"))
model.compile(optimzier="rmsprop", loss="sparse_categorical_crossentropy", metrics=['accuracy'])
model.summary()
model.fit(train_x, train_y, epochs=10, batch_size=1000)
test_x = train_x[10:60]
test_y = train_y[10:60]
model.evaluate(test_x, test_y, batch_size=100)
Result:
loss: 2.3026 - accuracy: 0.1000

There are few ways to improve your model's accuracy
Reduce the batch size (You are using whole dataset)
Increase the number of layers, units.
Increase the number of epochs.
Use unseen data to evaluate the model. (You are using 60 elements of training data)
I suggest you to read Deep Learning with Python by Francois Chollet, section 3.5 "A multiclass classification example"

Related

Require 'flatttened_input' when building ANN

Hello i need to build an ANN using binary_alpha_digits from tensorflow but i am unable to pass in the train data inside as it requires 'flatten_input' but I am passing in ['image','label'] dictionary. How do i solve this problem? Appreciate any help on this problem thanks.
from matplotlib import pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers
train_ds, test_ds = tfds.load('BinaryAlphaDigits',
split=['train[:60%]', 'train[60%:]'])
model = tf.keras.Sequential()
model.add(layers.Flatten(input_shape=(28, 28)))
model.add(layers.Dense(10, activation=tf.nn.relu))
model.add(layers.Dense(10, activation=tf.nn.relu))
model.add(layers.Dense(10, activation=tf.nn.softmax))
model.compile(optimizer= tf.optimizers.Adam(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
epochs = 10
model.fit(train_ds, epochs=epochs)
as you feed images into model, so the input shape must have defined in shape (Height, Width, Channel) which refers to image dimensions and color mode and the second one is that you should preprocess dataset before fitting model on it.
Even notice the output layers units for multi-class classification is not set correctly for this dataset, while there are more than 10 labels, based on dataset it contains 39 labels and so the last layer units would be set to 39.
Here i would implement code which work correctly for you with preprocessing function for images and labels, And even notice the images of the dataset are in shape (20, 16, 1) so you could resize images to set it into (28, 28, 1) or just fed model with the images in their size.
After preprocessing, images are grouped by creating batches or mini-batches, and even shuffle training set to avoid high variance on testing set, so the operations below will be have done cause of that
from matplotlib import pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers
import tensorflow_datasets as tfds
train_ds, test_ds = tfds.load('BinaryAlphaDigits', split=['train[:60%]', 'train[60%:]'])
def preprocess(data):
image = data['image']
image = tf.image.resize(image, (28, 28))
label = data['label']
return image, label
train_ds = train_ds.map(preprocess)
train_ds = train_ds.shuffle(1024)
train_ds = train_ds.batch(batch_size = 32)
test_ds = test_ds.map(preprocess)
test_ds = test_ds.batch(batch_size = 32)
model = tf.keras.Sequential()
model.add(layers.Flatten(input_shape=(28, 28, 1)))
model.add(layers.Dense(10, activation=tf.nn.relu))
model.add(layers.Dense(10, activation=tf.nn.relu))
model.add(layers.Dense(39, activation=tf.nn.softmax))
model.compile(optimizer= tf.optimizers.Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
epochs = 10
model.fit(train_ds, epochs=epochs)
tfds.load by default gives a dictionary with image and label as the keys.
train_ds, test_ds = tfds.load('BinaryAlphaDigits',
split=['train[:60%]', 'train[60%:]'])
train_ds = train_ds.shuffle(1024).batch(4)
for x in train_ds.take(1):
print(type(x))
print(x['image'].shape, x['label'])
>>>
<class 'dict'>
(4, 20, 16, 1) tf.Tensor([ 6 32 6 12], shape=(4,), dtype=int64)
There is a setting called as_supervised that gives it as a proper dataset. Check docs here
If you use that setting and use proper input and output sizes, your model works
train_ds, test_ds = tfds.load('BinaryAlphaDigits',
split=['train[:60%]', 'train[60%:]'],as_supervised=True)
train_ds = train_ds.shuffle(1024).batch(4)
for x in train_ds.take(1):
print(type(x))
print(x[0].shape, x[1])
>>>
<class 'tuple'>
(4, 20, 16, 1) tf.Tensor([13 13 22 31], shape=(4,), dtype=int64)
model = tf.keras.Sequential()
model.add(layers.Flatten(input_shape=(20, 16,1)))
model.add(layers.Dense(10, activation=tf.nn.relu))
model.add(layers.Dense(10, activation=tf.nn.relu))
model.add(layers.Dense(36, activation=tf.nn.softmax))
model.compile(optimizer= tf.optimizers.Adam(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
epochs = 10
model.fit(train_ds, epochs=epochs)
>>>
Epoch 1/10
211/211 [==============================] - 1s 3ms/step - loss: 3.5428 - accuracy: 0.0629
Epoch 2/10
211/211 [==============================] - 0s 2ms/step - loss: 3.2828 - accuracy: 0.1105

TensorFlow 2 Quantization Aware Training (QAT) with tf.GradientTape

Can anyone point to references where one can learn how to perform Quantization Aware Training (QAT) with tf.GradientTape on TensorFlow 2?
I only see this done with the tf.keras API. I do not use tf. keras, I always build customized training with tf.GradientTape provides more control over the training process. I now need to quantize a model but I only see references on how to do it using the tf. keras API.
In the official examples here, they showed QAT training with model. fit. Here is a demonstration of Quantization Aware Training using tf.GradientTape(). But for complete reference, let's do both here.
Base model training. This is directly from the official doc. For more details, please check there.
import os
import tensorflow as tf
from tensorflow import keras
import tensorflow_model_optimization as tfmot
# Load MNIST dataset
mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# Normalize the input image so that each pixel value is between 0 to 1.
train_images = train_images / 255.0
test_images = test_images / 255.0
# Define the model architecture.
model = keras.Sequential([
keras.layers.InputLayer(input_shape=(28, 28)),
keras.layers.Reshape(target_shape=(28, 28, 1)),
keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(10)
])
# Train the digit classification model
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
model.fit(
train_images,
train_labels,
epochs=1,
validation_split=0.1,
)
10ms/step - loss: 0.5411 - accuracy: 0.8507 - val_loss: 0.1142 - val_accuracy: 0.9705
<tensorflow.python.keras.callbacks.History at 0x7f9ee970ab90>
QAT .fit.
Now, performing QAT over the base model.
# -----------------------
# ------------- Quantization Aware Training -------------
import tensorflow_model_optimization as tfmot
quantize_model = tfmot.quantization.keras.quantize_model
# q_aware stands for for quantization aware.
q_aware_model = quantize_model(model)
# `quantize_model` requires a recompile.
q_aware_model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
q_aware_model.summary()
train_images_subset = train_images[0:1000]
train_labels_subset = train_labels[0:1000]
q_aware_model.fit(train_images_subset, train_labels_subset,
batch_size=500, epochs=1, validation_split=0.1)
356ms/step - loss: 0.1431 - accuracy: 0.9629 - val_loss: 0.1626 - val_accuracy: 0.9500
<tensorflow.python.keras.callbacks.History at 0x7f9edf0aef90>
Checking performance
_, baseline_model_accuracy = model.evaluate(
test_images, test_labels, verbose=0)
_, q_aware_model_accuracy = q_aware_model.evaluate(
test_images, test_labels, verbose=0)
print('Baseline test accuracy:', baseline_model_accuracy)
print('Quant test accuracy:', q_aware_model_accuracy)
Baseline test accuracy: 0.9660999774932861
Quant test accuracy: 0.9660000205039978
QAT tf.GradientTape().
Here is the QAT training part on the base model. Note we can also perform custom training over the base model.
batch_size = 500
train_dataset = tf.data.Dataset.from_tensor_slices((train_images_subset,
train_labels_subset))
train_dataset = train_dataset.batch(batch_size=batch_size,
drop_remainder=False)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()
for epoch in range(1):
for x, y in train_dataset:
with tf.GradientTape() as tape:
preds = q_aware_model(x, training=True)
loss = loss_fn(y, preds)
grads = tape.gradient(loss, q_aware_model.trainable_variables)
optimizer.apply_gradients(zip(grads, q_aware_model.trainable_variables))
_, baseline_model_accuracy = model.evaluate(
test_images, test_labels, verbose=0)
_, q_aware_model_accuracy = q_aware_model.evaluate(
test_images, test_labels, verbose=0)
print('Baseline test accuracy:', baseline_model_accuracy)
print('Quant test accuracy:', q_aware_model_accuracy)
Baseline test accuracy: 0.9660999774932861
Quant test accuracy: 0.9645000100135803

Improve Prediction Accuracy of Keras Neural Network Algorithm

How can I modify my code below to improve its current accuracy of 71.38%? The dataset is 6 independant variables of numbers and 1 dependant variable of either 0 or 1.
from numpy import loadtxt
from keras.models import Sequential
from keras.layers import Dense
dataset = loadtxt('numbers/numbers.csv', delimiter=',')
X = dataset[:,0:6]
y = dataset[:,6]
model = Sequential()
model.add(Dense(32, input_dim=6, activation='softsign'))
model.add(Dense(16, activation='softsign'))
model.add(Dense(1, activation='softsign'))
model.compile(loss='binary_crossentropy', optimizer='SGD', metrics=['accuracy'])
model.fit(X, y, epochs=50, batch_size=100)
_, accuracy = model.evaluate(X, y)
print('Accuracy: %.2f' % (accuracy*100))
predictions = model.predict_classes(X)
for i in range(5):
print('%s => %d (expected %d)' % (X[i].tolist(), predictions[i], y[i]))

Why is ImageDataGenerator() performing poorly?

I am trying to build a image classification model, using ImageDataGenerator().
It seems that the model trains and performs poorly. The training loss stays at around 15 and the accuracy is barely 10%, the validation is about the same.
Just to see what would happen, I tried training without using the ImageDataGenerator() and set up the data in a similar way. It performed much better in training, validation and testing. With training loss of 0.71 and accuracy of 75% and validation loss of 0.8 and accuracy of 72%.
I need to figure out this model with the data generator because I will be moving on to a larger dataset, where it will not fit into memory.
So, I guess my question is what am I doing wrong with the ImageDataGenerator() that it is performing so badly and how can I improve the outcome?
When setting up the files (in all Train, Test, Validation folders), there are the classes with its own folder and in those folders is where the images are.
Here is the code:
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import pickle
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten, Conv2D, MaxPooling2D, Dropout
data_gen = ImageDataGenerator()
IMG_SIZE = 100
train_it = data_gen.flow_from_directory('D:/.../Train/', class_mode='sparse',
target_size=(IMG_SIZE, IMG_SIZE),color_mode='grayscale', shuffle=True,batch_size=32)
val_it = data_gen.flow_from_directory('D:/.../Validation/', class_mode='sparse',
target_size=(IMG_SIZE, IMG_SIZE),color_mode='grayscale', shuffle=True,batch_size=32)
IMAGE_SIZE = [100, 100]
model=Sequential()
model.add(Conv2D(32,(3,3), input_shape=[*IMAGE_SIZE, 1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))
model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))
model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(len(train_it.class_indices), activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit_generator(train_it, epochs=20, validation_data=val_it )
Here is my code without ImageDataGenerator():
SETUP the data, using OpenCV
DATADIR='D:\...\Train'
CATEGORIES = pickle.load(open("CATEGORIES.p" , "rb"))
print(len(CATEGORIES))
IMG_SIZE = 100
training_data=[]
def create_training_data():
for category in CATEGORIES:
path = os.path.join(DATADIR,category)
class_num = CATEGORIES.index(category)
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
training_data.append([new_array, class_num])
except:
print(category)
print(img)
create_training_data()
random.shuffle(training_data)
X=[]
y=[]
for features, label in training_data:
X.append(features)
y.append(label)
X=np.array(X).reshape(-1,IMG_SIZE, IMG_SIZE, 1)
X=X/255.0
MODEL SETUP:
model=Sequential()
model.add(Conv2D(32,(3,3), input_shape=[*IMAGE_SIZE, 1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))
model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))
model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(len(CATEGORIES), activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X,y, epochs=20, batch_size=32, validation_split=0.1)
#acho,
Mentioning the solution to this issue cited by you in the comments, for the benefit of the community.
Reason for the issue is that Input Data is not Normalized by dividing each Pixel Value by 255. It has an impact on Training because of the reasons mentioned below:
It converts Pixel Values from Integers to Float, in a range of 0.0-1.0 where 0.0 means 0 (0x00) and 1.0 means 255 (0xFF). Conv Nets work better on Float Values compared to Integer Values, and by normalizing it in a range of 0-1, computations will be reduced.
Normalization will help you to remove distortions caused by lights and shadows in an image.

Should I convert classification output to integer and how?

I'm using a neural network to classify text, and the label of the training data is 0 or 1(i.e. binary classification). It works well in the training and evaluating process, but the prediction output is float values rather than integer 0 or 1. How could I always get integer results? Do i need to manually convert them or change network parameters?
model = Sequential()
e = Embedding(vocab_size, embedding_dim, weights=[embedding_matrix],
input_length=max_length, trainable=False)
model.add(e)
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
# compile
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
print(model.summary())
# fit
model.fit(padded_docs, labels, epochs=5, verbose=2)
# eval
loss, accuracy = model.evaluate(padded_docs, labels, verbose=0)
print('Accuracy: %f' % (accuracy*100))
# predict
result = model.predict(padded_docs_test, verbose=2)
You need to manually convert them by setting a threshold, like:
threshold = 0.5
result = model.predict(padded_docs_test, verbose=2)
result = result > threshold
This will give binary predictions. Keras uses a threshold of 0.5 when computing binary accuracy.