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

Machine Learning in Elixir, Chapter 1

machine-learning-in-elixir-chapter-1.livemd

Machine Learning in Elixir, Chapter 1

Mix.install([
  {:axon, "~> 0.5"},
  {:nx, "~> 0.5"},
  {:explorer, "~> 0.5"},
  {:kino, "~> 0.8"}
])

Section

require Explorer.DataFrame, as: DF
iris = Explorer.Datasets.iris()
cols = ~w(sepal_length sepal_width petal_length petal_width)

normalized_iris =
  DF.mutate(
    iris,
    for col <- across(^cols) do
      {col.name, (col - mean(col)) / standard_deviation(col)}
    end
  )

shuffled_normalized_iris = DF.shuffle(normalized_iris)
train_df = DF.slice(shuffled_normalized_iris, 0..119)
test_df = DF.slice(shuffled_normalized_iris, 120..149)
feature_columns = [
  "sepal_length",
  "sepal_width",
  "petal_length",
  "petal_width"
]

label_column = "species"
# see https://elixirforum.com/t/book-question-machine-learning-in-elixir-poor-accuracy-for-chapter-1s-example/57185/8

feature_columns = ["sepal_length", "sepal_width", "petal_length", "petal_width"]
label_column = "species"

x_all = Nx.stack(shuffled_normalized_iris[feature_columns], axis: 1)

y_all =
  shuffled_normalized_iris[label_column]
  |> Explorer.Series.cast(:category)
  |> Nx.stack(axis: -1)
  |> Nx.equal(Nx.iota({1, 3}, axis: -1))

x_train = x_all[0..119]
x_test = x_all[120..149]

y_train = y_all[0..119]
y_test = y_all[120..149]
model =
  Axon.input("iris_features", shape: {nil, 4})
  |> Axon.dense(3, activation: :softmax)
Axon.Display.as_graph(model, Nx.template({1, 4}, :f32))
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}]

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