Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何改进此cntk xor实现_Python_Neural Network_Cntk - Fatal编程技术网

Python 如何改进此cntk xor实现

Python 如何改进此cntk xor实现,python,neural-network,cntk,Python,Neural Network,Cntk,我已经用cntk(python)实现了“xor问题” 目前它只是偶尔解决这个问题。如何实现更可靠的网络 我想只要开始的随机权重接近最优,问题就会得到解决。我尝试过将二元交叉熵作为损失函数,但没有改进。我尝试将tanh作为非线性函数,但它也不起作用。我还尝试了许多不同的参数组合learning\u rate,minibatch\u size和num\u minibatch\u to\u train。请帮忙 谢谢 # -*- coding: utf-8 -*- import numpy as np

我已经用cntk(python)实现了“xor问题”

目前它只是偶尔解决这个问题。如何实现更可靠的网络

我想只要开始的随机权重接近最优,问题就会得到解决。我尝试过将二元交叉熵作为损失函数,但没有改进。我尝试将tanh作为非线性函数,但它也不起作用。我还尝试了许多不同的参数组合
learning\u rate
minibatch\u size
num\u minibatch\u to\u train
。请帮忙

谢谢

# -*- 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"))

我能够通过添加更多隐藏层来提高稳定性
h1=密集层(特征,5,S形,比例=10)
并将学习率提高到
learning\u rate=0.8

这提高了稳定性,但仍不时出错。另外,将损失修改为二进制交叉熵
loss=binary\u cross\u entropy(z,label)
大大提高了正确处理的机会

之前:

Minibatch: 1900, Loss: 0.1272, Error: 0.13
Minibatch: 1950, Loss: 0.1272, Error: 0.13
  query  test      pred
0    11     0  0.502307
1    00     0  0.043964
2    10     1  0.951571
3    01     1  0.498055
之后:

Minibatch: 1900, Loss: 0.0041, Error: 0.00
Minibatch: 1950, Loss: 0.0040, Error: 0.00
  query  test      pred
0    11     0  0.006617
1    00     0  0.000529
2    10     1  0.997219
3    01     1  0.994183
此外,还通过提高收敛速度将比例从10修改为1:

比额表10:

Minibatch: 1300, Loss: 0.0732, Error: 0.01
Minibatch: 1350, Loss: 0.0483, Error: 0.00
比额表1:

Minibatch: 500, Loss: 0.0875, Error: 0.01
Minibatch: 550, Loss: 0.0639, Error: 0.00
总之,需要的是:

  • 将比例从10更改为1(对于稳定的解算器,它需要更多的迭代)
  • 从2到5添加更多隐藏层(克服了来自
    scale=10
    但偶尔需要更多迭代的问题)
  • 将损失函数从
    平方误差
    修改为
    二进制交叉熵
    (收敛速度更快,即搜索正确权重更有效)

  • 我不认为通过直接将输入映射到输出,并带有一定的权重和偏差,就可以真正“解决”XOR。它们之间至少需要一个隐藏层(至少有两个节点)。

    scale=10
    的四个实例更改为
    scale=1
    似乎可以修复脚本

    我没有做任何其他更改,并且能够连续运行它几次,并在2000次迭代中获得良好的结果。当然,增加迭代次数(例如20000次或更多)会得到更好的结果

    可能初始重量的-10到10的原始范围允许偶尔非常大的重量使一些神经元饱和并干扰训练。贪婪的学习率可能会进一步加剧这种效应

    另外,与当前的深网趋势相比,XOR网非常稀疏。对于一些饱和的神经元来说,锁定深层网络的训练可能会更加困难,但也可能并非不可能


    在过去的日子里,我似乎记得我们经常将初始权重设置为相对较小的值,并分布在零左右。不确定理论家现在推荐的是什么。

    按照第一张海报提供的脚本运行,总是会产生类似的结果(这里只给出了结果的结尾)-这是之前的结果:

    ...
    Minibatch: 1900, Loss: 0.1266, Error: 0.13
    Minibatch: 1950, Loss: 0.1266, Error: 0.13
      query  test      pred
    0    11     0  0.501515
    1    00     0  0.037678
    2    10     1  0.497704
    3    01     1  0.966931
    
    我只是重复了几次,得到了类似的结果。 即使将迭代次数增加到20000次,也会得到类似的结果。这个最初构建的脚本似乎不能为XOR问题提供可行的解决方案。网络的训练不收敛于异或真值表,误差和损失也不收敛于零

    scale=10的4个实例更改为scale=1似乎总能为XOR问题提供可行的解决方案。典型结果如下。这是后面的

    ...
    Minibatch: 1900, Loss: 0.0129, Error: 0.01
    Minibatch: 1950, Loss: 0.0119, Error: 0.01
      query  test      pred
    0    11     0  0.115509
    1    00     0  0.084174
    2    10     1  0.891398
    3    01     1  0.890891
    
    多次重新运行会产生类似的结果。训练似乎收敛于异或真值表,误差和损失收敛于零。 将迭代次数增加到20000次会产生以下典型结果。培训现在产生了一个可行的XOR解决方案,而且脚本似乎是“固定的”

    更准确地说,拟议的脚本更改可能修复了用于设置权重初始条件的方法。我对CNTK相当陌生,所以我不知道使用scale=10进行烘焙会有什么效果。由于我发现的CNTK程序的大多数示例都是针对深网类型的问题,因此我怀疑使用scale=10设置权重初始条件可能与这些问题解决方案有关,这些问题解决方案大多数都是在网上发布的


    最后,在这些测试过程中,我的系统上的库没有任何更改(安装或更新)。因此,断言图书馆版本存在问题似乎没有事实依据。

    我想说,它试图这样做。异或不是一个线性问题,我们可以在输入和输出之间没有隐藏层来解决。我们只能解决或,而不是没有任何隐藏层。但是,我们肯定需要一个隐藏层来执行XOR、XNOR等。XOR的数据点之间没有平面分隔,这就是为什么需要一个隐藏层来引入所需的非线性。答案用一个很好的图表解释了它。我以为我在这么做。第一层是
    h1
    第二层也是最后一层是
    z
    。你所说的“试图这么做”是什么意思?你只有一个重量和一个偏见。假设W和B。那么,您的代码所做的是
    y=Input*W+B
    。然而,要实现XOR,您至少需要做的是:
    h1=sigmoid(Input*W1+B1)h2=sigmoid(Input*W2+B2)y=sigmoid([h1h2]*W+B)
    ,或者在CNTK中,简单地说:
    model=Sequential([Dense(2),Dense(1)])
    *当然需要适当的缩放和激活。@Vasco抱歉,我的浏览器没有加载完整的代码。现在我看到您正在使用这些函数创建隐藏层。很抱歉评论风暴p可能有些输出有助于理解
    似乎修复了脚本
    ,有点像是在之前/之后。我觉得使用的库版本可能会对输出产生影响。好的,我添加了输出。还使用最新的cntk版本2.6进行了测试。不变
    
    ...
    Minibatch: 19900, Loss: 0.0003, Error: 0.00
    Minibatch: 19950, Loss: 0.0003, Error: 0.00
      query  test      pred
    0    11     0  0.017013
    1    00     0  0.015626
    2    10     1  0.982118
    3    01     1  0.982083