第五章 神经网络(待补充)

在这里插入图片描述

5.1

神经网络中的激活函数是为了给线性分类添加非线性因素,使其能很好进行非线性划分。如果在使用线性函数进行激活,那么无论多少层神经网络都会退化成线性回归,无法进行非线性分类。因此激活函数主要有以下几个要求:

  • 非线性,内在反映的是模型的非线性;
  • 可微性,以支持梯度下降法等基于微分的优化方法;
  • 单调性,以保证单层网络是凸约束,从而存在最优;
  • 输出值范围受限,当输出有限时,寻优算法(如梯度下降)变得更加稳定;
  • 导数可由原函数计算出,以便重复利用;

5.2

神经元和对率回归模型都是由于阶跃函数不光滑,不连续的性质,选择了sigmoid函数。不过神经元的激活函数只要是非线性的即可,因此不一定都是sigmoid函数。

5.3

在这里插入图片描述

5.4

学习率小的话,参数更新的幅度就小,迭代次数就多,找到全局最优解的速度就慢。但是学习率大的话,刚开始走向全局最优解的速度会比较快,但是最后可能会振荡,即在最小值附近来回波动

5.5(有问题,再调)

步骤:
1.准备数据
2.调整数据格式
3.准备参数
4.开始训练
5.进行预测

西瓜数据集如下:

