這是這段時間學校裡一直在忙的事情,由於專業的原因,並未接觸到太多關於neural network的知識,所以作為神經網路的初學者,走了很多彎路花了很多功夫,今天在這裡寫出來給大家做乙個參考,避免以後如果有孩子碰到類似的問題苦苦尋求解決辦法還得不到,只能自己去鑽研,費時費力。
這個神經網路算是比較基礎的神經網路,在閱讀我朋友的demo之後及他的幫助下最終實現了我的相關要求。
在運籌學這門學科中,乙個典型的問題就是任務/資源分配問題,也就是說,我們需要將某幾項任務分配給某幾個人去完成,每乙個人完成一項任務其對應有最小代價(例如時間)或者最大收益等(這要依據實際情況而定),我們的目標也就隨之產生——即最小或最大化目標函式(代價/或收益)。以下給出其數學表達:
人們從很早就開始研究相關問題的演算法,由於重點會放在神經網路的搭建上,所以現在我們直接給出匈牙利演算法且不再多做介紹,具體的流程及相關介紹請移步度娘或wikipedia。匈牙利演算法可以直接求出任務與待分配人數相等的情況下的精確解,而我們也將會把這個作為整個神經網路的基礎資料——精確解來進行使用,具體的我們後面再說。
我們在開始編寫相關程式之前,必須搞清楚我們要做什麼,這也是我在編寫程式之前花了很長時間研究的東西。這一點不單純要結合我們的需求,也要結合神經網路的實際狀況及實現方法,神經網路的機理我也會在這一部分做乙個簡要的介紹。
經過之前的介紹,我們已經可以很清楚地了解到我們所面臨地問題了,那就是構建乙個神經網路以匈牙利演算法求得的精確解作為基礎訓練解集,使其在經過訓練後能夠達到**最優解集以及最小目標函式值的要求。現在我們的腦子裡很顯然有了乙個大概的印象(神經網路要實現不斷逼近精確值的過程),現在我們就可以開始具體的學習了。
神經網路的型別很多,包括但不限於bp、cnn、rnn等等,每一種神經網路的具體結構都有細微的區別,但總的不外乎輸入層(input_layer)→隱層層(hidden_layer)→輸出層(output_layer)的大三層結構,其分別實現的功能也就顯而易見在這裡不做解釋了。但我們需要了解的是我們這次做的這個神經網路需要一些什麼結構,在這裡我分成兩個型別,因為目前筆者實現的是全連線法下的神經網路結構,cnn型別的可以留下來繼續**。
全連線網路
全連線網路是歷史最為悠久且最基礎的神經網路,其結構與大三層結構相同,包括輸入-隱藏-輸出三層。
cnn(卷積)網路
這是目前主流的神經網路結構之一,其具有可接受資料量大以及運算快速等特點,這一點我們在後面介紹。其結構則為輸入層→卷積層(convolved_layer)→池化層(pooled_layer)→全連線層(full-connected_layer)→輸出層,顯然其結構更加複雜。
應用場景
這一次我們首先採用全連線的方式,其應用業主要體現在一些資料量不大且較為線性的問題中(實際上,等分配問題是線性問題,其存在匈牙利法的最優解即可很好說明這一點)。cnn則主要運用於影象識別等領域(現有blog基本都屬於這一類),在一張1920x1080的中,我們如果採用全連線方式,其節點數會非常龐大,一般電腦根本無法接受,這時候cnn的優勢性就體現出來,其能通過卷積+池化方式極大縮小資料量。
說了這麼多,需要說在前面的我們已經說完了,接下來就進入我們的實際程式編寫階段。
首先我們需要構建訓練資料——匈牙利法的精確解。我在這個部分採取了倒推法,通過要求一步步前推,從而得到我第一步應該準備什麼。即:得到精確解→匈牙利法計算→構造資料陣,這樣也就很容易得到,我們首先構造資料陣。
為了保證結果的準確性以及簡便操作,我們直接隨機產生乙個權值矩陣即可。我們將這樣乙個權值陣的規模定為10x10。
對了,為了保證後面使用方便,我們直接定義乙個函式來產生隨機矩陣:
def chanshengshuju():
x = np.random.randint(1, 100, (10, 10)) # 10*10
y, z = hungary(x)
return x, y
def hungary(juzhen):
cost = juzhen
row_ind, col_ind = linear_sum_assignment(cost)
hangxuhao = row_ind.tolist()
liexuhao = col_ind.tolist()
length = len(hangxuhao)
lingyi = np.zeros(cost.shape, dtype=np.int)
for i in range(length):
lingyi[hangxuhao[i]][liexuhao[i]] = 1
jieguoji = cost[row_ind, col_ind]
return jieguoji, lingyi
我用的是scipy模組下的乙個線性計算函式,其在面對這個問題時可以直接返回矩陣最優值所對應的行和列(是不是很方便!),然後我們就可以根據這個返回值得出最優解集以及對應的0-1陣(我們在學習運籌學時手算出的陣是0-1陣)。
我們再def乙個求和函式,來求最優解集的最小值。
def qiuhe(juzhen):
zhi = 0
for k in juzhen:
zhi += k
return zhi
於是資料的準備部分就完成了,我貼一下相關執行結果:
經過上面的步驟,我們得到了可以拿來訓練用的資料,已經開了乙個好頭,接下來我們開始進入神經網路的部分——卷積+池化。為什麼我把這一部分叫做資料處理呢,因為我覺得這是對我們剛剛產生資料的提取,因為我們知道cnn的好處就是這個,縮小資料量,提取特徵!
卷積
卷積其實是乙個很簡單的過程,簡單來說就是通過乙個我們給定的矩陣(我們將其叫做卷積核),在給定步幅的情況下與我們的原始權值資料陣相乘,再對結果進行加和,從而構成乙個新的矩陣,上面的這乙個gif就形象地表示了這一過程,也很明顯地看到,這一過程是可以縮小資料量的。
卷積過程的**實現如下:
我們將卷積核大小設定為4x4,注意到,我們第一句進行了reshape,這一點是因為我們feed到卷積過程中的資料必須是符合要求的,因為其不是影象輸入(傳統cnn影象輸入是rgb的三維矩陣,這裡我們是純資料矩陣只有二維,即深度為1),然後padding=「same」,這個意思是在卷積過程中也許會遇到邊緣資料缺失的現象,為了避免這種情況的發生,我們要告訴計算機在碰到這種情況時怎麼做,設定為」same「就意味著0補齊。
mm = np.reshape(origin,(1,10,10,1))
filter_weight = tf.get_variable("weights",[4,4,1,1],initializer = tf.constant_initializer([[-1,4],[2,1]]))
biases = tf.get_variable("biase",[1],initializer = tf.constant_initializer(1))
x = tf.placeholder('float32',[1,none,none,1])
conv = tf.nn.conv2d(x,filter_weight,strides=[1,1,1,1],padding="same")
add_bias = tf.nn.bias_add(conv,biases)
init_op = tf.global_variables_initializer()
with tf.session() as sess:
init_op.run()
mm_conv = sess.run(add_bias,feed_dict=)
```
pool = tf.nn.max_pool(add_bias,ksize=[1,2,2,1],strides=[1,2,2,1],padding="same")
add_bias = tf.nn.bias_add(conv,biases)
with tf.session() as sess:
tf.global_variables_initializer().run()
mm_conv = sess.run(add_bias,feed_dict=)
mm_pool = sess.run(pool,feed_dict=)
``
在此之後,我們便進行完神經網路搭建的前期處理工作,資料的產生與處理了,效果我也貼在下面。
部分卷積結果:
全部池化結果:
我們可以清楚看到,現有資料量被縮小成了25,僅有源資料量的1/4.
從零開始 用Python實現KNN演算法
目錄 python 2016年6月15日 k nearest neighbors演算法 簡稱knn演算法 的邏輯很簡單,它易於理解和實現,是你可以使用的有力工具。通過學習這個教程,你將能夠用python從0開始實現乙個knn演算法。這個實現主要用來處理分類問題,我們將使用鳶尾花分類問題來演示這個例子...
從零開始學貪心演算法
貪心演算法的定義 貪心演算法是指在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的區域性最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有...
從零開始學演算法 階乘求和
描述 求sn 1 2 3 4 5 n 之值,其中n是乙個數字 n不超過20 使用語言 c 我的分析 直接計算,沒有什麼技術 我的 結果錯誤的錯誤的 include using namespace std intmain cout return0 然而 我都已經防它一手了,再出這個結果就很有意思了。這...