-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- mutation algebra - TODO: - store new fitness in Sync only for success steps - try ensure mutation tests run after nodes tests
- Loading branch information
Showing
25 changed files
with
516 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ defmodule EXNN.Pattern do | |
end | ||
|
||
def map([], acc) do | ||
IO.puts "layers: #{inspect(acc)}" | ||
acc | ||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,6 @@ | ||
defmodule EXNN.Trainer do | ||
use Supervisor | ||
use EXNN.Utils.Supervisor | ||
|
||
def start_link do | ||
Supervisor.start_link(__MODULE__, :ok) | ||
def start do | ||
# here the trainer FSM enters training mode | ||
EXNN.Trainer.Sync.sync | ||
end | ||
|
||
def init(:ok) do | ||
IO.puts "starting trainer supervisor" | ||
[] | ||
# |> child(EXNN.Fitness.Supervisor, :supervisor, []) | ||
|> child(EXNN.Fitness.Starter, []) | ||
|> child(EXNN.Trainer.Sync, []) | ||
|> supervise(strategy: :one_for_all) | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
defmodule EXNN.Trainer.Mutations do | ||
use GenServer | ||
|
||
alias EXNN.Trainer.Mutations.Set | ||
alias EXNN.Trainer.Mutations.Agent | ||
|
||
import EXNN.Utils.Logger | ||
|
||
def start_link do | ||
GenServer.start_link __MODULE__, | ||
:ok, | ||
name: __MODULE__ | ||
end | ||
|
||
def init :ok do | ||
{:ok, %{ | ||
neurons: EXNN.Connectome.neurons, | ||
history: [] | ||
}} | ||
end | ||
|
||
# client api | ||
|
||
def step do | ||
GenServer.call __MODULE__, :step | ||
end | ||
|
||
def revert do | ||
GenServer.call __MODULE__, :revert | ||
end | ||
|
||
# server callbacks | ||
|
||
def handle_call :step, _from, state do | ||
log "step", [], :debug | ||
mutation_set = Set.generate(state.neurons) | ||
{:ok, neurons} = Agent.apply mutation_set | ||
|
||
{:reply, :ok, %{state | | ||
neurons: neurons, | ||
history: [mutation_set | state.history]} | ||
} | ||
end | ||
|
||
def handle_call :revert, _from, state do | ||
log "revert", [], :debug | ||
[mutation_set | rest] = state.history | ||
inverse_set = Set.invert mutation_set | ||
{:ok, neurons} = Agent.apply inverse_set | ||
{:reply, :ok, %{state | neurons: neurons, history: rest}} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
defmodule EXNN.Trainer.Mutations.Agent do | ||
@moduledoc false | ||
import EXNN.Utils.Logger | ||
alias EXNN.Trainer.Mutations.Set.Mutation | ||
|
||
def apply mutation_set do | ||
mutation_set | ||
|> Enum.map(&spawn_async_task/1) | ||
|> EXNN.Utils.Task.wait_all | ||
|
||
{:ok, EXNN.Connectome.neurons} | ||
end | ||
|
||
def spawn_async_task(mutation) do | ||
Task.async __MODULE__, :apply_mutation, [mutation] | ||
end | ||
|
||
def apply_mutation %Mutation{ | ||
type: :alter_weights, | ||
id: id, | ||
changes: changes} do | ||
|
||
patch_fn = fn(genome)-> | ||
new_weights = changes |> Enum.reduce genome.ins, fn({key, old, new}, weights)-> | ||
Keyword.put weights, key, new | ||
end | ||
%{ins: new_weights} | ||
end | ||
|
||
res = EXNN.NodeServer.patch(id, patch_fn) | ||
EXNN.Connectome.update(id, res) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
defmodule EXNN.Trainer.Mutations.Set do | ||
@moduledoc false | ||
import EXNN.Utils.Logger | ||
|
||
alias EXNN.Utils.Math | ||
alias EXNN.Utils.Random | ||
alias EXNN.Trainer.Mutations.Set.Mutation | ||
# alias EXNN.Config | ||
|
||
@mutation_types [ | ||
:alter_weights, | ||
# :add_link, | ||
# :delete_link, | ||
# :add_node, | ||
# :remove_node | ||
] | ||
|
||
def generate(neurons) do | ||
length = Enum.count neurons | ||
candidates = Random.sample neurons, Math.inv_sqrt(length) | ||
Enum.map candidates, &generate_for(&1) | ||
end | ||
|
||
def generate_for(genome) do | ||
# type = Random.sample @mutation_types | ||
Mutation.new genome, type: :alter_weights | ||
end | ||
|
||
def invert(set), do: invert(set, []) | ||
|
||
def invert([], done), do: done | ||
|
||
def invert([first|rest], done) do | ||
invert(rest, [Mutation.inverse(first) | done]) | ||
end | ||
|
||
defmodule Mutation do | ||
defstruct type: nil, id: nil, changes: [] | ||
|
||
def new(genome, type: type) do | ||
struct(__MODULE__, [type: type, id: genome.id]) | ||
|> build_changes(genome) | ||
end | ||
|
||
def build_changes %Mutation{type: :alter_weights}=mutation, genome do | ||
weights = genome.ins | ||
keys = Keyword.keys(weights) | ||
length = Enum.count keys | ||
space = Math.inv_sqrt(length) | ||
sampled = keys |> Random.sample(space) | ||
sampled |> Enum.reduce mutation, fn(key, acc)-> | ||
old = weights[key] | ||
new = Random.coefficient(old) | ||
%{acc | changes: [{key, old, new} | acc.changes]} | ||
end | ||
end | ||
|
||
def inverse(%Mutation{type: :alter_weights, changes: changes}=mutation) do | ||
inverse_changes = Enum.map changes, | ||
fn({key, old, new}) -> {key, new, old} end | ||
%{mutation | changes: inverse_changes} | ||
end | ||
end | ||
end |
Oops, something went wrong.