Hebb规则实现缺损数字识别

464 阅读3分钟

神经网络设计第二版7.2.4应用

这里只是根据《神经网络设计》这本书实现数字0,1,2的下半部分50%,70%缺损数字识别,输出的图像可以在同级目录ouput_image下看到(学习参考) 参考这篇文章 # 神经网络第二版--学习笔记

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import os
import random
import copy

plt.rcParams["font.sans-serif"] = ["SimHei"]  # 设置字体


# 用于画图展示
def drawPicture(figureList, title):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    t = 0
    for i in range(5):
        for j in range(6):
            if(figureList[t] == -1):
                rect = matplotlib.patches.Rectangle((i*10, 50-j*10), 10, 10, color='yellow')
            else:
                rect = matplotlib.patches.Rectangle((i*10, 50-j*10), 10, 10, color='red')
            t = t + 1
            ax.add_patch(rect)
    plt.xlim([0, 50])
    plt.ylim([0, 60])
    plt.title(label=str(title))
    plt.show()
    # 保存图片
    fig.savefig('ouput_image/'+title+'.png')


def hardlims(input):
    for i in range(input.size):
        if(input[i]>=0):
            input[i] = 1
        else:
            input[i] = -1
    return input


if os.path.exists('ouput_image') is False:
    os.mkdir('ouput_image')

# 数字0
Template0 = [-1, 1, 1, 1, 1, -1,
             1, -1, -1, -1, -1, 1,
             1, -1, -1, -1, -1, 1,
             1, -1, -1, -1, -1, 1,
             -1, 1, 1, 1, 1, -1]
# 数字1
Template1 = [-1, -1, -1, -1, -1, -1,
             1, -1, -1, -1, -1, -1,
             1, 1, 1, 1, 1, 1,
             -1, -1, -1, -1, -1, -1,
             -1, -1, -1, -1, -1, -1]
# 数字2
Template2 = [1, -1, -1, -1, -1, -1,
             1, -1, -1, 1, 1, 1,
             1, -1, -1, 1, -1, 1,
             -1, 1, 1, -1, -1, 1,
             -1, -1, -1, -1, -1, 1]
# 从列表转换成数组
figureZero = np.array(Template0)
figureOne = np.array(Template1)
figureTwo = np.array(Template2)
# 转换成列向量
RowVetorZero = figureZero.reshape(figureZero.size, 1)
RowVetorOne = figureOne.reshape(figureOne.size, 1)
RowVetorTwo = figureTwo.reshape(figureTwo.size, 1)
# 进行矩阵乘法以获得权重矩阵
WeightMartix = np.matmul(RowVetorZero, RowVetorZero.T)+np.matmul(RowVetorOne, RowVetorOne.T)+np.matmul(RowVetorTwo, RowVetorTwo.T)
arases = [RowVetorZero, RowVetorOne, RowVetorTwo]
# 做标准数字识别
for index, arase in enumerate(copy.deepcopy(arases)):
    drawPicture(arase, '标准数字'+str(index)+'识别原始图像')
    # 将标准数字输入网络中
    output = np.matmul(WeightMartix, arase)
    # 将所有元素输入到对称硬限值传输函数中
    output = hardlims(output)
    # 画图
    drawPicture(output, '标准数字'+str(index)+'识别结果')
# 将下半部分抹去,做缺损数字识别
for index, arase in enumerate(copy.deepcopy(arases)):
    for i in range(30):
        t = int((i - int(i/6)*6)/3)
        if t > 0:
            arase[i] = -1
    # 画出抹去后的图片
    drawPicture(arase, '50.0%缺损数字'+str(index)+'识别原始图像')
    # 将抹去下半部分的模式输入网络中
    output = np.matmul(WeightMartix, arase)
    # 将所有元素输入到对称硬限值传输函数中
    output = hardlims(output)
    # 画出恢复图
    drawPicture(output, '50.0%缺损数字'+str(index)+'识别恢复图像')
# 将下半部分67.7%抹去,做缺损数字识别
for index, arase in enumerate(copy.deepcopy(arases)):
    for i in range(30):
        t = int((i - int(i/6)*6)/2)
        if t > 0:
            arase[i] = -1
    # 画出抹去后的图片
    drawPicture(arase, '67.7%缺损数字'+str(index)+'识别原始图像')
    # 将抹去下半部分的模式输入网络中
    output = np.matmul(WeightMartix, arase)
    # 将所有元素输入到对称硬限值传输函数中
    output = hardlims(output)
    # 画出恢复图
    drawPicture(output, '67.7%缺损数字'+str(index)+'识别恢复图像')
for index, arase in enumerate(copy.deepcopy(arases)):
    # 加7个噪声
    nums = random.sample(range(0, 30), 7)
    for i, temp in enumerate(nums):
        if i > 3:
            arase[temp] = -1
        else:
            arase[temp] = 1
    # 画出抹去后的图片
    drawPicture(arase, 'noise缺损数字'+str(index)+'识别原始图像')
    # 将抹去下半部分的模式输入网络中
    output = np.matmul(WeightMartix, arase)
    # 将所有元素输入到对称硬限值传输函数中
    output = hardlims(output)
    # 画出恢复图
    drawPicture(output, 'noise缺损数字'+str(index)+'识别恢复图像')