2018年5月27日 星期日

Python Deep Learning 深學筆記 - 梯度

←前一篇     後一篇→

梯度法(Thui-tōo huat)


一維个微分, 佇兩維以上, 就號做梯度 (Gradient).


一維微分較簡單了解意義, 咱毋才先用伊做例, 了解切線 (tangent line), 斜率 (slope), 和 f(x) 變化个趨勢个關係. 利用這个趨勢, 咱會用咧寬寬仔倚近上懸點抑是上低點.

啥乜是偏微分?

若是維度是 2 以上, 就愛利用偏微分 (partial differential), 一擺對其中一个變數微分, 比如講: 

f(x0, x1) = x0**2 + x1**2

咱會看伊的生張: 運行 meshplot-x2y2.py: (咱無欲深入了解按怎共伊畫出來, 若是對伊有興趣, 遮有一寡討論)

現此時 f(x0, x1) 有兩个變數, 佇一个點, 都愛分開: 先 x1 固定數字, 對 x0 微分一擺, 才閣固定 x0, 對 x1 微分(詳細个理論當然愛去上課, 咱遮先抾來用), 掠準咱佇 (5, 6) 這點:

對 x0 偏微分, 先共 x1 固定佇咧 6:

def function_tmp1(x0):
    return x0 ** 2 + 6 ** 2.0

對 x1 偏微分, 先共 x0 固定咧 5:


def function_tmp2(x1):
    return 5 ** 2 + x1 ** 2.0

這兩的合起來, 就成做 f 函式佇 (5, 6) 這點个微分, 咱佇記做:
                            

用 Python 來寫二維个偏微分

咱理解了後, 欲按怎寫二維个偏微分咧? 參考 gradient_2d.py 內面个 numerical_gradient():

