2021年人工神经网络第三次作业-第一题-参考答案

举报
tsinghuazhuoqing 发表于 2021/12/25 23:56:49 2021/12/25
【摘要】 简 介: 第一题是对离散Hopfield网络的构造与回复进行测试。利用外积方法可以很容易计算出DHNN的系数。对于存储的八个字符,在没有噪声的情况下,它们都是DHNN的吸引子。在分别增加10%,...

简 介: 第一题是对离散Hopfield网络的构造与回复进行测试。利用外积方法可以很容易计算出DHNN的系数。对于存储的八个字符,在没有噪声的情况下,它们都是DHNN的吸引子。在分别增加10%,20%的噪声下,可以通过迭代将它们恢复。随着增加的噪声增加,恢复的可能性越来越小。在10%,20%的噪声情况下,可以看到,2, 9 都会存在伪吸引子。

关键词 DHNN伪吸引子

第一题
文章目录
题目要求
题目求解
作业总结
全部代码

 

§01 一题:DHNN


一、题目要求

1、题目内容

  离散Hopfield网络,也被称为联想存储器,通过迭代方式可以增加网络恢复能力。请设计一个离散Hopfield网络,将右边八个字符点阵进行存储。并测试在不同噪声下恢复的情况。

▲ 图1.1.1 八个点阵字符

▲ 图1.1.1 八个点阵字符

  在 截取图片中的点阵模式 - 012345.9 通过Python程序将图片转换成对应0101编码字符了。

  下面是字符“0,1,2,3,4,6,.,9”字符对应的10×12的01编码:

000000000000011110000011111100011100111001110011100111001110011100111001110011100111001110001111110000011110000000000000
000111100000011110000001111000000111100000011110000001111000000111100000011110000001111000000111100000011110000001111000
111111110011111111000000001100000000110000000011001111111100111111110011000000001100000000110000000011111111001111111100
001111110000111111100000000110000000011000000001100000111100000011110000000001100000000110000000011000111111100011111100
011000011001100001100110000110011000011001100001100111111110011111111000000001100000000110000000011000000001100000000110
111111000011111100001100000000110000000011000000001111110000111111000011001100001100110000110011000011111100001111110000
111110000011111000001111100000111110000011111000001111100000000000000000000000000000000000000000000000000000000000000000
000011111100001111110000110011000011001100001100110000111111000011111100000000110000000011000000001100001111110000111111

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2、题目要求

  1. 通过外积方法建立DHNN网络权系数,并验证上述存储的字符都是DHNN的吸引子。

  2. 测试在原来图片中增加10%,20% 的噪声的情况下,也就是随机选择其中一定比例像素值将其从原来的0修改为1,从1修改0,测试信息恢复情况;

  3. 对于2,6,两个字符,测试在多大噪声情况下,这两个字符就不可以完全恢复了。

  4. 观察在无法恢复的情况下出现的“伪吸引子”的情况。

二、题目求解

1、读取数据显示

(1)显示代码

from headm import *

textid = 3
filename = tspgetdopfile(textid)
printf(filename)

chardim = []
with open(filename, 'r') as f:
    lines = f.readlines()
    for l in lines:
        str01 = [int(c) for c in l if c == '0' or c == '1']
        chardim.append(str01)

def showchar01(c, offsetx=0, offsety=0):
    cc = list(zip(*([iter(c)]*10)))

    x = []
    y = []

    X = []
    Y = []

    for id,a in enumerate(cc):
        YY = offsety+12 - id
        for iidd, b in enumerate(a):
            XX = offsetx+iidd
            if b == 0:
                x.append(XX)
                y.append(YY)
            else:
                X.append(XX)
                Y.append(YY)

    plt.scatter(x, y, s = 1)
    plt.scatter(X, Y, s = 40)

for id, c in enumerate(chardim):
    offsety = 15
    offsetx = id*12
    if id >= 4:
        offsety = 0
        offsetx = (id-4)*12

    showchar01(c, offsetx, offsety)

plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

(2)字符显示

▲ 图1.2.1 显示八个字符

▲ 图1.2.1 显示八个字符

2、计算离散Hopfield网络

  利用外积方法计算离散Hopfield链接权系数矩阵,并将对角线置零。

  在计算外积之前,将原来的 0,1表示的向量转换成 -1,1表示的向量。

x i j ′ = 2 x i j − 1 ,    i = 0 , 1 , ⋯ 11 , j = 0 , 1 , ⋯   , 9 x'_{ij} = 2x_{ij} - 1,\,\,i = 0,1, \cdots 11,j = 0,1, \cdots ,9 xij=2xij1,i=0,1,11,j=0,1,,9

(1)计算代码

cca = array(chardim)*2-1
cclen = len(chardim[0])

for id,c in enumerate(cca):
    if id == 0:
        w = outer(c,c)
    else:
        w += outer(c,c)

for i in range(cclen):
    w[(i, i)] = 0

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

(2)显示权系数矩阵

  计算出的矩阵系数,存储在 w中。

