(32)代码优化二 修改均方误差值
代码优化二:计算方法优化,根据下图的公式修改均方误差值(mean-square error,
MSE),MSE 反映估计量与被估计量之间差异程度的一种度量。求方差的时候可以将公式稍微改一下,除以2,再次运行看一下效果。
将Create_AI_Framework_In5Classes(Day4)的LossComputation.py 中的代码:
total_loss =total_loss + squared_error
修改成如下代码。total_loss = total_loss + squared_error/2
修改以后,再次重新运行Neuron_Network_Entry.py,运行结果如下:
将修改以后代码运行效果跟之前的运行结果做对比,将平方差除以2的运行结果发现左侧不规则的现象更明显了,这跟实际数据的不同情况有关系,除以2这是求方差的一个正常的公式,实际在写代码的时候要不断的调整。
1) 正则化处理Feature Normalization。
接下来我们将进行数据正则化,看看效果怎么样?数据正则化要写一个正则化的方法。前面我们已经讲解了正则化的背景、意义及工作的过程,这里将只有0,1的数据变成-4到4之间的数据。正则化有一个幅度的问题,数据的最小值是-4,最大值是4,尽可能平衡的将数据分布在-4到4的区间,这是基本思路。
在service目录中创建一个FeatureNormalization.py文件。先创建一个类FeatureNormalization,在类FeatureNormalization中定义一个方法normalize,normalize方法对输入的数据instances进行正则化的过程。Neuron_Network_Entry.py中有输入的数据源:[0,0],[0 ,1],[1,0],[1,1],将对输入的数据(第1列数据,第2列数据)进行正则化,正则化到什么程度?需正则化到-4到4之间。首先获得特征数num_of_elements,取出整个输入数据的第0个实例,正则化的时候是否需要将结果(第3列数据)正则化?结果(第3列数据)需要进行正则化,输入数据0,1(第1列数据,第2列数据)变成了-4到4的内容,如果结果(第3列数据)不相应进行正则化,那计算的数据和原来的结果就不太符合,因此,这len(instances[0])不用再减去1,将所有的输入数据第1列,第2列,第3列数据都进行正则化。
max_items、min_items记录里面的成员,接下来进行循环遍历,temp_max是临时的最大值,计算的时候要进行比较,这里涉及一些数学内容,数学公式根据激活函数来的,按照激活函数本身的形态以及求导要求的内容进行正则化实现,temp_max、temp_min是instances第0个输入实例中的值,instances的值有4行3列,第0行的值是[0,0,0],然后循环遍历所有的元素,得到每一个元素。注意:为什么先循环遍历num_of_elements,然后循环遍历instances?循环的时候num_of_elements本身j是不变的,变化的是实例instances本身i,每一次循环遍历实例的时候,计算的是每一行的数据还是计算每1列的数据呢?这里计算的是每1列的数据,为什么按列进行操作,因为instances中的1列就是一个feature。instances有3列,循环的时候变量j取range(num_of_elements)的下标0,1,2 ,如当变量j在初始位置0的时候,循环遍历所有的实例,将第0列的所有数据获取过来,进行正则化的时候是针对Input Source(这里指的是数据源Input Source,而不是指Input Layer输入层)的每一列数据进行的操作。例如TensorFlow的可视化图中,x1是一个神经元的数据,是一个Feature,x2是另外一个Feature,x1和x2里面的数据是输入实例不同列的数据,正则化需对输入的每一列的数据进行相应的正则化,不可能对每一行的数据进行正则化,在进行某种算法计算的时候,对第一行第一个元素进行了一种算法操作,第二行第一个元素也要进行了同种类型的算法操作,这才是所谓的正则化。
接下来,计算这1列数据中的最大值、最小值。如果当前的值大于临时设置的最大值,将当前的值赋值给临时的最大值,这里指不是整个区间的最大值,整个区间的值在-4和4之间。如果当前的值小于临时设置的最小值,将当前的值赋值给临时的最小值。循环以后找到这1列的最大值,最小值,这里Instances的最小值是0,最大值是1。实际的数据可能有几百个Feature,数据的多样化就极大的提升。计算出这1列中的最大值、最小值以后,将最大值、最小值追加到max_items、min_items数组中,因为变量j循环遍历是对每1列的遍历,追加到数组时就获得当前每1列的最大值、最小值。这样就求出了每一个Feature(在这里也包含了对结果的正则化操作,这样才能保证误差的真实性)的最大值和最小值。最后1列是真实值,如果不进行结果的正则化,而只进行特征Feature的正则化,然后将预测值和真实值相减,计算出的误差肯定不符合实际情况。
接下来实现正则化的逻辑。正则化要循环所有的实例,循环所有的Feature,正则化和前面的操作是不一样的,前面的操作是针对一列一列的数据,这里的操作是针对一行一行的数据,操作每一行具体的值,对每一行的内容进行修改,提取出当前输入行对应列的元素本身,例如instances第1行第1列的元素是0,第1行第2列的元素是0,第1行第3列的元素是0,然后获取当前行的元素所在的列的最大值maxItem和最小值minItem,之前我们计算的是每1列的最大值和最小值,现在根据列的索引进行提取,max_items[j]取j列的最大值,min_items[j]取j列的最小值。如果j等于最后一个元素,最后一个元素是真实的值,则记录一下结果,newMax是1,newMin是0;否则,newMax是4,newMin是-4。为什么最后1列的值最大值是1,最小值是0?如果是最后1列,最后1列是实际的值,在0到1之间,而Sigmoid激活函数计算的值也在0到1之间,因此,最小值是0,最大值是1;但是如果是Feature,Feature是x的值,例如是神经网络输入层节点的x1,x2,x值在-4到4之间,Feature进行正则化的时候,为了最大程度的发挥Sigmoid函数的功能,把最大值newMax设置4,最小值newMin设置为-4。正则化到什么地步?正则化到符合Sigmoid函数的定义域和值域,定义域和值域分别是x和y 的区间,x的有效区间是-4到4,y的有效区间是0到1。然后按照正则化计算公式,根据((newMax - newMin)*((value - minItem) /(maxItem - minItem))) + newMin计算出value值。这样就实现了正则化,然后将value赋值给instances[i][j],返回instances。
本文根据王家林老师《5节课内从零起步(无需数学和Python基础)编码实现AI人工智能框架电子书》整理。