当前位置:   article > 正文

机器学习 BP神经网络(Python实现)_python机器学习实现字母y和n的识别。请给出权重调整的过程,得出网络权重,并画出神经网络结构。

python机器学习实现字母y和n的识别。请给出权重调整的过程,得出网络权重,并画出神经网络结构。

一个神经元即一个感知机模型,由多个神经元相互连接形成的网络,即神经网络

这里我们只讨论单隐层前馈神经网络,其连接形式入下:

神经网络模型的待估参数即,每个神经元的阈值,以及神经元之间的连接权重。

对于该模型有如下定义:

训练集:D={(x1, y1), (x2, y2), ......, (xm, ym)},x具有d个属性值,y具有k个可能取值

则我们的神经网络(单隐层前馈神经网络)应该是具有d个输入神经元,q个隐层神经元,k个输出层神经元的神经网络 ,我们默认输入层只是数据的输入,不对数据做处理,即输入层没有阈值。

阈值函数使用对数几率函数:

有如下定义:

输出层第j个神经元的阈值为:θj

隐层第h个神经元的阈值为:γh(γ是Gamma)

输入层第i个神经元与隐层第h个神经元的连接权重为:vih

隐层第h个神经元与输出层第j个神经元的连接权重为:ωhj

由上述定义我们可以得到:

隐层第h个神经元接收到输入:

 隐层第h个神经元的输出:

输出层第j个神经元接收到的输入:

现在我们定义好了所有的参数,接下来我们要求这些模型。

对参数进行估计,需要有优化方向,我们继续使用欧式距离,或者均方误差来作为优化目标:

我们使用梯度下降的策略对参数进行迭代优化,所以任意一个参数的变化大小为(θ代表任意参数):

 下面根据这个更新公式,我们来求各个参数的更新公式:

对数几率函数的导数如下:

输出层第j个神经元的阈值θj:

 

 隐层第h个神经元的阈值γh:

 

输入层第i个神经元与隐层第h个神经元的连接权重vih :

 

隐层第h个神经元与输出层第j个神经元的连接权重ωhj:

 

现在四个参数的更新规则都计算出来了,我们可以开始编码实现了。

现在有一个问题:在二分类任务中,输出层神经元有几个?

                             一个:如果只有1个,那么输出0表示反例,1表示正例

                             二个:那么输出(1,0)表示反例,(0,1)表示正例

一下实例我们使用第一种:

 

我们使用一个二分类数据集:马疝病数据集

UCI下载地址为:http://archive.ics.uci.edu/ml/datasets/Horse+Colic

代码和数据集,我已经上传到我的资源:https://download.csdn.net/download/qq_41398808/11231315

 

数据读取:

  1. def loaddataset(filename):
  2. fp = open(filename)
  3. #存放数据
  4. dataset = []
  5. #存放标签
  6. labelset = []
  7. for i in fp.readlines():
  8. a = i.strip().split()
  9. #每个数据行的最后一个是标签
  10. dataset.append([float(j) for j in a[:len(a)-1]])
  11. labelset.append(int(float(a[-1])))
  12. return dataset, labelset

 

初始化各个参数:

  1. #x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
  2. def parameter_initialization(x, y, z):
  3. #隐层阈值
  4. value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)
  5. #输出层阈值
  6. value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)
  7. #输入层与隐层的连接权重
  8. weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)
  9. #隐层与输出层的连接权重
  10. weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)
  11. return weight1, weight2, value1, value2

初始化的各参数数值不能一样,否则无法进行学习。 

 

对数几率函数(sigmoid函数):

  1. def sigmoid(z):
  2. return 1 / (1 + np.exp(-z))

 

 训练过程(参数调整过程):

  1. '''
  2. weight1:输入层与隐层的连接权重
  3. weight2:隐层与输出层的连接权重
  4. value1:隐层阈值
  5. value2:输出层阈值
  6. '''
  7. def trainning(dataset, labelset, weight1, weight2, value1, value2):
  8. #x为步长
  9. x = 0.01
  10. for i in range(len(dataset)):
  11. #输入数据
  12. inputset = np.mat(dataset[i]).astype(np.float64)
  13. #数据标签
  14. outputset = np.mat(labelset[i]).astype(np.float64)
  15. #隐层输入
  16. input1 = np.dot(inputset, weight1).astype(np.float64)
  17. #隐层输出
  18. output2 = sigmoid(input1 - value1).astype(np.float64)
  19. #输出层输入
  20. input2 = np.dot(output2, weight2).astype(np.float64)
  21. #输出层输出
  22. output3 = sigmoid(input2 - value2).astype(np.float64)
  23. #更新公式由矩阵运算表示
  24. a = np.multiply(output3, 1 - output3)
  25. g = np.multiply(a, outputset - output3)
  26. b = np.dot(g, np.transpose(weight2))
  27. c = np.multiply(output2, 1 - output2)
  28. e = np.multiply(b, c)
  29. value1_change = -x * e
  30. value2_change = -x * g
  31. weight1_change = x * np.dot(np.transpose(inputset), e)
  32. weight2_change = x * np.dot(np.transpose(output2), g)
  33. #更新参数
  34. value1 += value1_change
  35. value2 += value2_change
  36. weight1 += weight1_change
  37. weight2 += weight2_change
  38. return weight1, weight2, value1, value2

 

