Installing Keras 2.6 on Windows and Running the Iris Example

One of the biggest challenges in machine learning is staying up to date with new releases of code libraries. I noticed that Keras released a new version 2.6 a few days ago so I figured I’d do a complete end-to-end example of installation and the Iris Dataset classification problem. I use Windows but the process is almost the same for Linux and Mac.

In the old days, you would install TensorFlow first, then Keras second. Now TensorFlow contains Keras.

First, I installed the Anaconda3-2020.02 distribution which contains Python 3.7.6 and over 500 Python packages. But before I did this, I uninstalled a couple of phantom Pythons (3.5, 3.6) that appeared on my machine. Many programs “helpfully” install a Python for you without being asked, which creates versioning collisions and errors.


Left: I uninstalled an old Python to prevent Python version collisions. Right: I like the Anaconda distribution of Python.

Next I looked for the correct TensorFlow/Keras 2.6.0 whl (“wheel”) installation file. The default .whl file at pypi.org gives you a combined CPU – GPU version. If you install the dual version, when you run a program, TensorFlow/Keras will attempt to determine if your machine has a GPU or not and then run the correct version. Because I was installing on a machine that didn’t have a GPU, I looked for a CPU-only version of TensorFlow/Keras. I eventually found a whl file for a CPU-only version of TensorFlow/Keras — but finding it wasn’t easy.



The standard location for the whl install files gives only the combined GPU-CPU version of TensorFlow/Keras. It’s very easy to get the wrong version of anythind related to machine learning — versioning hell is a significant problem.


Left: While searching for a CPU-only whl file for Windows, I found a URL for a CPU-only version for Linux. Right: After a bit of experimenting with the URL, I eventually found a CPU-only version for Windows at https://storage.googleapis.com/tensorflow/windows/cpu/tensorflow_cpu-2.6.0-cp37-cp37m-win_amd64.whl. I saved the whl file to my local machine, and then installed TensorFlow/Keras, 2.6, CPU-only, for Python 3.7, for Windows.


I used pip to install the CPU-only 2.6.0 version of TensorFlow without any problems. Minor miracle.

Next, I coded up a Iris Dataset demo. I found the 150-item Iris Dataset online — it’s in dozens of places. I manually one-hot encoded the labels by replacing “setosa” with 1, 0, 0 and replacing “versicolor” with 0, 1, 0 and replacing “virginica” with 0, 0, 1.
An alternative strategy is to first manually ordinal encode setosa = 0, versocolor = 1, virginica = 2, and then use tf.keras.utils.to_categorical() to programmatically convert the ordinal values to one-hot values.

I ran the demo without too much trouble. There were about six errors I had to deal with, but that’s to be expected.

Good fun. I’m satisfied that I’m meeting the challenge of keeping up to date with Keras versions, and if I need to work on a Keras project, I can get up to speed quickly.



One of the challenges for people who have an inexplicable desire to follow Hollywood actors is keeping up to date with their wife versions. Here is American actor Nicolas Cage with wife version 1.0, wife version 2.0, wife version 3.0, and wife version 4.0.


Code below.

# iris_tfk.py
# Iris classification
# Anaconda3-2020.02  (Python 3.7.6)
# TensorFlow 2.6.0 (includes KerasTF 2.6.0)
# Windows 10  August 2021

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 MyLogger(K.callbacks.Callback):
  def __init__(self, n):
    self.n = n   # print loss and 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"
  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.np.int64)
  #  train_y = np.loadtxt(data_file, usecols=4,
  #    delimiter=",", skiprows=0, dtype=np.np.int64)  # ordinal
  #  train_y = tf.keras.utils.to_categorical(train_y) # one-hot

  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.compile(loss='categorical_crossentropy',
    optimizer='sgd', metrics=['accuracy'])  # default LR

  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")

  # --------------
  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()
This entry was posted in Keras. Bookmark the permalink.