python 如何在等高线图上绘制梯度向量
How to plot gradient vector on contour plot in python
我有两个变量 W1、W2 和输出 z = F(W1,W2) 的损失函数。
现在绘制这个损失函数的等值线图。现在说,我已经计算了两个点的梯度向量,因此我现在有两个梯度向量。我想在我的等高线图上绘制这些梯度向量,但我不知道如何处理。感谢任何帮助
enter code here
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
feature_x = np.arange(-50, 50, 2)
feature_y = np.arange(-50, 50, 3)
# Creating 2-D grid of features
[X, Y] = np.meshgrid(feature_x, feature_y)
fig, ax = plt.subplots(1, 1)
z = 0.5*np.array((Y-X)*(Y-X) + 0.5*(1-X)*(1-X))
# plots contour lines
ax.contour(X, Y, z, 10, cmap = 'jet')
ax.grid(True)
ax.axis('scaled')
#ax.clabel(cp, inline=1, fontsize=10)
ax.set_title('Contour Plot')
ax.set_xlabel('feature_x')
ax.set_ylabel('feature_y')
plt.show()
您可以使用 FancyArrowPatch 在几个选定的位置绘制渐变。
from matplotlib.patches import FancyArrowPatch
x1 = -20 # position of the gradient
y1 = 10
dz1_dx = 10 # value of the gradient at that position
dz1_dy = -5
arrow = FancyArrowPatch((x1, y1), (x1+dz1_dx, y1+dz1_dy),
arrowstyle='simple', color='k', mutation_scale=10)
ax.add_patch(arrow)
否则,如果您想绘制整个矢量场,quiver 可能是一个选项:
feature_x = np.arange(-50, 50, 2)
feature_y = np.arange(-50, 50, 2)
x, y = np.meshgrid(feature_x, feature_y)
z = 0.5*(y-x)**2 + 0.5*(1-x)**2
u = 2*x - y - 1
v = y - x
# Normalize all gradients to focus on the direction not the magnitude
norm = np.linalg.norm(np.array((u, v)), axis=0)
u = u / norm
v = v / norm
fig, ax = plt.subplots(1, 1)
ax.set_aspect(1)
ax.plot(feature_x, feature_y, c='k')
ax.quiver(x, y, u, v, units='xy', scale=0.5, color='gray')
ax.contour(x, y, z, 10, cmap='jet', lw=2)
arrow = FancyArrowPatch((35, 35), (35+34*0.2, 35+0), arrowstyle='simple',
color='r', mutation_scale=10)
ax.add_patch(arrow) # NOTE: this gradient is scaled to make it better visible
我在这个图中添加了 line y = x
并标记了这条线与等高线相交的点。在这里你可以清楚地看到
那:
Gradients are orthogonal to level surfaces
所以对于你的观点 (80, 80)
梯度 (79, 0)
是正确的,即使等值线的一般形状可能表明 y-direction 中应该有一部分。
但是如果你沿着 y=x 线看,你会发现那里的梯度总是只在 x-direction.
我有两个变量 W1、W2 和输出 z = F(W1,W2) 的损失函数。
现在绘制这个损失函数的等值线图。现在说,我已经计算了两个点的梯度向量,因此我现在有两个梯度向量。我想在我的等高线图上绘制这些梯度向量,但我不知道如何处理。感谢任何帮助
enter code here
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
feature_x = np.arange(-50, 50, 2)
feature_y = np.arange(-50, 50, 3)
# Creating 2-D grid of features
[X, Y] = np.meshgrid(feature_x, feature_y)
fig, ax = plt.subplots(1, 1)
z = 0.5*np.array((Y-X)*(Y-X) + 0.5*(1-X)*(1-X))
# plots contour lines
ax.contour(X, Y, z, 10, cmap = 'jet')
ax.grid(True)
ax.axis('scaled')
#ax.clabel(cp, inline=1, fontsize=10)
ax.set_title('Contour Plot')
ax.set_xlabel('feature_x')
ax.set_ylabel('feature_y')
plt.show()
您可以使用 FancyArrowPatch 在几个选定的位置绘制渐变。
from matplotlib.patches import FancyArrowPatch
x1 = -20 # position of the gradient
y1 = 10
dz1_dx = 10 # value of the gradient at that position
dz1_dy = -5
arrow = FancyArrowPatch((x1, y1), (x1+dz1_dx, y1+dz1_dy),
arrowstyle='simple', color='k', mutation_scale=10)
ax.add_patch(arrow)
feature_x = np.arange(-50, 50, 2)
feature_y = np.arange(-50, 50, 2)
x, y = np.meshgrid(feature_x, feature_y)
z = 0.5*(y-x)**2 + 0.5*(1-x)**2
u = 2*x - y - 1
v = y - x
# Normalize all gradients to focus on the direction not the magnitude
norm = np.linalg.norm(np.array((u, v)), axis=0)
u = u / norm
v = v / norm
fig, ax = plt.subplots(1, 1)
ax.set_aspect(1)
ax.plot(feature_x, feature_y, c='k')
ax.quiver(x, y, u, v, units='xy', scale=0.5, color='gray')
ax.contour(x, y, z, 10, cmap='jet', lw=2)
arrow = FancyArrowPatch((35, 35), (35+34*0.2, 35+0), arrowstyle='simple',
color='r', mutation_scale=10)
ax.add_patch(arrow) # NOTE: this gradient is scaled to make it better visible
我在这个图中添加了 line y = x
并标记了这条线与等高线相交的点。在这里你可以清楚地看到
那:
Gradients are orthogonal to level surfaces
所以对于你的观点 (80, 80)
梯度 (79, 0)
是正确的,即使等值线的一般形状可能表明 y-direction 中应该有一部分。
但是如果你沿着 y=x 线看,你会发现那里的梯度总是只在 x-direction.