如何使用Keras进行XOR运算

6

我想通过编写一个 XOR 实例来练习 Keras,但是结果不正确。以下是我的代码,请大家帮忙看看,谢谢。

from keras.models import Sequential
from keras.layers.core import Dense,Activation
from keras.optimizers import SGD
import numpy as np

model = Sequential()# two layers
model.add(Dense(input_dim=2,output_dim=4,init="glorot_uniform"))
model.add(Activation("sigmoid"))
model.add(Dense(input_dim=4,output_dim=1,init="glorot_uniform"))
model.add(Activation("sigmoid"))
sgd = SGD(l2=0.0,lr=0.05, decay=1e-6, momentum=0.11, nesterov=True)
model.compile(loss='mean_absolute_error', optimizer=sgd)
print "begin to train"
list1 = [1,1]
label1 = [0]
list2 = [1,0]
label2 = [1]
list3 = [0,0]
label3 = [0]
list4 = [0,1]
label4 = [1] 
train_data = np.array((list1,list2,list3,list4)) #four samples for epoch = 1000
label = np.array((label1,label2,label3,label4))

model.fit(train_data,label,nb_epoch = 1000,batch_size = 4,verbose = 1,shuffle=True,show_accuracy = True)
list_test = [0,1]
test = np.array((list_test,list1))
classes = model.predict(test)
print classes

输出

[[ 0.31851079] [ 0.34130159]] [[ 0.49635666] [0.51274764]] 

“not right” 是什么意思?你得到了什么结果?你期望得到什么? - Daniel
谢谢,我想获取类别列表 = [a,b],其中a接近1,b接近0,但事实上a和b就像随机数一样,有两个结果:[[0.31851079] [0.34130159]] [[0.49635666] [0.51274764]]。 - Jaspn Wjbian
请将此内容集成到您的问题中。这样我们就不必重现您的练习,才能知道出了什么问题... - Daniel
3个回答

2

如果我将你的代码中的epochs数量增加到50000,它通常会收敛到正确答案,只是需要一点时间 :)

但它有时候会卡住。如果我将你的损失函数改为'mean_squared_error',收敛性能会更好,因为它是一个更平滑的函数。

如果我使用Adam或RMSProp优化器,收敛速度会更快。我的最终编译行如下:

model.compile(loss='mse', optimizer='adam')
...
model.fit(train_data, label, nb_epoch = 10000,batch_size = 4,verbose = 1,shuffle=True,show_accuracy = True)

4个超参数正在拟合4个(数据点,标签)。不是在学习XOR运算符,而是过度拟合。 - J.Down
没错,@J.Down - Aditya

1
我使用了一个包含4个隐藏节点的单层隐藏层,几乎总是在500个时期内收敛到正确答案。我使用了sigmoid激活函数。

那会过拟合吗? - J.Down
2
你无法过度拟合异或运算,因为不存在噪声/方差误差! - JeffHeaton

1

Keras中的XOR训练

下面是学习XOR所需的最小神经网络架构,应该是一个(2,2,1)的网络。事实上,数学表明(2,2,1)网络可以解决XOR问题,但数学并没有表明(2,2,1)网络容易训练。有时候可能需要很多个周期(迭代)或者无法收敛到全局最小值。话虽如此,我用(2,3,1)或(2,4,1)的网络架构很容易得到好的结果。

这个问题似乎与存在许多局部最小值有关。看看Richard Bland在1998年发表的论文《Learning XOR: exploring the space of a classic problem》。此外,使用0.5到1.0之间的随机数进行权重初始化有助于收敛。

使用Keras或TensorFlow,使用损失函数'mean_squared_error'、sigmoid激活和Adam优化器都能很好地工作。即使使用相当好的超参数,我观察到学习的XOR模型大约有15%的时间会陷入局部最小值。

from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from tensorflow.keras import initializers
import numpy as np 

X = np.array([[0,0],[0,1],[1,0],[1,1]])
y = np.array([[0],[1],[1],[0]])

def initialize_weights(shape, dtype=None):
    return np.random.normal(loc = 0.75, scale = 1e-2, size = shape)

model = Sequential()
model.add(Dense(2, 
                activation='sigmoid', 
                kernel_initializer=initialize_weights, 
                input_dim=2))
model.add(Dense(1, activation='sigmoid'))

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

print("*** Training... ***")

model.fit(X, y, batch_size=4, epochs=10000, verbose=0)

print("*** Training done! ***")

print("*** Model prediction on [[0,0],[0,1],[1,0],[1,1]] ***")

# print(model.predict_proba(X))
print(model.predict([X])

***训练中...***
***训练完成!***
***模型对[[0,0],[0,1],[1,0],[1,1]]的预测结果***
***[[0.08662204] [0.9235283 ] [0.92356336] [0.06672956]]***

从tensorflow.python.keras.layers导入Dense,而且Sequential中似乎不再存在predict_proba。 - Daniel Lidström
@DanielLidström 谢谢,我已经编辑了我的代码。 - Claude COULOMBE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接