#1.准备数据
dataSet = [
        # 色泽    根蒂    敲声    纹理    脐部    触感    密度  含糖率  好瓜
        # 1
        ['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.697, 0.460, 1],
        # 2
        ['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', 0.774, 0.376, 1],
        # 3
        ['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.634, 0.264, 1],
        # 4
        ['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', 0.608, 0.318, 1],
        # 5
        ['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.556, 0.215, 1],
        # 6
        ['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', 0.403, 0.237, 1],
        # 7
        ['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', 0.481, 0.149, 1],
        # 8
        ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', 0.437, 0.211, 1],

        # ----------------------------------------------------
        # 9
        ['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', 0.666, 0.091, 0],
        # 10
        ['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', 0.243, 0.267, 0],
        # 11
        ['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', 0.245, 0.057, 0],
        # 12
        ['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', 0.343, 0.099, 0],
        # 13
        ['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', 0.639, 0.161, 0],
        # 14
        ['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', 0.657, 0.198, 0],
        # 15
        ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', 0.360, 0.370, 0],
        # 16
        ['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', 0.593, 0.042, 0],
        # 17
        ['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', 0.719, 0.103, 0]
    ]
print(len(dataSet))
17
#2.调整数据格式
import numpy as np

data=[i[0:-1] for i in dataSet]
print(data)
target=[i[8:9] for i in dataSet]
print(target)
[['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.697, 0.46], ['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', 0.774, 0.376], ['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.634, 0.264], ['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', 0.608, 0.318], ['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.556, 0.215], ['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', 0.403, 0.237], ['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', 0.481, 0.149], ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', 0.437, 0.211], ['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', 0.666, 0.091], ['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', 0.243, 0.267], ['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', 0.245, 0.057], ['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', 0.343, 0.099], ['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', 0.639, 0.161], ['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', 0.657, 0.198], ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', 0.36, 0.37], ['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', 0.593, 0.042], ['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', 0.719, 0.103]]
[[1], [1], [1], [1], [1], [1], [1], [1], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
attributeMap={}
attributeMap['浅白']=0
attributeMap['青绿']=0.5
attributeMap['乌黑']=1
attributeMap['蜷缩']=0
attributeMap['稍蜷']=0.5
attributeMap['硬挺']=1
attributeMap['沉闷']=0
attributeMap['浊响']=0.5
attributeMap['清脆']=1
attributeMap['模糊']=0
attributeMap['稍糊']=0.5
attributeMap['清晰']=1
attributeMap['凹陷']=0
attributeMap['稍凹']=0.5
attributeMap['平坦']=1
attributeMap['硬滑']=0
attributeMap['软粘']=1
for i in data:
    for j in range(len(i)):
        if i[j] in attributeMap:
            i[j]=attributeMap[i[j]]
print(data)
data=np.array(data)
target=np.array(target)
[[0.5, 0, 0.5, 1, 0, 0, 0.697, 0.46], [1, 0, 0, 1, 0, 0, 0.774, 0.376], [1, 0, 0.5, 1, 0, 0, 0.634, 0.264], [0.5, 0, 0, 1, 0, 0, 0.608, 0.318], [0, 0, 0.5, 1, 0, 0, 0.556, 0.215], [0.5, 0.5, 0.5, 1, 0.5, 1, 0.403, 0.237], [1, 0.5, 0.5, 0.5, 0.5, 1, 0.481, 0.149], [1, 0.5, 0.5, 1, 0.5, 0, 0.437, 0.211], [1, 0.5, 0, 0.5, 0.5, 0, 0.666, 0.091], [0.5, 1, 1, 1, 1, 1, 0.243, 0.267], [0, 1, 1, 0, 1, 0, 0.245, 0.057], [0, 0, 0.5, 0, 1, 1, 0.343, 0.099], [0.5, 0.5, 0.5, 0.5, 0, 0, 0.639, 0.161], [0, 0.5, 0, 0.5, 0, 0, 0.657, 0.198], [1, 0.5, 0.5, 1, 0.5, 1, 0.36, 0.37], [0, 0, 0.5, 0, 1, 0, 0.593, 0.042], [0.5, 0, 0, 0.5, 0.5, 0, 0.719, 0.103]]
#3.准备参数
import random
d = 8    #输入向量的维度
l = 1    #输出向量的维度
q = 20  #隐层神经元个数
theta = [random.random() for i in range(l)]  #l个输出层神经元的阈值
gamma = [random.random() for i in range(q)]  #q个隐层神经元的阈值
v = [[random.random() for i in range(q)] for j in range(d)]  #输入层到隐层的连接权重,v=d*q
w = [[random.random() for i in range(l)] for j in range(q)]  #隐层到输出层的连接权重,w=q*l
eta = 0.1      #学习率
epoch=20   #训练轮次

import math
def sigmoid(iX,dimension):#iX is a matrix with a dimension
    if dimension==1:
        for i in range(len(iX)):
            iX[i] = 1 / (1 + math.exp(-iX[i]))
    else:
        for i in range(len(iX)):
            iX[i] = sigmoid(iX[i],dimension-1)
    return iX
#4.开始训练,下面是标准bp
for i in range(epoch):
    sumE = 0
    for i in range(17):
        alpha = np.dot(data[i],v)              #shape=1*q p102 从输入层到隐层的计算结果(用来计算激活函数的输入)
        b = sigmoid(alpha-gamma,1)          #shape=1*q 5.3 激活函数1的输出
        beta = np.dot(b,w)                  #shape=(1*q)*(q*l)=1*l p102 从隐层到输出层的计算结果(用来计算激活函数的输入)
        predictY = sigmoid(beta-theta,1)    #shape=1*l 5.3 激活函数2的输出
        E = sum((predictY-target[i]),2)/2    #5.4
        sumE += E                           #5.16
        g = predictY*(1-predictY)*(target[i]-predictY)       #shape=1*l , p103--5.10
        e = b*(1-b)*((np.dot(w,g.T)).T)                     #shape=1*q , p104--5.15
        w += eta*np.dot(b.reshape((q,1)),g.reshape((1,l)))  #5.11
        theta -= eta*g                                      #5.12
        v += eta*np.dot(data[i].reshape((d,1)),e.reshape((1,q)))   #5.13
        gamma -= eta*e                                          #5.14
        #dot是矩阵乘,T是转置


#4.开始训练,下面是累积bp
# target=target.reshape(17,1)
# for i in range(epoch):
#     sumE = 0
#     alpha = np.dot(data, v)#p101 line 2 from bottom, shape=m*q
#     b = sigmoid(alpha - gamma,2)  # b=f(alpha-gamma), shape=m*q
#     beta = np.dot(b, w)  # shape=(m*q)*(q*l)=m*l
#     predictY = sigmoid(beta - theta,2)  # shape=m*l ,p102--5.3
#     E = sum(sum((predictY - target) * (predictY - target))) / 2  # 5.4
#     g = predictY * (1 - predictY) * (target - predictY)  # shape=m*l p103--5.10
#     e = b * (1 - b) * ((np.dot(w, g.T)).T)  # shape=m*q , p104--5.15
#     w += eta * np.dot(b.T, g)  # 5.11 shape (q*l)=(q*m) * (m*l)
#     theta -= eta * g  # 5.12
#     v += eta * np.dot(X.T, e)  # 5.13 (d,q)=(d,m)*(m,q)
#     gamma -= eta * e  # 5.14

#预测
def predict(iX):
    alpha = np.dot(iX, v)  # p101 line 2 from bottom, shape=m*q
    b=sigmoid(alpha-gamma,2)#b=f(alpha-gamma), shape=m*q
    beta = np.dot(b, w)  # shape=(m*q)*(q*l)=m*l
    predictY=sigmoid(beta - theta,2)  # shape=m*l ,p102--5.3
    return predictY


py = predict(data)
for i in range(len(py)):
    if py[i][0] < 0.5:
        py[i][0] = 0
    else:
        py[i][0] = 1

5.6

https://blog.csdn.net/qq_34405401/article/details/104351357
上述链接是一些优化器的介绍,其中的Adam就可以动态调整学习率;
手工实现思路:
一开始给予较高的学习率进行累积训练,每训练一次后,采用P105的早停策略,即用验证机估计误差,如果发现误差下降的趋势比以前慢了,甚至还上升了,那么此刻调整学习率

5.7(待写)

https://blog.csdn.net/snoopy_yuan/article/details/71024046

扫描二维码关注公众号,回复: 10428426 查看本文章

5.8(待写)

5.9(待写)

5.10

https://blog.csdn.net/qq_34405401/article/details/104708460

发布了105 篇原创文章 · 获赞 8 · 访问量 4712

猜你喜欢

转载自blog.csdn.net/qq_34405401/article/details/104943008