TensorFlow 教程:3. 基础中的基础之,单层感知器

前言:

为什么从单层感知器开始补基础, 因为机器学习从没接触的人来说,不看这个 直接看卷曲神经会看不懂。 所以这篇补基础的文章,即是从单层感知器开始入手。

配置环境:

操作系统:windos7

语言: python3.5(建议使用 Anaconda3-4.2.0-Windows-x86_64)

所需数学基础: 高中数学, 知道什么是坐标, 知道怎么把 方程式转化为坐标曲线

1 简单必须的概念 (尽量用大白话概括)

1.1:tensorflow是什么?

是卷曲神经网络,一种机器学习的框架。

1.2: 机器学习是什么?

用代码去解决一些 现实中的问题。 比如 图像识别,字符识别,语音转文字 之类的。

1.3:怎么入门 ,好多东西看不懂, 数学不会?

卷曲神经的基础是机器学习,机器学习的入门是 单层感知器。 我们从单层感知器入手

数学用到哪看哪。 好多东西不会就从基础入手。 学着学着就会了。

1.4: 具体入门方式?:

好多教程,收费的,免费的 。 QQ群, 网易云课堂

2 什么是单层感知器:

首先我们要知道作为最基础的单层感知器是干什么的?

单层感知器是用来分类的。是机器学习的基础。 由多个单层感知器构成复杂的神经网络。

单层感知器功能 如下图: 对这个坐标系中的两个蓝点和一个黄点进行了一次 分类。 本文要讨论实现的问题就是如何实现下图的分类

《TensorFlow 教程:3. 基础中的基础之,单层感知器》
《TensorFlow 教程:3. 基础中的基础之,单层感知器》

3 解决问题 :

在一个坐标系中 点[3,3], [4,3] 是正值。点[1,1]是负值。 来构建一个神经网络,区分开这三个点。

首先补一下数学知识:

什么是矩阵: 矩阵是用长方阵列排列的 数字

矩阵加法和减法:加法减法类似 如下图

《TensorFlow 教程:3. 基础中的基础之,单层感知器》
《TensorFlow 教程:3. 基础中的基础之,单层感知器》

矩阵乘法: 数字乘矩阵

《TensorFlow 教程:3. 基础中的基础之,单层感知器》
《TensorFlow 教程:3. 基础中的基础之,单层感知器》

矩阵乘矩阵:

《TensorFlow 教程:3. 基础中的基础之,单层感知器》
《TensorFlow 教程:3. 基础中的基础之,单层感知器》

我们要解决的问题就是找到一根直线 使 正样本和负样本分开:

实现思路:

简单通俗的来说 : 就是把这个直线 作为一个方程。 例如 w0 + w1*x +w2y = 0

也就是把w0, w1 w2 不停的变换值 直到 找到一个合适的值,使正负样本分开。 就实现了我们的分类目的。 这里的w0 w1 w2 组合乘一个矩阵 [w0 ,w1 , w2]. 就是神经网络里面所所说的权重 权值。

如下就是代码实现。 先看我的注释 再抄两遍就会了

复制代码 跑一边 就会出现文章开始的图片了 。 python 自动生成的图片

以下是代码实现:

# coding:utf-8
import numpy as np
import matplotlib.pyplot as plt


X = np.array([
	[1, 3, 3],
	[1, 4, 3],
	[1, 1, 1]
])
# 为什么样本坐标是 [3,3][4,3][1,1] 而这里多了个1 变成了
# [1, 3, 3],
# [1, 4, 3],
# [1, 1, 1]
# 因为 函数方程有一个常数项 比如 5 + x + 2y = 0 这里面的5 即是常数项。 
# 如果矩阵没有第一位为1 则这个常数项无法体现





# 期望输出值
Y = np.array([1, 1, -1])

# 权重初始化 一行三列矩阵,取值范围 -1到1
W = (np.random.random(3)-0.5)*2

# 学习率
lr = 0.11
# 记录 循环点带次数
n = 0
# 输出值
O = 0


