Keras-Alexnet,NIN,Vgg16,ResNet,Inception,Xception,Densenet实现
win10
ananconda keras 2.2.4
GTX 1060
1.此处使用的数据集均为猫狗数据集,可在kaggle下载,如果不可访问(需要 VPN),有百度盘资源可供下载。链接如下:
猫狗数据集
2.本次网络依据CNN的发展历史轨迹进行学习与实现,如下图所示:
1.Alexnet:初代卷积网络,具体原理不再赘述。实现代码如下:
import os
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras import layers
from keras import optimizers
import matplotlib.pyplot as plt
#调取相关的库
在这base_dir='E:/dogs_and_cats/cats_and_dogs_small'
train_dir=os.path.join(base_dir,'train')
val_dir=os.path.join(base_dir,'val')
test_dir=os.path.join(base_dir,'test')
#从文件夹中读取数据,迭代器,训练数据进行数据增强,增加样本的多样性
train_datagen=ImageDataGenerator(rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
val_datagen=ImageDataGenerator(rescale=1./255)
train_generator=train_datagen.flow_from_directory(
train_dir,
target_size=(227,227),
batch_size=20,
class_mode='binary')
val_generator=val_datagen.flow_from_directory(val_dir,
target_size=(227,227),
batch_size=20,
class_mode='binary')
#构造Alex网络
model=Sequential()
#第一块儿
model.add(layers.Conv2D(96,(11,11),strides=(4,4),input_shape=(227,227,3),activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(3,3),strides=(2,2)))
#第二块儿
model.add(layers.Conv2D(256,(5,5),padding='same',activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(3,3),strides=(2,2)))
#第三块儿
model.add(layers.Conv2D(384,(3,3),padding='same',activation='relu'))
model.add(layers.Conv2D(384,(3,3),padding='same',activation='relu'))
model.add(layers.Conv2D(256,(3,3),padding='same',activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(3,3),strides=(2,2)))
#全连接部分
model.add(layers.Flatten())
model.add(layers.Dense(4096,activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(4096,activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1,activation='sigmoid'))
model.summary()
#画图并保存模型
train_acc=history.history['acc']
val_acc=history.history['val_acc']
train_loss=history.history['loss']
val_loss=history.history['val_loss']
epochs=range(1,len(train_acc)+1)
plt.plot(epochs,train_loss,'bo',label='Training loss')
plt.plot(epochs,val_loss,'r',label='Validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.figure()
plt.plot(epochs,train_acc,'bo',label='Training accuracy')
plt.plot(epochs,val_acc,'r',label='Validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
model.save('alexnet.h5')
在猫狗数据集中可以达到82%左右的精确度,还算不错。
2.NIN网络实现
NIN网络对CNN的发展提供了一个新的思路,之后的Inception、Xception网络都受到NIN的一些启发。代码实现如下:
#调入相关库
from keras.models import Model
from keras.layers import Input,GlobalAveragePooling2D
from keras.layers import Conv2D,MaxPool2D,BatchNormalization
from keras.preprocessing.image import ImageDataGenerator
import os
from keras import optimizers
import matplotlib.pyplot as plt
from keras import regularizers
#数据集准备同上不再详述。
train_datagen=ImageDataGenerator(rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
val_datagen=ImageDataGenerator(rescale=1./255)
train_generator=train_datagen.flow_from_directory(
train_dir,
target_size=(227,227),
batch_size=batch_size,
class_mode='binary')
val_generator=val_datagen.flow_from_directory(val_dir,
target_size=(227,227),
batch_size=batch_size,
class_mode='binary')
#NIN网络结构
def mlp_layer(x,filters,size,stride,padding):
x=Conv2D(filters=filters,kernel_size=(size,size),kernel_regularizer=regularizers.l2(0.01),strides=(stride,stride),padding=padding,activation='relu')(x)
x=BatchNormalization()(x)
x=Conv2D(filters=filters,kernel_size=(1,1),kernel_regularizer=regularizers.l2(0.01),strides=(1,1),padding='same',activation='relu')(x)
x=BatchNormalization()(x)
x=Conv2D(filters=filters,kernel_size=(1,1),kernel_regularizer=regularizers.l2(0.01),strides=(1,1),padding='same',activation='relu')(x)
x=BatchNormalization()(x)
return x
input=Input(shape=(227,227,3))
x=mlp_layer(input,96,11,4,'valid')
x=MaxPool2D(pool_size=(3,3),strides=(2,2))(x)
x=mlp_layer(x,256,5,1,'same')
x=MaxPool2D(pool_size=(3,3),strides=(2,2))(x)
x=mlp_layer(x,384,3,1,'same')
x=MaxPool2D(pool_size=(3,3),strides=(2,2))(x)
x=mlp_layer(x,1024,3,1,'same')
x=MaxPool2D(pool_size=(3,3),strides=(2,2))(x)
x=mlp_layer(x,1,3,1,'same')
x=GlobalAveragePooling2D()(x)
model=Model(input,x)
#model.summary()
model.compile(optimizer=optimizers.RMSprop(lr=1e-5),loss='binary_crossentropy',metrics=['acc'])
history=model.fit_generator(train_generator,
steps_per_epoch=train_generator.n/batch_size,
epochs=100,
validation_data=val_generator,
validation_steps=val_generator.n/batch_size )
train_acc=history.history['acc']
val_acc=history.history['val_acc']
train_loss=history.history['loss']
val_loss=history.history['val_loss']
epochs=range(1,len(train_acc)+1)
plt.plot(epochs,train_loss,'bo',label='Training loss')
plt.plot(epochs,val_loss,'r',label='Validation loss')
plt.title('The loss of training and validation')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.figure()
plt.plot(epochs,train_acc,'bo',label='Training accuracy')
plt.plot(epochs,val_acc,'r',label='Validation accuracy')
plt.title('The accuracy of training and validation')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
model.save('NIN2.h5')
#对输出的图像做一个平滑
def smooth_curve(points,factor=0.8):
smoothed_points=[]
for point in points:
if smoothed_points:
previous=smoothed_points[-1]
smoothed_points.append(previous*factor+point*(1-factor))
else:
smoothed_points.append(point)
return smoothed_points
plt.plot(epochs,smooth_curve(train_acc),'bo',label='Smoothed training acc')
plt.plot(epochs,smooth_curve(val_acc),'b',label='Smoothed validation acc')
plt.title('The loss of training and validation')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.figure()
plt.plot(epochs,smooth_curve(train_loss),'bo',label='Training loss')
plt.plot(epochs,smooth_curve(val_loss),'r',label='Validation loss')
plt.title('The loss of training and validation')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
在猫狗数据集中精确度只有57%左右,其效果不尽人意,但是网络的思想值的学习。
其他网络实现代码不断更新中 ,尽情期待!