Skip to content

Commit

Permalink
fix some compiler warnings -- remove EXNN.Utils.Logger
Browse files Browse the repository at this point in the history
  • Loading branch information
zampino committed Feb 22, 2016
1 parent 6dd15d6 commit 245ab25
Show file tree
Hide file tree
Showing 29 changed files with 145 additions and 140 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ as well as OTP application components.

# :construction: All this is quite still in progress :construction:

This library is in a very early stage, and it can at the moment only train a trivial _xor_ function. With some love and time, it will see some improvements.
This library is in a very early stage, and it can at the moment only train a trivial _xor_ function. With some love and time, it will see some improvements. Contributions
are welcome, of course.

# Docs

Expand Down Expand Up @@ -204,13 +205,16 @@ mix test test/examples/xor_test.exs


# Future Plans

- Instrumentation for learning times and logging.

- Explorative search along mutation paths (see `EXNN.Trainer.Mutations`)
to split an individuum into two or more (mutation + mitosis).

- Handle sync among a population of nets through routing with fixed sensors and actuators.

- A State Machine for states 'loading'/'learning'/'production'.
State should switch to 'production' whenever fitness enters a tolerance
- Rewrite `EXNN.Trainer.Sync` as a `:gen_fsm` with states 'learning'/'production'.
Switching to 'production' whenever fitness stably enters a tolerance
neighborhood of 1.

# References
Expand Down
8 changes: 4 additions & 4 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ config :exnn,

# Sample configuration:
#
# config :logger, :console,
# level: :info,
# format: "$date $time [$level] $metadata$message\n",
# metadata: [:user_id]
config :logger, :console,
level: :info,
format: "$date $time [$level] $metadata$message\n",
metadata: [:user_id]

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
Expand Down
7 changes: 4 additions & 3 deletions lib/exnn/actuator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ defmodule EXNN.Actuator do
end

def notify_fitness(message, metadata) do
EXNN.Events.Manager.notify :fitness, {message, metadata}
:ok = EXNN.Events.Manager.notify :fitness, {message, metadata}
# :ok = EXNN.Fitness.eval message, metadata
end

defimpl EXNN.Connection, for: unquote(caller) do
defimpl EXNN.Connection do
require Logger
Logger.debug "PROTOCOL #{inspect @protocol} IMPL FOR #{inspect @for}"
def signal(actuator, message, metadata) do
Logger.debug "[EXNN.Actuator] - signal: #{inspect message}"

state = unquote(caller).act(actuator, message, metadata)
# TODO: pass actuator state to fitness as well
unquote(caller).notify_fitness(message, metadata)
Expand Down
8 changes: 4 additions & 4 deletions lib/exnn/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ defmodule EXNN.Config do
end

def sensor_dimensions(config) do
filter = fn({type, id, mod, opts})->
filter = fn {type, _id, _mod, _opts} ->
type == :sensor
end
mapper = fn({type, id, mod, opts})->
mapper = fn {_type, id, _mod, opts} ->
{id, opts[:dim]}
end
Map.get(config, :remote_nodes) |> Enum.filter_map(filter, mapper)
end

def sensors do
filter = fn({type, id, mod, opts})->
filter = fn {type, _id, _mod, _opts} ->
type == :sensor
end
mapper = fn({type, id, mod, opts})-> id end
mapper = fn {_type, id, _mod, _opts} -> id end
get_remote_nodes |> Enum.filter_map(filter, mapper)
end

