手写数字识别

分手后的思念是犯贱 2021-12-21 13:23 541阅读 0赞

1. 创建、训练和查询3层神经网络:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import scipy.special as spp
  4. class Ann2020:
  5. # 初始化神经网络
  6. def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
  7. # 设置每个输入层、隐藏层和输出层的节点数
  8. self.inodes = inputnodes
  9. self.hnodes = hiddennodes
  10. self.onodes = outputnodes
  11. # 链接权重矩阵,wih和who
  12. # 数组中的权值为w_i_j,其中链接是从下一层的节点i到节点j
  13. # w11 w21
  14. # w12 w22 etc
  15. self.wih = np.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))
  16. self.who = np.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))
  17. # 学习率
  18. self.lr = learningrate
  19. # 激活函数
  20. self.activation_function = lambda x: spp.expit(x)
  21. pass
  22. # 训练神经网络
  23. def train(self, inputs_list, targets_list):
  24. # convert inputs list to 2d array
  25. inputs = np.array(inputs_list, ndmin=2).T
  26. targets = np.array(targets_list, ndmin=2).T
  27. # 计算信号到隐藏层
  28. hidden_inputs = np.dot(self.wih, inputs)
  29. # 计算从隐层发出的信号
  30. hidden_outputs = self.activation_function(hidden_inputs)
  31. # 将信号计算到最终的输出层
  32. final_inputs = np.dot(self.who, hidden_outputs)
  33. # 计算最终输出层发出的信号
  34. final_outputs = self.activation_function(final_inputs)
  35. # 输出层误差为(目标-实际)
  36. output_errors = targets - final_outputs
  37. # 隐藏层错误是output_errors,按权重拆分,在隐藏节点上重新组合
  38. hidden_errors = np.dot(self.who.T, output_errors)
  39. # 更新隐藏层和输出层之间链接的权重
  40. self.who += self.lr * np.dot((output_errors * final_outputs * (1.0 - final_outputs)),
  41. np.transpose(hidden_outputs))
  42. # 更新输入层和隐藏层之间链接的权重
  43. self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),
  44. np.transpose(inputs))
  45. pass
  46. # 查询神经网络
  47. def query(self, inputs_list):
  48. # 将输入列表转换为2d数组
  49. inputs = np.array(inputs_list, ndmin=2).T
  50. # 计算信号到隐藏层
  51. hidden_inputs = np.dot(self.wih, inputs)
  52. # 计算从隐层发出的信号
  53. hidden_outputs = self.activation_function(hidden_inputs)
  54. # 将信号计算到最终的输出层
  55. final_inputs = np.dot(self.who, hidden_outputs)
  56. # 计算最终输出层发出的信号
  57. final_outputs = self.activation_function(final_inputs)
  58. return final_outputs
  59. # 输入、隐藏和输出节点的数量
  60. input_nodes = 784
  61. hidden_nodes = 200 #最佳可调整至500
  62. output_nodes = 10
  63. # 学习率为 0.3
  64. learning_rate = 0.1
  65. # 创建神经网络实例
  66. n = Ann2020(input_nodes, hidden_nodes, output_nodes, learning_rate)
  67. # 测试查询(目前还没有任何有用的含义)
  68. f = np.load('mnist.npz')
  69. x_train, y_train = f['x_train'], f['y_train']
  70. x_test, y_test = f['x_test'], f['y_test']
  71. f.close()
  72. epochs = 5
  73. for e in range(epochs):
  74. # 遍历所有数据
  75. for record,y_trainn in zip(x_train,y_train):
  76. # 缩放输入值
  77. inputs = (np.asfarray(record[:]).ravel() / 255.0 * 0.99) + 0.01
  78. # 创建目标输出值(除所需的标签为0.99外,其余均为0.01)
  79. targets = np.zeros(output_nodes) + 0.01
  80. # 记录标签
  81. targets[int(y_trainn)] = 0.99
  82. n.train(inputs, targets)
  83. pass
  84. pass
  85. scorecard = []
  86. for record,y_testn in zip(x_test,y_test):
  87. # 导入标签
  88. correct_label = int(y_testn)
  89. # 预处理输入
  90. inputs = (np.asfarray(record[:]).ravel() / 255.0 * 0.99) + 0.01
  91. # 查询神经网络
  92. outputs = n.query(inputs)
  93. # 将最大值的索引对应到标签
  94. label = np.argmax(outputs)
  95. # 将识别分数添加进列表
  96. if (label == correct_label):
  97. # 匹配 计1
  98. scorecard.append(1)
  99. else:
  100. # 不匹配 计0
  101. scorecard.append(0)
  102. pass
  103. pass
  104. scorecard_array = np.asarray(scorecard)
  105. print ("准确率 = ", scorecard_array.sum() / scorecard_array.size)
