I am required to implement a simple perceptron based neural network for an image classification task, with a binary output and a single layer, however I am having difficulties. I have a few problems:
I am required to use a tanh() axtivation function, which has the range [-1, 1], however, my training labels are 1 and 0. Should I scale the activation function, or simply change 0 labels to -1?
So the gradient descent rule dictates that I shift the weights according to the rule:
$$ \Delta \omega = -\eta \frac{\delta E}{\delta \omega} $$
I am using the mean square error for my error:
$$ E = (output - label)^2 $$
Considering my output is $o = tanh(\omega .x)$, x is my input vector and $y_i$ is the corresponding label here. $$ \frac{\delta E}{\delta \omega} = \frac{\delta (y_i - tanh(wx))^2}{\delta \omega} \\= -2(y_i - tanh(wx))(1 -tanh^2(wx)) \frac{\delta wx}{\delta w} \\= -2(y_i - tanh(wx))(1 -tanh^2(wx)) x \\= -2(y_i - o)(1 - o^2)x $$
I implemented this is python, the dot product of the input vector with the weights turns out to be too large, which makes $tanh(x)=1$ and $1-o^2 = 0$, so I can't learn. How can I circumvent this problem?
Thanks for the replies.
The implementation:
def perc_nnet(X, y, iter = 10000, eta=0.0001):
a, b, c = X.shape
W_aug = np.random.normal(0, 0.01, a*b+1)
errors = []
for i in range(iter):
selector = rd.randint(0,c-1)
x_n = X[:,:,selector].ravel() #.append(1) #has the bias as well
x_n = np.append(x_n, 1)
v = x_n.dot(W_aug)
o = np.tanh(v)
y_i = y[:,selector] if y[:,selector]==1 else -1
MSE = 0.5*(o - y_i)**2
errors.append(MSE)
delta = - eta * (o - y_i) * (1 - o**2) * x_n
W_aug = W_aug + delta
return W_aug, errors