LeNet 誕生于 1994 年,,是最早的卷積神經(jīng)網(wǎng)絡(luò)之一,,并且推動(dòng)了深度學(xué)習(xí)領(lǐng)域的發(fā)展LeNet-5一共有8層:1個(gè)輸入層+3個(gè)卷積層(C1,、C3、C5)+2個(gè)下采樣層(S2,、S4)+1個(gè)全連接層(F6)+1個(gè)輸出層,,每層有多個(gè)feature map(自動(dòng)提取的多組特征)。采用keras自帶的MNIST數(shù)據(jù)集,,輸入像素矩陣為28×28的單通道圖像數(shù)據(jù),。 由6個(gè)feature map組成,每個(gè)feature map由5×5卷積核生成(feature map中每個(gè)神經(jīng)元與輸入層的5×5區(qū)域像素相連),,考慮每個(gè)卷積核的bias,,該層需要學(xué)習(xí)的參數(shù)個(gè)數(shù)為:(5×5+1)×6=156個(gè),神經(jīng)元連接數(shù)為:156×24×24=89856個(gè),。該層每個(gè)feature map一一對(duì)應(yīng)上一層的feature map,,由于每個(gè)單元的2×2感受野采用不重疊方式移動(dòng),所以會(huì)產(chǎn)生6個(gè)大小為12×12的下采樣feature map,,如果采用Max Pooling/Mean Pooling,,則該層需要學(xué)習(xí)的參數(shù)個(gè)數(shù)為0個(gè)(如果采用非等權(quán)下采樣——即采樣核有權(quán)重,則該層需要學(xué)習(xí)的參數(shù)個(gè)數(shù)為:(2×2+1)×6=30個(gè)),,神經(jīng)元連接數(shù)為:30×12×12=4320個(gè),。這層略微復(fù)雜,S2神經(jīng)元與C3是多對(duì)多的關(guān)系,,比如最簡單方式:用S2的所有feature map與C3的所有feature map做全連接(也可以對(duì)S2抽樣幾個(gè)feature map出來與C3某個(gè)feature map連接),,這種全連接方式下:6個(gè)S2的feature map使用6個(gè)獨(dú)立的5×5卷積核得到C3中1個(gè)feature map(生成每個(gè)feature map時(shí)對(duì)應(yīng)一個(gè)bias),C3中共有16個(gè)feature map,,所以該層需要學(xué)習(xí)的參數(shù)個(gè)數(shù)為:(5×5×6+1)×16=2416個(gè),,神經(jīng)元連接數(shù)為:2416×8×8=154624個(gè)。同S2,,如果采用Max Pooling/Mean Pooling,,則該層需要學(xué)習(xí)的參數(shù)個(gè)數(shù)為0個(gè),神經(jīng)元連接數(shù)為:(2×2+1)×16×4×4=1280個(gè),。類似C3,,用S4的所有feature map與C5的所有feature map做全連接,這種全連接方式下:16個(gè)S4的feature map使用16個(gè)獨(dú)立的1×1卷積核得到C5中1個(gè)feature map(生成每個(gè)feature map時(shí)對(duì)應(yīng)一個(gè)bias),,C5中共有120個(gè)feature map,,所以該層需要學(xué)習(xí)的參數(shù)個(gè)數(shù)為:(1×1×16+1)×120=2040個(gè),神經(jīng)元連接數(shù)為:2040個(gè),。 將C5層展開得到4×4×120=1920個(gè)節(jié)點(diǎn),,并接一個(gè)全連接層,考慮bias,,該層需要學(xué)習(xí)的參數(shù)和連接個(gè)數(shù)為:(1920+1)*84=161364個(gè),。該問題是個(gè)10分類問題,,所以有10個(gè)輸出單元,通過softmax做概率歸一化,,每個(gè)分類的輸出單元對(duì)應(yīng)84個(gè)輸入,。Minist(Modified NIST)數(shù)據(jù)集下使用LeNet-5的訓(xùn)練可視化:可以看到其實(shí)全連接層之前的各層做的就是特征提取的事兒,且比較通用,,對(duì)于標(biāo)準(zhǔn)化實(shí)物(人,、車、花等等)可以復(fù)用,,后面會(huì)單獨(dú)介紹模型的fine-tuning,。 import copy import numpy as np import pandas as pd import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt from matplotlib.pyplot import plot,savefig from keras.datasets import mnist, cifar10 from keras.models import Sequential, Graph from keras.layers.core import Dense, Dropout, Activation, Flatten, Reshape from keras.optimizers import SGD, RMSprop from keras.utils import np_utils from keras.regularizers import l2 from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D, AveragePooling2D from keras.callbacks import EarlyStopping from keras.preprocessing.image import ImageDataGenerator from keras.layers.normalization import BatchNormalization import tensorflow as tf tf.python.control_flow_ops = tf from PIL import Image def build_LeNet5(): model = Sequential() model.add(Convolution2D(6, 5, 5, border_mode='valid', input_shape = (28, 28, 1), dim_ordering='tf')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Activation("relu")) model.add(Convolution2D(16, 5, 5, border_mode='valid')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Activation("relu")) model.add(Convolution2D(120, 1, 1, border_mode='valid')) model.add(Flatten()) model.add(Dense(84)) model.add(Activation("sigmoid")) model.add(Dense(10)) model.add(Activation('softmax')) return model if __name__=="__main__": from keras.utils.visualize_util import plot model = build_LeNet5() model.summary() plot(model, to_file="LeNet-5.png", show_shapes=True) (X_train, y_train), (X_test, y_test) = mnist.load_data() X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32') / 255 X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') / 255 Y_train = np_utils.to_categorical(y_train, 10) Y_test = np_utils.to_categorical(y_test, 10) # training model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy']) batch_size = 128 nb_epoch = 1 model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=1, validation_data=(X_test, Y_test)) score = model.evaluate(X_test, Y_test, verbose=0) print('Test score:', score[0]) print('Test accuracy:', score[1]) y_hat = model.predict_classes(X_test) test_wrong = [im for im in zip(X_test,y_hat,y_test) if im[1] != im[2]] plt.figure(figsize=(10, 10)) for ind, val in enumerate(test_wrong[:100]): plt.subplots_adjust(left=0, right=1, bottom=0, top=1) plt.subplot(10, 10, ind + 1) im = 1 - val[0].reshape((28,28)) plt.axis("off") plt.text(0, 0, val[2], fontsize=14, color='blue') plt.text(8, 0, val[1], fontsize=14, color='red') plt.imshow(im, cmap='gray') savefig('error.jpg') 網(wǎng)絡(luò)結(jié)構(gòu)記得把公號(hào)加星標(biāo),,會(huì)第一時(shí)間收到通知,。 創(chuàng)作不易,如果覺得有點(diǎn)用,,希望可以隨手轉(zhuǎn)發(fā)或者”在看“,,拜謝各位老鐵
|