Expand Down
16 changes: 7 additions & 9 deletions lib/exnn/connectome.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule EXNN.Connectome do
"""

alias EXNN.Utils.Random
# import EXNN.Utils.Logger


# TODO: decouple storage from link/patterns
# into Connectome.Links and Connectome.Pattern
Expand All @@ -27,14 +27,14 @@ defmodule EXNN.Connectome do
store = pattern
|> EXNN.Pattern.build_layers
|> link([], dimensions)
|> Enum.reduce HashDict.new, &store/2
|> Enum.reduce(HashDict.new, &store/2)

Agent.start_link(fn() -> store end, name: __MODULE__)
end

@doc "returns the list of all genomes"
def all do
unkey = fn(dict)-> dict |> Enum.map &(elem(&1, 1)) end
unkey = fn(dict)-> dict |> Enum.map(&elem &1, 1) end
Agent.get __MODULE__, unkey
end

Expand Down Expand Up @@ -71,25 +71,23 @@ defmodule EXNN.Connectome do

defp link([], acc, _), do: List.flatten(acc)

@doc "actuators are processe as first"
defp link([{:actuator, list} | rest], [], dimensions) do
[{previous_type, previous_list} | tail] = rest
[{_previous_type, previous_list} | _tail] = rest
genomes = EXNN.Genome.collect(:actuator, list)
|> EXNN.Genome.set_ins(previous_list)
link(rest, [genomes], dimensions)
end

@doc "and sensors are last"
defp link([{:sensor, first_list}], acc, dimensions) do
[outs | rest] = acc
[outs | _rest] = acc
genomes = EXNN.Genome.collect(:sensor, first_list)
|> EXNN.Genome.set_outs(outs)
link([], [genomes | acc], dimensions)
end

defp link([{type, list} | rest], acc, dimensions) do
[{previous_type, previous_list} | tail] = rest
[outs | tail] = acc
[{_previous_type, previous_list} | _tail] = rest
[outs | _tail] = acc
genomes = EXNN.Genome.collect(type, list)
|> EXNN.Genome.set_ins(previous_list, dimensions)
|> EXNN.Genome.set_outs(outs)
Expand Down
16 changes: 8 additions & 8 deletions lib/exnn/dsl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,23 @@ defmodule EXNN.DSL do
end

defmacro __before_compile__(env) do
_nodes = Module.get_attribute(env.module, :nodes)
|> Macro.escape
_pattern = Module.get_attribute(env.module, :initial_pattern)
|> Macro.escape
_fitness = Module.get_attribute(env.module, :fitness)
nodes = Module.get_attribute(env.module, :nodes)
|> Macro.escape
pattern = Module.get_attribute(env.module, :initial_pattern)
|> Macro.escape
fitness = Module.get_attribute(env.module, :fitness)

quote do
def initial_pattern do
unquote _pattern
unquote pattern
end

def nodes do
unquote _nodes
unquote nodes
end

def fitness do
unquote _fitness
unquote fitness
end
end
end
Expand Down
12 changes: 7 additions & 5 deletions lib/exnn/events/manager.ex
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
defmodule EXNN.Events.Manager do
use GenEvent
require Logger

def start_link do
GenEvent.start_link(name: __MODULE__)
end

def init(:ok) do
{:ok, %{}}
{:ok, nil}
end

# PUBLIC CLIENT API
Expand All @@ -17,13 +18,14 @@ defmodule EXNN.Events.Manager do

# SERVER CALLBACKS

def handle_event({:fitness, {message, metadata}}, messages) do
def handle_event {:fitness, {message, metadata}}, state do
Logger.debug "[EXNN.Events.Manager] -- handle :fitness event message #{inspect message} - meta: #{inspect metadata}"
:ok = EXNN.Fitness.eval message, metadata
{:ok, messages}
{:ok, state}
end

def handle_event(_event, messages) do
{:ok, messages}
def handle_event(_event, state) do
{:ok, state}
end

end
2 changes: 1 addition & 1 deletion lib/exnn/events/stream.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule EXNN.Events.Stream do
# # :ok = EXNN.Fitness.eval(message, meta)
# end

def dispatch({_, msg}) do
def dispatch({_, _msg}) do
# IO.puts "dispatching event #{inspect(msg)}"
:ok
end
Expand Down
3 changes: 2 additions & 1 deletion lib/exnn/fitness.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ defmodule EXNN.Fitness do
defmacro __using__(options \\ []) do
quote location: :keep do
use GenServer
defstruct unquote(options) |> Keyword.get(:state, [])
defstruct unquote(options)
|> Keyword.get(:state, [])

def start_link do
GenServer.start_link(__MODULE__, :ok, name: EXNN.Fitness)
Expand Down
2 changes: 1 addition & 1 deletion lib/exnn/genome.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule EXNN.Genome do
alias EXNN.Utils.Math

def collect(type, ids) do
ids |> Enum.map &build(type, &1)
ids |> Enum.map(&build type, &1)
end

def random_bias, do: (Math.pi * Random.uniform)
Expand Down
12 changes: 7 additions & 5 deletions lib/exnn/neuron.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule EXNN.Neuron do
require Logger
@moduledoc """
# Neuron Data Structure
Expand All @@ -21,10 +22,9 @@ defmodule EXNN.Neuron do
@doc "broadcast input to registered outs and resets its trigger"
def fire(%{trigger: []} = neuron) do
{neuron, value} = impulse(neuron)

Logger.debug "[EXNN.Neuron] #{neuron.id} firing #{inspect value} to #{inspect neuron.outs}"
neuron.outs |>
Enum.each(&forward(&1, neuron, value))

Enum.each(&forward(&1, neuron, value))
%{neuron | trigger: Dict.keys(neuron.ins)}
end

