秉着邊學邊寫邊折騰的原則,開始粗糙的工作。真正掌握還是得講解給別人聽。
先給出網課
https://www.icourse163.org/course/BIT-1001871001
Mayavi官方
http://docs.enthought.com/mayavi/mayavi/index.html
本來這個文章就是斷斷續續的,打算單開這一篇來寫一些實用的繪製實例。
如果篇幅長了,就會重開一篇,初步設想就是幾個例子一篇。
所以這篇是長期隨時更新的,不完結。
繪製一些好玩的圖。
1
*
擴展的實例。
前段時間剛開始接觸機器學習,(菜雞,你怎麼纔開始?啊對,就是菜雞,就是纔開始,萌新瑟瑟發抖。)
爲了更好地鞏固複習(現炒現賣)我決定,儘可能多做圖,採用Mayavi
,適當的matplotlib
,這裏
這是我想要的效果如下。(這個是網上偷的,我的圖下面,我只繪製了1/4)
1.繪製基本外形
1.設置下降起點,我選的(2,3,13),這個無所謂
2.mgrid
離散網格,利用r1 = 0.25*(x1**2+y1**2)
獲得網格高度r1
3.surf
分別繪製漸變的surface
和wireframe
,並選用熱辣的LUT配色方案'hot'
(我喜歡),然後細節上微調線徑寬度line_width=1.2
和opacity
兩種最好不一樣,我們需要強調的是網格,至於surface
只爲了突出它的值是變化的,hot~
4.修飾outline
方便觀察值域,xlable
這個稍微注意添加的位置,這裏添加的位置是surf
下,surf
是全局繪製
5.繪製一個起點points3d
6.設置figure
的bgcolor
,這裏是背景色。
start_x,start_y,start_z = 2,3,13 #下降起點
figure(bgcolor=(0.5,0.5,0.5))
x1,y1 = np.mgrid[0:3:15j, 0:3:15j] #離散不要太大,太密集不好觀察
r1 = 0.25*(x1**2+y1**2)
surf(x1,y1,r1,colormap='hot',opacity=0.2)
surf(x1,y1,r1,colormap='hot',line_width=1.2,opacity=0.4,representation='wireframe')
xlabel('x')
outline(color=(1,0,0),opacity=0.8)
x_start,y_start,z_start = np.array([start_x]),np.array([start_y]),np.array([start_z])*0.25
points3d(x_start,y_start,z_start,z_start,colormap="copper",name='StartPoint',scale_factor=.05)
2.上面的部分繪製了一個下降起點和具有誘惑的網格,現在繼續。
1.涉及符號計算
sympy
,做了必要的命名之後,diff()
進行求導,機器學習裏面的alp
學習速率,再一併設置迭代次數times
,這裏我只迭代10次。
2.中間的處理我不說了,都是計算
3.從points3d
開始繪製每次迭代之後產生的新的點,contour_surf
這次的用法唯一特殊在於contours
接受的是list,也就是以每個點所在的位置繪製等高線。quiver3d
也就是這篇文章的重點了,接受了6個參數,是對位置和三個方向的向量描述。最後,plot3d
把沿梯度下降的點連接起來。
theta0,theta1 = symbols('theta0,theta1')
f = theta0**2 + theta1**2
vector0,vector1 = f.diff(theta0),f.diff(theta1) #偏微
alp = 0.1 #下降速率
times = 10 #迭代次數
kx,ky = vector0.subs(theta0,start_x),vector1.subs(theta1,start_y)
list_x,list_y,list_z = [],[],[] #[start_x],[start_y],[start_z]
vect_x,vect_y,vect_z = [],[],[]
for ti in range(times):
kx,ky = vector0.subs(theta0,start_x),vector1.subs(theta1,start_y) #斜率
vect_x.append(float(-kx));vect_y.append(float(-ky));vect_z.append(-1)
start_x -= alp*kx;start_y -= alp*ky;start_z = (start_x ** 2 + start_y ** 2)*0.25 #按方向下降
list_x.append(float(start_x));list_y.append(float(start_y));list_z.append(float(start_z))
sca = [3 for num in range(times)]
points3d(list_x,list_y,list_z,sca,colormap='cool',name='GradientPoint',scale_factor=.04)
contour_surf(x1,y1,r1,contours=list_z,name='GradientContour',opacity=1)
quiver3d(list_x,list_y,list_z,vect_x,vect_y,vect_z,scale_factor=.1)
plot3d(list_x,list_y,list_z,sca,name='Connection',tube_radius=None,line_width=4.2)
show()
源碼我都貼出來了。也上傳了。
2.f(x,y)=(1−x)^2+100(y−x^2)^2
這圖不是我畫的,是別人家的圖
https://blog.csdn.net/pengjian444/article/details/71075544?utm_source=blogxgwz0&tdsourcetag=s_pcqq_aiomsg
.
.
.這個圖的代碼繪製是非常好寫的,這個圖原圖是採用的matplotlib
,先贊,做出來的圖漂亮得沒話說,印刷級的。
我們在Mayavi中重現它。
代碼原型很簡單,如下:
import numpy as np
from mayavi import mlab
x,y = np.mgrid[-3:3:40j,-1.5:3:40j]
z = (1-x)**2 + 100*(y-x**2)**2
mlab.surf()
mlab.show()
以上完成基本圖形。
但是注意了,mayavi中會按照原始比例作圖,z的值幾k,x,y是小數點級別的變化,你會得到一個長條。所以要進行修改。
爲了突出網格,
import numpy as np
from mayavi import mlab
#f(x,y)=(1−x)2+100(y−x2)2
x,y = np.mgrid[-2:2:60j,-1.5:3:60j]
z = (1-x)**2 + 100*(y-x**2)**2
z_max = np.max(z)
x_max = np.max(x)
adj_warp = x_max/z_max
sc = np.zeros_like(z)+1
# adj_warp = 0.0005
mlab.surf(x,y,z,vmax=130,vmin=0,representation='wireframe',name='Grid',warp_scale=adj_warp)
mlab.surf(x,y,z,vmax=130,vmin=0,opacity=0.4,warp_scale=adj_warp)
mlab.outline(color=(1,0,0))
mlab.show()
.
中間我將繼續追加梯度下降的繪製會在最後一步show()之前插入,然後會對這個圖形繼續進行修飾。
未更新完、
更新
2018.10.23. ——將原來寫在2.1.0.5.points3d,.quiver3d
下的一個舉例插過來、補充f(x,y)=(1−x)^2+100(y−x^2)^2