The most common way to define a simple Keras neural network network/model is to just crank it out as a sequence of Dense layers. For example, to create a 4-5-3 network for the Iris Dataset where the labels are already one-hot encoded:
import Keras as K
print("Creating 4-5-3 neural network ")
model = K.models.Sequential()
model.add(K.layers.Dense(units=5, input_dim=4,
activation='tanh', kernel_initializer='glorot_uniform',
bias_initializer='zeros'))
model.add(K.layers.Dense(units=3,
activation='softmax', kernel_initializer='glorot_uniform',
bias_initializer='zeros'))
model.compile(loss='categorical_crossentropy',
optimizer='sgd', metrics=['accuracy'])
A more modular approach is to define a network/model as a Python class:
class Net(K.models.Model):
def __init__(self):
super(Net, self).__init__()
my_init = K.initializers.glorot_uniform(seed=1)
self.net = K.models.Sequential()
self.net.add(K.layers.Dense(units=5, input_dim=4,
activation='tanh',
kernel_initializer=my_init,
bias_initializer='zeros'))
self.net.add(K.layers.Dense(units=3,
activation='softmax',
kernel_initializer=my_init,
bias_initializer='zeros'))
def call(self, x):
oupt = self.net(x)
return oupt
print("\nCreating 4-5-3 neural network ")
model = Net()
model.compile(loss='categorical_crossentropy',
optimizer='sgd', metrics=['accuracy'])
The class definition approach is a lot more code (you have to add __init__() and call() methods) and therefore adds complexity, but the design is a bit cleaner. I don’t have a clear preference. The more complex a network architecture is, the more appealng the class definition approach is. There are some non-simple scenarios, such as an autoencoder, where the class definition approach is very helpful.
Note that when you use the class definition approach, if you save the model you must use the SavedModel format rather than the simpler Save format.
Interesting.

The steampunk style combines design simplicity and complexity. Two steampunk style submarine models. I like to look at them as art but I’m not so sure I’d feel confident about traveling in them.
Demo code:
# iris_tfk.py
# Iris classification
# Anaconda3-2020.02 (Python 3.7.6)
# TensorFlow 2.6.0 (includes KerasTF 2.6.0)
# Windows 10
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import numpy as np
import tensorflow as tf
from tensorflow import keras as K
class Net(K.models.Model):
# 4-5-3
def __init__(self):
super(Net, self).__init__()
my_init = K.initializers.glorot_uniform(seed=1)
self.net = K.models.Sequential()
self.net.add(K.layers.Dense(units=5, input_dim=4,
activation='tanh',
kernel_initializer=my_init,
bias_initializer='zeros'))
self.net.add(K.layers.Dense(units=3,
activation='softmax',
kernel_initializer=my_init,
bias_initializer='zeros'))
def call(self, x):
oupt = self.net(x)
return oupt
class MyLogger(K.callbacks.Callback):
def __init__(self, n):
self.n = n # print loss & acc every n epochs
def on_epoch_end(self, epoch, logs={}):
if epoch % self.n == 0:
curr_loss =logs.get('loss')
curr_acc = logs.get('accuracy') * 100
print("epoch = %4d loss = %0.6f acc = %0.2f%%" % \
(epoch, curr_loss, curr_acc))
def main():
print("\nIris dataset using Keras/TensorFlow ")
np.random.seed(1)
tf.random.set_seed(1)
print("\nLoading Iris data into memory ")
data_file = ".\\Data\\iris_data.txt" # one-hot labels
train_x = np.loadtxt(data_file, usecols=[0,1,2,3],
delimiter=",", skiprows=0, dtype=np.float32)
train_y = np.loadtxt(data_file, usecols=[4,5,6],
delimiter=",", skiprows=0, dtype=np.int64)
# data_file = ".\\Data\\iris_data_ordinal_labels.txt" # ord
# train_y = np.loadtxt(data_file, usecols=4,
# delimiter=",", skiprows=0, dtype=np.int64)
# train_y = tf.keras.utils.to_categorical(train_y)
print("\nCreating 4-5-3 neural network ")
# model = K.models.Sequential()
# model.add(K.layers.Dense(units=5, input_dim=4,
# activation='tanh', kernel_initializer='glorot_uniform',
# bias_initializer='zeros'))
# model.add(K.layers.Dense(units=3, activation='softmax'))
model = Net()
model.compile(loss='categorical_crossentropy',
optimizer='sgd', metrics=['accuracy'])
my_logger = MyLogger(n=3)
print("\nStarting training ")
h = model.fit(train_x, train_y, batch_size=1,
epochs=12, verbose=0, callbacks=[my_logger]) # 1=chatty
print("Training finished ")
eval = model.evaluate(train_x, train_y, verbose=0)
print("\nModel evaluation: loss = %0.6f \
accuracy = %0.2f%% " \
% (eval[0], eval[1]*100) )
print("\nSaving trained model as file iris_model.h5 ")
# model.save_weights(".\\Models\\iris_model.h5")
# model.save(".\\Models\\iris_model.h5")
model.save(".\\Models\\iris_model") # no extension
# --------------
np.set_printoptions(precision=4, suppress=True)
wts = model.get_weights()
print("\nTrained model weights and biases: ")
for ar in wts:
print(ar)
print("")
# --------------
np.set_printoptions(precision=4)
unknown = np.array([[6.1, 3.1, 5.1, 1.1]],
dtype=np.float32)
predicted = model.predict(unknown)
print("\nUsing model to predict species for features: ")
print(unknown)
print("\nPredicted species is: ")
print(predicted)
if __name__=="__main__":
main()

.NET Test Automation Recipes
Software Testing
SciPy Programming Succinctly
Keras Succinctly
R Programming
2026 Visual Studio Live
2025 Summer MLADS Conference
2026 DevIntersection Conference
2025 Machine Learning Week
2025 Ai4 Conference
2026 G2E Conference
2026 iSC West Conference
You must be logged in to post a comment.