神經(jīng)網(wǎng)絡(luò)之CNN與RNN的關(guān)系

極市導(dǎo)讀
?本文主要是對(duì)CNN和RNN的理解,通過(guò)對(duì)比總結(jié)各自的優(yōu)勢(shì),同時(shí)加深自己對(duì)這方面知識(shí)的理解,其中代碼引用采用的是VQA模型中對(duì)圖像和文本的處理。?>>加入極市CV技術(shù)交流群,走在計(jì)算機(jī)視覺(jué)的最前沿
1、CNN介紹
CNN是一種利用卷積計(jì)算的神經(jīng)網(wǎng)絡(luò)。它可以通過(guò)卷積計(jì)算將原像素很大的圖片保留主要特征變成很小的像素圖片。本文以李宏毅老師ppt內(nèi)容展開(kāi)具體介紹。
1.1 Why CNN for Image

①為什么引入CNN ?
圖片示意:給定一個(gè)圖片放入全連接神經(jīng)網(wǎng)絡(luò),第一個(gè)hidden layer識(shí)別這張圖片有沒(méi)有綠色出現(xiàn)?有沒(méi)有黃色出現(xiàn)?有沒(méi)有斜的條紋?第二個(gè)hidden layer結(jié)合第一個(gè)hidden layer的輸出實(shí)現(xiàn)更復(fù)雜的功能,例如:如圖如果看到直線+橫線就是框框一部分,如果看到棕色+條紋就是木紋,如果看到斜條紋+綠色就是灰色類(lèi)條紋一部分。再根據(jù)第二個(gè)hidden layer輸出結(jié)果,如果某個(gè)神經(jīng)元看到蜂巢就會(huì)activate,某個(gè)神經(jīng)元如果看到人就會(huì)activate。
但是我們?nèi)绻话愕赜胒ully network(全連接)神經(jīng)網(wǎng)絡(luò)處理的話,我們會(huì)需要很多的參數(shù),例如如果input的vector是個(gè)30000維,第一個(gè)hidden layer假設(shè)是1000個(gè)神經(jīng)元,那么第一個(gè)hidden layer就會(huì)30000*1000個(gè),數(shù)據(jù)量非常大,導(dǎo)致計(jì)算效率和準(zhǔn)確率效果低,而引入CNN,主要就是解決我們這些問(wèn)題,簡(jiǎn)化我們神經(jīng)網(wǎng)絡(luò)架構(gòu)。因?yàn)?某些weight我們是用不到的,CNN會(huì)使用過(guò)濾手段(filter)將一些不需要的參數(shù)過(guò)濾掉,保留一些重要的參數(shù)做圖像處理。
②為什么使用比較少的參數(shù)就足夠進(jìn)行圖像處理 ?
三個(gè)特性:
大部分的patterns要比整張圖片小,一個(gè)神經(jīng)元不需要去觀察整個(gè)圖片,只需要觀察圖片的一小部分就能找到一個(gè)想要的pattern,例如:給定一張圖片,第一個(gè)hidden layer的某個(gè)神經(jīng)元找圖像中的鳥(niǎo)的嘴,另一個(gè)神經(jīng)元找鳥(niǎo)的爪子。如下圖只需要看紅色框不需要觀察整張圖就可以找到鳥(niǎo)嘴。

不同位置的鳥(niǎo)嘴只需要訓(xùn)練一個(gè)識(shí)別鳥(niǎo)嘴的參數(shù)就Ok了,不需要分別訓(xùn)練。
我們可以采用子樣品來(lái)使圖片變小,子樣不會(huì)改變目標(biāo)圖像。
1.2 CNN架構(gòu)圖

1.1節(jié)的前兩個(gè)property需要卷積計(jì)算,后一個(gè)池化層處理,具體下節(jié)介紹。
1.3 卷積層
1.3.1 重要參數(shù)

1.3.2 卷積計(jì)算
矩陣卷積計(jì)算如下:

