机器学习第5章第3节 : LMS的学习率退火算法

机器学习第5章第3节 : LMS的学习率退火算法

说明

模拟退火算法来源于固体退火原理,退火就是讲材料加热后再经过特定速率冷却,目的是增大晶粒的体积,并且减少晶格的缺陷。材料中的原子原来会停留在使内能有局部最小值的位置,加热使能量变大,原子会离开原来的位置,而随机在其他位置中移动。退火冷却时速度较慢,徐徐冷却时粒子渐趋有序,原子有可能找到内能比原先更低的位置,最后在常温时达到基态,内能减为最小。

根据Metropolis准则,粒子在温度T时趋于平衡的概率为e-△E/(kT),其中E为温度T时的内能,△E 为其改变量,K为Boltzmann常数。用固体退火模拟组合优化问题,将内能E模拟为目标函数值f,温度T演化成控制参数t,即得到解组合优化问题的模拟退火算法: 由初始解i和控制参数初值t开始,对当前解重复进行“产生新解 –>计算目标函数差 –> 接受或舍弃”的迭代,并逐步衰减t值,算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。退火过程由冷却进度表控制,包括控制参数的初值t及其衰减因子△t,每个t值时的迭代次数L和停止条件S。

思路

针对学习率不变化、收敛速度较慢的情况,即可使用退火算法方案,让学习率随时时间而变化。学习率计算公式为:
learn_speed

我们针对 机器学习第5章第2节 : LMS算法-二值分类 应用退火算法进行改动。

代码

# -*- coding: utf-8 -*-
"""
Created on Sat Dec  9 15:05:13 2017

@author: Oscar

针对学习率不变化、收敛速度较慢的情况,即可使用退火算法方案,让学习率随时时间而变化。
针对 机器学习第5章第2节 : LMS算法-二值分类 应用退火算法进行改动.

使用LMS算法实现在输入矩阵中,如果x向量的整除结果为6,则表示一类,输出为1;
                          如果整除结果为3,则表示另一类,输出为-1.
"""
import numpy as np
import math

#-------------------------------开始定义变量-------------------------------#

#最小误差精度
min_error_signal = 0.05

#学习率的初始值
learn_speed_start = 0.1

#学习率
learn_speed = 0.0

#衰减因子
r = 5.0

#当前学习次数
current_try_count = 0
#最大学习次数
max_try_count = 20

#偏置
b = 1

#最终的权值
weight = np.array([b,0,0])


#学习的数据
x = np.array([
        [1,1,6],    #1
        [1,2,12],   #1
        [1,3,9],    #-1
        [1,8,24]    #-1
        ])

#期望输出,对应的是学习数据的分类
d = np.array([1,1,-1,-1])

#测试数据
test_data1 = np.array([1,9,27]) #-1
test_data2 = np.array([1,11,66])#1

#-------------------------------开始定义函数-------------------------------#

#感知器
def sgn(v):
    if v > 0 :
        return 1
    else:
        return -1

#拿到感知器的返回值
def get_sgn(current_weight,current_x):
    #当前权值矩阵转置后与当前的学习的数据进行矩阵相乘,得到一个实数,然后调用sgn函数得到感知器的返回值
    return sgn(np.dot(current_weight.T,current_x))

#获取误差信号
def get_error_signal(current_weight,current_x,current_d):
    return current_d - get_sgn(current_weight,current_x)

#更新权值和误差信号值
def update_weight_and_error_signal(old_weight,current_d,current_x):
    current_error_signal = get_error_signal(old_weight,current_x,current_d)
    current_learn_speed = learn_speed_start / (1 + float(current_try_count) / r) #这里请见上面的学习率计算公式.
    return ((old_weight + current_learn_speed * current_error_signal * current_x),(current_error_signal))

#--------------------------------开始训练--------------------------------#
while True:
    final_error_signal = 0.0
    i = 0
    for xn in x:
        weight,current_error_signal = update_weight_and_error_signal(weight,d[i],xn)
        i += 1
        final_error_signal += pow(current_error_signal,2)
    final_error_signal = math.sqrt(final_error_signal)
    current_try_count += 1
    print("第",current_try_count,"次调整,调整后的权值为:",weight,",误差信号值为:",final_error_signal)

    if (abs(final_error_signal) < min_error_signal) or (current_try_count > max_try_count) : break

#--------------------------------训练完毕,开始查看分类情况--------------------------------#
for xn in x:
    print("当前数据:",xn,",当前分类:",get_sgn(weight,xn))

#--------------------------------开始验证--------------------------------#
print("当前验证数据:",test_data1,",当前分类:",get_sgn(weight,test_data1))
print("当前验证数据:",test_data2,",当前分类:",get_sgn(weight,test_data2))

运行结果

1 次调整,调整后的权值为: [ 0.8 -0.6 -1.8] ,误差信号值为: 2.02 次调整,调整后的权值为: [ 0.96666667 -0.6        -0.3       ] ,误差信号值为: 3.46410161513775443 次调整,调整后的权值为: [ 0.96666667 -0.88571429 -0.72857143] ,误差信号值为: 2.82842712474619034 次调整,调整后的权值为: [ 0.96666667 -1.88571429 -2.60357143] ,误差信号值为: 4.05 次调整,调整后的权值为: [ 1.18888889 -1.55238095 -0.60357143] ,误差信号值为: 2.82842712474619036 次调整,调整后的权值为: [ 1.28888889 -1.55238095  0.29642857] ,误差信号值为: 3.46410161513775447 次调整,调整后的权值为: [ 1.28888889 -1.55238095  0.29642857] ,误差信号值为: 0.0
当前数据: [1 1 6] ,当前分类: 1
当前数据: [ 1  2 12] ,当前分类: 1
当前数据: [1 3 9] ,当前分类: -1
当前数据: [ 1  8 24] ,当前分类: -1
当前验证数据: [ 1  9 27] ,当前分类: -1
当前验证数据: [ 1 11 66] ,当前分类: 1

笔记

上次的数据为: 第 9 次调整后的权值为: [ 1.4 -2.8 0.6] 误差信号值为: 0.0

本次的数据为: 第 7 次调整,调整后的权值为: [ 1.28888889 -1.55238095 0.29642857] ,误差信号值为: 0.0

两次误差信号值都达到了0,但是本次训练次数为7次,相比而言,减少了两次的训练,达到了我们想要的优化效果。

发布了57 篇原创文章 · 获赞 1690 · 访问量 76万+

猜你喜欢

转载自blog.csdn.net/u013733326/article/details/78759144