2020年人工神经网络第二次作业-参考答案第六题

如下是 2020年人工神经网络第二次作业 中第六题的参考答案。

 

01 第六题参考答案


1.题目分析

(1) 数据处理

将题目中给定的十个景点位置 { x i , y i } i = 1 , 2 , ⋯   , 10 \left\{ {x_i ,y_i } \right\}_{i = 1,2, \cdots ,10} {xi,yi}i=1,2,,10进行归一化,将坐标值归一化到区间(0,1)之内。
x ^ i = x i / 1000 ,     y ^ i = y i / 600 \hat x_i = x_i /1000,\,\,\,\hat y_i = y_i /600 x^i=xi/1000,y^i=yi/600

(2) 网络结构

SOFM的网络结构:

  • 输入节点数量:2
  • 竞争层神经元个数:10,结构采取首尾相连的一维结构。
    ▲ SOFM网络结构
    ▲ SOFM网络结构

(3) 网络初始化

对于网络的神经元使用(0,1)×(0,1)之内的随机数进行初始化。
▲ 初始化后的网络神经元的位置分布

▲ 初始化后的网络神经元的位置分布

2.求解过程

求解过程中相关程序参见后面附录中 作业中的程序

(1) 学习参数

  • 训练步骤:N=200
  • 学习速率:从0.3 线性减少到0.01
  • 学习半径:从2 线性减少到0

(2) 训练过程

训练过程,神经元所处在的位置变化过程如下图所示。

※ 很奇怪的情况,就是在收敛半径R大于零的时候,整个网络在旋转。不知道这个原因如何进行解释。

※ 上面问题后来经过检查,造成旋转的原因是在求取神经元左右近邻节点语句出现错误造成的。

具体原因来自于neighborid10()函数中的for循环语句:
最开始写成如下的模式:

for i in range(-r,r):

这 实际上对于变量 i i i 的遍历区间为 [ − r , r − 1 ] \left[ { - r,r - 1} \right] [r,r1],而并非是 [ − r , r ] \left[ { - r,r} \right] [r,r]。这样造成神经元邻域不对称,从而造成网络循转。

下面是修改后的程序, 将对变量的遍历区间改为 range(-r,r+1),这样它就等效为[-r,r]。

def neighborid10(id, row, r):
    if r <= 0: return [id]

    iddim = []
    for i in range(-r,r+1):
        iidd = id + i
        if iidd < 0:    iidd += row
        if iidd >= row: iidd -= row

        if  iidd not in range(0, row): continue

        iddim.append(iidd)

    return iddim

下面显示程序修改后网络训练演变过程,其中就不再有旋转的情况了。
▲ 程序修改后网络训练的演变过程

▲ 程序修改后网络训练的演变过程

但是,通过对比,这种不旋转的情况,反而产生的好的路径结果的可能性降低了。

3.结果讨论

(1) 从网络训练结果得到可行路线

根据网络训练结果,可以分析出一条可行的旅行路线。

在10个神经元中,有两个神经元没有收敛到任何一个景点,其中一个神经元处在两个景点的正中间(“居中”节点);另外一个神经元则停止在图中的某一个位置(“迷失”节点)。

▲ 一次训练结果

▲ 一次训练结果

对于处在两个景点中间位置的神经元,指定其位于最左下角的景点。对于另外一个处在空地中的神经元,使其处在剩余的景点处。这样就可以得到一个可行的旅行路线了。

(2) 训练结果出现迷失节点

下面给出更多次训练的结果,可以看出,有的结果很好,也有的结果出现较大的误差。

  • 神经网络训练收敛好的情况:

其中结果中包含一个“居中”节点,一个“迷失节点”。

▲ 产生两个居中,两个迷失节点的结果

▲ 产生两个居中,两个迷失节点的结果

  • 神经网络训练收敛不好的情况:

在这次训练中,包括了三个“居中”节点,三个“迷失”节点。
▲ 出现三个居中,三个迷失节点的情况

▲ 出现三个居中,三个迷失节点的情况

(3) 加入随机噪声

从上面训练过程来看,造成训练过程中出现较多的“迷失”节点的情况是网络中出现较多的节点在训练过程后半阶段始终无法胜出。为了了改善这种情况,下面测试一下在竞争节点中加入随机噪声。随机噪声随着训练逐步降低。
w i = w i + η 2 ⋅ σ ( 0 , 0.5 ) ,    i = 1 , 2 , ⋯   , 10 w_i = w_i + \eta ^2 \cdot \sigma \left( {0,0.5} \right),\,\,i = 1,2, \cdots ,10 wi=wi+η2σ(0,0.5),i=1,2,,10