[[ 0  6  4 ... -2 -2  0]
 [ 6  0  6 ...  0  0 -2]
 [ 4  6  0 ...  2 -2 -4]
 ...
 [-2  0  2 ...  0  4  2]
 [-2  0 -2 ...  4  0  6]
 [ 0 -2 -4 ...  2  6  0]]

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  利用plt.show()显示矩阵。
▲ 图1.2.2 显示离散Hopfield矩阵

▲ 图1.2.2 显示离散Hopfield矩阵

3、测试八个字符恢复

(1)测试代码

#------------------------------------------------------------
plt.clf()

def dhnn(w, x):
    xx = dot(w, x)
    xx01 = [(lambda x: 1 if x > 0 else -1)(a) for a in xx]
    return xx01

#------------------------------------------------------------

for id, c in enumerate(chardim):
    offsety = 15
    offsetx = id*12
    if id >= 4:
        offsety = 0
        offsetx = (id-4)*12

    x = dhnn(w, array(c)*2-1)
    showchar01(x, offsetx, offsety)

plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

(2)测试八个字符恢复结果

  将八个字符分别乘以w,利用符号函数判定之后,便可以获得网络的输出。可以看到这八个字符都是DHNN的吸引子。

▲ 图1.2.3 八个字符经过一次迭代便可以恢复,证明它们都是DHNN的吸引子

▲ 图1.2.3 八个字符经过一次迭代便可以恢复,证明它们都是DHNN的吸引子

4、增加10%噪声

(1)增加噪声

def addnoise(c, noise_ratio = 0.1):
    noisenum = int(len(c) * noise_ratio)
    noisepos = [1]*len(c)
    noisepos[:noisenum] = [-1]*noisenum
    random.shuffle(noisepos)

    cc = array([x*y for x,y in zip(c, noisepos)])
    return cc

plotgif = PlotGIF()

for i in range(50):
    plt.clf()

    for id, c in enumerate(cca):
        offsety = 15
        offsetx = id*12
        if id >= 4:
            offsety = 0
            offsetx = (id-4)*12

        cn = addnoise(c, 0.1)
#        x = dhnn(w, cn)
        showchar01(cn, offsetx, offsety)

    plt.draw()
    plt.pause(.1)
    plotgif.append(plt)

plotgif.save()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

▲ 图1.2.4  增加10%的噪声,50个样本情况

▲ 图1.2.4 增加10%的噪声,50个样本情况

(2)经过一次迭代恢复情况

  下面是将增加有10%的样本进行一次DHNN迭代回复的情况。
▲ 图1.2.5  经过一次迭代后恢复的情况

▲ 图1.2.5 经过一次迭代后恢复的情况

(3)经过两次迭代恢复情况

▲ 图1.2.6  经过两次迭代恢复情况

▲ 图1.2.6 经过两次迭代恢复情况

(4)经过10次迭代恢复情况

def addnoise(c, noise_ratio = 0.1):
    noisenum = int(len(c) * noise_ratio)
    noisepos = [1]*len(c)
    noisepos[:noisenum] = [-1]*noisenum
    random.shuffle(noisepos)

    cc = array([x*y for x,y in zip(c, noisepos)])
    return cc

plotgif = PlotGIF()

for i in range(50):
    plt.clf()

    for id, c in enumerate(cca):
        offsety = 15
        offsetx = id*12
        if id >= 4:
            offsety = 0
            offsetx = (id-4)*12

        cn = addnoise(c, 0.1)
        x = cn
        for _ in range(10):
            x = dhnn(w, x)

        showchar01(x, offsetx, offsety)

    plt.draw()
    plt.pause(.1)
    plotgif.append(plt)

plotgif.save()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

▲ 图1.2.7  经过10次迭代恢复情况

▲ 图1.2.7 经过10次迭代恢复情况

5、串行与并行工作

  下面代码分别给出了并行与穿行工作模式。

  • 并行工作模式: dhnn(w,x)
  • 串行工作模式: dhnns(w,x)
def dhnn(w, x):
    xx = dot(w, x)
    xx01 = [(lambda x: 1 if x > 0 else -1)(a) for a in xx]
    return xx01

def dhnns(w, x):
    for i in range(len(x)):
        xx = inner(w[i], x)
        if xx > 0: xx = 1
        else: xx = -1
        x[i] = xx

    return x

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

  串行工作模式,迭代10次恢复情况:
▲ 图1.2.8  串行工作模式,迭代10次恢复情况

▲ 图1.2.8 串行工作模式,迭代10次恢复情况

  串行工作模式,迭代100次恢复情况:
▲ 图1.2.9  串行工作模式,迭代100次恢复情况

▲ 图1.2.9 串行工作模式,迭代100次恢复情况

6、增加20%噪声

  增加20%的噪声利用串行工作模式,迭代100次恢复情况。
▲ 图1.2.10  增加20%的噪声样本情况

▲ 图1.2.10 增加20%的噪声样本情况

▲ 图1.2.10  增加20%的噪声利用串行工作模式,迭代100次恢复情况

▲ 图1.2.10 增加20%的噪声利用串行工作模式,迭代100次恢复情况

7、增加更多的噪声

(1)增加25%噪声

▲ 图A1.2.12  增加25%噪声样本

