前言
先舉個機器學習的應用例子:圖片的風格轉換。
機器學習
通過計算機強大的計算能力進行迭代運算、試錯得到相關知識。
形象生動的描述請看:機器學習
深度學習
上圖是一個網(wǎng)絡神經(jīng)示意圖,左邊的是輸入層,最右邊的是
輸出層
,兩層之間的叫隱藏層
,隱藏層大于2的神經(jīng)網(wǎng)絡就叫深度神經(jīng)網(wǎng)絡,深度學習就是基于深度神經(jīng)網(wǎng)絡的機器學習,深度學習是機器學習中的一種。
深度學習的相關概念
1、感知器
2、線性單元和梯度下降
3、神經(jīng)網(wǎng)絡和反向傳播算法
4、卷積神經(jīng)網(wǎng)絡
一、感知器
1、輸入權值:
x1,x2...是值,w1,w2....是權重。
2、激活函數(shù) :
這里舉個最簡單的例子,采用階躍函數(shù)
輸入權值,經(jīng)過激活函數(shù)后就是0或1。
3、輸出:
感知器就是通過輸入的權重與值,經(jīng)過激活函數(shù)預算,再通過輸出公式得出結果
二、線性單元和梯度下降
1、什么是線性單元
激活函數(shù)為線性函數(shù)的感知器就叫做線性單元。
當面對的數(shù)據(jù)集不是線性可分的時候,『感知器規(guī)則』可能無法收斂,所以我們用可導的線性函數(shù)來替代感知器的激活函數(shù),例如f(x) = x
之后,線性單元將返回一個實數(shù)值而不是0,1分類。因此線性單元用來解決回歸問題。
2、監(jiān)督學習和無監(jiān)督學習
機器學習有一類學習方法叫做監(jiān)督學習,它是說為了訓練一個模型,我們要提供這樣一堆訓練樣本:每個訓練樣本即包括輸入特征x,也包括對應的輸出y(y也叫做標記,label)。也就是說,我們要找到很多人,我們既知道他們的特征x(工作年限,行業(yè)...),也知道他們的收入y。我們用這樣的樣本去訓練模型,讓模型既看到我們提出的每個問題(輸入特征x),也看到對應問題的答案(標記y)。當模型看到足夠多的樣本之后,它就能總結出其中的一些規(guī)律。然后,就可以預測那些它沒看過的輸入所對應的答案了。
另外一類學習方法叫做無監(jiān)督學習,這種方法的訓練樣本中只有x而沒有y。模型可以總結出特征x的一些規(guī)律,但是無法知道其對應的答案y。
3、線性單元的目標函數(shù)
模型的訓練,實際上就是求取到合適的w,使誤差E取得最小值。這在數(shù)學上稱作優(yōu)化問題,而就是我們優(yōu)化的目標,稱之為目標函數(shù)
4、梯度下降優(yōu)化算法
梯度是一個向量,它指向函數(shù)值上升最快的方向,梯度的反方向當然就是函數(shù)值下降最快的方向.沿著梯度相反方向去修改x的值,進行迭代獲得最小值。
首先我們選擇一個點開始,x0,接下來迭代x1,x2,x3..一直到函數(shù)最小值。
梯度下降算法的公式如下:
三、神經(jīng)網(wǎng)絡和反向傳播算法
神經(jīng)元
神經(jīng)元就是激活函數(shù)或tanh函數(shù)的感知器。
多個神經(jīng)元構成神經(jīng)網(wǎng)絡
神經(jīng)網(wǎng)絡的輸出
神經(jīng)網(wǎng)絡實際上就是一個輸入向量x(向量,不是普通的變量,具有方向)到輸出向量y的函數(shù),即:
反向傳播算法(Back Propagation)
我們需要知道一個神經(jīng)網(wǎng)絡的每個連接上的權值是如何得到的。我們可以說神經(jīng)網(wǎng)絡是一個模型,那么這些權值就是模型的參數(shù),也就是模型要學習的東西。然而,一個神經(jīng)網(wǎng)絡的連接方式、網(wǎng)絡的層數(shù)、每層的節(jié)點數(shù)這些參數(shù),則不是學習出來的,而是人為事先設置的。對于這些人為設置的參數(shù),我們稱之為超參數(shù)(Hyper-Parameters)。而我們需要做的是通過算法對神經(jīng)網(wǎng)絡進行訓練,反向傳播算法是神經(jīng)網(wǎng)絡訓練算法。
計算一個節(jié)點的誤差項,需要先計算每個與其相連的下一層節(jié)點的誤差項。這就要求誤差項的計算順序必須是從輸出層開始,然后反向依次計算每個隱藏層的誤差項,直到與輸入層相連的那個隱藏層。這就是反向傳播算法的名字的含義,最后我們可以通過計算出的誤差反過來修正權重。
就這樣,通過不斷迭代,不斷修正權重對神經(jīng)網(wǎng)絡進行訓練。
四、卷積神經(jīng)網(wǎng)絡
適合圖像、語音識別任務的神經(jīng)網(wǎng)絡結構——卷積神經(jīng)網(wǎng)絡
1、Relu激活函數(shù)
在卷積神經(jīng)網(wǎng)絡中Relu函數(shù)更為適合作為激活函數(shù),公式如下:
Relu函數(shù)圖像如下圖所示:
采用Relu函數(shù),有以下優(yōu)點:
速度快
減輕梯度消失問題
稀疏性
2、卷積神經(jīng)網(wǎng)絡
一個卷積神經(jīng)網(wǎng)絡由若干卷積層、Pooling層、全連接層組成
我們可以發(fā)現(xiàn)卷積神經(jīng)網(wǎng)絡的層結構和全連接神經(jīng)網(wǎng)絡的層結構有很大不同。全連接神經(jīng)網(wǎng)絡每層的神經(jīng)元是按照一維排列的,也就是排成一條線的樣子;而卷積神經(jīng)網(wǎng)絡每層的神經(jīng)元是按照三維排列的,也就是排成一個長方體的樣子,有寬度、高度和深度
實踐應用:
一、通過深度學習對圖片進行風格轉換
原圖與名畫合成新圖片:
主要的流程是:利用Caffe框架進行深度學習,通過梯度算法,完成顏色、線條等的訓練集,然后對圖片進行重繪。
1、框架、依賴等準備
(1)、安裝python、pip、numpy。
(2)、安裝深度學習框架caffe
(3)、下載訓練模型:我采用的是googlenet model
(4)、下載style-transfer代碼,根據(jù)自己的需求進行修改、優(yōu)化。
(5)、根據(jù)style-transfer文檔運行。
這幾個步驟操作起來都是比較困難的,也算是個不小的門檻。其中Caffe的安裝瑣碎,會出現(xiàn)很多意外,是個大難題;style-transfer代碼修改是最核心的部分。
2、核心代碼展示
梯度處理代碼:
def _compute_style_grad(F, G, G_style, layer):
(Fl, Gl) = (F[layer], G[layer])
c = Fl.shape[0]**-2 * Fl.shape[1]**-2
El = Gl - G_style[layer]
loss = c/4 * (El**2).sum()
grad = c * sgemm(1.0, El, Fl) * (Fl>0)
return loss, grad
def _compute_content_grad(F, F_content, layer):
Fl = F[layer]
El = Fl - F_content[layer]
loss = (El**2).sum() / 2
grad = El * (Fl>0)
return loss, grad
矩陣計算
def _compute_reprs(net_in, net, layers_style, layers_content, gram_scale=1):
(repr_s, repr_c) = ({}, {})
net.blobs["data"].data[0] = net_in
net.forward()
for layer in set(layers_style)|set(layers_content):
F = net.blobs[layer].data[0].copy()
F.shape = (F.shape[0], -1)
repr_c[layer] = F
if layer in layers_style:
repr_s[layer] = sgemm(gram_scale, F, F.T)
return repr_s, repr_c
進行轉換:
def transfer_style(self, img_style, img_content, length=512, ratio=1e5,
n_iter=512, init="-1", verbose=False, callback=None):
# assume that convnet input is square
orig_dim = min(self.net.blobs["data"].shape[2:])
# rescale the images
scale = max(length / float(max(img_style.shape[:2])),
orig_dim / float(min(img_style.shape[:2])))
img_style = rescale(img_style, STYLE_SCALE*scale)
scale = max(length / float(max(img_content.shape[:2])),
orig_dim / float(min(img_content.shape[:2])))
img_content = rescale(img_content, scale)
# compute style representations
self._rescale_net(img_style)
layers = self.weights["style"].keys()
net_in = self.transformer.preprocess("data", img_style)
gram_scale = float(img_content.size)/img_style.size
G_style = _compute_reprs(net_in, self.net, layers, [],
gram_scale=1)[0]
# compute content representations
self._rescale_net(img_content)
layers = self.weights["content"].keys()
net_in = self.transformer.preprocess("data", img_content)
F_content = _compute_reprs(net_in, self.net, [], layers)[1]
# generate initial net input
# "content" = content image, see kaishengtai/neuralart
if isinstance(init, np.ndarray):
img0 = self.transformer.preprocess("data", init)
elif init == "content":
img0 = self.transformer.preprocess("data", img_content)
elif init == "mixed":
img0 = 0.95*self.transformer.preprocess("data", img_content) + \
0.05*self.transformer.preprocess("data", img_style)
else:
img0 = self._make_noise_input(init)
# compute data bounds
data_min = -self.transformer.mean["data"][:,0,0]
data_max = data_min + self.transformer.raw_scale["data"]
data_bounds = [(data_min[0], data_max[0])]*(img0.size/3) + \
[(data_min[1], data_max[1])]*(img0.size/3) + \
[(data_min[2], data_max[2])]*(img0.size/3)
# optimization params
grad_method = "L-BFGS-B"
reprs = (G_style, F_content)
minfn_args = {
"args": (self.net, self.weights, self.layers, reprs, ratio),
"method": grad_method, "jac": True, "bounds": data_bounds,
"options": {"maxcor": 8, "maxiter": n_iter, "disp": verbose}
}
# optimize
self._callback = callback
minfn_args["callback"] = self.callback
if self.use_pbar and not verbose:
self._create_pbar(n_iter)
self.pbar.start()
res = minimize(style_optfn, img0.flatten(), **minfn_args).nit
self.pbar.finish()
else:
res = minimize(style_optfn, img0.flatten(), **minfn_args).nit
return res
二、其他比較出名的應用:
1、谷歌的deepdream:可以讓你的機器自己做夢。
2、雅虎的色情圖片檢測神經(jīng)網(wǎng)絡:效果不知道,千萬不能結合爬蟲去爬圖片,違法的。