Lenet神經網絡實現
手寫字體識別模型LeNet5誕生于1994年,是最早的卷積神經網絡之一。LeNet5通過巧妙的設計,利用卷積、參數共享、池化等操作提取特征,避免了大量的計算成本,最后再使用全連接神經網絡進行分類識別,這個網絡也是最近大量神經網絡架構的起點。雖然現在看來Lenet基本實際用處不大,而且架構現在基本也沒人用了,但是可以作為神經網絡架構的一個很好的入門基礎。
Lenet神經網絡架構圖如下:
LeNet5由7層CNN(不包含輸入層)組成,上圖中輸入的原始圖像大小是32×32像素。下面分別介紹每一層的含義。
input: 在原始的架構中,神經網絡的輸入是一張 32*32的灰度圖像,不過這里我們選用的dataset是cifar10,是RGB圖像,也就是 (32*32*3),3表示通道是3通道,即RGB三顏色。
conv1: 第一層是一個卷積層啦,卷積核(kernel size)大小 5*5,步長(stride)為 1 ,不進行padding,所以剛才的輸入圖像,經過這層后會輸出6張 28*28?的特征圖(feature map)。
maxpooling2: 接下來是一個降采樣層,用的是maxpooling哦,stride為 2?, kernel size為 2*2 ,恩,所以很明顯subsampling之后,輸出6張 14*14的feature map。
conv3: 第三層又是一個卷積層,kernel size和stride均與第一層相同,不過最后要輸出16張feature map。
maxpooling4:第四層,恩,又是一個maxpooling。
fc5:對,第五層開始就是全連接(fully connected layer)層了,把第四層的feature map攤平,然后做最直白的舉證運算,輸入是120個結點。
fc6:輸出是84個結點。
output:我們的dataset是cifar10,剛好也是10類哦,所以就是接一個softmax分成10類。
下面是基于Keras的簡單代碼實現
import keras
import numpy as np
from keras import optimizers
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Conv2D, Dense, Flatten, MaxPooling2D
from keras.callbacks import LearningRateScheduler, TensorBoard
from keras.preprocessing.image import ImageDataGenerator
from keras.regularizers import l2
batch_size = 128
epochs = 200
iterations = 391
num_classes = 10
weight_decay = 0.0001
mean = [125.307, 122.95, 113.865]
std = [62.9932, 62.0887, 66.7048]
def build_model():
model = Sequential()
model.add(Conv2D(6, (5, 5), padding='valid', activation = 'relu', kernel_initializer='he_normal', kernel_regularizer=l2(weight_decay), input_shape=(32,32,3)))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Conv2D(16, (5, 5), padding='valid', activation = 'relu', kernel_initializer='he_normal', kernel_regularizer=l2(weight_decay)))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(120, activation = 'relu', kernel_initializer='he_normal', kernel_regularizer=l2(weight_decay) ))
model.add(Dense(84, activation = 'relu', kernel_initializer='he_normal', kernel_regularizer=l2(weight_decay) ))
model.add(Dense(10, activation = 'softmax', kernel_initializer='he_normal', kernel_regularizer=l2(weight_decay) ))
sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
return model
def scheduler(epoch):
if epoch < 100:
return 0.01
if epoch < 150:
return 0.005
return 0.001
if __name__ == '__main__':
# load data
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# data preprocessing [raw - mean / std]
for i in range(3):
x_train[:,:,:,i] = (x_train[:,:,:,i] - mean[i]) / std[i]
x_test[:,:,:,i] = (x_test[:,:,:,i] - mean[i]) / std[i]
# build network
model = build_model()
print(model.summary())
# set callback
tb_cb = TensorBoard(log_dir='./lenet_dp_da_wd', histogram_freq=0)
change_lr = LearningRateScheduler(scheduler)
cbks = [change_lr,tb_cb]
# using real-time data augmentation
print('Using real-time data augmentation.')
datagen = ImageDataGenerator(horizontal_flip=True,
width_shift_range=0.125,height_shift_range=0.125,fill_mode='constant',cval=0.)
datagen.fit(x_train)
# start train
model.fit_generator(datagen.flow(x_train, y_train,batch_size=batch_size),
steps_per_epoch=iterations,
epochs=epochs,
callbacks=cbks,
validation_data=(x_test, y_test))
# save model
model.save('lenet_dp_da_wd.h5')
神經網絡
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。