Expand All @@ -37,8 +37,10 @@ defmodule EXNN.Neuron do
def impulse(neuron) do
{activation_input, acc} = Enum.reduce(neuron.ins,
{0, neuron.acc}, &Math.labelled_scalar_product/2)
_impulse = neuron.activation.(activation_input + neuron.bias)
{%{neuron | acc: acc}, _impulse}
{
%{neuron | acc: acc},
neuron.activation.(activation_input + neuron.bias)
}
end

def signal(neuron, message, metadata\\[]) do
Expand Down
11 changes: 8 additions & 3 deletions lib/exnn/node_server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@ defmodule EXNN.NodeServer do
GenServer.call(id, {:patch, partial})
end

# TODO: multi-patch
# def patch [{id, changes} | rest] do
# [patch {id, changes} | patch rest]
# end
#
# def patch list when is_list(list) do: list

@doc "dumps current genome to Connectome"
def dump(id) do
GenServer.call(id, :dump)
end

defmacro __using__(options) do
defmacro __using__(_) do
quote do
use GenServer
# import EXNN.Utils.Logger

def start_link(genome) do
GenServer.start_link(__MODULE__, genome, name: genome.id)
Expand All @@ -40,7 +46,6 @@ defmodule EXNN.NodeServer do
{:reply, :ok, EXNN.Connection.signal(connectable, message, metadata)}
end

# TODO: move to neuron
def handle_call({:patch, fun}, _from, node) do
state = Map.merge(node, fun.(node))
destruct = Map.from_struct state
Expand Down
5 changes: 3 additions & 2 deletions lib/exnn/nodes.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule EXNN.Nodes do
require Logger
use GenServer, async: true

def start_link do
Expand Down Expand Up @@ -46,9 +47,9 @@ defmodule EXNN.Nodes do
{:reply, state.names[id], state}
end

def handle_info({:DOWN, ref, :process, pid, _reason}, state) do
def handle_info({:DOWN, ref, :process, _pid, reason}, state) do
{name, refs} = HashDict.pop(state.refs, ref)
IO.puts "/////// node: #{name} went DOWN with reason: #{inspect(_reason)} ////////////////////"
Logger.info "[EXNN.Nodes] - DOWN - node: #{name} went down with reason: #{inspect reason}"
names = HashDict.delete(state.names, name)
# TODO: reload the node from current connectome
# genome = EXNN.Connectome.at name
Expand Down
10 changes: 5 additions & 5 deletions lib/exnn/pattern.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ defmodule EXNN.Pattern do
expand({type, number}, acc, nil)
end

def expand({type, number}, acc, pref) when is_integer(number) do
names = Enum.map 1..number, &(label(type, &1, pref))
[{type, names} | acc]
end

def expand({type, list}, acc) when is_list(list) do
[{type, list} | acc]
end
Expand All @@ -33,6 +28,11 @@ defmodule EXNN.Pattern do
acc
end

def expand({type, number}, acc, pref) when is_integer(number) do
names = Enum.map 1..number, &(label(type, &1, pref))
[{type, names} | acc]
end

def label(type, int, prefix) do
front = type
if prefix do
Expand Down
11 changes: 7 additions & 4 deletions lib/exnn/sensor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ defmodule EXNN.Sensor do
defmacro __using__(options \\ []) do
caller = __CALLER__.module
quote location: :keep do
require Logger
use EXNN.NodeServer
defstruct unquote(options) |>
Keyword.get(:state, []) |> Dict.merge([id: nil, outs: []])
defstruct unquote(options)
|> Keyword.get(:state, [])
|> Dict.merge([id: nil, outs: []])

@doc "#sense must be implemented in the sensor implementation"
def sync(sensor, metadata) do
Expand All @@ -50,7 +52,8 @@ defmodule EXNN.Sensor do
cast_out = fn(out_id) ->
EXNN.NodeServer.forward(out_id, spread_value, [{sensor.id, value}])
end
:ok = sensor.outs |> Enum.each(cast_out)
sensor.outs |> Enum.each(cast_out)
Logger.debug "[EXNN.Sensor] - fanned out #{inspect value} (#{inspect spread_value}) from #{sensor.id} to #{inspect sensor.outs}"
sensor
end

Expand All @@ -70,7 +73,7 @@ defmodule EXNN.Sensor do
list
end

defimpl EXNN.Connection, for: __MODULE__ do
defimpl EXNN.Connection do
def signal(sensor, :sync, metadata) do
unquote(caller).sync(sensor, metadata)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/exnn/trainer/mutations.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule EXNN.Trainer.Mutations do
alias EXNN.Trainer.Mutations.Set
alias EXNN.Trainer.Mutations.Agent

# import EXNN.Utils.Logger


def start_link do
GenServer.start_link __MODULE__,
Expand Down
Loading

0 comments on commit 245ab25

Please sign in to comment.