▲ 图A1.2.12 增加25%噪声样本

▲ 图A1.2.13  增加25%噪声样本,串行工作,迭代100次恢复情况

▲ 图A1.2.13 增加25%噪声样本,串行工作,迭代100次恢复情况

(2)增加30%噪声

▲ 图1.2.14  增加30%噪声样本

▲ 图1.2.14 增加30%噪声样本

▲ 图1.2.15  增加30%噪声样本,串行工作,迭代100次恢复情况

▲ 图1.2.15 增加30%噪声样本,串行工作,迭代100次恢复情况

(3)增加50%噪声

▲ 图1.2.12  增加50%的噪声

▲ 图1.2.12 增加50%的噪声

▲ 图1.2.13  增加50%的噪声,串行工作,迭代100次恢复情况
▲ 图1.2.13 增加50%的噪声,串行工作,迭代100次恢复情况

  通过上面讨论,可以看到:

  • 随着增加的噪声比率越大,回复错误率越高;
  • 使用同步工作,异步工作对应的回复效果很相似。

 

业总结 ※


  一题是对离散Hopfield网络的构造与回复进行测试。

  利用外积方法可以很容易计算出DHNN的系数。对于存储的八个字符,在没有噪声的情况下,它们都是DHNN的吸引子。

  在分别增加10%,20%的噪声下,可以通过迭代将它们恢复。随着增加的噪声增加,恢复的可能性越来越小。

  在10%,20%的噪声情况下,可以看到,2, 9 都会存在伪吸引子。

● 全部代码

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# HMW3-1.PY                    -- by Dr. ZhuoQing 2021-11-24
#
# Note:
#============================================================

from headm import *
import random

textid = 3
filename = tspgetdopfile(textid)
#printf(filename)

#------------------------------------------------------------
chardim = []
with open(filename, 'r') as f:
   lines = f.readlines()
   for l in lines:
       str01 = [int(c) for c in l if c == '0' or c == '1']
       chardim.append(str01)

#------------------------------------------------------------
#printf(chardim)

def showchar01(c, offsetx=0, offsety=0):
   cc = list(zip(*([iter(c)]*10)))
#    [printf(i) for i in cc]

   x = []
   y = []

   X = []
   Y = []

   for id,a in enumerate(cc):
       YY = offsety+12 - id
       for iidd, b in enumerate(a):
           XX = offsetx+iidd
           if b <= 0:
               x.append(XX)
               y.append(YY)
           else:
               X.append(XX)
               Y.append(YY)


   plt.scatter(x, y, s = 1)
   plt.scatter(X, Y, s = 40)


#------------------------------------------------------------
'''

for id, c in enumerate(chardim):
   offsety = 15
   offsetx = id*12
   if id >= 4:
       offsety = 0
       offsetx = (id-4)*12

   showchar01(c, offsetx, offsety)


plt.show()
'''
#------------------------------------------------------------
cca = array(chardim)*2-1
cclen = len(chardim[0])

for id,c in enumerate(cca):
   if id == 0:
       w = outer(c,c)
   else:
       w += outer(c,c)

for i in range(cclen):
   w[(i, i)] = 0

#------------------------------------------------------------
'''
plt.imshow(w)
plt.show()

'''
#------------------------------------------------------------
plt.clf()
#printf(w)

def dhnn(w, x):
   xx = dot(w, x)
   xx01 = [(lambda x: 1 if x > 0 else -1)(a) for a in xx]
   return xx01

def dhnns(w, x):
   for i in range(len(x)):
       xx = inner(w[i], x)
       if xx > 0: xx = 1
       else: xx = -1
       x[i] = xx

   return x

#------------------------------------------------------------
'''
for id, c in enumerate(chardim):
   offsety = 15
   offsetx = id*12
   if id >= 4:
       offsety = 0
       offsetx = (id-4)*12


   x = dhnn(w, array(c)*2-1)
   showchar01(x, offsetx, offsety)

plt.show()
'''
#------------------------------------------------------------
def addnoise(c, noise_ratio = 0.1):
   noisenum = int(len(c) * noise_ratio)
   noisepos = [1]*len(c)
   noisepos[:noisenum] = [-1]*noisenum
   random.shuffle(noisepos)

   cc = array([x*y for x,y in zip(c, noisepos)])
   return cc

plotgif = PlotGIF()

for i in range(40):
   plt.clf()

   for id, c in enumerate(cca):
       offsety = 15
       offsetx = id*12
       if id >= 4:
           offsety = 0
           offsetx = (id-4)*12

       cn = addnoise(c, 0.3)
       x = cn.copy()
       for _ in range(100):
           x = dhnns(w, x)

       showchar01(x, offsetx, offsety)

   plt.draw()
   plt.pause(.1)
   plotgif.append(plt)

plotgif.save()








#------------------------------------------------------------
#        END OF FILE : HMW3-1.PY
#============================================================

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164


■ 相关文献链接:

● 相关图表链接:

文章来源: zhuoqing.blog.csdn.net,作者:卓晴,版权归原作者所有,如需转载,请联系作者。

原文链接:zhuoqing.blog.csdn.net/article/details/121528286

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。