# Neural Network, dependence among outputs?

Is there a way to train a neural network in the following manner:

You have $n$ observations in the training set.

The neural net will start with random weights, and produce $n$ outputs. I want to then apply a function, $f$, on these $n$ outputs. $f$ will output a single real valued number $\alpha$. The goal of the neural net is to then maximize $\alpha$.

That is, I don't care what the neural net outputs for any single observation. I want it to maximize some property of the outputs as a whole (e.g. I want to maximize the variance of the outputs).

Are there neural networks like this, or other techniques for what I am looking for?

Any insight is appreciated!

• You can use genetic algorithm for optimization. Just approach it as any other optimization problem, where you have an output you'd like to maximize. Commented Mar 17, 2014 at 23:00
• sashkello, You use GAs to optimize over a neural network structure? Had no idea, gotta look into this! Commented Mar 17, 2014 at 23:13
• This is what I usually do with customized NN's, maybe there could be better ways, but always worked for me. Commented Mar 17, 2014 at 23:19
• What is your dataset and what are you trying to do with $n$, $f$ and $\alpha$. From a training standpoint, this sounds like you want sparsity. Commented Mar 17, 2014 at 23:30
• @ssdecontrol the OP has not been around since shortly after this question was asked, and the question itself is not fully clear*. If you have something in mind, you might be better off posting a new question. (*In the simplest instance where their function $f$ is a summation over the training examples, the problem is just the standard NN training problem. Technically this may even be true for general $f$, though the standard stochastic gradient descent may not be appropriate in that case. The only difference is not caring about generalization error) Commented Sep 26, 2016 at 19:14

The neural net will start with random weights, and produce $n$ outputs. I want to then apply a function, $f$, on these $n$ outputs. $f$ will output a single real valued number $\alpha$. The goal of the neural net is to then maximize $\alpha$.

This means that the training set is not used. The problem is just maximizing $f(x_1, ..., x_n)$ given $x_1, ..., x_n$. There exist a fair amount of literature on that topic, the choice of technique depending on $f$: Mathematical optimization.

Yes, you can do it but with some modification to your proposed algorithm. In order to train your network, you need to know error (which you are computing), but also the direction of the error (derivative) with respect to the activity of the neuron and the weight. So you need to know if the error would increase or decrease if you change the weight.

So you can do

1. compute outputs for all your samples (and save activations of the neurons for each sample)
2. compute where should each of your sample move, to minimize your custom criterion.
3. us this as the error term in your training and update your weights accordingly

Another question is however if the neural network is the right tool to do it. For example if you want to find projection that would maximize variance, (nonlinear) PCA might be better.

Edit: Although after bounty period, but here is an example hacky code that does that.

This is a neural network trained to create outputs that are equally distant from each other.

import numpy as np
from sklearn import neural_network

def get_new_targets(x):
"""
Function to get points that are in the middle of the neighbouring points"""
try:
x = [e[1] for e in x]
except:
pass
enumerated_x = [e for e in enumerate(x)]
enumerated_x.sort(key=lambda x: x[1])
targets = []
for i, elem in enumerate(enumerated_x):
previous_sample, next_sample = 0, 0
#        current_sample =  enumerated_x[i][1]
if i == 0:
previous_sample = 0
else:
previous_sample = enumerated_x[i-1][1]
if i == len(enumerated_x)-1:
next_sample = 50
else:
next_sample = enumerated_x[i+1][1]
target = (previous_sample + next_sample)/2.
targets.append(target)
targets_in_order = sorted([(enum[0], t) for enum, t in zip(enumerated_x, targets)])
targets_in_order = [e[1] for e in targets_in_order]
return np.array(targets_in_order)

# create training data
# in this example we care only about one axis
X = np.array([[0,3], [0,4], [0,10], [0,15], [0,35], [0,36] ,[0,50]])
# create initial targers. This will change every epoch
Y = get_new_targets(X)

preds = [] # save predictions
epochs = []

# warm start True and max_iter 1 to simulate batch training
clf = neural_network.MLPRegressor(max_iter=1, warm_start=True, alpha=0.005,
hidden_layer_sizes=(50,), activation='logistic')

for i in range(4000): # for each epoch
# since warms_start=True it will reuse weights from previous epoch
clf.fit(X, Y)
predictions =  clf.predict(X)
Y = get_new_targets(predictions)
if i % 100 == 0:
pred = clf.predict(X)
preds.append([pred])
epochs.append(i)


Plots that show that it kindof worked, but not really