下面是对每一个循环,对于网络矩阵W加入噪声的语句。

for id in range(W.shape[0]):
    W[id] = W[id] + (random.random(2) - 0.5) * eta**2

下面显示通过增加噪声,网络收敛到只有一个“迷失”节点的结果。
▲ 加入随机噪声提高搜索效果

▲ 加入随机噪声提高搜索效果

总结一下:

  • 在开始编程实现过程中,错误的将邻域搜索范围变成不对称( range(-r,r)),造成网络旋转。这个过程在一定程度上扩大了网络的搜索空间,提高了搜索效果;
  • 在搜索过程中增加随机噪声,也可以扩大搜索空间,提高搜索效果。

如果将上面两种方法(循环加噪声)合并使用,是否可以提高搜索效果呢?

下面是两种方法结合后的效果,这也是所做实验中唯一一次没有“迷失”节点的 一次训练结果。

▲ 循环和增加噪声两种效果下的搜索结果

▲ 循环和增加噪声两种效果下的搜索结果


 

※ 作业中的程序


#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# HW26.PY                      -- by Dr. ZhuoQing 2020-11-26
#
# Note:
#============================================================

from headm import *

#------------------------------------------------------------
x_data = [[236,53], [408,79], [909,89], [115,264], [396,335], \
          [185,456], [699,252], [963,317], [922,389], [649,515]]

x_data = array([[xy[0]/1000,xy[1]/600] for xy in x_data])

#------------------------------------------------------------
def show_data(data, lineflag=0, title=''):
#    plt.clf()

    if lineflag ==0:
        plt.scatter(data[:,0], data[:,1], s=10, c='blue', label='View Site')
    else:
        plt.scatter(data[:,0], data[:,1], s=35, c='red', label='Neural Position')
        plt.plot(data[:,0], data[:,1], 'y--', linewidth=1)

    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.axis([-0.05, 1.05, -0.05, 1.05])

    if len(title) > 0: plt.title(title)

    plt.grid(True)
    plt.tight_layout()
    plt.legend(loc='upper right')

#------------------------------------------------------------
SAMPLE_NUM          = x_data.shape[0]
NEURAL_NUM          = SAMPLE_NUM

W = random.rand(NEURAL_NUM, x_data.shape[1])

#------------------------------------------------------------
def WTA2(x, w):
    """ Win-Take-All

    In: x-sample(x1,x2)
           w-net argument
    Ret: id-Win ID of w
    """
    dist = array([(x-ww).dot(x-ww) for ww in w])

    return list(where(dist==amin(dist)))[0][0]

#------------------------------------------------------------
def neighborid10(id, row, r):
    if r <= 0: return [id]

    iddim = []
    for i in range(-r,r+1):
        iidd = id + i
        if iidd < 0:    iidd += row
        if iidd >= row: iidd -= row

        if  iidd not in range(0, row): continue

        iddim.append(iidd)

    return iddim

def compete1(x, w, eta, r):
    for xx in x:
        id = WTA2(xx, w)

        iddim = neighborid10(id, w.shape[0], r)

        for iidd in iddim:
            w[iidd] = w[iidd] + eta * (xx - w[iidd])

    return w

#------------------------------------------------------------
TRAIN_NUM       = 200
ETA_BEGIN       = 0.3
ETA_END         = 0.01
RATIO_BEGIN     = 2
RATIO_END        = 0

plt.draw()
plt.pause(.2)

pltgif = PlotGIF()
for i in range(TRAIN_NUM):

    eta = (ETA_BEGIN - ETA_END) * (TRAIN_NUM - i) / (TRAIN_NUM - 1) + ETA_END
    ratio = int((RATIO_BEGIN - RATIO_END) * (TRAIN_NUM - i) / (TRAIN_NUM - 1) + RATIO_END)

    W = compete1(x_data, W, eta, ratio)

    plt.clf()
    show_data(x_data, 0)
    show_data(W, 1, "Step:%d/%d, R:%d, eta:%4.2f"%(i+1, TRAIN_NUM, ratio, eta))
    plt.draw()
    plt.pause(0.001)
    pltgif.append(plt)

pltgif.save(r'd:\temp\1.gif')
plt.show()

#------------------------------------------------------------
#        END OF FILE : HW26.PY
#============================================================
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页