anchor.diff:      conn :: term()
   }).
   
  +%% Default network values.
  +-define(LEARNING_RATE, 0.001).
  +-define(BATCH_SIZE, 512).
  +-define(EPOCHS, 1).
  +-define(SCALE, null).
  +
   -spec start_link(binary(), inet:socket_address() | inet:hostname(), inet:port_number()) -> {ok, pid()} | {error, term()}.
   start_link(NetworkId, Address, Port) ->
       gen_server:start_link(?NETWORK_GID(NetworkId), ?MODULE, [NetworkId, Address, Port], []).
  
positive.code: 
  -spec initialize(binary(), pos_integer(), pos_integer()) -> ok | {error, binary()}.
  initialize(NetworkId, InpSize, OutSize) ->
      gen_server:call(?NETWORK_GID(NetworkId), {initialize, InpSize, OutSize}).
  
  -spec add_layer(binary(), pos_integer()) -> ok | {error, binary()}.
  add_layer(NetworkId, Size) ->
      gen_server:call(?NETWORK_GID(NetworkId), {add_layer, Size}).
  
  -spec add_activation(binary(), atom()) -> ok | {error, binary()}.
  add_activation(NetworkId, Activation) ->
      gen_server:call(?NETWORK_GID(NetworkId), {add_activation, Activation}).
  
  -spec set_cost(binary(), atom()) -> ok | {error, binary()}.
  set_cost(NetworkId, CostFunc) ->
      gen_server:call(?NETWORK_GID(NetworkId), {set_cost, CostFunc}).
  
  -spec add_data_chunk(binary(), list(), list()) -> ok | {error, binary()}.
  add_data_chunk(NetworkId, Inputs, Labels) ->
      gen_server:call(?NETWORK_GID(NetworkId), {add_data_chunk, [Inputs, Labels]}).
  
  -spec add_data_chunk(binary(), list(), list(), list()) -> ok | {error, binary()}.
  add_data_chunk(NetworkId, Inputs, Labels, Scale) ->
      gen_server:call(?NETWORK_GID(NetworkId), {add_data_chunk, [Inputs, Labels, Scale]}).
  
  -spec set_learning_rate(binary(), float()) -> ok | {error, binary()}.
  set_learning_rate(NetworkId, LearningRate) ->
      gen_server:call(?NETWORK_GID(NetworkId), {set_learning_rate, LearningRate}).
  
  -spec train(binary()) -> ok | {error, binary()}.
  train(NetworkId) -> train(NetworkId, []).
  
  -spec train(binary(), pos_integer() | [pos_integer()]) -> ok | {error, binary()}.
  train(NetworkId, Epochs) when is_integer(Epochs) -> train(NetworkId, [Epochs]);
  train(NetworkId, Args) when is_list(Args) ->
      gen_server:call(?NETWORK_GID(NetworkId), {train, Args}).
  
  -spec train(binary(), pos_integer(), pos_integer()) -> ok | {error, binary()}.
  train(NetworkId, Epochs, BatchSize) -> train(NetworkId, [Epochs, BatchSize]).
  
  -spec get_weights(binary()) -> ok | {error, binary()}.
  get_weights(NetworkId) ->
      gen_server:call(?NETWORK_GID(NetworkId), get_weights).
  
  -spec set_weights(binary(), [float()]) -> ok | {error, binary()}.
  set_weights(NetworkId, Weights) ->
      gen_server:call(?NETWORK_GID(NetworkId), {set_weights, Weights}).
  
  -spec predict(binary(), [number()]) -> list() | {error, binary()} .
  predict(NetworkId, [N|_]=Input) when is_number(N) ->
      %% TODO: Check for errors...
      [Result] = gen_server:call(?NETWORK_GID(NetworkId), {predict, [Input]}),
      Result;
  predict(NetworkId, Set) ->
      gen_server:call(?NETWORK_GID(NetworkId), {predict, Set}).
  
  %% Gen server related functions
  
  
negative.code:     create_neural_network/4,
      supported_activations/0,
      initialize/3,
      initialize/4,
      add_layer/2,
      add_activation/2,
      set_cost/2,
  