如何使用 keras 进行异或运算

Posted

技术标签:

【中文标题】如何使用 keras 进行异或运算【英文标题】:How to use keras for XOR 【发布时间】:2015-10-11 22:09:35 【问题描述】:

我想通过code a xor来练习keras,但是结果不对,下面是我的code,谢谢大家帮助我。

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]] 

【问题讨论】:

“不正确”是什么意思?你得到什么结果?你会期待什么? 谢谢,我想得到列表 classes = [a,b],a approach to 1,b approach to 0,但事实是 a,b 就像随机数一样,有两个结果:[[ 0.31851079] [ 0.34130159]] [[ 0.49635666] [ 0.51274764]] 请将此整合到您的问题中。这样我们就不必重现你的练习来知道哪里出了问题...... 【参考方案1】:

如果我将代码中的 epoch 数增加到 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【参考方案2】:

我使用具有 4 个隐藏节点的单个隐藏层,它几乎总是在 500 个 epoch 内收敛到正确答案。我使用了 sigmoid 激活函数。

【讨论】:

那会不会过拟合? 不能过拟合异或,没有噪声/方差错误!【参考方案3】:

使用 Keras 进行异或训练

下面是学习 XOR 所需的最小神经元网络架构,它应该是 (2,2,1) 网络。事实上,如果数学表明 (2,2,1) 网络可以解决 XOR 问题,但数学并没有表明 (2,2,1) 网络易于训练。它有时可能需要很多时期(迭代)或不会收敛到全局最小值。也就是说,使用 (2,3,1) 或 (2,4,1) 网络架构,我很容易得到很好的结果。

这个问题似乎与许多局部最小值的存在有关。看看理查德·布兰德 1998 年的这篇论文,«Learning XOR: exploring the space of a classic problem»。此外,使用 0.5 到 1.0 之间的随机数初始化权重有助于收敛。

使用损失函数“mean_squared_error”、sigmoid 激活和 Adam 优化器,它可以与 Keras 或 TensorFlow 完美配合。即使有相当好的超参数,我观察到学习的 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))

*** 培训... ***

*** 训练完成! ***

*** [[0,0],[0,1],[1,0],[1,1]] 上的模型预测 ***

[[0.08662204] [0.9235283] [0.92356336] [0.06672956]]

【讨论】:

以上是关于如何使用 keras 进行异或运算的主要内容,如果未能解决你的问题,请参考以下文章

二进制异或运算怎么算

C语言异或运算会自动转化成2进制?

与、或、异或运算

使用异或运算符对整数进行加密

按键^异或运算符

ShareCode不错的技术文章 -- 如何使用异或(XOR)运算找到数组中缺失的数?