Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Iris Classification

chapt1.livemd

Iris Classification

Chapt 1

  Mix.install([
      {:axon, "~> 0.6.1"},
      {:nx, "~> 0.7.3"},
      {:bumblebee, "~> 0.5.3"},
      {:explorer, "~> 0.9.1"},
      {:kino, "~> 0.13.2"}
  ])
require Explorer.DataFrame, as: DF
iris = Explorer.Datasets.iris()
cols = ~w(sepal_width sepal_length petal_length petal_width)
shuffled_normalized_iris = iris
  |> DF.mutate(
  for col <- across(^cols) do
    {col.name, (col - mean(col)) / standard_deviation(col)}
  end) 
  |> DF.mutate([
    species: Explorer.Series.cast(species, :category)
  ])
|> DF.shuffle()
train_df = DF.slice(shuffled_normalized_iris, 0..119)
test_df = DF.slice(shuffled_normalized_iris, 120..149)

| One hot encoding of labels?? Kinda like enum to numbers 0,1,2,3 <- :a,:b,:c,:d but more binary

  • [1, 0, 0]
  • [0, 1, 0]
  • [0, 0, 1]
feature_columns = [
  "sepal_length",
  "sepal_width",
  "petal_length",
  "petal_width"
]

x_train = Nx.stack(train_df[feature_columns], axis: -1)
y_train = train_df["species"]
|> Nx.stack(axis: -1)
|> Nx.equal(Nx.iota({1, 3}, axis: -1))

x_test = Nx.stack(test_df[feature_columns], axis: -1)
y_test = test_df["species"]
|> Nx.stack(axis: -1)
|> Nx.equal(Nx.iota({1, 3}, axis: -1))
model = "iris_features"
|> Axon.input(shape: {nil, 4})
|> Axon.dense(3, activation: :softmax)
Axon.Display.as_graph(model, Nx.template({1, 4}, :f32))

“Axon expects input data to be in pairs of {features, targets}”

  • features = train_data tensor
  • targets = train_labels one-hot encoded tensor
data_stream = Stream.repeatedly(fn -> {x_train, y_train} end)
trained_model_state = model
|> Axon.Loop.trainer(:categorical_cross_entropy, :sgd)
|> Axon.Loop.metric(:accuracy)
|> Axon.Loop.run(data_stream, %{}, iterations: 500, epochs: 10)
data = [{x_test, y_test}]

model
|> Axon.Loop.evaluator()
|> Axon.Loop.metric(:accuracy)
|> Axon.Loop.run(data, trained_model_state)