def _numerical_gradient_no_batch(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    
    for idx in range(x.size):
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + h
        fxh1 = f(x) # f(x+h)
        
        x[idx] = tmp_val - h 
        fxh2 = f(x) # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val # 値を元に戻す
        
    return grad

共空逝算在內, 干焦 16 逝, 就會使做 2 維个數字微分 (numerical), 真奅!

佇遮, 輸入个參數兩个: f 是函式, x 是 numpy 陣列 (array). 這个 array 照理是 (x0, x1), idx == 0 是維度 0, idx == 1 是維度 2.咱用頭前个 (5, 6) 做例, x 就是 [x0=5, x1=6]. 你會使奕看覓, 使用 gradient_2d.py, 這个例, 起

python3 -m pdb gradient_2d.py

pdb 是 Python 个 debug module, 會使予你一步一步來掠蟲, 伊就是 Python 个 GDB, 你若是對 GDB 有熟, 伊對你就是零星个. 就算你袂曉, 你就照我紲落來寫个起字--落去就用得:

你看著:

-> import numpy as np
(Pdb)

表示你入去 pdb, 起 "b 59", 徙落去起 "l 58"

(Pdb) b 59
Breakpoint 1 at /..../deep-learning-from-scratch/ch04/gradient_2d.py:59
(Pdb) l 58
 53       x1 = np.arange(-2, 2.5, 0.25)
 54       X, Y = np.meshgrid(x0, x1)
 55   
 56       X = X.flatten()
 57       Y = Y.flatten()
 58   
 59 B     grad = numerical_gradient(function_2, np.array([X, Y]) )
 60   
 61       plt.figure()
 62       plt.quiver(X, Y, -grad[0], -grad[1],  angles="xy",color="#666666")#,headwidth=10,scale=40,color="#444444")
 63       plt.xlim([-2, 2])

(Pdb)

"b 59" 是叫伊踮 59 彼逝設擋點 (break point), "l 58" 只是予你看咱較實佇 59 有一个擋點.

紲落來, 起 "c", "interact":

(Pdb) c
> /.../deep-learning-from-scratch/ch04/gradient_2d.py(59)()
-> grad = numerical_gradient(function_2, np.array([X, Y]) )
(Pdb) interact
*interactive*
>>> 

"c" 是 continue, 就是叫程式起行, 伊會擋佇咧 59 逝, "interact" 是進入對話模式 (interactive mode), 這个咱會使用 numerical_graident() 和 function_2() 這个函式:

>>> numerical_gradient(function_2, np.array([5.0,6.0]))
array([ 10.,  12.])
>>> numerical_gradient(function_2, np.array([3.0,4.0]))
array([ 6.,  8.])
>>> numerical_gradient(function_2, np.array([0.0,2.0]))
array([ 0.,  4.])

咱看著 function_2 佇 [5, 6], [3, 4], [ 0, 2] 个梯度. 內面 [3, 4], [0, 2] 和書頂仔个答案仝款

使用 pdb, 就是我貧惰閣 copy numerical_gradient()/funcion_2 來做單元測試, 直接用 gradient_2d.py 寫便个來看伊的功能.

踮 gradient_2d.py 內面 numerical_gradient() 个疑問

佇課本伊的梯度圖是用 gradient_2d.py 共伊畫--出來:

圖看起來真媠嘛真合理: 箭頭較長的, 就是變動較大个, 上中方是上低點. 毋過, 我一直卡牢佇咧一个所在:

    X = X.flatten()
    Y = Y.flatten()
    
    grad = numerical_gradient(function_2, np.array([X, Y]) )

照道理, _numerical_gradient_no_batch 个第二个參數是 x 是 [x, y] 對, 佇遮就是 [ X, Y] 對, 分別對應著 x 杆, y 杆个值.

毋過佇 numerical_gradient() 呼 _numerical_gradient_batch() 个時,

def numerical_gradient(f, X):
    if X.ndim == 1:
        return _numerical_gradient_no_batch(f, X)
    else:
        grad = np.zeros_like(X)
        
        for idx, x in enumerate(X):
            grad[idx] = _numerical_gradient_no_batch(f, x)
        
        return grad

進前小節 用 Python 來寫二維个偏微分 咱使干焦使用

 numerical_gradient(function_2, np.array([5.0,6.0]))


是一維陣列, 伊的  X.ndim==1, 會行 if 彼个 case, 所以 X 是真正 (x, y), 一个 x 杆, 一个 y 杆, 傳入去 _numerical_gradient_no_batch(), 這無問題! (x0 對應著 X, x1 對應著 Y).


毋過, 因為這馬 X, Y 毋是孤一个數字, 是 array, 所致 X.ndim 會是 2, 行 else 這爿. 

若是經過 for idx, x in enumerate(X) 處理, 變成原在:

idx=0 是 原在个 X, 傳入去 _numerical_gradient_no_batch(function_2, X).
idx=1 是 _numerical_gradient_no_batch(function_2, Y)if 和 else 這兩條路線傳入去 _numerical_gradient_no_batch() 个參數意義無仝, 我踮遮就拍結矣!

我踮遮擋真久, 想袂通. 毋過, 無法度閣再拖落去, 就先共伊記錄起來, 後擺有機會才閣轉來解決一个問題!


2018年5月5日 星期六

Python matplotlib 欲按怎畫網仔圖 (Mesh plot)

佇做深學个筆記个時陣, 發現我畫袂出來 f(x0, x1) = x0**2 + x1**2 个圖, 所致家己揣資料來試看覓:

咱參考: meshplot-x2y2.py:


伊親像一个垂落來个網仔. 這个程式書頂仔無寫, 我是家己試--出來:


    x0 = np.arange(-3, 3, 0.1)
    x1 = np.arange(-3, 3, 0.1)
    X, Y = np.meshgrid(x0, x1)

    ## This is OK
    Z = X**2 +Y**2 

    ## This have errors
    # ValueError: shape mismatch: objects cannot be broadcast to a single shape
    # Z = function_2(np.array([X, Y])) 
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')

    surf = ax.plot_surface(X, Y, Z)
    plt.show()

總講一句: 用 np.meshgrid() 產生 X, Y 來做底蒂, 才共你的 z = f(x, y) 用落去, 就是這幾步:
    X, Y = np.meshgrid(x0, x1)
    ... 你的函式來生出 Z
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    surf = ax.plot_surface(X, Y, Z)

就會用之.

我拄著一个問題: 用 np.meshgrid(x0, x1) 轉出个 X, Y 無法度用咧咱寫好个 function_2. 毋過 Z = X**2 + Y**2 會使. 這當然是因為咱的 function_2 个寫法無支援, 聽候我有閒研究看按怎解較好勢!

2018年5月3日 星期四

Python Deep Learning 深學筆記 - 微分和揣上細值

←前一篇     後一篇→


微分(bî-hun)个觀念

微分个基礎觀念真簡單: 咱若有一个函式 y=f(x), 若是 x 變化真幼, 咱共伊標做 dx, 按呢 y 嘛綴 dx 變一點點矣, 咱共伊標做 dy, dy 親像這張圖:

y = f(x) 是一个函式, dy/dx 嘛是一个函式. in 兩的是啥物關係咧? 咱舉一个例: y = x**2, 這是真簡單个微積分, 咱先寫伊的表示:

def func_y(x):
     return x**2.0

紲落來, 欲按怎表示微分咧? 若是數學个微分理論, 愛處理連紲性(continuity) 和無限細个問題, 伊的答案號做解析 (analytic), 是完全正確--ê, 比如講: d(x**2)/dx = 2x, 就是解析. 伊佇 x = 0.5 个 dy/dx 就是 2*0.5 =1, 佇 x = 0 个 dy/dx 就是 2*0 = 0.

數值微分(Numerical differential)个觀念


若是電腦, 伊毋捌數彼款抽象思考, 數學家和電腦專家嘛發展出方法來處理微分, 彼就是數值微分(sòo-ta̍t-bî-hun). 咱用 Python 來奕看覓.

Python, 咱用一个真幼个數來逼倚, 比如講 1e-4 是 10 个負 4 次方:

def numerical_diff(f, x):
      h = 1e-4
      d =  (f(x+h) - f(x-h))/(2.0*h)
      return d

按呢共伊敆--起來:

#!/usr/bin/python3
def func_y(x):
    return x**2.0

def numerical_diff(f, x):
    h = 1e-4
    d =  (f(x+h) - f(x-h))/(2.0*h)
    return d

print(numerical_diff(func_y, 0.5))
print(numerical_diff(func_y, 0))

答案是:

0.9999999999998899
0.0

和 1 佮 0 精差是夭壽幼.  這款个方式, 號做數值微分 (numerical differentiation).

切線(tangent line) 和斜率 (slope)


佇 y=f(x), x=5 个彼點个微分, 就是彼个點个斜率 (tshiâ-lu̍t), 咱會使用彼斜率畫一條線迵過彼點, 這條線就是切線(tangent line), 咱來運行書頂的 ch04/gradient_1d.py, 伊的輸出是:

這的程式踮短短 31 逝, 就畫出一个函式佮伊的切線, 咱看伊的後半段:

def tangent_line(f, x):
    d = numerical_diff(f, x)
    print(d)
    y = f(x) - d*x
    return lambda t: d*t + y
     
x = np.arange(0.0, 20.0, 0.1)
y = function_1(x)
plt.xlabel("x")
plt.ylabel("f(x)")

tf = tangent_line(function_1, 5)
y2 = tf(x)

plt.plot(x, y)
plt.plot(x, y2)
plt.show()

函式 tagent_line(f, x) 是一个有影媠氣个寫法, 佇 4 逝就共函式 f 佇 x 點个切線函式生--出來. 伊利用一寡數學推算, 佮 lambda 這種 "生函式" 个方法.

閣紲落來就是使用 matplotlib.pylab 真勥(khiàng)个畫圖功能.

落梯法(lo̍h-thui-huat)


咱共這个函式小改一个, 親像這个程式: gradient_x2.py:

我予伊畫三條切線出來, 佇 x=5 伊的斜率是正个, x=0 伊的斜率拄拄好是 0, 佇 x=-5 伊的斜率是負个. 咱若是凊彩揣一點 x 想欲揣 f(x) 的上細值, 也就是 0 的所在, 欲按怎做咧?

咱會使那呢想: 斜率正个彼點, 咱 x 就向倒爿行. 斜率負个彼點, 咱就向正爿行, 若是伊有上細值, 伊的斜率就會那來若接近 0, 這就是上細點. 這種方法, 號做落梯法(gradient descent method).

共這个想法成做算式:

x = x - lr * df/dx

這就是逐擺 x 愛徙落去个下一步. 斜率正, df/dx > 0, 負號予 -n*df/dx 變細向倒爿. 斜率負 df/dx < 0, -n*df/dx 負負得正向正爿. n 是咱愛斟酌揀个一个數字, 傷大佮傷細攏會歹收縮. 咱用tha̍h-拄仔个 y=0.01*x**2 來做例, 參考: gradient_1_descent.py:

def gradient_descent(f, init_x, lr=0.1, step_num=10000):
    x = init_x

    for i in range(step_num):
        grad = numerical_diff(f, x)
        x -= lr * grad
    return x, f(x)


x1, y1 = gradient_descent(function_1, 10)
print(x1, y1)
x1, y1 = gradient_descent(function_1, -10)
print(x1, y1)

伊的結果是:
2.0202860902402727e-08 4.0815558864183276e-18
-2.0202860902402727e-08 4.0815558864183276e-18

雖然無仝, 毋過攏是倚 0, 彼差別幼微个程度, 會使共伊當做無差別.


2018年4月14日 星期六

Python Deep Learning 深學筆記 - 損失函式


←前一篇     後一篇→

損失函式(Loss function)是用來計算神經網路个輸出, 到底精差偌濟? 凡勢無仝个應用, 愛揀無仝个損失函式. 譬如講, 認聲音裡个字, 和認圖裡个數字, 損失函式無仝. 這嘛和輸出棧个樣有關係. 你欲認 0~9 十个數字, 和欲認人面, 嘛是無相siâng.

現此時佇這本冊的例是用認捌 0~9 做例, 伊的輸出棧是 10 粒神經元, 逐粒代表一个數字, 咱就先就這个例來紹介.


均方誤差 (Mean squared error)

這是上蓋出名的損失函式, 伊的數學算式是:

佇遮 y 是神經網路輸出, t 是訓練資料. k 是維度. 咱佇咧遮有 0~9 十个輸出, 伊的維度就是 10.
咱先轉去看進前彼篇的例:ch03/neuralnet_mnist.py, 共伊小改一个來共伊的過程看予斟酌:

import sys, os
sys.path.append(os.pardir)  # 設 module 搜揣路草
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax


def get_data():
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
    return x_test, t_test


def init_network():
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network


def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)

    return y


