NeuraLegion / shainet

SHAInet - a pure Crystal machine learning library
MIT License
181 stars 19 forks source link

Evolution Strategies Optimizer [WIP] #73

Closed bararchy closed 6 years ago

bararchy commented 6 years ago

This PR adds a new optimizer using Evolution Strategies instead of SGD

Usage:

 puts "---"
    puts "works on iris dataset using evolutionary strategies as optimizer"
    label = {
      "setosa"     => [0.to_f64, 0.to_f64, 1.to_f64],
      "versicolor" => [0.to_f64, 1.to_f64, 0.to_f64],
      "virginica"  => [1.to_f64, 0.to_f64, 0.to_f64],
    }
    iris = SHAInet::Network.new
    iris.add_layer(:input, 4, :memory, SHAInet.sigmoid)
    iris.add_layer(:hidden, 4, :memory, SHAInet.sigmoid)
    iris.add_layer(:output, 3, :memory, SHAInet.sigmoid)
    iris.fully_connect

    outputs = Array(Array(Float64)).new
    inputs = Array(Array(Float64)).new
    CSV.each_row(File.read(__DIR__ + "/test_data/iris.csv")) do |row|
      row_arr = Array(Float64).new
      row[0..-2].each do |num|
        row_arr << num.to_f64
      end
      inputs << row_arr
      outputs << label[row[-1]]
    end
    normalized = SHAInet::TrainingData.new(inputs, outputs)
    normalized.normalize_min_max

    # Interesting Part starts here 
    # This will create a pool with 1000 organisms
    iris.train_es(
      data: normalized.data.shuffle,
      pool_size: 1000,
      cost_function: :mse,
      epochs: 100,
      mini_batch_size: 10,
      error_threshold: 0.0,
      log_each: 1)

    result = iris.run(normalized.normalized_inputs.first)
    ((result.first < 0.3) && (result[1] < 0.3) && (result.last > 0.7)).should eq(true)
  end