Python 什么';我的神经网络实现有什么问题?

Python 什么';我的神经网络实现有什么问题?,python,scikit-learn,neural-network,Python,Scikit Learn,Neural Network,我想画一条神经网络的学习误差曲线,它与训练样本的数量有关。代码如下: import sklearn import numpy as np from sklearn.model_selection import learning_curve import matplotlib.pyplot as plt from sklearn import neural_network from sklearn import cross_validation myList=[] myList2=[] w=[]

我想画一条神经网络的学习误差曲线,它与训练样本的数量有关。代码如下:

import sklearn
import numpy as np
from sklearn.model_selection import learning_curve
import matplotlib.pyplot as plt
from sklearn import neural_network
from sklearn import cross_validation

myList=[]
myList2=[]
w=[]

dataset=np.loadtxt("data", delimiter=",")
X=dataset[:, 0:6]
Y=dataset[:,6]
clf=sklearn.neural_network.MLPClassifier(hidden_layer_sizes=(2,3),activation='tanh')

# split the data between training and testing
X_train, X_test, Y_train, Y_test = cross_validation.train_test_split(X, Y, test_size=0.25, random_state=33)

# begin with few training datas
X_eff=X_train[0:int(len(X_train)/150), : ]
Y_eff=Y_train[0:int(len(Y_train)/150)]

k=int(len(X_train)/150)-1


for m in range (140) :


    print (m)

    w.append(k)

    # train the model and store the training error
    A=clf.fit(X_eff,Y_eff)
    myList.append(1-A.score(X_eff,Y_eff))

      # compute the testing error
    myList2.append(1-A.score(X_test,Y_test))

    # add some more training datas
    X_eff=np.vstack((X_eff,X_train[k+1:k+101,:]))
    Y_eff=np.hstack((Y_eff,Y_train[k+1:k+101]))
    k=k+100

plt.figure(figsize=(8, 8))
plt.subplots_adjust()
plt.title("Erreur d'entrainement et de test")
plt.plot(w,myList,label="training error")
plt.plot(w,myList2,label="test error")
plt.legend()
plt.show()
然而,我得到了一个非常奇怪的结果,随着曲线的波动,训练误差非常接近测试误差,这似乎不正常。 错在哪里?我不明白为什么会有这么多的起伏,为什么训练错误不会像预期的那样增加。任何帮助都将不胜感激


编辑:我正在使用的数据集是我摆脱了少于1000个实例的类的地方。我手动重新编码了一般数据。

我认为,您看到这种曲线的原因是,您正在测量的性能指标与您正在优化的性能指标不同

优化度量 神经网络使损失函数最小化,在tanh激活的情况下,我假设您使用的是交叉熵损失的修改版本。如果你画出损失随时间的变化,你会看到一个更单调递减的误差函数,就像你所期望的那样。 (实际上不是单调的,因为神经网络是非凸的,但这不是重点。)

性能指标 您正在测量的性能指标是精度百分比,这与损失不同。为什么这些不同?损失函数以可微的方式告诉我们误差有多大(这对于快速优化方法很重要)。精度指标告诉我们预测的好坏,这对神经网络的应用非常有用

把它放在一起 因为您正在绘制相关指标的性能,所以可以预期该图将与优化指标的性能相似。但是,由于它们不一样,您可能会在绘图中引入一些未解释的差异(如您发布的绘图所示)

有几种方法可以解决这个问题

  • 绘制损失图,而不是精度图。如果你真的需要精确的曲线图,这实际上并不能解决你的问题,但是它会给你更平滑的曲线
  • 绘制多次运行的平均值。在算法的20次独立运行中保存精度图(如在网络中训练20次),然后将其平均并绘制此图。这将大大减少差异
  • TL;博士 不要期望精度图总是平滑的,单调递减的,它不会


    问题编辑后: 现在您已经添加了数据集,我看到了一些可能导致您看到的问题的其他因素

    信息量 数据集定义了几个棋子的等级和文件(行和列)。这些输入为1到6之间的整数。然而,2真的比1好吗?6真的比2好吗?我认为就国际象棋的位置而言,情况并非如此

    想象一下,我正在构建一个以金钱为输入的分类器。我的价值观有多少信息被描绘出来?是的,1美元与100美元大不相同;我们可以看出,有一种基于震级的关系

    对于国际象棋比赛,第1行的意思是否与第8行不同?一点也不,事实上这些维度是对称的!在网络中使用偏差单位有助于解释对称性,方法是将输入从[-3,4]有效地“重新缩放”,该输入现在以0为中心(ish)

    解决
    但是,我认为,您可以从tile编码或对每个功能进行一次热编码中获得最大的收益。不要让网络依赖于每个特征的大小中包含的信息,因为这可能会导致网络陷入糟糕的局部最优。

    随机化训练集并重复

    如果您希望公平比较训练样本数量对准确性的影响,我建议从您的训练集中随机挑选
    n_样本
    ,而不是在前一批中添加100个样本。您还可以为每个
    N_样本
    值重复拟合
    N_repeat
    次数

    这将给出如下结果(未测试):

    热启动

    当您使用
    fit
    功能时,您可以从头开始重新启动优化。如果您希望在将几个示例添加到以前训练过的相同网络时看到优化的改进,可以使用选项
    warm\u start=True

    根据:

    热启动:布尔,可选,默认为False

    当设置为True时,将上一次调用的解决方案重新用作初始化,否则,只需擦除上一次调用的解决方案即可


    除了前面的答案之外,您还应该记住,您可能必须调整网络的
    学习率
    (通过在初始值设定项中设置
    学习率=值
    )。如果选择“速率”为“大”,则会从局部最小值跳到另一个或围绕这些点旋转,但实际上不会收敛(请参见下图,取自)

    此外,还请绘制
    损失
    ,而不仅仅是网络的准确性。这会让你对它有更好的了解

    此外,请记住,您必须使用大量的训练和测试数据来获得或多或少的“平滑”曲线,甚至是代表性曲线;如果您只使用了几个(可能几百个)数据点,那么生成的度量实际上不会非常准确,因为它们包含很多随机的东西。要解决此错误,您不应每次都使用相同的示例来训练网络,而应更改训练数据的顺序,并可能将其拆分到不同的网络上。我非常有信心,你可以通过关注这些方面并加以实施来解决甚至减少你的问题

    根据您的问题类型,您应该将激活功能更改为其他功能
    n_samples_array = np.arange(100,len(X_train),100)
    N_repeat = 10
    
    for n_samples in n_samples_array:
        print(n_samples)
        
        # repeat the fit several times and take the mean
        myList_tmp, myList2_tmp = [],[]
        for repeat in range(0,N_repeat):
            # Randomly pick samples
            selection = np.random.choice(range(0,len(X_train)),n_samples,repeat=False)
        
            # train the model and store the training error
            A=clf.fit(X_train[selection],Y_train[selection])
            myList_tmp.append(1-A.score(X_train[selection],Y_train[selection]))
    
              # compute the testing error
            myList2_tmp.append(1-A.score(X_test,Y_test))
        
        myList.append(np.mean(myList_tmp))
        myList2.append(np.mean(myList2_tmp))