計(jì)算如下:圖像傳入的是553的像素值,經(jīng)過(guò)padding=1的填充構(gòu)成773的像素值,卷積核是333的大小,2個(gè)卷積核,步數(shù)stride=2。注意這里的卷積核深度要核傳入過(guò)來(lái)的像素值深度相同,當(dāng)每次掃描到的藍(lán)色位置數(shù)對(duì)應(yīng)卷積核紅色位置數(shù)位置相乘后相加得到綠色位置的數(shù)據(jù)。
像素?cái)?shù)變化為:(n+2p-f)\s = (5+2-3)\2 + 1= 3得到332的數(shù)據(jù),經(jīng)過(guò)卷積輸出的像素深度等于上一層輸入的卷積核數(shù)目。將得的結(jié)果作為池化層的輸入值。
卷積核大小選取往往是奇數(shù)。深度要和它的上一層輸出像素值深度相同,如動(dòng)圖卷積核的選取是3*3*3,而輸出像素值深度=本次卷積的卷積核數(shù)。這點(diǎn)不要混淆。
1.3.3 卷積層與全連接層的關(guān)系
其實(shí)卷積就是將全連接層的一些weight拿掉,卷積層計(jì)算輸出的結(jié)果,其實(shí)就是全連接層的hidden layer輸出的結(jié)果。如下圖所示:

卷積沒(méi)有考慮輸入的全部特征,只和filter中經(jīng)過(guò)的特征有關(guān),如下:6*6的圖像展開(kāi)成36pixel,然后下一層只和輸入層的9個(gè)pixel有關(guān),沒(méi)有連接全部,這樣就會(huì)使用很少的參數(shù),具體圖解如下:

由上圖也可發(fā)現(xiàn),計(jì)算結(jié)果3和-1不像全連接網(wǎng)絡(luò)那樣全部都需要不同的weight,而這個(gè)3和-1的部分計(jì)算的weight相同,這就是所謂的參數(shù)共享(權(quán)值共享)
1.4 池化層
根據(jù)前一個(gè)卷積計(jì)算后的矩陣,再進(jìn)行池化處理(將一個(gè)框框內(nèi)的四個(gè)值合并一個(gè)值,可取最大值或者平均值),如下圖:


1.5 應(yīng)用
主要使用pytorch框架來(lái)介紹卷積神經(jīng)網(wǎng)絡(luò)。
源代碼:
torch.nn.Conv2d(
in_channels:?int,?#輸入圖像的通道數(shù)
out_channels:?int,?#卷積產(chǎn)生的輸出通道數(shù)
kernel_size:?Union[T,?Tuple[T,?T]],?#卷積核大小
stride:?Union[T,?Tuple[T,?T]]?=?1,?#卷積的步數(shù)?默認(rèn):1
padding:?Union[T,?Tuple[T,?T]]?=?0,?#0填充添加到輸入的兩邊?默認(rèn):0
dilation:?Union[T,?Tuple[T,?T]]?=?1,?#核元素之間的間距?默認(rèn):1
groups:?int?=?1,?#從輸入通道到輸出通道的阻塞鏈接數(shù),默認(rèn):1
#groups:控制輸入和輸出之間的連接,輸入和輸出通道數(shù)必須被組整除,
#當(dāng)groups=1:所有輸入移交給所有輸出
#當(dāng)groups=2:相當(dāng)于兩個(gè)卷積層,一個(gè)看到一半的輸入通道并產(chǎn)生一半的輸出通道,將兩個(gè)合并
#當(dāng)groups=in_channels:每個(gè)通道都有自己的一組過(guò)濾器,其大小為out_channel/in_channel
bias:?bool?=?True,?#將可學(xué)習(xí)的偏差添加到輸出中?默認(rèn):true
padding_mode:?str?=?'zeros')
#注:kenerl_size,stride,padding,dilation參數(shù)類(lèi)型可以是int,可以是tuple,當(dāng)是tuple時(shí),第一個(gè)int是高度維度,第二個(gè)是寬度維度。當(dāng)是單個(gè)int時(shí),高度寬度值相同
#?方形核和等步幅
m?=?nn.Conv2d(16,?33,?3,?stride=2)
#?非方形核和不等步幅和填充
m?=?nn.Conv2d(16,?33,?(3,?5),?stride=(2,?1),?padding=(4,?2))
#?非方形核和不等步幅和填充和擴(kuò)展
m?=?nn.Conv2d(16,?33,?(3,?5),?stride=(2,?1),?padding=(4,?2),?dilation=(3,?1))
input?=?torch.randn(20,?16,?50,?100)
output?=?m(input)
應(yīng)用:此處采用的是VGG16,順便介紹以下pytorch的torchsummary庫(kù),可以把網(wǎng)絡(luò)模型打印出來(lái),例如:
import?torchvision.models?as?models
import?torch.nn?as?nn
import?torch
from?torchsummary?import?summary
device?=?torch.device('cuda'?if?torch.cuda.is_available()?else?'cpu')
model?=?models.vgg16(pretrained=True).to(device)
print(model)
輸出:
VGG(
??(features):?Sequential(
????(0):?Conv2d(3,?64,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(1):?ReLU(inplace)
????(2):?Conv2d(64,?64,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(3):?ReLU(inplace)
????(4):?MaxPool2d(kernel_size=2,?stride=2,?padding=0,?dilation=1,?ceil_mode=False)
????(5):?Conv2d(64,?128,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(6):?ReLU(inplace)
????(7):?Conv2d(128,?128,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(8):?ReLU(inplace)
????(9):?MaxPool2d(kernel_size=2,?stride=2,?padding=0,?dilation=1,?ceil_mode=False)
????(10):?Conv2d(128,?256,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(11):?ReLU(inplace)
????(12):?Conv2d(256,?256,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(13):?ReLU(inplace)
????(14):?Conv2d(256,?256,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(15):?ReLU(inplace)
????(16):?MaxPool2d(kernel_size=2,?stride=2,?padding=0,?dilation=1,?ceil_mode=False)
????(17):?Conv2d(256,?512,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(18):?ReLU(inplace)
????(19):?Conv2d(512,?512,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(20):?ReLU(inplace)
????(21):?Conv2d(512,?512,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(22):?ReLU(inplace)
????(23):?MaxPool2d(kernel_size=2,?stride=2,?padding=0,?dilation=1,?ceil_mode=False)
????(24):?Conv2d(512,?512,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(25):?ReLU(inplace)
????(26):?Conv2d(512,?512,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(27):?ReLU(inplace)
????(28):?Conv2d(512,?512,?kernel_size=(3,?3),?stride=(1,?1),?padding=(1,?1))
????(29):?ReLU(inplace)
????(30):?MaxPool2d(kernel_size=2,?stride=2,?padding=0,?dilation=1,?ceil_mode=False)
??)
??(classifier):?Sequential(
????(0):?Linear(in_features=25088,?out_features=4096,?bias=True)
????(1):?ReLU(inplace)
????(2):?Dropout(p=0.5)
????(3):?Linear(in_features=4096,?out_features=4096,?bias=True)
????(4):?ReLU(inplace)
????(5):?Dropout(p=0.5)
????(6):?Linear(in_features=4096,?out_features=1000,?bias=True)
??)
)
model.classifier?=?nn.Sequential(
????*list(model.classifier.children())[:-1])????#?remove?last?fc?layer
print(model)
summary(model,(3,224,224))
輸出:
----------------------------------------------------------------
????????Layer?(type)???????????????Output?Shape?????????Param?#
================================================================
????????????Conv2d-1?????????[-1,?64,?224,?224]???????????1,792
??????????????ReLU-2?????????[-1,?64,?224,?224]???????????????0
????????????Conv2d-3?????????[-1,?64,?224,?224]??????????36,928
??????????????ReLU-4?????????[-1,?64,?224,?224]???????????????0
?????????MaxPool2d-5?????????[-1,?64,?112,?112]???????????????0
????????????Conv2d-6????????[-1,?128,?112,?112]??????????73,856
??????????????ReLU-7????????[-1,?128,?112,?112]???????????????0
????????????Conv2d-8????????[-1,?128,?112,?112]?????????147,584
??????????????ReLU-9????????[-1,?128,?112,?112]???????????????0
????????MaxPool2d-10??????????[-1,?128,?56,?56]???????????????0
???????????Conv2d-11??????????[-1,?256,?56,?56]?????????295,168
?????????????ReLU-12??????????[-1,?256,?56,?56]???????????????0
???????????Conv2d-13??????????[-1,?256,?56,?56]?????????590,080
?????????????ReLU-14??????????[-1,?256,?56,?56]???????????????0
???????????Conv2d-15??????????[-1,?256,?56,?56]?????????590,080
?????????????ReLU-16??????????[-1,?256,?56,?56]???????????????0
????????MaxPool2d-17??????????[-1,?256,?28,?28]???????????????0
???????????Conv2d-18??????????[-1,?512,?28,?28]???????1,180,160
?????????????ReLU-19??????????[-1,?512,?28,?28]???????????????0
???????????Conv2d-20??????????[-1,?512,?28,?28]???????2,359,808
?????????????ReLU-21??????????[-1,?512,?28,?28]???????????????0
???????????Conv2d-22??????????[-1,?512,?28,?28]???????2,359,808
?????????????ReLU-23??????????[-1,?512,?28,?28]???????????????0
????????MaxPool2d-24??????????[-1,?512,?14,?14]???????????????0
???????????Conv2d-25??????????[-1,?512,?14,?14]???????2,359,808
?????????????ReLU-26??????????[-1,?512,?14,?14]???????????????0
???????????Conv2d-27??????????[-1,?512,?14,?14]???????2,359,808
?????????????ReLU-28??????????[-1,?512,?14,?14]???????????????0
???????????Conv2d-29??????????[-1,?512,?14,?14]???????2,359,808
?????????????ReLU-30??????????[-1,?512,?14,?14]???????????????0
????????MaxPool2d-31????????????[-1,?512,?7,?7]???????????????0
???????????Linear-32?????????????????[-1,?4096]?????102,764,544
?????????????ReLU-33?????????????????[-1,?4096]???????????????0
??????????Dropout-34?????????????????[-1,?4096]???????????????0
???????????Linear-35?????????????????[-1,?4096]??????16,781,312
?????????????ReLU-36?????????????????[-1,?4096]???????????????0
??????????Dropout-37?????????????????[-1,?4096]???????????????0
================================================================
Total?params:?134,260,544
Trainable?params:?134,260,544
Non-trainable?params:?0
----------------------------------------------------------------
Input?size?(MB):?0.57
Forward/backward?pass?size?(MB):?218.58
Params?size?(MB):?512.16
Estimated?Total?Size?(MB):?731.32
----------------------------------------------------------------
2、RNN介紹
2.1 引言
每個(gè)訂票系統(tǒng)都會(huì)有一個(gè)空位填充(slot filling),有些slot是Destination,有些slot是time of arrival,系統(tǒng)要知道哪些詞屬于哪個(gè)slot;例如:
I?would?like?to?arrive?Taipei?on?November?2nd;
這里的Taipei就是Destination,November?2nd就是time?of?arrival;
采用普通的神經(jīng)網(wǎng)絡(luò),將Taipei這個(gè)詞丟入到網(wǎng)絡(luò)中,當(dāng)然在丟入之前要將其轉(zhuǎn)化成向量表示,如何表示成向量?方法很多此處采用:1-of-N Encoding,表示方式如下:

其他詞向量方式如下:

但是,如果有如下情況,系統(tǒng)就會(huì)出錯(cuò)。

問(wèn): 怎么辦?使有時(shí)輸入Taipei時(shí),輸出dest概率高,有時(shí)輸入Taipei時(shí)輸出出發(fā)地概率高?
答: 此時(shí)就要使我們的網(wǎng)絡(luò)有“記憶”,能記住前面輸入的數(shù)據(jù)。例如:Taipei是目的地時(shí)看到了arrive,Taipei是出發(fā)地時(shí)看到了leave。那么這種有記憶的網(wǎng)絡(luò)就叫做:Recurrent Neural Network(RNN)
2.2 RNN簡(jiǎn)介
RNN的隱藏層的輸出會(huì)存儲(chǔ)在內(nèi)存中,當(dāng)下次輸入數(shù)據(jù)時(shí)會(huì)使用到內(nèi)存中存儲(chǔ)的上次的輸出。圖解如下:

圖中,同樣的weight用同樣的顏色表示。當(dāng)然hidden layer可以有很多層;以上介紹的RNN是最簡(jiǎn)單的,接下來(lái)介紹加強(qiáng)版的LSTM;
2.3 RNN之LSTM
現(xiàn)在常用的內(nèi)存(memory)是Long short-term內(nèi)存。
當(dāng)外部信息需要輸入到memory時(shí)需要一個(gè)“閘門(mén)”——input gate,而input gate什么時(shí)候打開(kāi)和關(guān)閉是被神經(jīng)網(wǎng)絡(luò)學(xué)到的,同理output gate也是神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)的,forget gate也是如此。
所以LSTM有四個(gè)input,1個(gè)output。簡(jiǎn)圖如下:


公式如下:

2.4 LSTM例子

圖中x2 = 1將x1送入memory中,如果x2=-1就清空memory的數(shù)值,如果x3=1,就將memory中的數(shù)據(jù)輸出。如上圖,第一列,x2=0不送入memory,第二列x2=1,將此刻x1=3送入memory中(注意memory中的數(shù)據(jù)是x1的累加,例如第四列,x2=1,此時(shí)有x1=4,memory中=3,所以一起就是7)第五列發(fā)現(xiàn)x3=1,可以輸出,所以輸出memory中的值7.
結(jié)合LSTM簡(jiǎn)圖如下:

假設(shè)進(jìn)來(lái)的是第一列:x1=3,x2=1,x3=0步驟:g—Tanh: x1w1+x2w2+x3w3 = 3f—sigmod: x1w1+x2w2+x3w3=90 sigmod后=1算好f和g后傳入input gate=3*1=3,forget gate = 1,代表不需要清0,x3=0,代表output gate鎖上,輸出的還是0。
2.5 LSTM實(shí)戰(zhàn)
pytorch中封裝好了LSTM網(wǎng)絡(luò),直接采用nn.lstm即可使用,例如
class?QstEncoder(nn.Module):
????def?__init__(self,?qst_vocab_size,?word_embed_size,?embed_size,?num_layers,?hidden_size):
????????super(QstEncoder,?self).__init__()
????????self.word2vec?=?nn.Embedding(qst_vocab_size,?word_embed_size)
????????self.tanh?=?nn.Tanh()
????????self.lstm?=?nn.LSTM(word_embed_size,?hidden_size,?num_layers)
????????self.fc?=?nn.Linear(2*num_layers*hidden_size,?embed_size)?????#?2?for?hidden?and?cell?states
????def?forward(self,?question):
????????qst_vec?=?self.word2vec(question)?????????????????????????????#?[batch_size,?max_qst_length=30,?word_embed_size=300]
????????qst_vec?=?self.tanh(qst_vec)
????????qst_vec?=?qst_vec.transpose(0,?1)?????????????????????????????#?[max_qst_length=30,?batch_size,?word_embed_size=300]
????????_,?(hidden,?cell)?=?self.lstm(qst_vec)????????????????????????#?[num_layers=2,?batch_size,?hidden_size=512]
????????qst_feature?=?torch.cat((hidden,?cell),?2)????????????????????#?[num_layers=2,?batch_size,?2*hidden_size=1024]
????????qst_feature?=?qst_feature.transpose(0,?1)?????????????????????#?[batch_size,?num_layers=2,?2*hidden_size=1024]
????????qst_feature?=?qst_feature.reshape(qst_feature.size()[0],?-1)??#?[batch_size,?2*num_layers*hidden_size=2048]
????????qst_feature?=?self.tanh(qst_feature)
????????qst_feature?=?self.fc(qst_feature)????????????????????????????#?[batch_size,?embed_size]
????????return?qst_feature
3、CNN與RNN的區(qū)別
CNN與RNN區(qū)別鏈接如下,引用了這個(gè)博客作者總結(jié),(https://blog.csdn.net/lff1208/article/details/77717149)具體如下。
DNN形成
為了克服梯度消失,ReLU、maxout等傳輸函數(shù)代替了sigmoid,形成了如今DNN的基本形式。結(jié)構(gòu)跟多層感知機(jī)一樣,如下圖所示:

我們看到全連接DNN的結(jié)構(gòu)里下層神經(jīng)元和所有上層神經(jīng)元都能夠形成連接,從而導(dǎo)致參數(shù)數(shù)量膨脹。假設(shè)輸入的是一幅像素為1K*1K的圖像,隱含層有1M個(gè)節(jié)點(diǎn),光這一層就有10^12個(gè)權(quán)重需要訓(xùn)練,這不僅容易過(guò)擬合,而且極容易陷入局部最優(yōu)。
CNN形成
由于圖像中存在固有的局部模式(如人臉中的眼睛、鼻子、嘴巴等),所以將圖像處理和神將網(wǎng)絡(luò)結(jié)合引出卷積神經(jīng)網(wǎng)絡(luò)CNN。CNN是通過(guò)卷積核將上下層進(jìn)行鏈接,同一個(gè)卷積核在所有圖像中是共享的,圖像通過(guò)卷積操作后仍然保留原先的位置關(guān)系。

通過(guò)一個(gè)例子簡(jiǎn)單說(shuō)明卷積神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)。假設(shè)我們需要識(shí)別一幅彩色圖像,這幅圖像具有四個(gè)通道ARGB(透明度和紅綠藍(lán),對(duì)應(yīng)了四幅相同大小的圖像),假設(shè)卷積核大小為100*100,共使用100個(gè)卷積核w1到w100(從直覺(jué)來(lái)看,每個(gè)卷積核應(yīng)該學(xué)習(xí)到不同的結(jié)構(gòu)特征)。
用w1在ARGB圖像上進(jìn)行卷積操作,可以得到隱含層的第一幅圖像;這幅隱含層圖像左上角第一個(gè)像素是四幅輸入圖像左上角100*/100區(qū)域內(nèi)像素的加權(quán)求和,以此類(lèi)推。
同理,算上其他卷積核,隱含層對(duì)應(yīng)100幅“圖像”。每幅圖像對(duì)是對(duì)原始圖像中不同特征的響應(yīng)。按照這樣的結(jié)構(gòu)繼續(xù)傳遞下去。CNN中還有max-pooling等操作進(jìn)一步提高魯棒性。

注意到最后一層實(shí)際上是一個(gè)全連接層,在這個(gè)例子里,我們注意到輸入層到隱藏層的參數(shù)瞬間降低到了100100100=10^6個(gè)!這使得我們能夠用已有的訓(xùn)練數(shù)據(jù)得到良好的模型。題主所說(shuō)的適用于圖像識(shí)別,正是由于CNN模型限制參數(shù)了個(gè)數(shù)并挖掘了局部結(jié)構(gòu)的這個(gè)特點(diǎn)。順著同樣的思路,利用語(yǔ)音語(yǔ)譜結(jié)構(gòu)中的局部信息,CNN照樣能應(yīng)用在語(yǔ)音識(shí)別中。
RNN形成
DNN無(wú)法對(duì)時(shí)間序列上的變化進(jìn)行建模。然而,樣本出現(xiàn)的時(shí)間順序?qū)τ谧匀徽Z(yǔ)言處理、語(yǔ)音識(shí)別、手寫(xiě)體識(shí)別等應(yīng)用非常重要。為了適應(yīng)這種需求,就出現(xiàn)了大家所說(shuō)的另一種神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)——循環(huán)神經(jīng)網(wǎng)絡(luò)RNN。
在普通的全連接網(wǎng)絡(luò)或CNN中,每層神經(jīng)元的信號(hào)只能向上一層傳播,樣本的處理在各個(gè)時(shí)刻獨(dú)立,因此又被成為前向神經(jīng)網(wǎng)絡(luò)(Feed-forward Neural Networks)。而在RNN中,神經(jīng)元的輸出可以在下一個(gè)時(shí)間段直接作用到自身,即第i層神經(jīng)元在m時(shí)刻的輸入,除了(i-1)層神經(jīng)元在該時(shí)刻的輸出外,還包括其自身在(m-1)時(shí)刻的輸出!表示成圖就是這樣的:

為方便分析,按照時(shí)間段展開(kāi)如下圖所示:

(t+1)時(shí)刻網(wǎng)絡(luò)的最終結(jié)果O(t+1)是該時(shí)刻輸入和所有歷史共同作用的結(jié)果!這就達(dá)到了對(duì)時(shí)間序列建模的目的。RNN可以看成一個(gè)在時(shí)間上傳遞的神經(jīng)網(wǎng)絡(luò),它的深度是時(shí)間的長(zhǎng)度!正如我們上面所說(shuō),“梯度消失”現(xiàn)象又要出現(xiàn)了,只不過(guò)這次發(fā)生在時(shí)間軸上。
所以RNN存在無(wú)法解決長(zhǎng)時(shí)依賴的問(wèn)題。為解決上述問(wèn)題,提出了LSTM(長(zhǎng)短時(shí)記憶單元),通過(guò)cell門(mén)開(kāi)關(guān)實(shí)現(xiàn)時(shí)間上的記憶功能,并防止梯度消失,LSTM單元結(jié)構(gòu)如下圖所示:

除了DNN、CNN、RNN、ResNet(深度殘差)、LSTM之外,還有很多其他結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò)。如因?yàn)樵谛蛄行盘?hào)分析中,如果我能預(yù)知未來(lái),對(duì)識(shí)別一定也是有所幫助的。因此就有了雙向RNN、雙向LSTM,同時(shí)利用歷史和未來(lái)的信息。
事實(shí)上,不論是哪種網(wǎng)絡(luò),他們?cè)趯?shí)際應(yīng)用中常常都混合著使用,比如CNN和RNN在上層輸出之前往往會(huì)接上全連接層,很難說(shuō)某個(gè)網(wǎng)絡(luò)到底屬于哪個(gè)類(lèi)別。不難想象隨著深度學(xué)習(xí)熱度的延續(xù),更靈活的組合方式、更多的網(wǎng)絡(luò)結(jié)構(gòu)將被發(fā)展出來(lái)。
簡(jiǎn)單總結(jié)如下:

如果覺(jué)得有用,就請(qǐng)分享到朋友圈吧!
公眾號(hào)后臺(tái)回復(fù)“CVPR21檢測(cè)”獲取CVPR2021目標(biāo)檢測(cè)論文下載~

#?CV技術(shù)社群邀請(qǐng)函?#

備注:姓名-學(xué)校/公司-研究方向-城市(如:小極-北大-目標(biāo)檢測(cè)-深圳)
即可申請(qǐng)加入極市目標(biāo)檢測(cè)/圖像分割/工業(yè)檢測(cè)/人臉/醫(yī)學(xué)影像/3D/SLAM/自動(dòng)駕駛/超分辨率/姿態(tài)估計(jì)/ReID/GAN/圖像增強(qiáng)/OCR/視頻理解等技術(shù)交流群
每月大咖直播分享、真實(shí)項(xiàng)目需求對(duì)接、求職內(nèi)推、算法競(jìng)賽、干貨資訊匯總、與?10000+來(lái)自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺(jué)開(kāi)發(fā)者互動(dòng)交流~

