python 高维空间:机器如何面对越来越复杂的问题(学习笔记) 电脑版发表于:2023/4/23 11:17 ![](https://img.tnblog.net/arcimg/hb/55a6e3fdaa9846cb81829fd20288e216.jpg) >#python 高维空间:机器如何面对越来越复杂的问题(学习笔记) [TOC] 机器如何面对越来越复杂的问题? ------------ tn2>当我们豆豆的毒性不仅与大小有关,还与颜色有关的时候我们就需要三维坐标系,来显示各不相同的豆豆和毒性的关系。 ![](https://img.tnblog.net/arcimg/hb/4d7e4b1f88864d7cbae616edba6b4398.png) tn2>而只有满足某些大小和颜色深浅的豆豆才有毒,红色的豆豆有毒的概率是1,其他无毒的是0。 ![](https://img.tnblog.net/arcimg/hb/4f31c444fd5c46ac8e817ddaed28ed19.png) tn2>由于多了一项颜色的树突输入,预测函数的线性部分也从一元一次函数变成二元一次函数,这个函数通过三维画出来就是一个平面,再通过Sigmoid函数画出来就是一个曲面。 ![](https://img.tnblog.net/arcimg/hb/bd06fdd9ff0443d0aa147f065cbc5431.png) ![](https://img.tnblog.net/arcimg/hb/826dbf3ce20841a98a516f55cd88146d.png) ![](https://img.tnblog.net/arcimg/hb/f1da8c2b61b34bc9a1a3fba48da64c37.png) tn2>当我们找到预测曲面上预测值为0.5的点,连接在一起用地理里的概念来讲就是为0.5的等高线,连接起来是一条直线。 这条直线大于0.5表示有毒,小于0.5表示无毒。 ![](https://img.tnblog.net/arcimg/hb/5688b6b172904487943768922720b0b1.png) tn2>当我们从上往下看俯视图效果的时候,这个0.5的等高线也就是**类型分割线**。 ![](https://img.tnblog.net/arcimg/hb/592fc845a8fc4d6681586a34414bf4a1.png) tn2>在之前的sigmoid中,也有等高线,只是在二维平面化成了一个点称为**等高点**。 ![](https://img.tnblog.net/arcimg/hb/0728f48950b541ddb51648d154395b14.png) tn2>通过不断调节权重参数w1,w2以及偏置项b,可以让预测模型的登高线顺利分割出有毒和无毒两类豆豆。 ![](https://img.tnblog.net/arcimg/hb/72a292739d554ac7a83781053d86ada7.png) tn2>而当有毒的豆豆是一个曲面时,这时候就需要多个神经元来进行扭曲才行。 ![](https://img.tnblog.net/arcimg/hb/2b55be358ccd450c83b44570a8cde36a.png) tn2>在三维空间中的等高线是一个曲线,而从二维的视角这两个点被称为直点。 ![](https://img.tnblog.net/arcimg/hb/c724ae6dccd0444f952cbfad606c3bc3.png) tn2>当我们考虑的输入数据越多,特征维度就越多。 ![](https://img.tnblog.net/arcimg/hb/01ecf5bb9c0a41909dee73ae346ae13f.png) tn2>如果一个一个去写它们的表达式就太麻烦了,到后面我们可以使用向量和矩阵来进行计算。 编程实践 ------------ tn2>接下来的编程实验,我们将一个输入编程两个输入的神经元,豆豆预测的维度为二。 ![](https://img.tnblog.net/arcimg/hb/6a803f389d944d23bf7244b6e9d3f11c.png) tn2>张量与数组的关系 ![](https://img.tnblog.net/arcimg/hb/6b057a99a18f4ac5ba261d071ac4e690.png) tn2>首先我们导入豆豆的取值。 ```python import numpy as np def get_beans7(counts): xs = np.random.rand(counts,2)*2 ys = np.zeros(counts) for i in range(counts): x = xs[i] if (x[0]-0.5*x[1]-0.1)>0: ys[i] = 1 return xs,ys ``` tn2>然后添加绘图工具的代码`plot_utils.py` ```python import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np def show_scatter(xs,y): x = xs[:,0] z = xs[:,1] fig = plt.figure() # 创建3D对象 ax = fig.add_subplot(111,projection='3d') ax.scatter(x, z, y) plt.show() def show_surface(x,z,forward_propgation): x = np.arange(np.min(x),np.max(x),0.1) z = np.arange(np.min(z),np.max(z),0.1) x,z = np.meshgrid(x,z) y = forward_propgation(x,z) fig = plt.figure() ax = fig.add_subplot(111,projection='3d') ax.plot_surface(x, z, y, cmap='rainbow') plt.show() def show_scatter_surface(xs,y,forward_propgation): x = xs[:,0] z = xs[:,1] fig = plt.figure() ax = fig.add_subplot(111,projection='3d') ax.scatter(x, z, y) x = np.arange(np.min(x),np.max(x),0.01) z = np.arange(np.min(z),np.max(z),0.01) x,z = np.meshgrid(x,z) y = forward_propgation(x,z) ax.plot_surface(x, z, y, cmap='rainbow') plt.show() ``` tn2>先编写几行简单的代码,来生成豆豆,第一列是大小,第二列是颜色值。 ```python import dataset import numpy as np import plot_utils m = 100 xs,ys = dataset.get_beans7(m) print(xs) print(ys) ``` ![](https://img.tnblog.net/arcimg/hb/b86ae8954de741de990a384ec09a31a7.png) tn2>这个ys表示毒性,0表示无毒,1表示有毒。 ![](https://img.tnblog.net/arcimg/hb/8b6a8013b61340119b6a71c6a489f5c0.png) tn2>接下来我们通过调用`plot_utils`类的`show_scatter`方法来绘制散点图。 ```python import dataset import numpy as np import plot_utils m = 100 xs,ys = dataset.get_beans7(m) print(xs) print(ys) # 三维散点图 plot_utils.show_scatter(xs,ys) ``` ![](https://img.tnblog.net/arcimg/hb/273ec5901356431cab5434cd1ce4ad25.png) ```python w1 = 0.1 w2 = 0.1 b = 0.1 # 大小 x1s = xs[:,0] # 深浅 x2s = xs[:,1] # 前向传播 def forward_propgation(x1s,x2s): # 预测函数 z = w1 * x1s + w2 * x2s + b # sigmoid函数求导 a = 1/(1+np.exp(-z)) return a # 绘制一次求导的过程 plot_utils.show_scatter_surface(xs,ys,forward_propgation) ``` ![](https://img.tnblog.net/arcimg/hb/b3b713ff79164ab0adc8c859b488a284.png) ```python import dataset import numpy as np import plot_utils m = 100 xs,ys = dataset.get_beans7(m) print(xs) print(ys) # 三维散点图 plot_utils.show_scatter(xs,ys) w1 = 0.1 w2 = 0.1 b = 0.1 # 大小 x1s = xs[:,0] # 深浅 x2s = xs[:,1] # 前向传播 def forward_propgation(x1s,x2s): # 预测函数 z = w1 * x1s + w2 * x2s + b # sigmoid函数求导 a = 1/(1+np.exp(-z)) return a # 绘制一次求导的过程 plot_utils.show_scatter_surface(xs,ys,forward_propgation) # 梯度下降 500 * 100 for _ in range(500): for i in range(m): x = xs[i] y = ys[i] # 单个大小 x1 = x[0] # 单个颜色值 x2 = x[1] # 进行前向传播一次 a = forward_propgation(x1,x2) # 平方差 e = (y - a) ** 2 # e对a的求导 deda = -2*(y-a) # a对z的求导 dadz = a*(1-a) # z对w1的求导 dzdw1 = x1 # z对w2的求导 dzdw2 = x2 # z对b的求导 dzdb = 1 # 获取de对dw1求导 dedw1 = deda * dadz * dzdw1 # 获取de对dw2求导 dedw2 = deda * dadz * dzdw2 # 获取de对db求导 dedb = deda * dadz * dzdb # 设置阿尔法的弧度为0.01 alpha = 0.01 # 计算误差 w1 = w1 - alpha * dedw1 w2 = w2 - alpha * dedw2 b = b - alpha * dedb # 绘制 plot_utils.show_scatter_surface(xs,ys,forward_propgation) ``` ![](https://img.tnblog.net/arcimg/hb/49f66995c6a849e18c411549437a6f18.png)