卷積神經網路 -- PyTorch 實現系列之 LeNet(datasets: CIFAR-10)
阿新 • • 發佈:2019-01-24
參考文獻:Gradient-Based Learning Applied to Document Recognition
摘要:
本文利用PyTorch實現了經典神經網路LeNet。
引入:
目前有很多部落格都系統介紹了LeNet的結構以及在各個框架下的程式碼實現,然而本人發現其中很大一部分博文是存在比較多的問題的,經過仔細閱讀LeCun的文章,我把原始LeNet的整個思路在此分享給各位,在下也是剛入門,如有疏漏或錯誤,請各位讀者指正!
PS:由於用的是torch.nn.Modules實現,有些部分被我簡化了,帶我深入學習Pytorch後,再研究一下怎麼把這些忽略掉的引數再加進去吧……
資料集:
原文使用的是MNIST,這裡我是用了CIFAR-10,最大的不同點只是圖片深度從1變成3(黑白和彩色的區別)。
網路結構:
LeNet是一個由2個卷積層,2個池化層和3個全連線層組成的深度神經網路結構。
關於池化層:文中描述為取樣層,可以理解為一個帶引數的AvgPooling,但是肯定不是MaxPooling。這裡我用torch.nn.AvgPool2d代替,忽略掉了6+6個引數。
關於C3:實際上是不是所有的單元都和S2的所有輸出相連,這裡也是簡化了……
最後一層:後面接的是一個帶引數的tanh,這裡也把引數忽略了。
主要程式碼如下:
print_every = 100 learning_rate = 1e-2 input_depth = 3 ''' layer_0 : [64, 3, 32, 32] (Input) layer_1 : [64, 6, 28, 28] (Conv) layer_2 : [64, 6, 14, 14] (AvgPool) layer_3 : [64, 16, 10, 10] (Conv) layer_4 : [64, 16, 5, 5] (AvgPool) layer_5 : [16*5*5, 120] (Linear) layer_5 : [120, 84] (Linear) layer_7 : [84, 10] (Linear) ''' layer_1_depth, layer_1_pad, layer_1_kernel = 6, 0,(5, 5) layer_2_kernel = (2,2) layer_3_depth, layer_3_pad, layer_3_kernel= 16, 0,(5, 5) layer_4_kernel = (2,2) layer_5_input, layer_5_output = 400, 120 layer_6_input, layer_6_output = 120, 84 layer_7_input, layer_7_output = 84, 10 model = nn.Sequential( nn.Conv2d(input_depth, layer_1_depth, layer_1_kernel, padding=layer_1_pad), nn.AvgPool2d(layer_2_kernel), nn.Sigmoid(), nn.Conv2d(layer_1_depth, layer_3_depth, layer_3_kernel, padding=layer_3_pad), nn.AvgPool2d(layer_4_kernel), Flatten(), nn.Linear(layer_5_input,layer_5_output), nn.Linear(layer_6_input,layer_6_output), nn.Linear(layer_7_input,layer_7_output), ) # you can use Nesterov momentum in optim.SGD optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9, nesterov=True) iterations,losss,val_accs = train(model, optimizer, epochs = 10)