我已经用cntk(python)实现了“xor问题”。在
目前它只是偶尔解决这个问题。如何实现更可靠的网络?在
我想只要初始随机权重接近最优,问题就会迎刃而解。我试过binary_cross_entropy
作为损失函数,但没有得到改善。我尝试了tanh
作为非线性函数,但它也不起作用。我还尝试了许多不同的参数组合learning_rate
、minibatch_size
和{
谢谢
# -*- coding: utf-8 -*-
import numpy as np
from cntk import *
import random
import pandas as pd
input_dim = 2
output_dim = 1
def generate_random_data_sample(sample_size, feature_dim, num_classes):
Y = []
X = []
for i in range(sample_size):
if i % 4 == 0:
Y.append([0])
X.append([1,1])
if i % 4 == 1:
Y.append([0])
X.append([0,0])
if i % 4 == 2:
Y.append([1])
X.append([1,0])
if i % 4 == 3:
Y.append([1])
X.append([0,1])
return np.array(X,dtype=np.float32), np.array(Y,dtype=np.float32)
def linear_layer(input_var, output_dim,scale=10):
input_dim = input_var.shape[0]
weight = parameter(shape=(input_dim, output_dim),init=uniform(scale=scale))
bias = parameter(shape=(output_dim))
return bias + times(input_var, weight)
def dense_layer(input_var, output_dim, nonlinearity,scale=10):
l = linear_layer(input_var, output_dim,scale=scale)
return nonlinearity(l)
feature = input(input_dim, np.float32)
h1 = dense_layer(feature, 2, sigmoid,scale=10)
z = dense_layer(h1, output_dim, sigmoid,scale=10)
label=input(1,np.float32)
loss = squared_error(z,label)
eval_error = squared_error(z,label)
learning_rate = 0.5
lr_schedule = learning_rate_schedule(learning_rate, UnitType.minibatch)
learner = sgd(z.parameters, lr_schedule)
trainer = Trainer(z, (loss, eval_error), [learner])
def print_training_progress(trainer, mb, frequency, verbose=1):
training_loss, eval_error = "NA", "NA"
if mb % frequency == 0:
training_loss = trainer.previous_minibatch_loss_average
eval_error = trainer.previous_minibatch_evaluation_average
if verbose:
print ("Minibatch: {0}, Loss: {1:.4f}, Error: {2:.2f}".format(mb, training_loss, eval_error))
return mb, training_loss, eval_error
minibatch_size = 800
num_minibatches_to_train = 2000
training_progress_output_freq = 50
for i in range(0, num_minibatches_to_train):
features, labels = generate_random_data_sample(minibatch_size, input_dim, output_dim)
trainer.train_minibatch({feature : features, label : labels})
batchsize, loss, error = print_training_progress(trainer, i, training_progress_output_freq, verbose=1)
out = z
result = out.eval({feature : features})
a = pd.DataFrame(data=dict(
query=[str(int(x[0]))+str(int(x[1])) for x in features],
test=[int(l[0]) for l in labels],
pred=[l[0] for l in result]))
print(pd.DataFrame.drop_duplicates(a[["query","test","pred"]]).sort_values(by="test"))
按照第一个海报提供的脚本运行,结果总是与此类似(这里只给出了结果的结尾)-这是前面的:
我只是用类似的结果重复了几次。 即使将迭代次数增加到20000次也会得到类似的结果。这个脚本最初的结构似乎并没有给XOR问题带来一个可行的解决方案。网络训练不收敛于异或真值表,误差和损失也不收敛于零。在
将scale=10的4个实例改为scale=1似乎总能为XOR问题提供一个可行的解决方案。典型结果如下。这是后面的。在
^{pr2}$几次重演产生了类似的结果。训练似乎向异或真值表收敛,误差和损失趋于零。 将迭代次数增加到20000次将产生以下典型结果。培训现在产生了一个可行的XOR解决方案,而且脚本似乎是“修复的”。在
更准确地说,建议的脚本更改可能会修复用于设置权重初始条件的方法。我对CNTK相当陌生,所以我不知道使用scale=10会有什么样的效果。由于我发现的CNTK程序的大多数例子都是针对深网类型的问题,我怀疑使用scale=10设置权重初始条件可能与这些问题的解决方案有关,大多数comm只发布在网上。在
最后,在这些测试过程中,我的系统上的库没有任何更改(安装或更新)。因此,关于库版本存在问题的断言似乎没有事实依据。在
将
scale=10
的四个实例更改为scale=1
似乎可以修复脚本。在我没有做任何其他的更改,并且能够连续运行几次,并通过2000次迭代获得不错的结果。当然,增加20000次迭代可以得到更好的结果。在
可能最初的初始重量范围是-10到10,这是因为偶尔会有非常大的重量使一些神经元饱和,从而干扰训练。贪婪的学习率可能会进一步加剧这种影响。在
此外,与当前的深层网络趋势相比,异或网络相当稀少。对于一些饱和的神经元来说,锁定一个深网的训练可能更困难,但可能并非不可能。在
在过去的日子里,我似乎记得我们经常把初始权重设置为相对较小的,并且分布在零左右。不知道理论家现在推荐什么。在
我不认为你可以通过直接映射输入到输出并使用一些权重和偏差来真正“解决”XOR。在它们之间至少需要一个隐藏层(至少有两个节点)。在
相关问题 更多 >
编程相关推荐