日期:2019/2/4
以下是將在三張小圖並列在同一張圖中的作法,部分內容與〈Matplotlib 繪圖技巧:在同一張圖上繪製兩個函數、兩張圖並列〉相似,但使用兩種不同的作法。這次要畫的圖形是在人工神經網路中常用的激勵函數 (activation function):
$$sigmoid:~~~~~f(x) = \frac{1}{1 + e^{-x}}$$
$$ReLU:~~~~~f(x) = \left\{\begin{matrix}
0 & \mathrm{for}~x < 0\\ x & \mathrm{for}~x \ge 0 \end{matrix}\right.$$ $$tanh:~~~~~f(x) = tanh(x)$$
三種激勵函數圖形
方法1: 用 subplot 切換繪圖位置
import matplotlib.pyplot as plt
import numpy as np
# 產生陣列x, sigmoid, relu, tanh
xmin, xmax, num = -6, 6, 200
x = np.linspace(xmin, xmax, num)
sigmoid = 1 / (1 + np.exp(-x))
# 不能寫成 relu = x, 這樣會改變 x 的數值
relu = x.copy()
relu[np.where(relu < 0)] = 0
tanh = np.tanh(x)
plt.figure(figsize = (12, 3), dpi = 72)
plt.subplots_adjust(left = 0.1, bottom = 0.2, right = 0.9, top = 0.9, wspace = 0.4, hspace = 0.1)
plt.subplot(131)
plt.plot(x, sigmoid, color = 'blue', linestyle = '-', linewidth = 3)
plt.xlabel('x', fontsize = 14)
plt.ylabel('f(x)', fontsize = 14)
plt.xlim(xmin,xmax)
plt.tick_params(axis = 'both', which = 'major', labelsize = 10)
plt.title('Sigmoid', fontsize = 14)
plt.grid('on')
plt.subplot(132)
plt.plot(x, relu, color = 'blue', linestyle = '-', linewidth = 3)
plt.xlabel('x', fontsize = 14)
plt.ylabel('f(x)', fontsize = 14)
plt.xlim(xmin,xmax)
plt.tick_params(axis = 'both', which = 'major', labelsize = 10)
plt.title('ReLU', fontsize = 14)
plt.grid('on')
plt.subplot(133)
plt.plot(x, tanh, color = 'blue', linestyle = '-', linewidth = 3)
plt.xlabel('x', fontsize = 14)
plt.ylabel('f(x)', fontsize = 14)
plt.xlim(xmin,xmax)
plt.tick_params(axis = 'both', which = 'major', labelsize = 10)
plt.title('tanh', fontsize = 14)
plt.grid('on')
plt.savefig('subplots.svg')
plt.savefig('subplots.png')
plt.show()
以下說明程式碼中較特別的部分
- 產生陣列 relu 時分為兩個步驟,先用 relu = x.copy() 將 x 的值複製給 relu,如果寫成 relu = x,之後變 relu 的數值時 x 的數值會跟著變化;接著再用 relu[np.where(relu < 0)] = 0 將小於 0 的元素都改成 0。
- 使用 plt.subplots_adjust 調整圖片的空間配置。
- 使用 plt.subplot 切換繪圖的位置,例如 (132) 代表整張圖中有 1 列、3 欄的小圖,目前繪製第 2 張圖。
方法2: 用 plt.subplots
import matplotlib.pyplot as plt
import numpy as np
# 產生陣列x, sigmoid, relu, tanh
xmin, xmax, num = -6, 6, 200
x = np.linspace(xmin, xmax, num)
sigmoid = 1 / (1 + np.exp(-x))
# 不能寫成 relu = x, 這樣會改變 x 的數值
relu = x.copy()
relu[np.where(relu < 0)] = 0
tanh = np.tanh(x)
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex = True, figsize=(12, 3), dpi = 72)
fig.subplots_adjust(left = 0.1, bottom = 0.2, right = 0.9, top = 0.9, wspace = 0.4, hspace = 0.1)
ax1.plot(x, sigmoid, color = 'blue', linestyle = '-', linewidth = 3)
ax1.set_xlabel('x', fontsize = 14)
ax1.set_ylabel('f(x)', fontsize = 14)
ax1.set_xlim(xmin,xmax)
ax1.tick_params(axis = "both", labelsize = 10)
ax1.set_title('Sigmoid', fontsize = 14)
ax1.grid('on')
ax2.plot(x, relu, color = 'blue', linestyle = '-', linewidth = 3)
ax2.set_xlabel('x', fontsize = 14)
ax2.set_ylabel('f(x)', fontsize = 14)
ax2.tick_params(axis = "both", labelsize = 10)
ax2.set_title('ReLU', fontsize = 14)
ax2.grid('on')
ax3.plot(x, tanh, color = 'blue', linestyle = '-', linewidth = 3)
ax3.set_xlabel('x', fontsize = 14)
ax3.set_ylabel('f(x)', fontsize = 14)
ax3.tick_params(axis = "both", labelsize = 10)
ax3.set_title('tanh', fontsize = 14)
ax3.grid('on')
fig.savefig('subplots.svg')
fig.savefig('subplots.png')
fig.show()
以下說明程式碼中較特別的部分
- 使用 fig, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex = True, figsize=(12, 3), dpi = 72) 產生繪圖物件 fig,其中共有 1 列、3 欄的小圖,3 張小圖的名稱依序為 ax1、ax2、ax3,並且 3 張小圖共用相同的 x 軸。
- 使用 ax1.plot(x, sigmoid, color = 'blue', linestyle = '-', linewidth = 3) 繪製第 1 張小圖,橫軸為 x,縱軸為 sigmoid,另外兩張小圖的繪圖方法相同,只需要修改縱軸資料即可。
參考資料
- plt.subplots_adjust: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots_adjust.html
- plt.subplots: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots.html
HackMD 版本連結:https://hackmd.io/s/S1RDRYNNN
這筆記太精美了,感謝!!
回覆刪除感謝您的留言,希望這篇文章能解決您的問題。
刪除