zoukankan      html  css  js  c++  java
  • 周志华西瓜书习题5.5

    前言 

    这是第一次自己尝试着把书上的代码去编写成程序,但遗憾的是,没有达到预想的结果

    但是,我调了半天,终于调出来了,hahahahahahahaha

    主要是犯了两个重大错误:

    1,只调eta2,却忘记了调eta1,eta1要比eta2重要的多,

    2,自己粗心,测试时居然用数据集X_train进行测试,而用y_test和测试集进行对比,我TM。。。。。。。。。。

    第一次

    第一次使用3.0a数据集,隐层有三个神经元,代码如下

    '''
    主要按照图5.8的伪代码进行
    使用数据集3.0a,两个输入一个输出,对于数据集3.0,不知道怎么把类别转化为数字
    使用的神经网络模型如下
             +++++++++++++++++++++++++
             +          O            +     输出层  有一个阈值 theta
             +        / |           +
             +       /  |           +     隐层到输出层的三个权值 w
             +      /   |           +
             +     O    O    O       +     隐层    有三个阈值 gamma
             +                       +
             +  中间太难画了,直接省略了  +     输入层到隐层有三个权值 v
             +                       +
             +      O       O        +     输入层
             +++++++++++++++++++++++++
    '''
    
    import numpy as np
    import matplotlib.pyplot as plt
    import self_def
    
    #读取数据集
    data = np.loadtxt('watermelon_3a.csv',delimiter=',')
    X = data[:,1:3]
    y = data[:,3]
    
    #划分数据集
    from sklearn import model_selection
    X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.4, random_state=0)
    m,n = np.shape(X_train)
    
    #参数初始化
    theta = np.random.rand(1) #np.random.rand()可产生0到1内的随机数
    w = np.random.rand(3)
    gamma = np.random.rand(3)
    v = np.random.rand(3,2)
    eta1 = 0.1
    eta2 = 0.2
    
    #参数的历史数据,用于查看迭代情况
    theta_history = np.zeros(m)
    w_history = np.zeros((m,3))
    gamma_history = np.zeros((m,3))
    v_history = np.zeros((3*m,2))
    
    #训练
    for k in range(m):
    
        #计算三个隐层神经元的输出
        b = np.zeros(3)
        for h in range(3):
            b[h] = self_def.neuron_out1(X_train[k],v[h],gamma[h])
    
        #输出层神经元的输出估计,式5.3
        y_esti = self_def.neuron_out1(b,w,theta)
    
        #计算g,式5.10
        g = y_esti*(1-y_esti)*(y_train[k]-y_esti)
    
        #计算e,式5.15
        e = np.zeros(3)
        for h in range(3):
            e[h] = b[h]*(1-b[h])*(w[h]*g)  # j = 1,5.15的求和式不必再计算
    
        #计算5.11-5.14
        delta_w = np.zeros(3)
        for h in range(3):
            delta_w[h] = eta1*g*b[h]
    
        delta_theta = -1*eta1*g #检查一下
    
        delta_v = np.zeros((3,2))
        for h in range(3):
            for i in range(2):
                delta_v[h,i] = eta2*e[h]*X_train[k,i]
    
        delta_gamma = -1*eta2*e
    
        #参数更新
        theta += delta_theta
        w += delta_w
        gamma += delta_gamma
        v += delta_v
    
        #记录历史数据
        theta_history[k] = theta
        w_history[k] = w
        gamma_history[k] = gamma
        v_history[3*k:3*k+3] = v
    
    #训练
    mm = np.shape(X_test)[0]
    y_pred = np.zeros((mm,1))
    for k in range(mm):
    
        #计算三个隐层神经元的输出
        for h in range(3):
            b[h] = self_def.neuron_out1(X_train[k],v[h],gamma[h])
    
        #输出层神经元的输出估计,式5.3
        y_esti = self_def.neuron_out1(b,w,theta)
        if y_esti >= 0.5:
            y_pred[k] = 1
    
    #计算混淆矩阵
    cfmat = np.zeros((2, 2))
    for i in range(mm):
    
        if y_pred[i] == y_test[i] == 0:
            cfmat[0, 0] += 1
    
        elif y_pred[i] == y_test[i] == 1:
            cfmat[1, 1] += 1
    
        elif y_pred[i] == 0:
            cfmat[1, 0] += 1
    
        elif y_pred[i] == 1:
            cfmat[0, 1] += 1
    
    print(cfmat)
    
    #查看迭代情况
    t = np.arange(m)
    p1 = plt.subplot(411)
    p1.plot(t,theta_history)
    
    p2 = plt.subplot(412)
    w0 = np.ravel(w_history[:,0])
    p2.plot(t,w0)
    w1 = np.ravel(w_history[:,1])
    p2.plot(t,w1)
    w2 = np.ravel(w_history[:,2])
    p2.plot(t,w2)
    
    p3 = plt.subplot(413)
    gamma0 = np.ravel(gamma_history[:,0])
    p3.plot(t,gamma0)
    gamma1 = np.ravel(gamma_history[:,1])
    p3.plot(t,gamma1)
    gamma2 = np.ravel(gamma_history[:,2])
    p3.plot(t,gamma2)
    
    plt.show()
    
    print('end')

    但是结果不怎么样,我感觉是因为数据量太小,啥也训不出来,于是换数据集

    第二次

    数据集选用的是UCI数据集iris的一部分,共有100个,正例反例各50个

    代码如下

    '''
    主要按照图5.8的伪代码进行
    使用数据集UCI中的iris的一个子数据集,四输入一个输出
    使用的神经网络模型如下
             +++++++++++++++++++++++++
             +          O            +     输出层  有一个阈值 theta_j     1
             +       // |          +
             +     / /  |          +     隐层到输出层的五个权值 w_hj     5*1
             +   /  /   |          +
             + O   O    O   O   O    +     隐层    有五个阈值 gamma_h     5
             +                       +
             +  中间太难画了,直接省略了 +     输入层到隐层有5*4个权值 v_hj    5*4
             +                       +
             +    O   O    O   O     +     输入层
             +++++++++++++++++++++++++
    '''

    #以下是自己改进程序的过程 #2、把三个神经元改为五个神经元 #3、调节eta2的值 #4、参数不再随机化赋值,改为赋指定值 #5、初始参数赋指定值,调节eta2 #6、将训练过程和测试过程简化为函数,见main_3 import numpy as np import matplotlib.pyplot as plt import self_def #读取数据集 data = np.loadtxt('iris_2.csv',delimiter=',') X = data[:,0:4] y = data[:,4] #划分数据集 from sklearn import model_selection X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.25, random_state=0) m,n = np.shape(X_train) #参数初始化 theta = np.random.rand(1) #np.random.rand()可产生0到1内的随机数 w = np.random.rand(5) gamma = np.random.rand(5) v = np.random.rand(5,4) #参数赋指定值 theta = 0.5 w = np.arange(0,1,0.2) gamma = np.arange(0,1,0.2) for ii in range(5): v[ii] = np.arange(0,1,0.25) eta1 = 0.4 eta2 = 0.5 delta_w = np.zeros(5) delta_theta = 0 delta_v = np.zeros((5,4)) delta_gamma = 0 #参数的历史数据,用于查看迭代情况 theta_history = np.zeros(m) w_history = np.zeros((m,5)) gamma_history = np.zeros((m,5)) v_history = np.zeros((5*m,4)) #训练 for k in range(m): #计算三个隐层神经元的输出 b = np.zeros(5) for h in range(5): b[h] = self_def.neuron_out1(X_train[k],v[h],gamma[h]) #输出层神经元的输出估计,式5.3 y_esti = self_def.neuron_out1(b,w,theta) #计算g,式5.10 g = y_esti*(1-y_esti)*(y_train[k]-y_esti) #计算e,式5.15 e = np.zeros(5) for h in range(5): e[h] = b[h]*(1-b[h])*(w[h]*g) # j = 1,5.15的求和式不必再计算 #计算5.11-5.14 for h in range(5): delta_w[h] = eta1*g*b[h] delta_theta = -1*eta1*g #检查一下 for h in range(5): for i in range(4): delta_v[h,i] = eta2*e[h]*X_train[k,i] delta_gamma = -1*eta2*e #参数更新 theta += delta_theta w += delta_w gamma += delta_gamma v += delta_v #记录历史数据 theta_history[k] = theta w_history[k] = w gamma_history[k] = gamma v_history[5*k:5*k+5] = v #预测 mm = np.shape(X_test)[0] y_pred = np.zeros((mm,1)) for k in range(mm): #计算三个隐层神经元的输出 for h in range(5): b[h] = self_def.neuron_out1(X_test[k],v[h],gamma[h]) #输出层神经元的输出估计,式5.3 y_esti = self_def.neuron_out1(b,w,theta) #y_pred[k] = y_test[k] if y_esti >= 0.5: y_pred[k] = 1 #计算混淆矩阵 cfmat = np.zeros((2, 2)) for i in range(mm): if y_pred[i] == y_test[i] == 0: cfmat[0, 0] += 1 elif y_pred[i] == y_test[i] == 1: cfmat[1, 1] += 1 elif y_pred[i] == 0: cfmat[1, 0] += 1 elif y_pred[i] == 1: cfmat[0, 1] += 1 print(cfmat) print('end') # 查看迭代情况 t = np.arange(m) p1 = plt.subplot(411) p1.plot(t, theta_history) plt.ylabel('theta') p2 = plt.subplot(412) w0 = np.ravel(w_history[:, 0]) plt.ylabel('w') p2.plot(t, w0) w1 = np.ravel(w_history[:, 1]) p2.plot(t, w1) w2 = np.ravel(w_history[:, 2]) p2.plot(t, w2) p3 = plt.subplot(413) gamma0 = np.ravel(gamma_history[:, 0]) plt.ylabel('gamma') p3.plot(t, gamma0) gamma1 = np.ravel(gamma_history[:, 1]) p3.plot(t, gamma1) gamma2 = np.ravel(gamma_history[:, 2]) p3.plot(t, gamma2) gamma3 = np.ravel(gamma_history[:, 3]) p3.plot(t, gamma3) plt.show()

    结果

    虽然准确率已经达到了100%,但是各个参数没有趋于稳定,这跟标准BP算法自身有很大的关系

    心得

     以下是自己改进程序的过程
    #2、把三个神经元改为五个神经元
    #3、调节eta2的值
    #4、参数不再随机化赋值,改为赋指定值,每次都使用不同的初值,肯定不方便观察eta2对训练结果的影响
    #5、初始参数赋指定值,调节eta2
    #6、跟着程序一步一步的走,发现eta1的作用远比eta2大得多

    进一步改进:简化函数主体的结构,并作出 precision = f(eta1,eta2)的图像,寻找合适的eta1和eta2

  • 相关阅读:
    Axis,axis2,Xfire以及cxf对比 (转)
    客户端调用服务器端三种方式
    webservice发送数据,取数据的方式
    强制关闭myeclipse出现的问题
    取当前系统的上月时间
    oracle 报Ora-01008错误:oracle 并非所有变量都已绑定的原因.TO_number();动态执行select..into..语句时
    ResultSetMetaData rsmd = rs.getMetaData()是什么意思?
    概率质量函数:怀孕周期的PMF
    Python 正则表达式
    TF-IDF
  • 原文地址:https://www.cnblogs.com/jingxin-gewu/p/13451970.html
Copyright © 2011-2022 走看看