【问题标题】:Why Can't I train the ANN for XNOR?为什么我不能为 XNOR 训练 ANN?
【发布时间】:2019-10-26 15:44:15
【问题描述】:

我制作了一个简单的 NN,用于在输入层中用两个二进制值确定 XNOR 值。 我有带有标签的所有可能组合的 Numpy 数组。

代码:

from keras.models import Sequential
from keras.layers import Dense
import numpy

data = numpy.array([[0.,0.,1.],[0.,1.,0.],[1.,0.,0.],[1.,1.,1.]])
train = data[:,:-1] # Taking The same and All data for training
test = data[:,:-1]  

train_l = data[:,-1]
test_l = data[:,-1]

train_label = []
test_label = []

for i in train_l:
    train_label.append([i])
for i in test_l:
    test_label.append([i])   # Just made Labels Single element...

train_label = numpy.array(train_label)
test_label = numpy.array(test_label)  # Numpy Conversion


model = Sequential()

model.add(Dense(2,input_dim = 2,activation = 'relu'))
model.add(Dense(2,activation = 'relu'))
model.add(Dense(1,activation = 'relu'))

model.compile(loss = "binary_crossentropy" , metrics = ['accuracy'], optimizer = 'adam')

model.fit(train,train_label, epochs = 10, verbose=2)

model.predict_classes(test)

即使使用相同的数据集进行训练和测试......它也不能正确预测...... 我哪里错了?

我故意采用了整个数据集,因为它没有用 2 个值进行预测...

【问题讨论】:

    标签: python numpy tensorflow machine-learning keras


    【解决方案1】:

    你的架构对于这个功能来说太简单了。如果您使用下面的架构并训练 100 个 epoch,您将获得准确度 = 1。

    model = Sequential()
    model.add(Dense(20,input_dim = 2,activation = 'relu'))
    model.add(Dense(20,activation = 'relu'))
    model.add(Dense(1,activation = 'sigmoid'))
    

    更新: 为什么一个简单的模型效果不好?

    一个原因是,使用 ReLU 激活时,如果一个神经元在每个数据点上都变为负数,则其梯度变为零,并且其权重不再训练。一开始你的神经元很少,如果其中一些以这种方式“死亡”,剩余的神经元可能不足以逼近函数。

    另一个问题是神经元越少,模型就越容易陷入局部最小值。

    但是,您说得对,理论上,几个神经元就足够了。 下面的模型即使只有一层也能工作。我已经用 LeakyReLU 替换了 ReLU 来解决第一个问题。它大部分时间都有效,但有时会卡在局部最小值。

    model = Sequential()
    
    model.add(Dense(2,input_dim = 2,activation = LeakyReLU(alpha=0.3)))
    model.add(Dense(1,activation = 'sigmoid'))
    
    optimizer = Adam(lr=0.01)
    model.compile(loss = "binary_crossentropy" , metrics = ['accuracy'], optimizer=optimizer)
    
    model.fit(train,train_label, epochs = 500, verbose=2)
    

    【讨论】:

    • 另外,将最后一层的激活从 relu 更改为 sigmoid 对于当前使用的损失函数可能很重要。
    • 是的,sigmoid 激活与二元交叉熵损失非常匹配,这就是我选择它的原因。
    • @seed 发生了!你能告诉我为什么会这样吗?当我们只需要 2 个作为节点或神经元时,我们需要 20 个?请解释...感谢您的架构。
    猜你喜欢
    • 2017-03-27
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    相关资源
    最近更新 更多