x, t = get_data()
network = init_network()

for i in range(100):
    y = predict(network, x[i])
    print(list(map(lambda x:round(x,1), y)))


伊會印出逐擺資料的輸出結果. 因為這是訓練好的資料, 所以大部份攏是 0, 正確的答案伊會真接近 1, 但是咱有時嘛會看著:

[0.0, 0.0, 0.0, 0.0, 0.40000001, 0.0, 0.0, 0.0, 0.0, 0.5]
[0.0, 0.0, 0.2, 0.69999999, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0, 0.89999998, 0.1, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.60000002, 0.0, 0.0, 0.0, 0.2, 0.1, 0.0, 0.0]

若是抑袂訓練好, index 0~9 就會攏有數字, 咱揀一兩个來算伊的均方誤差:

import numpy as np
def mean_squared_error(y, t):
    return 0.5 * np.sum((y-t)**2)

y1 = [0.0, 0.0, 0.2, 0.69999999, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
t1 = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
y2 = [0.0, 0.0, 0.0, 0.0, 0.89999998, 0.1, 0.0, 0.0, 0.0, 0.0]
t2 = [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]

print(mean_squared_error(np.array(y1), np.array(t1)))
print(mean_squared_error(np.array(y2), np.array(t2)))

伊的結果是:
0.065000003
0.010000002

愈細表示愈接近正確的答案, 佇遮, y2 較倚!

Khu-ló-sù Én-tso-phì 精差 (Cross Entropy Error)

Cross Entropy Error 是另一个四常用个損失函式, 伊的公式是按呢:


咱先來看 y = log(x) 个圖生做啥乜款?

#!/usr/bin/python3
import numpy as np
import matplotlib.pylab as plt

x = np.arange(-0.0, 1.0, 0.001)
delta = 1e-7
y = np.log(x + 1e-7) 
plt.plot(x, y)
plt.ylim(-5, 0)    # siat-tīng y kuainn ê huān-uî
plt.show()

運行這个程式, 出現:



log(1) 是 0, x < 1 是負數, 愈接近 0, 伊就負愈大. log(0) 是毋成數, 窮實, 伊是負个無限大, 咱共伊標做 -inf. 毋過, 這電腦無法度算落去, 咱共伊添一个 1e-7 這个微微仔數來閃過這个問題.

若是看 croess entropy error 本身: 若是完全對同, 比如講 3, t3 會是 1, 賰的 t0~t2, t4~t9 攏是 0, 所致成做 E = -t3 * log(y3), log(1)=0, E 是 0 表示完全無精差.

咱來計算看覓頭前个例:

#!/usr/bin/python3
import numpy as np
def cross_entropy_error(y, t):
    delta = 1e-7
    return -np.sum(t * np.log(y+delta))

y1 = [0.0, 0.0, 0.2, 0.69999999, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
t1 = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
y2 = [0.0, 0.0, 0.0, 0.0, 0.89999998, 0.1, 0.0, 0.0, 0.0, 0.0]
t2 = [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]

print(cross_entropy_error(np.array(y1), np.array(t1)))
print(cross_entropy_error(np.array(y2), np.array(t2)))


伊的輸出:
0.356674815367
0.105360426769

伊的值, 和均方差無仝, 毋過猶原是 y2 較接近.

批次學習

到今, 咱討論ê是一擺訓練个誤差有偌大. 若是開始訓練, 咱會揀一批一批, 一批訓練了, 才規批來算伊有偌準, 所致:


就是共 N 个攏加--起來, 才閣分做 N 來平均. 紲落來 ê 問題是: 欲按怎 <凊彩> 揀 N 出來咧?

若以 MNIST 有 60000 筆資料, 咱一擺揀 100 筆來訓練, N 是 100. Numpy 有一个 random.choice() 函數, 會使共咱鬥做這个 '凊彩揀' 个工課:

batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_maskmask]
t_batch = y_train[batch_mask]

train_size=600000, batch_size=100, batch_mask 是 10 个元素的 Numpy array, 逐个元素攏是 0~60000 个數字. 閣利用進前 Numpy array 索引 (Fancy indexing), 真輕可就共欲挃个物捎--出來.


 伊的 cross_entropy_erorr(y, t) 就愛修改:

def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
    batch_size = y.shape[0]
    return -np.sum(t * np.log(y)) / batch_size

這 if y.ndim == 1 所做的 reshape, 是 Numpy array 个一个鋩角, 你若毋知, 會使去, 搜揣 <鋩角> 兩字就知.

按呢修改, 伊就仝時支援 "干焦一筆資料" 和 "濟筆資料". 為啥物? 因為濟筆資料, 伊是成做 2 維陣列, 逐个列 row 是一筆資料. 干焦一筆 y.ndim==1, 100 筆 y.ndim == 100. Numpy array 个運算攏是逐个元素相對同 (element-wise), 所致, 一擺就攏算好阿. np.sum() 也是一改就攏總加--起來



方法確定了後, 就是訓練个循環:

  1. 揀一批資料, 共資料飼予咱的神經網路, 算看覓伊的平均誤差是偌濟? 
  2. 閣修正 W 這个陣列
  3. 閣揀另外一批資料, 轉去 1, 看誤差有變較細--無?

紲--落來, 欲按怎予 W 佇咧調整个過程中方, 愈來愈倚正確个答案, 也就是損失函式愈來愈細? 這就愛uì微分个觀念開是講起!




2018年4月1日 星期日

Python Deep Learning 深學筆記 - 予神經網路學習

←前一篇     後一篇→

你若是這个系列對頭開始讀到今, 算是到一个崁站: 咱進前講个攏是神經網路的基本結構. 佇頂一篇, 咱展現這个結構, 會使認个出來 MNIST 資料集裡的數字. 閣紲落來, 欲介紹个是: 欲按怎共咱的神經網路牽教, 予伊學習咧?

用資料學習


咱人个學習, 上直接就是不斷的刺激, 反應, 修正. 你敢知ê你家己个神經按怎去調整伊家己? 毋知, 你就是目睭看世界, 咱共你講彼是啥, 你就記起來. 咱講彼个聲是啥, 你共伊記咧.
佇神經網路, 若是決定好幾棧, 逐棧个數目, 欲按怎輸入和輸出, 賰的問題就是決定伊的權重 W1, W2, W3, ... 个數字. 你無法度一个一个家己指定, 你愛用攢好个資料飼--伊, 看伊反應按怎, 予伊家己修正 W1, W2, .. 這寡權重.

這寡資料咱事先攏有正確的答案, 會使和伊的回答做比較, 一方面看伊學習个成果, 一方面嘛是看紲落來欲修正个方向.
若是捌學過控制理論, 對這種圖一定真熟:






這是一種經典的 feedback (closed-loop) 的概念圖. 雖然伊是用佇電子電路, 毋過伊的概念是天跤下共通个.

咱共小改一个, 予伊用佇神經網路頂懸:


這馬, 咱就注心佇咧揣出 E 欲按怎來改變 W 个原理和方法.
一開始, 咱愛揣出方法來算出輸出佮正確答案到底是偌倚? 咱愛有一个數學/函式, 會使算出个客觀數字, 這佇神經網路是損失函式(Loss Function).
紲落來, 欲按怎改變 W 咧? 這就是愛用著微積分(Bî-tsik-hun) 个觀念



2018年3月3日 星期六

佇 Ubuntu Artful 17.10 頂仔安裝 rubyripper


因端

我慣勢佇 CD 買--轉來了後, kā 伊內底个歌掠出來, 轉做 MP3 抑是其他个格式, 成做家己个資料庫 (database), 才閣捒起雲頂, 親像 Google Music, 按呢生我用手機就會使隨時聽.

往過我攏是用 itune 來轉. 這當然是因為 Apple 自 ipod 開始, 就是隨身音樂的領導者, itune 嘛誠實好用, 伊 uì 掠音軌, 轉檔, 輸入歌个資料, 親像歌名, 作詞者, 專輯名,甚至專輯封面, 攏真好勢用.

毋過對我來講, 唯一麻煩 ê 所在是: 伊無出 Linux 版本. 較早我攏是開 Virtual Box 安裝窗仔門(Windows), 才佇窗仔門頂仔安裝 itune.

毋過, 近--來 itune 佇 Windows 10 頂仔安裝起來煞袂開--得. 掠規半晡掠無摠. 想講應該離搜揣 Linux 頂懸 ê 物件來取代.

需求

我的需求
  • 會當轉出 MP3, 抑是無失真个格式
  • ài支援 id3v2 版本的 mp3 tag
  • ài 支援圖片來做封面
  • ài 支援 batch process
  • 上好是會使 uì 雲頂个 database 直接掠著歌曲ê資料

Rubyripper


我搜揣ê結果, sound-jucier 會使掠, 毋過 mp3 ê tag 傷簡單. 看--來, 掠 CD 音樂 ê 程式和轉檔ài分開. 而且, uì 網路頂仔 ê 討論, 掠 CD 音軌个品質嘛真重要, uì Ubuntu Community CD Ripping ê 討論看--來, Rubyripper 是真濟論壇(lūn-tuânn) 推薦个軟體. 

毋過, ubuntu 个程式資料庫 (repository) 無收 Rubyripper. 所以咱無法度用 apt 輕輕鬆鬆來安裝.

紲--落來, 看有法度揣著捌人款好个包袱仔(package) deb 檔, 若按呢, 咱嘛會使用 dpkg 來安裝(an-tsong). 毋過 uì 伊的官方網站搝(giú)--落來个 deb, 煞傷舊, 裝袂--起來. 紲落尾个辦法, 就是家己 uì 原始碼來起造 (build).


欲按怎 build Rubyripper

首先, uì github kā source code 搝落來:

$ git clone https://github.com/bleskodev/rubyripper.git

紲--落來, 愛安裝起造 binary 需要个包袱仔 (dependent pacakges). 佇 ubuntu 17.10 artful 這个環境中方, 我是按呢做:

$ sudo apt install cdparanoia ruby ruby-gettext ruby-gtk2 cd-discid flac  lame wavpack sox \
cdrdao libcdio-utils vorbisgain ruby-gnome2

行看 ./configure 來看欠啥乜物件:

$ cd rubbyripper
$ ./configure --enable-gtk2 --enable-cli --enable-lang-all


CHECKING FORCED DEPENDENCIES

cdparanoia: [OK]

CHECKING OPTIONAL DEPENDENCIES

ruby-gtk2: [OK]
ruby-gettext: [OK]
discid: [NOT OK]
You won't have accurate freedb string calculation unless Cd-discid is installed.
cd-discid: [OK]
eject: [OK]
flac: [OK]
vorbis: [OK]
lame: [OK]
wavegain: [NOT OK]
You won't be able to replaygain WAVE files.
vorbisgain: [OK]
mp3gain: [OK]
normalize: [NOT OK]
You won't be able to normalize audio files.
cdrdao: [OK]
cd-info: [OK]
ls: [OK]
diskutil: [NOT OK]


Creating the Makefile...
A summary of your settings:

Using the following locations for install:
* Executables: /usr/local/bin
* Localization files: /usr/local/share/locale
* Icon file: /usr/local/share/icons/hicolor/128x128/apps
* Desktop file: /usr/local/share/applications
* Library files: /usr/local/lib/rubyripper

Gtk2 frontend will be installed
Cli frontend will be installed
Languages to be installed: nl, de, fr, hu, ru, es, se, bg, it, da

You can now run make install
Make sure you've got the writing privileges

佇遮, 我是盡量予 [NOT OK] 成做 [OK], 若無, 可能有一寡功能會無正常. 若是欲像我連 mp3gain 嘛 OK, 閣愛裝:

$ sudo add-apt-repository ppa:flexiondotorg/audio
$ sudo apt update
$ sudo apt install mp3gain aacgain

因為 Ubuntu Artfulmp3gain, 所以咱愛 uì 捌人抾好个所在去捎. 這步做了, 閣愛行一擺 ./configure.

落尾, 就是來 build 閣安裝囉!

$ sudo make install

這馬, 你會使起行, 伊有兩種介面: 圖形 (GUI) 和命令列 (CLI), 分別是 rrip_guirrip_cli, 咱開 rrip_gui 看覓:


起行了後,  kā 音樂 CD 囥入去, 揤 Scan drive, 伊就會顯示幾塊歌. 較拍損个是: 伊去 freedb 掠歌个資訊, 是掠無. 所以就愛家己共伊添入去, 閣揤 Rip cd now, 伊就開始kā音軌抽出來囉!


欲轉做啥乜格式?

伊預設是 Vorbis. 你若是欲用捌種, 愛去 Preferences->Codecs->Active audio codecs 設定.

伊支援 mp3, aac, 和 flac 編碼. 我佮意用 flac, 佇 Active audio codecs kā flac 揤 "加入" 添入去, 若無用 Vorbis, 就揤 "移除" kā 伊徙掉就好阿!


欲按怎調整加入封面咧?

這愛和另外个程式配合. easytag 和 kid3 攏袂䆀. 我是較佮意 kid3, 因為伊會使 batch process

2018年1月17日 星期三

Python Deep Learning 深學筆記 - 訓練好个神經網路

←前一篇     後一篇→


佇遮, 咱欲結合學著 ê 神經網路智識, 來認捌前一篇所介紹 ê MNIST 資料集.

一个完整 ê 神經網路智識, 愛有 "學習" 佮 "推論" 兩个階段, 就敢若咱人若是欲會曉一種技術, 嘛是愛先學習, 出師了後, 才開始展工夫. 毋過, 這篇, 干焦有展工夫予你看. 這个神經網路已經訓練好阿. 原作者佇遮, 想欲展示予咱看會是: 咱進前介紹 ê 三棧神經網路, 予伊有夠濟个神經元, 用咱學過 ê Mé-thuì Dot 運算, 閣有定義好个戛火函數, 伊是有法度認捌 MNIST 內底ê資料集--ê.

Python Pickle 功能 ê 介紹

PicklePython ê module, 若是看伊英文說明: "The pickle module implements binary protocols for serializing and de-serializing a Python object structure.", 伊是 kā Python ê 物件 (object) 成做二元 ê 資料水(註1, 看下跤) (serial data stream).  按呢抑是誠抽象.

咱來做一个比喻: 物件 (object) 你會當想做一个立體, 有佔著空間 ê 物件, 親像棉襀被, 椅仔, .... 若是有一个奇術師, 有一條長長 ê 水管, 伊會當 kā 棉襀被硩扁, 縮小, uì 水管頭櫼入去. 紲落來, 嘛 kā 椅仔櫼入去, 紲落來啥乜 li-li-khok-khok 攏照順序櫼入去....

按呢, 立體 ê 物件變做無維度 (dimension) 抑就是無結構 (structure), 敢若親像水佇水管裡排隊, 這就是
資料水 (serial data stream).

會使變做資料水, 當然嘛愛會使變轉來, 若無這个魔術師就失業囉! 變做資料水 ê 過程號做 serializing, 變轉來 ê 過程號做  de-serializing.

講到遮你若是閣霧嗄嗄嘛bua̋i 緊. Pickle ê 意思是 "泡菜/醬菜/豉ê物", 就是會使囥真久袂歹去. 所以  Pickle 就會使予咱用內囥一寡咱做到一半 ê 資料, 先儉起來, 欲食才提出來.

咱進前講个, 這个神經網路, 已經訓練好阿, 作者就先用 Pickle ê 形式儉起來, 咱就 kā 豉好个"泡菜" 提出來食就好阿.

 MNIST ê 推論網路

這愛用著作者 ê 例, 佇前一篇已經有講按怎去 github 掠伊的例, 佇 ch03/neuralnet_mnist.py:

import sys, os
sys.path.append(os.pardir)  # 設 module 搜揣路草
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax


def get_data():
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
    return x_test, t_test


def init_network():
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network


def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)

    return y