准确率高达98%

2. 自制自己的手写数字图像进行测试:

我所使用的手机拍摄图片:
在这里插入图片描述

自制图像的去噪与黑白转换代码:

  1. # -*- coding: utf-8 -*-
  2. # 图像去噪并转化为黑白图像
  3. import os
  4. from PIL import Image
  5. curdir = "F:\\pyth\\shendu\\CNN2019\\image"
  6. os.chdir(curdir)
  7. def RGB2B(filename):
  8. im = Image.open(filename)
  9. print("image info,", im.format, im.mode, im.size)
  10. (w, h) = im.size
  11. R = 0
  12. G = 0
  13. B = 0
  14. for x in range(w):
  15. for y in range(h):
  16. pos = (x, y)
  17. rgb = im.getpixel(pos)
  18. (r, g, b) = rgb
  19. R = R + r
  20. G = G + g
  21. B = B + b
  22. rate1 = R * 1000 / (R + G + B)
  23. rate2 = G * 1000 / (R + G + B)
  24. rate3 = B * 1000 / (R + G + B)
  25. print("rate:", rate1, rate2, rate3)
  26. for x in range(w):
  27. for y in range(h):
  28. pos = (x, y)
  29. rgb = im.getpixel(pos)
  30. (r, g, b) = rgb
  31. n = r * rate1 / 1000 + g * rate2 / 1000 + b * rate3 / 1000
  32. # print "n:",n
  33. if n >= 155:
  34. im.putpixel(pos, (255, 255, 255))
  35. else:
  36. im.putpixel(pos, (0, 0, 0))
  37. im.save('my_image3_whiteb.png')
  38. def saveAsBmp(fname):
  39. pos1 = fname.rfind('.')
  40. fname1 = fname[0:pos1]
  41. fname1 = fname1 + '_hui.png'
  42. im = Image.open(fname)
  43. new_im = Image.new("RGB", im.size)
  44. new_im.paste(im)
  45. new_im.save(fname1)
  46. return fname1
  47. if __name__ == "__main__":
  48. filename = saveAsBmp("my_image3.png")
  49. RGB2B(filename)

将测试部分转换为自己的图像测试:

  1. our_own_dataset = []
  2. # 获得测试图像信息
  3. for image_file_name in glob.glob('my_image?.png'):
  4. # 使用倒数第五个字符作为正确标签
  5. label = int(image_file_name[-5:-4])
  6. # 获得图像
  7. print("loading ... ", image_file_name)
  8. img_array = imageio.imread(image_file_name, as_gray=True)
  9. # 转化为一维数组 并反转
  10. img_data = 255.0 - img_array.reshape(784)
  11. # 把像素值转为到0.01到0.99之间
  12. img_data = (img_data / 255.0 * 0.99) + 0.01
  13. print(np.min(img_data))
  14. print(np.max(img_data))
  15. # 添加图像标签和信息到列表
  16. record = np.append(label, img_data)
  17. our_own_dataset.append(record)
  18. pass
  19. item = 3
  20. # 画出图像
  21. plt.imshow(our_own_dataset[item][1:].reshape(28,28), cmap='Greys', interpolation='None')
  22. #拿到正确标签
  23. correct_label = our_own_dataset[item][0]
  24. # data is remaining values
  25. inputs = our_own_dataset[item][1:]
  26. # 查询神经网络
  27. outputs = n.query(inputs)
  28. print (outputs)
  29. # 与输出最高的得分标签进行比较
  30. label = np.argmax(outputs)
  31. print("机器判断为:", label)
  32. # 输出判断正误
  33. if (label == correct_label):
  34. print ("识别正确!")
  35. else:
  36. print ("识别错误!")
  37. pass
  38. plt.show()

效果展示:

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,541人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数字识别

    前面的博客介绍过[神经网络结构][Link 1]以及相关的[损失函数][Link 2],在这里我们通过一个简单的神经网络实现一个机器学习问题:识别手写数字图像。 和求解机器