如何在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,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)

Contour Plot with Arrow 否则,如果要绘制整个矢量场quiver,则可以选择:

feature_x = np.arange(-50,50,2)
feature_y = np.arange(-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,z,10,cmap='jet',lw=2)

arrow = FancyArrowPatch((35,35),(35+34*0.2,35+0),color='r',mutation_scale=10)  
ax.add_patch(arrow)  # NOTE: this gradient is scaled to make it better visible

Gradient Field

我在该图中添加了line y = x,并标记了这些线与轮廓线相交的点。在这里你可以清楚地看到

渐变与水平面正交

因此,对于您的点(80,80),坡度(79,0)是正确的,即使等值线的一般形状可能表明在y方向上也应该有一部分。 但是,如果沿着y = x线看,您会发现那里的渐变总是只在x方向上。