x, t = get_data()
network = init_network()
accuracy_cnt = 0
for i in range(len(x)):
    y = predict(network, x[i])
    p= np.argmax(y) # 揣 y 內底上大, 也都是機率上大--ê
    if p == t[i]:
        accuracy_cnt += 1

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
                                                                                                                                                              44,1         底端

get_data() 佇前一篇介紹, 就是去 kā MNIST 捎--入來.

init_network() 就是 kā 咱事先做好个神經網路, 囥佇 ch03/sample_weight.pkl 掠轉來.

predict() 伊个樣都和咱佇 Python 實作 3 棧 ê 神經網路 ê 樣欲相sia̋ng 阿相 siâng. 你看伊嘛是三棧 ê 網路 毋過, 伊 ê 輸入有 784 ê  神經元, 輸出有 10 ê 神經元. 中方藏兩棧, 這隱藏 ê 頭一棧是  50 个神經元, 第二棧是 100 个神經元.

for i in range(len(x)):
    y = predict(network, x[i])
    p= np.argmax(y) # 揣 y 內底上大, 也都是機率上大--ê
    if p == t[i]:
        accuracy_cnt += 1

這个 for loop, kā 測試 ê 資料用  predict() 來臆, 咱个 10 ê 輸出神經元, 對應到 0~9  十 ê 數字, 佗一个 ê 機率上大, 就是伊--阿. 才閣和答案 t[i] 比看著抑是毋著