def update():
	global X, Y, W, lr, n
	n += 1
	# 矩阵乘法 也即是 (3行3列)矩阵X 乘以 1列矩阵W.T
	# (一行矩阵W, W.T 是将矩阵偏转成 1列)
	# 其中 np.dat() 是矩阵相乘, 返回一个矩阵结果 在这里返回的是一个 3行1列
	# np.sign() 返回数组中各元素的正负符号,用1和-1表示 数组元素分类
	O = np.sign(np.dot(X, W.T))

	''' 获取改变权值 这一块比较难懂。  因为我们的目的是在坐标上找到一根直线 来区分正样本和负样本   也即是 输入矩阵X  X = np.array([  [1, 3, 3],  [1, 4, 3],  [1, 1, 1]  ])   用权重矩阵W和X的每行相乘。 这里W矩阵为 [w0,w1,w2]   例如X的第一行和W相乘 1*w0 + 3*w1 + 3*w2   最后 X*W.T会得到一个3行1列矩阵, 我们用np.sign() 返回数组中各元素的正负符号,  用1和-1表示 数组元素分类  最后会得到矩阵 O。 当矩阵O和期望输出 Y = np.array([1, 1, -1]) 相等时 我们的权重则计算完成    当我们获取到这个权重后, 我们就可以拿这个权重 去生成一个方程 w0 + x*w1 + y*w2=0  这个方程 输入我们的正样本 得出正值 输入负样本得出负值   这个方程 也即是 y = (-x*w1/w2) + (-w0/w2)  也即是 斜率为 -w1/w2 截距为 -w0/w2    '''
	W_C = lr*(Y-O.T).dot(X)/int(X.shape[0])
	W = W + W_C

for _ in range(100):
	update()
	O = np.sign(np.dot(X,W.T))
	if (O == Y.T).all():# 如果实际输出等于期望输出 循环结束
		break

# 正样本
x1 = [3, 4]
y1 = [3, 3]
# 负样本
x2 = [1]
y2 = [1]

# k是斜率 d是截距 获取方式 在权重那块写了
k = -W[1]/W[2]
d = -W[0]/W[2]

'''生成图片显示出效果'''
xdata = np.linspace(0, 5)
plt.figure()
plt.plot(xdata,xdata*k+d, 'r')
plt.plot(x1, y1, 'bo')
plt.plot(x2, y2, 'yo')
plt.show()

备注: 我学习的时候,比较疑惑权重改变公式的原理。 在此再次细讲下:

为什么权重改变公式为 W_C = lr*(Y-O.T).dot(X)/int(X.shape[0])

在此举一个简单的例子:

我们设: 样本 X[1,3,3]的期望输出为 1 。 在权重W为[w0, w1, w2]时。

X * W.T=[1*w0 + 3*w1 + 3*w2] 小于零。

也即是 期望输出值 O= np.sign(负数)=[-1]

所以: 期望输出-实际输出=Y-O=1-(-1)=2

这里我们将学习率 lr设定为1. 便于计算:

则我们的权重改变公式转化为了:

W_C = lr*(Y-O.T).dot(X)/int(X.shape[0]) ( 这里的这个函数 int(X.shape[0])是获取矩阵有多上行, 是为了算出改变的平均值)

= 1*([2].[1, 3, 3])/1

=[2, 6, 6]

新的权重为 W=W+W_C

首先: 在题目初期 W为原先值时 X*W.T < 0

现在我们把 新的权值 W=W+W_C 代入原先的公式:

X*(W+W_C).T = [1,3,3]*([w0,w1,w2] + [2, 6, 6]).T

= [1,3,3]*[w0+2, w1+6, w2+6].T

=1*(w0+2) + 3*(w1+6) + 3*(w2+6)

=w0 + 2 + 3w1 +18 + 3*w2 +18

= w0 +3w1 + 3w2 + (2+18+18)

=w0+ 3w1 + 3w2 +38

因为:原先的权重 是 X*W.T<0

也即是 w0+ 3w1 + 3w2 < 0

而权值更新后: X *(W+W_C).T 是

(w0+ 3w1 + 3w2) + 38

也即是 我们迭代一次, 这个值就增加38 . 直到加到结果为正值时。 迭代结束。 求得所 需要的权重

本文 参考地址:

http://study.163.com/course/courseLearn.htm?courseId=1004111045#/learn/video?lessonId=1048017256&courseId=1004111045

    原文作者:羽一
    原文地址: https://zhuanlan.zhihu.com/p/32096625
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