深度学习--TensorFlow(3)线性神经网络(线性输入&&非线性输入)(实现)

目录

一、线性神经网络(线性输入)

1、基础理论 

2、线性输入代码

奇葩错误:

二、线性神经网络(非线性输入)

0、引言 

1、基础理论

三、线性神经网络(非线性输入)实战

1、设置初始参数

2、正向传播,求线性输出y

3、反向传播,更新权重w

4、训练&&预测(画图)

4-1、画正负样本点坐标

4-2、获取非线性输出模型(y)

非线性输入代码


​​​​​​​

一、线性神经网络(线性输入)

1、基础理论 

    线性神经网络和上面的单层感知器十分相似,只是把单层感知器的sign激活函数改成了purelin函数:y=x

有两个地方需要修改:

1、修改激活函数

 因为线性神经网络的激活函数是y=x,所以就不再需要np.sign()了。

2、 不需要拟合后退出

由于不是之前的sign激活函数(输出0/1),线性神经网络会无限逼近,一般不会与标签完全拟合,可以更好地训练样本

2、线性输入代码

和前面的单层感知器基本一致。

# 手写单层感知器(多数据分类)
import numpy as np
import matplotlib.pyplot as plt

# 1、设置初始参数
# 输入                       #每一行对应一个标签
x = np.array([[1, 0, 2],    #(0,2)坐标
              [1, 1, 3],    #(1,3)坐标
              [1, 4, 2],    #(4,2)坐标
              [1, 5, 1]     #(5,1)坐标
])
# 初始权重(0~1的随机生产数)
w = np.random.random([3, 1])      #3行1列

# 偏置
b = 1

# 标签(正确标签,训练结束的目标)
true = np.array([              #每一行对应一个标签
    [-1],
    [-1],
    [ 1],
    [ 1]
])

# 学习率
lr = 0.1


# 开始训练
for i in range(100):
    # 2、正向传播:计算输出y
    y = np.dot(x, w)                        #dot:矩阵乘法(x列==w行)
    print('epoch:', i)                      #迭代次数
    print('weight:', w)                     #权重
    print(y)                                #标签

    # 训练成功
    if (y == true).all():
        print('训练成功!')
        print('y = ', y)
        break

    # 3、反向传播:更新权重
    # 训练失败(更新权重)
    else:
        w += lr * np.dot(x.T, true-y)/x.shape[0]
# w:权重      lr:学习率      np.dot:矩阵点乘     true-y:差     x.T:x的转置     x.shape[0]:行数


# 4、画图
# 4-1、画点
# 正样本坐标
x1, y1 = [0,1], [2,3]   #坐标:(0,2), (1,3)
# 负样本坐标
x2, y2 = [4,5], [2,1]   #坐标:(4,2),(5,1)

plt.scatter(x1, y1, c='b')  #点:(x1,y1)坐标,blue颜色
plt.scatter(x2, y2, c='g')  #点:(x2,y2)坐标,green颜色

# 4-2、画线段
# 定义线段两点的x坐标
line_x = (0, 6)

# 计算线性方程的k和d:
# w0*x0+w1*x1+w2*x2 = 0
# 把x1、x2分别看作:x、y
# 可以得到:w0 + w1*x + w2*y = 0  -->  y = -w1/w2*x + -w0/w2  -->  k=-w1/w2, d=-w0/w2
# 线段两端点的y坐标
k = -w[1]/w[2]          #斜率
d = -w[0]/w[2]          #截距
line_y = k * line_x + d #y坐标

#画线段(通过两个点)
plt.plot(line_x, line_y, 'r')   #r:red

plt.show()

  

训练5次: 

 

 训练500次:

由于不断逼近训练的缘故,可以发现500次的拟合效果比5次的明显好不少。

奇葩错误:

 之前由于学习率设置过大,训练多少次都无法成功

二、线性神经网络(非线性输入)

0、引言 

有些比较复杂的情况是没办法用线性神经网络的线性输入处理的,比如异或问题:

  

 可以很明显发现,一条直线无法划分异或问题,这是非线性问题,这时就需要用线性神经网络的非线性输入来处理这些问题了。

1、基础理论

线性神经网络可以引入非线性输入特征来解决非线性问题。 

这是线性神经元非线性输入的模型:

三、线性神经网络(非线性输入)实战

1、设置初始参数

# 1、设置初始参数
# 输入                       #每一行对应一个标签
# 六个参数分别为:x0 x1 x2 x1*x1 x1*x2 x2*x2
x = np.array([[1, 0, 0, 0, 0, 0],    #坐标(0,0) -1
              [1, 0, 1, 0, 0, 1],    #坐标(0,1) 1
              [1, 1, 0, 1, 0, 0],    #坐标(1,0) 1
              [1, 1, 1, 1, 1, 1]     #坐标(1,1) -1
])
# 这些点者用来训练线性模型,作为线性模型的输入。

# 初始权重(0~1的随机生产数)
w = np.random.random([6, 1])      #3行1列

# 偏置
b = 1

# 标签(正确标签,训练结束的目标)
true = np.array([              #每一行对应一个标签
    [-1],
    [1],
    [1],
    [-1]
])

# 学习率
lr = 0.1