這是佇我的電腦ê運行結果:

$ python3 neuralnet_mnist.py 
Accuracy:0.9352

佮書上仝款. 0.9352 就是正確率 93.52%.

電腦就是電腦, 訓練煞就袂改變. 咱人有可能彼工心情無好結果會變無仝.

你看, 生做攏仝款 ê 神經元, 經過訓練, 就會認 0~9 ê 圖片. 訓練是改變啥物咧? 就是神經網路 ê  權重 W, 佇遮是 W1, W2, W3. 欲按怎調整 W1, W2, W3? 這就是神經網路 ê 手路, 咱就愛繼續看落去!

註1: 定定聽序大人講 "錢水活", 表示華語講个 "金流很大". "水" 這个字佇台語, 本底就有 "流" ê 意思. 和英文 ê flow/stream, ê 意思嘛真合. 當然, 你欲添一 ê "流" 也是會使啦!

←前一篇     後一篇→

佇 Linux 來看GPX 檔案

最近定定有戶外活動。使用𤆬路機 (GPS) 來記錄行過的路線。普通我記錄路線,攏是用手機仔抑是專門个𤆬路機,罕得用電腦來看。 毋過,"仙人拍鼓有時錯,跤步踏差啥人無"。有一擺我無細膩,袂記得共一擺活動的路線收煞起來,閣直接開始記錄下一擺的活動,按呢共幾落...