使用训练过的权重绘制3d超平面

时间:2016-03-04 14:24:23

标签: python python-3.x numpy matplotlib machine-learning

我不确定这对于回归任务有多么有用,但我很高兴看到我的算法在训练集方面的表现有多好。

我发现2D问题的绘图非常简单,但我在绘制3D时遇到了问题。

import numpy as np
import itertools
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


def gradient_descent(x, y, w, lr, m, iter):
    xTrans = x.transpose()
    for i in range(iter):
        prediction = np.dot(x, w)
        loss = prediction - y
        cost = np.sum(loss ** 2) / m

        print("Iteration %d | Cost: %f" % (i + 1, cost))

        gradient = np.dot(xTrans, loss) / m     # avg gradient

        w -= lr * gradient   # update the weight vector

    return w

it = np.ones(shape=(100, 3))    # it[:,2] will be set of bias values
x = np.arange(1, 200, 20)
d = np.random.uniform(-100, 100, 100)

m, n = np.shape(it)

# initialise weights to 0
w = np.zeros(n)

# produce a 100x2 containing every combination of x
indx = 0
for a, b in itertools.product(x, x):
    it[indx][0] = a
    it[indx][1] = b
    indx += 1

# function with uniform distribution
y = .4*it[:,0] + 1.4*it[:,1] + d

iter = 1500             # number of iterations
lr = 0.00001            # learning rate / alpha

trained_w = gradient_descent(it, y, w, lr, m, iter)
result = trained_w[0] * it[:,0] + trained_w[1] * it[:,1] + trained_w[2]  # linear plot of our predicted function
print("Final weights: %f | %f | %f" % (trained_w[0], trained_w[1], trained_w[2]))

# scatter of data set + trained function hyperplane
plt3d = plt.figure().gca(projection='3d')
plt3d.hold(True)
plt3d.scatter(it[:,0], it[:,1], y)
x_surf, y_surf = np.meshgrid(it[:,0], it[:,1])
plt3d.plot_surface(x_surf, y_surf, result)

plt.show()

我的情节结果有点奇怪:

enter image description here

1 个答案:

答案 0 :(得分:1)

问题在于你在图中混淆了尺寸。

首先从(x,x)构建网格。如果我理解正确,您可以使用meshgrid完成相同的操作:

x = np.arange(1, 200, 20)
N = x.size
a,b = np.meshrid(x,x)
it = np.array([b.ravel(),a.ravel(),np.ones(N)])

然后对随机输入数据进行训练,并获得函数result,这是一个长度为N^2的数组,并包含it中每个坐标对的单个点(形状(N^2,3))。最后,您it 生成一个新网格,并尝试使用这些坐标和result绘制曲面。

因此,您将形状x_surf的两个坐标y_surf(N^2,N^2)以及形状result的曲面值(N^2,)传递给{{1} }。这有效的唯一原因是matplotlib可能使用数组广播来解释输入,并将较少数量的值复制到较大数量的坐标。

所以你有两个选择。使用输入网格绘制曲面,或者如果由于某种原因需要使用不同的网格(例如,选择更大/更小的域来绘制曲面),请使用双线性插值/外推来重新计算曲面。好的,这是一种非常奇特的说法

plot_surf

如果您坚持使用原始网格物体,则必须result = trained_w[0] * x_surf + trained_w[1] * y_surf + trained_w[2] # instead of # result = trained_w[0] * it[:,0] + trained_w[1] * it[:,1] + trained_w[2] 将其重新塑造np.reshape以使(N,N)满意;如果采用上述方法,您的plot_surface已经具有适当的绘图形状。使用前一种方法:

result

结果:

plot

请注意,我将这个对象称为一个平面:“3d超平面”可能会过度销售它。