RNN 迴圈神經網路 訓練手寫數字

2021-10-01 09:03:49 字數 3642 閱讀 4025

rnn(recurrent neural network)迴圈(遞迴)神經網路主要用來處理序列資料。因為傳統的神經網路從輸入-隱含層-輸出是全連線的,層中的神經元是沒有連線的,所以對於輸入資料本身具有時序性(例如輸入的文字資料,每個單詞之間有一定聯絡)的處理表現並不理想。而rnn每乙個輸出與前面的輸出建立起關聯,這樣就能夠很好的處理序列化的資料。

單純迴圈神經網路也面臨一些問題,如無法處理隨著遞迴,權重指數級**或消失的問題,難以捕捉長期時間關聯。這些可以結合不同的lstm很好的解決這個問題。

本文主要介紹簡單的rnn用oc的實現,並通過訓練mnist資料來檢測模型。後面有時間再介紹lstm的實現。

簡單的rnn就三層,輸入-隱含層-輸出,如下:

將其展開的模型如下:

其中,a這個隱含層的操作就是將當前輸入與前面的輸出相結合,然後啟用就得到當前狀態訊號。如下:

計算公式如下:

其中xt是輸入資料序列,st是的狀態序列,v*st就是圖中ot輸出,softmax運算並沒有畫出來。

由於rnn結構簡單,反向傳播的公式結合一點數理知識就可以求得,這裡就不列出,詳見**實現。

由於沒找到比較好的訓練資料,這裡用的是前面《oc實現softmax識別手寫數字》文章裡面的mnist資料來源。輸入資料處理、softmax實現也都是復用的。

資料本質上並非是序列化的,我這裡將的每行的的畫素資料當作乙個訊號輸入,如果一共n行,序列長度就是n。訓練資料是28*28維的,那麼就是每個訊號是28*1,一共時間長度是28。

簡單的rnn實現流程並不複雜,需要訓練的引數就5個:輸入的權值、神經元間轉移的權值、輸出的權值、以及兩個轉移和輸出的偏置量。直接看**:

//

// mlrnn.m

// lstm

//// created by jiao liu on 11/9/16.

//#import "mlrnn.h"

@implementation mlrnn

#pragma mark - inner method

+ (double)truncated_normal:(double)mean dev:(double)stddev

hasspare = 1;

static double u,v,s;

do while ((s >= 1.0) || (s == 0.0));

s = sqrt(-2.0 * log(s) / s);

spare = v * s;

outp = mean + stddev * u * s;

} while (fabsl(outp) > 2*stddev);

return outp;

}+ (double *)fillvector:(double)num size:(int)size

+ (double *)weight_init:(int)size

return outp;

}+ (double *)bias_init:(int)size

+ (double *)tanh:(double *)input size:(int)size

else if (num < -20)

else

}return input;

}#pragma mark - init

- (id)initwithnodenum:(int)num layersize:(int)size datadim:(int)dim

return self;

}- (id)init

return self;

}- (void)setupnet

#pragma mark - main method

- (double *)forwardpropagation:(double *)input

else

[mlrnn tanh:temp1 size:_nodenum];

vdsp_vaddd((_state + i * _nodenum), 1, temp1, 1, (_state + i * _nodenum), 1, _nodenum);

vdsp_mmuld(_outweight, 1, temp1, 1, (_output + i * _datadim), 1, _datadim, 1, _nodenum);

vdsp_vaddd((_output + i * _datadim), 1, _outbias, 1, (_output + i * _datadim), 1, _datadim);

free(temp1);

free(temp2);

}return _output;

}- (void)backpropagation:(double *)loss

vdsp_vmuld(tanhloss, 1, tanhin, 1, tanhloss, 1, _nodenum);

vdsp_vaddd(_flowbias, 1, tanhloss, 1, _flowbias, 1, _nodenum);

if (i != 0)

double *inweightloss = calloc(_nodenum * _datadim, sizeof(double));

vdsp_mmuld(tanhloss, 1, (_input + i * _datadim), 1, inweightloss, 1, _nodenum, _datadim, 1);

vdsp_vaddd(_inweight, 1, inweightloss, 1, _inweight, 1, _nodenum * _datadim);

free(transweight);

free(tanhloss);

free(outweightloss);

free(tanhin);

free(one);

free(inweightloss);

}free(flowloss);

free(loss);

}@end

很多初始化方法以及內部函式直接是復用《oc實現(cnn)卷積神經網路》中相關的方法。

我這裡使用rnn,迭代2500次,每次訓練100張,單個神經元節點個數選擇50,得到的正確率94%左右。

有興趣的朋友可以點這裡看完整**。

本文參考:

understanding lstm networks

recurrent-neural-networks-tutorial

RNN迴圈神經網路

評測乙個句子出現的可能性 文字自動生成 rnn迴圈處理相同的任務,就是 句子接下來的單詞是什麼。rnn迴圈記錄前面所有文字的資訊 也叫做記憶 作為 當前詞的乙個輸入 1.語言模型和文字生成 語言模型中,輸入是經過編碼的詞向量序列,輸出是一系列 的詞 2.機器翻譯 機器翻譯必須等待所有輸入結束後才能輸...

迴圈神經網路 RNN

from torchnlp.word to vector import glove vectors glove vectors hello torch.nn.utils.clip grad norm p,10 10就是最大梯度的模閾值,即保留原來梯度的方向,但梯度大小縮放至10對與梯度瀰散現象,考慮...

RNN迴圈神經網路

神經網路基礎 神經網路可以當做是擬合任意函式的黑盒子,給定特定的輸入x,就能夠的得到希望的輸出y。神經網路結構如下圖 將神經網路模型訓練好之後,輸入層輸入乙個x,通過網路之後就能夠在輸出層輸出特定的y.有了這麼強大的模型,為什麼會出現rnn 迴圈神經網 它們單獨的乙個個的輸入,前乙個輸入和後乙個輸入...