我不确定这对于回归任务有多么有用,但我很高兴看到我的算法在训练集方面的表现有多好。
我发现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()
我的情节结果有点奇怪:
答案 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
结果:
请注意,我将这个对象称为一个平面:“3d超平面”可能会过度销售它。