测试:

  1. def testing(dataset, labelset, weight1, weight2, value1, value2):
  2. #记录预测正确的个数
  3. rightcount = 0
  4. for i in range(len(dataset)):
  5. #计算每一个样例通过该神经网路后的预测值
  6. inputset = np.mat(dataset[i]).astype(np.float64)
  7. outputset = np.mat(labelset[i]).astype(np.float64)
  8. output2 = sigmoid(np.dot(inputset, weight1) - value1)
  9. output3 = sigmoid(np.dot(output2, weight2) - value2)
  10. #确定其预测标签
  11. if output3 > 0.5:
  12. flag = 1
  13. else:
  14. flag = 0
  15. if labelset[i] == flag:
  16. rightcount += 1
  17. #输出预测结果
  18. print("预测为%d 实际为%d"%(flag, labelset[i]))
  19. #返回正确率
  20. return rightcount / len(dataset)

主函数:

  1. if __name__ == '__main__':
  2. dataset, labelset = loaddataset('基于神经网络的马疝病死亡预测/horseColicTraining.txt')
  3. weight1, weight2, value1, value2 = parameter_initialization(len(dataset[0]), len(dataset[0]), 1)
  4. for i in range(1500):
  5. weight1, weight2, value1, value2 = trainning(dataset, labelset, weight1, weight2, value1, value2)
  6. rate = testing(dataset, labelset, weight1, weight2, value1, value2)
  7. print("正确率为%f"%(rate))

 

结果:

  1. 正确率为0.769231
  2. [Finished in 68.2s]

上述实例只是一个测试我们模型是否推导正确的实例,在数据集上的学习效果并不好,有许多的细节没有考虑。

 

完整代码如下:

  1. import numpy as np
  2. def loaddataset(filename):
  3. fp = open(filename)
  4. #存放数据
  5. dataset = []
  6. #存放标签
  7. labelset = []
  8. for i in fp.readlines():
  9. a = i.strip().split()
  10. #每个数据行的最后一个是标签
  11. dataset.append([float(j) for j in a[:len(a)-1]])
  12. labelset.append(int(float(a[-1])))
  13. return dataset, labelset
  14. #x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
  15. def parameter_initialization(x, y, z):
  16. #隐层阈值
  17. value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)
  18. #输出层阈值
  19. value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)
  20. #输入层与隐层的连接权重
  21. weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)
  22. #隐层与输出层的连接权重
  23. weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)
  24. return weight1, weight2, value1, value2
  25. def sigmoid(z):
  26. return 1 / (1 + np.exp(-z))
  27. '''
  28. weight1:输入层与隐层的连接权重
  29. weight2:隐层与输出层的连接权重
  30. value1:隐层阈值
  31. value2:输出层阈值
  32. '''
  33. def trainning(dataset, labelset, weight1, weight2, value1, value2):
  34. #x为步长
  35. x = 0.01
  36. for i in range(len(dataset)):
  37. #输入数据
  38. inputset = np.mat(dataset[i]).astype(np.float64)
  39. #数据标签
  40. outputset = np.mat(labelset[i]).astype(np.float64)
  41. #隐层输入
  42. input1 = np.dot(inputset, weight1).astype(np.float64)
  43. #隐层输出
  44. output2 = sigmoid(input1 - value1).astype(np.float64)
  45. #输出层输入
  46. input2 = np.dot(output2, weight2).astype(np.float64)
  47. #输出层输出
  48. output3 = sigmoid(input2 - value2).astype(np.float64)
  49. #更新公式由矩阵运算表示
  50. a = np.multiply(output3, 1 - output3)
  51. g = np.multiply(a, outputset - output3)
  52. b = np.dot(g, np.transpose(weight2))
  53. c = np.multiply(output2, 1 - output2)
  54. e = np.multiply(b, c)
  55. value1_change = -x * e
  56. value2_change = -x * g
  57. weight1_change = x * np.dot(np.transpose(inputset), e)
  58. weight2_change = x * np.dot(np.transpose(output2), g)
  59. #更新参数
  60. value1 += value1_change
  61. value2 += value2_change
  62. weight1 += weight1_change
  63. weight2 += weight2_change
  64. return weight1, weight2, value1, value2
  65. def testing(dataset, labelset, weight1, weight2, value1, value2):
  66. #记录预测正确的个数
  67. rightcount = 0
  68. for i in range(len(dataset)):
  69. #计算每一个样例通过该神经网路后的预测值
  70. inputset = np.mat(dataset[i]).astype(np.float64)
  71. outputset = np.mat(labelset[i]).astype(np.float64)
  72. output2 = sigmoid(np.dot(inputset, weight1) - value1)
  73. output3 = sigmoid(np.dot(output2, weight2) - value2)
  74. #确定其预测标签
  75. if output3 > 0.5:
  76. flag = 1
  77. else:
  78. flag = 0
  79. if labelset[i] == flag:
  80. rightcount += 1
  81. #输出预测结果
  82. print("预测为%d 实际为%d"%(flag, labelset[i]))
  83. #返回正确率
  84. return rightcount / len(dataset)
  85. if __name__ == '__main__':
  86. dataset, labelset = loaddataset('基于神经网络的马疝病死亡预测/horseColicTraining.txt')
  87. weight1, weight2, value1, value2 = parameter_initialization(len(dataset[0]), len(dataset[0]), 1)
  88. for i in range(1500):
  89. weight1, weight2, value1, value2 = trainning(dataset, labelset, weight1, weight2, value1, value2)
  90. rate = testing(dataset, labelset, weight1, weight2, value1, value2)
  91. print("正确率为%f"%(rate))

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/94768
推荐阅读
相关标签
  

闽ICP备14008679号