《Python神经网络编程》1.4节虫子分类器的实现
最近在看这本书,觉得里面虫子分类器也值得试试实现,因为这个方法已经包含了神经网络的核心思想。
以下是实现的过程。
按照《Python神经网络编程》(异步图书出版)第一章虫子分类器训练的过程,模仿书中第二章的3层神经网络的实现过程,来构建一个可运行的虫子分类器。
首先,构造出来分类器的框架,包含训练和查询.
In [ ]:
class BugClassifier:def __init__(self):passdef train(self, target_bug_size, target_bug):passdef query(self, input_bug_size):pass
虫子分类器,核心是一个线性函数,分类器的主要参数就是其斜率,同时也包括了训练过程中的学习率。 由于书中已经预设了虫子和线形分类器的关系,所以需要把这个关系对应的修正量也预设好。 例如瓢虫在线形函数下面,毛虫在上面。在查询时,也需要根据这个关系来做分类的结论。 另外因此可以得到一个推论:该分类器并不需要就虫子和线形函数的位置关系进行学习(这算是已知的知识)。
In [ ]:
class BugClassifier:def __init__(self, coefficient, learning_rate, corrections):self.coefficient = coefficient # 初始系数self.learning_rate = learning_rate # 学习率self.corrections = corrections # 预定义的根据虫类的计算值修正量def train(self, target_bug_size, target_bug):passdef query(self, input_bug_size):pass# 测试代码
bc = BugClassifier(0.25, 0.5, {'瓢虫':{'修正量':0.1, '关系':lambda c,t:c>t and True or False}, '毛虫':{'修正量':-0.1, '关系':lambda c,t:c
训练的过程,核心思路就是利用训练数据来计算,得到与目标之间的误差。 再利用误差来反向传播到对核心参数(分类器所使用的线形函数的斜率系数)的调整, 调整的步伐,则是依据初始化时设定的学习率。
In [6]:
class BugClassifier:def __init__(self, coefficient, learning_rate, corrections):self.coefficient = coefficient # 初始系数self.learning_rate = learning_rate # 学习率self.corrections = corrections # 预定义的根据虫类的计算值修正量def feedforward(self, width):''' 前馈函数,此处是利用输入的宽度乘以分类器内部系数计算出来输出的长度 '''return width * self.coefficientdef feedback(self, width, error):''' 反馈函数,此处是利用输入的宽度和输出的误差来反向调节分类器内部系数 '''self.coefficient += self.learning_rate * (error / width)def train(self, target_bug_size, target_bug):target_bug_width = target_bug_size[0]target_bug_length = target_bug_size[1]computed_bug_length = self.feedforward(target_bug_width)# 误差计算。误差计算时,需要根据虫子分类和线形函数的预设关系来修正目标值error = (target_bug_length + self.corrections[target_bug]['修正量']) - computed_bug_length# 反馈误差self.feedback(target_bug_width, error)def query(self, input_bug_size):pass# 测试代码
bc = BugClassifier(0.25, 0.5, {'瓢虫':{'修正量':0.1, '关系满足?':lambda c,t:c>t and True or False}, '毛虫':{'修正量':-0.1, '关系满足?':lambda c,t:c
训练第一个样本后的斜率: 0.30833333333333335
训练第二个样本后的斜率: 1.6041666666666667
可以看到,两次训练的结果,和书上例子展示的结果一样,因此代码是正确的。
查询的过程,则是利用已经训练好的分类器,对比分类器计算的分界线值与目标值的大小, 并结合预设的关系满足谓词,例如分界线值>目标值,则为瓢虫;分界线值<目标值,则为毛虫,来给出分类的结果。
In [13]:
class BugClassifier:def __init__(self, coefficient, learning_rate, corrections):self.coefficient = coefficient # 初始系数self.learning_rate = learning_rate # 学习率self.corrections = corrections # 预定义的根据虫类的计算值修正量def feedforward(self, width):''' 前馈函数,此处是利用输入的宽度乘以分类器内部系数计算出来输出的长度 '''return width * self.coefficientdef feedback(self, width, error):''' 反馈函数,此处是利用输入的宽度和输出的误差来反向调节分类器内部系数 '''self.coefficient += self.learning_rate * (error / width)def train(self, target_bug_size, target_bug):target_bug_width = target_bug_size[0]target_bug_length = target_bug_size[1]computed_bug_length = self.feedforward(target_bug_width)# 误差计算。误差计算时,需要根据虫子分类和线形函数的预设关系来修正目标值error = (target_bug_length + self.corrections[target_bug]['修正量']) - computed_bug_length# 反馈误差self.feedback(target_bug_width, error)def query(self, input_bug_size):input_bug_width = input_bug_size[0]input_bug_length = input_bug_size[1]computed_bug_length = self.feedforward(input_bug_width)for bug, correction in self.corrections.items():if correction['关系满足?'](computed_bug_length, input_bug_length):return bug # 只有可能属于一种分类,因此立即返回# 测试代码
bc = BugClassifier(0.25, 0.5, {'瓢虫':{'修正量':0.1, '关系满足?':lambda c,t:c>t and True or False}, '毛虫':{'修正量':-0.1, '关系满足?':lambda c,t:c
训练第一个样本后的斜率: 0.30833333333333335
训练第二个样本后的斜率: 1.6041666666666667
输入: [2.8, 0.9] 识别结果: 瓢虫
可以看到,分类成功了!
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
