我正在使用皮马印第安人糖尿病发病数据集从头开始开发一个简单的神经网络,该数据集可以从 UCI 机器学习存储库下载。当我运行代码时,每次迭代的错误率始终相同,我不明白为什么会发生这种情况,但如果我使用 XOR 作为数据,它就可以正常工作。
这是我的代码
## Load Dependencies
import numpy as np
from sklearn.preprocessing import MinMaxScaler
## Seeding to reproduce random generated results
np.random.seed(1)
## We take input (X) and output (y)
data = np.loadtxt('diabetes.txt', delimiter=',')
scaler = MinMaxScaler()
scaler.fit(data)
data = scaler.transform(data)
X = data[:,0:8]
y = data[:,8].reshape(768,1)
## Define our activation function, in our case we will use sigmoid function: 1 / (1 + exp(-x))
def sigmoid(x, deriv=False):
if(deriv == True):
return x * (1 - x)
return 1 / (1 + np.exp(-x))
## Initialize weights with random values
wh = 2 * np.random.random((8, 768)) - 1
wo = 2 * np.random.random((768, 1)) - 1
# Training time
for i in range(1000):
## Forward propagation
h0 = X
## input * weigth + bias , activate
h1 = sigmoid(np.dot(h0,wh))
outl = sigmoid(np.dot(h1,wo))
## Compute the error of the predicted output layer to the actual result
errorout = y - outl
## Compute the slope (Gradient/Derivative) of hidden and output layers Gradient of sigmoid can be returned as x * (1 – x).
## Compute change factor(delta) at output layer,
## dependent on the gradient of error multiplied by the slope of output layer activation
deltaoutl = errorout * sigmoid(outl,deriv=True)
## At this step, the error will propagate back into the network which means error at hidden layer.
## For this, we will take the dot product of output layer delta with weight parameters of edges
## between the hidden and output layer (wout.T).
errorh1 = np.dot(deltaoutl,wo.T)
## Compute change factor(delta) at hidden layer, multiply the error at hidden layer with slope of hidden layer activation
deltah1 = errorh1 * sigmoid(h1,deriv=True)
## Print error values
if i % 10000:
print("Error :" + str(np.mean(np.abs(errorout))))
## Update weights at the output and hidden layer:
## The weights in the network can be updated from the errors calculated for training example(s).
wh += np.dot(h0.T,deltah1)
wo += np.dot(h1.T,deltaoutl)
结果是:
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
Error :0.651041666664
...
如果我们将数据更改为:
X = np.array([[0,0],
[0,1],
[1,0],
[1,1]])
y = np.array([[0],
[1],
[1],
[0]])
wh = 2 * np.random.random((2,4)) - 1
wo = 2 * np.random.random((4,1)) - 1
它按其应有的方式工作。我不明白为什么会发生这种情况,请有人启发我,谢谢。
最佳答案
关于神经网络的一些观察:
- 您没有使用偏见术语
- 您正在使用线性损失(尽管打印了 MAE)
- 您使用的学习率为 1.0
- 您在隐藏层中使用 sigmoid 激活
既然你的损失绝对没有任何意义,我怀疑缺乏偏见是你的问题。您的初始化可能会放在 sigmoid 平坦部分的某个位置,并且没有偏差就没有出路。
如果添加偏差不能解决您的问题,请尝试使用逻辑损失而不是线性损失,尝试使用较小的学习率,并尝试在隐藏层中使用 ReLU 激活函数。
更新:
我仔细观察后发现了一个主要错误:你的权重矩阵的形状错误。以下是正确的形状:
n_hidden_units = 16
## Initialize weights with random values
wh = np.random.uniform(size=(X.shape[1], n_hidden_units))
wo = np.random.uniform(size=(n_hidden_units, 1))
仅此更改并不能解决问题,我还必须尝试学习率。我发现 0.01
效果很好。该值对我使用的隐藏单元的数量很敏感。
通过添加偏差项,我还获得了稍微更好的性能。您可以通过以下方式执行此操作:
X = np.c_[X, np.ones(768)]
关于python - 使用皮马印第安人糖尿病发病数据集的神经网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47502648/