2、正向传播,求线性输出y

# 开始训练
for i in range(500):
    # 2、正向传播:计算输出y
    y = np.dot(x, w)                        #dot:矩阵乘法(x列==w行)

3、反向传播,更新权重w

# 3、反向传播:更新权重
    # 更新权重
    w += lr * np.dot(x.T, true-y)/x.shape[0]
# w:权重      lr:学习率      np.dot:矩阵点乘     true-y:差     x.T:x的转置     x.shape[0]:行数

4、训练&&预测(画图)

4-1、画正负样本点坐标

# 4-1、画点
# 正样本坐标
x1, y1 = [0,1], [1,0]   #坐标:(0,2), (1,3)
# 负样本坐标
x2, y2 = [0,1], [0,1]   #坐标:(4,2),(5,1)

plt.scatter(x1, y1, c='b')  #点:(x1,y1)坐标,blue颜色
plt.scatter(x2, y2, c='g')  #点:(x2,y2)坐标,green颜色

4-2、获取非线性输出模型(y)

1、生成100个输入点横坐标

# 获取训练集横坐标(在(-1,2)上均匀100个数,作为横坐标)
line_x = np.linspace(-1,2,100)

2、计算非线性输出 

根据前面输入的100个横坐标,求出它们的非线性输出y:

# 计算非线性方程的y:
# 计算非线性输出(非线性输入x的非线性输出y)
def Calculate(line_x, root):
    # 定义参数
    a = w[5]
    b = w[2] + w[4]*line_x
    c = w[0] + w[1]*line_x + w[3]*line_x*line_x
    # 计算输出y
    if root == 1:
        line_y = (-b+np.sqrt(b*b - 4*a*c))/(2*a)
        return line_y
    elif root == 2:
        line_y = (-b-np.sqrt(b*b - 4*a*c))/(2*a)
        return line_y

3、根据这100个点画出“曲线”

# 画曲线
plt.plot(line_x, Calculate(line_x,1), 'r')   #r:red
plt.plot(line_x, Calculate(line_x,2), 'r')   #r:red

plt.show()

 

 注:这里是点数量足够多 ,才能看起来像曲线,如果点数量不够,那么就是明显的折线了。

比如只生成3个点:

line_x = np.linspace(-1,2,3)

非线性输入代码

# 手写单层感知器(多数据分类)
import numpy as np
import matplotlib.pyplot as plt

# 1、设置初始参数
# 输入                       #每一行对应一个标签
# 六个参数分别为:x0 x1 x2 x1*x1 x1*x2 x2*x2
x = np.array([[1, 0, 0, 0, 0, 0],    #坐标(0,0) -1
              [1, 0, 1, 0, 0, 1],    #坐标(0,1) 1
              [1, 1, 0, 1, 0, 0],    #坐标(1,0) 1
              [1, 1, 1, 1, 1, 1]     #坐标(1,1) -1
])
# 这些点者用来训练线性模型,作为线性模型的输入。

# 初始权重(0~1的随机生产数)
w = np.random.random([6, 1])      #3行1列

# 偏置
b = 1

# 标签(正确标签,训练结束的目标)
true = np.array([              #每一行对应一个标签
    [-1],
    [1],
    [1],
    [-1]
])

# 学习率
lr = 0.1


# 开始训练
for i in range(500):
    # 2、正向传播:计算输出y
    y = np.dot(x, w)                        #dot:矩阵乘法(x列==w行)

    # 3、反向传播:更新权重
    w += lr * np.dot(x.T, true-y)/x.shape[0]
# w:权重      lr:学习率      np.dot:矩阵点乘     true-y:差     x.T:x的转置     x.shape[0]:行数
print('epoch:', i)                      #迭代次数
print('weight:', w)                     #权重
print(y)                                #标签

# 4、训练&&预测(画图)
# 4-1、画点
# 正样本坐标
x1, y1 = [0,1], [1,0]   #坐标:(0,2), (1,3)
# 负样本坐标
x2, y2 = [0,1], [0,1]   #坐标:(4,2),(5,1)

plt.scatter(x1, y1, c='b')  #点:(x1,y1)坐标,blue颜色
plt.scatter(x2, y2, c='g')  #点:(x2,y2)坐标,green颜色

# 4-2、非线性输出
# 获取训练集横坐标(在(-1,2)上均匀100个数,作为横坐标)
line_x = np.linspace(-1,2,100)

# 计算非线性方程的y:
# 计算非线性输出(非线性输入x的非线性输出y)
def Calculate(line_x, root):
    # 定义参数
    a = w[5]
    b = w[2] + w[4]*line_x
    c = w[0] + w[1]*line_x + w[3]*line_x*line_x
    # 计算输出y
    if root == 1:
        line_y = (-b+np.sqrt(b*b - 4*a*c))/(2*a)
        return line_y
    elif root == 2:
        line_y = (-b-np.sqrt(b*b - 4*a*c))/(2*a)
        return line_y

# 画曲线
plt.plot(line_x, Calculate(line_x,1), 'r')   #r:red
plt.plot(line_x, Calculate(line_x,2), 'r')   #r:red

plt.show()

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_(*^▽^*)_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值