Keras 最新《面向小数据集构建图像分类模型》

news/2024/7/7 19:22:05

本文地址:http://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html

本文作者:Francois Chollet

  • 按照官方的文章实现过程有一些坑,彻底理解代码细节实现,理解keras的api具体使用方法
  • 也有很多人翻译这篇文章,但是有些没有具体实现细节
  • 另外keres开发者自己有本书的jupyter:Companion Jupyter notebooks for the book "Deep Learning with Python"
  • 另外我自己实验三收敛的准确率并没有0.94+,可以参考前面这本书上的实现
  • 文章一共有三个实验:
      1. 第一个实验使用自定义的神经网络对数据集进行训练,三层卷积加两层全连接,训练并验证网络的准确率;
      2. 第二个实验使用VGG16网络对数据进行训练,为了适应自定义的数据集,将VGG16网络的全连接层去掉,作者称之为 “Feature extraction”, 再在上面添加自己实现的全连接层,然后训练并验证网络准确性;
      3. 第三个实验称为 “fine-tune” ,利用第二个实验的实验模型和weight,重新训练VGG16的最后一个卷积层和自定义的全连接层,然后验证网络准确性;
  • 实验二的代码:
'''This script goes along the blog post
"Building powerful image classification models using very little data"
from blog.keras.io.
It uses data that can be downloaded at:
https://www.kaggle.com/c/dogs-vs-cats/data
In our setup, we:
- created a data/ folder
- created train/ and validation/ subfolders inside data/
- created cats/ and dogs/ subfolders inside train/ and validation/
- put the cat pictures index 0-999 in data/train/cats
- put the cat pictures index 1000-1400 in data/validation/cats
- put the dogs pictures index 12500-13499 in data/train/dogs
- put the dog pictures index 13500-13900 in data/validation/dogs
So that we have 1000 training examples for each class, and 400 validation examples for each class.
In summary, this is our directory structure:
```
data/train/dogs/dog001.jpgdog002.jpg...cats/cat001.jpgcat002.jpg...validation/dogs/dog001.jpgdog002.jpg...cats/cat001.jpgcat002.jpg...
```
'''
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications# dimensions of our images.
img_width, img_height = 150, 150top_model_weights_path = 'bottleneck_fc_model.h5'data_root = 'M:/dataset/dog_cat/'
train_data_dir =data_root+ 'data/train'
validation_data_dir = data_root+'data/validation'
nb_train_samples = 2000
nb_validation_samples = 800
epochs = 50
batch_size = 16def save_bottlebeck_features():datagen = ImageDataGenerator(rescale=1. / 255)# build the VGG16 networkmodel = applications.VGG16(include_top=False, weights='imagenet')generator = datagen.flow_from_directory(train_data_dir,target_size=(img_width, img_height),batch_size=batch_size,class_mode=None,shuffle=False)bottleneck_features_train = model.predict_generator(generator, nb_train_samples // batch_size) #####2000//batch_size!!!!!!!!!!np.save('bottleneck_features_train.npy',bottleneck_features_train)generator = datagen.flow_from_directory(validation_data_dir,target_size=(img_width, img_height),batch_size=batch_size,class_mode=None,shuffle=False)bottleneck_features_validation = model.predict_generator(generator, nb_validation_samples // batch_size)np.save('bottleneck_features_validation.npy',bottleneck_features_validation)def train_top_model():train_data = np.load('bottleneck_features_train.npy')train_labels = np.array([0] * int(nb_train_samples / 2) + [1] * int(nb_train_samples / 2))validation_data = np.load('bottleneck_features_validation.npy')validation_labels = np.array([0] * int(nb_validation_samples / 2) + [1] * int(nb_validation_samples / 2))model = Sequential()model.add(Flatten(input_shape=train_data.shape[1:]))model.add(Dense(256, activation='relu'))model.add(Dropout(0.5))model.add(Dense(1, activation='sigmoid'))model.compile(optimizer='rmsprop',loss='binary_crossentropy', metrics=['accuracy'])model.fit(train_data, train_labels,epochs=epochs,batch_size=batch_size,validation_data=(validation_data, validation_labels))model.save_weights(top_model_weights_path)#save_bottlebeck_features()
train_top_model()
  • 实验三代码,自己添加了一些api使用方法,也是以后可以参考的:
'''This script goes along the blog post
"Building powerful image classification models using very little data"
from blog.keras.io.
It uses data that can be downloaded at:
https://www.kaggle.com/c/dogs-vs-cats/data
In our setup, we:
- created a data/ folder
- created train/ and validation/ subfolders inside data/
- created cats/ and dogs/ subfolders inside train/ and validation/
- put the cat pictures index 0-999 in data/train/cats
- put the cat pictures index 1000-1400 in data/validation/cats
- put the dogs pictures index 12500-13499 in data/train/dogs
- put the dog pictures index 13500-13900 in data/validation/dogs
So that we have 1000 training examples for each class, and 400 validation examples for each class.
In summary, this is our directory structure:
```
data/train/dogs/dog001.jpgdog002.jpg...cats/cat001.jpgcat002.jpg...validation/dogs/dog001.jpgdog002.jpg...cats/cat001.jpgcat002.jpg...
```
'''

# thanks sove bug @http://blog.csdn.net/aggresss/article/details/78588135from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras.models import Model
from keras.regularizers import l2# path to the model weights files.
weights_path = '../keras/examples/vgg16_weights.h5'
top_model_weights_path = 'bottleneck_fc_model.h5'
# dimensions of our images.
img_width, img_height = 150, 150data_root = 'M:/dataset/dog_cat/'
train_data_dir =data_root+ 'data/train'
validation_data_dir = data_root+'data/validation'nb_train_samples = 2000
nb_validation_samples = 800
epochs = 50
batch_size = 16# build the VGG16 network
base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(150,150,3)) # train 指定训练大小
print('Model loaded.')# build a classifier model to put on top of the convolutional model
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))  # base_model.output_shape[1:])
top_model.add(Dense(256, activation='relu',kernel_regularizer=l2(0.001),))
top_model.add(Dropout(0.8))
top_model.add(Dense(1, activation='sigmoid'))# note that it is necessary to start with a fully-trained
# classifier, including the top classifier,
# in order to successfully do fine-tuning
top_model.load_weights(top_model_weights_path)# add the model on top of the convolutional base
# model.add(top_model) # bugmodel = Model(inputs=base_model.input, outputs=top_model(base_model.output))# set the first 25 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in model.layers[:15]:  # :25 buglayer.trainable = False# compile the model with a SGD/momentum optimizer
# and a very slow learning rate.
model.compile(loss='binary_crossentropy',optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),metrics=['accuracy'])# prepare data augmentation configuration
train_datagen = ImageDataGenerator(rescale=1. / 255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True)test_datagen = ImageDataGenerator(rescale=1. / 255)train_generator = train_datagen.flow_from_directory(train_data_dir,target_size=(img_height, img_width),batch_size=batch_size,class_mode='binary')validation_generator = test_datagen.flow_from_directory(validation_data_dir,target_size=(img_height, img_width),batch_size=batch_size,class_mode='binary')model.summary() # prints a summary representation of your model.
# let's visualize layer names and layer indices to see how many layers
# we should freeze:
for i, layer in enumerate(base_model.layers):print(i, layer.name)from keras.utils import plot_model
plot_model(model, to_file='model.png')from keras.callbacks import History
from keras.callbacks import ModelCheckpoint
import keras
history = History()
model_checkpoint = ModelCheckpoint('temp_model.hdf5', monitor='loss', save_best_only=True)
tb_cb = keras.callbacks.TensorBoard(log_dir='log', write_images=1, histogram_freq=0)
# 设置log的存储位置,将网络权值以图片格式保持在tensorboard中显示,设置每一个周期计算一次网络的
# 权值,每层输出值的分布直方图
callbacks = [history,model_checkpoint,tb_cb]
# model.fit()# fine-tune the model
history=model.fit_generator(train_generator,steps_per_epoch=nb_train_samples // batch_size,epochs=epochs,callbacks=callbacks,validation_data=validation_generator,validation_steps=nb_validation_samples // batch_size,verbose = 2)model.save('fine_tune_model.h5')
model.save_weights('fine_tune_model_weight')
print(history.history)from matplotlib import pyplot as plt
history=history
plt.plot()
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()import  numpy as np
accy=history.history['acc']
np_accy=np.array(accy)
np.savetxt('save_acc.txt',np_accy)
  • result
Model loaded.
Found 2000 images belonging to 2 classes.
Found 800 images belonging to 2 classes.
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 150, 150, 3)       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 150, 150, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 150, 150, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 75, 75, 64)        0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 75, 75, 128)       73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 75, 75, 128)       147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 37, 37, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 37, 37, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 37, 37, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 37, 37, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 18, 18, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 18, 18, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 9, 9, 512)         0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 9, 9, 512)         2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 9, 9, 512)         2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 9, 9, 512)         2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 4, 4, 512)         0         
_________________________________________________________________
sequential_1 (Sequential)    (None, 1)                 2097665   
=================================================================
Total params: 16,812,353
Trainable params: 9,177,089
Non-trainable params: 7,635,264
_________________________________________________________________
0 input_1
1 block1_conv1
2 block1_conv2
3 block1_pool
4 block2_conv1
5 block2_conv2
6 block2_pool
7 block3_conv1
8 block3_conv2
9 block3_conv3
10 block3_pool
11 block4_conv1
12 block4_conv2
13 block4_conv3
14 block4_pool
15 block5_conv1
16 block5_conv2
17 block5_conv3
18 block5_pool
Backend TkAgg is interactive backend. Turning interactive mode on.
  • reference: 第八期 使用 Keras 训练神经网络 《显卡就是开发板》

http://lihuaxi.xjx100.cn/news/239525.html

相关文章

aws lambda使用_使用AWS Lambda安排Slack消息

aws lambda使用Migrating to serverless brings a lot of questions. How do you do some of the non-serverless tasks, such as a cronjob in a serverless application?迁移到无服务器带来了很多问题。 您如何执行一些非无服务器的任务,例如无服务器应用程序中的…

powershell连接数据库_PowerShell 连接SQL Server 数据库

PowerShell 通过ADO.NET连接SQL Server数据库,并执行SQL脚本。工作中整理的一小段脚本,后来没有用上,先记录在这里:建立数据库连接查询返回一个DataTatble对象执行一条SQL语句通过事物执行多条SQL语句## 建立数据库连接.#function…

16G 手机清理

1.16G 手机清理 清理top 5 的应用的缓存即可 2,hw wife 连接模块 低于 app wifi 的连接模块。 在同样的电脑热点面前,hw 连补上电脑热点,apple 可以连上电脑热点。 其他差异不大。 2.奇兔刷机 tencent应用宝 and 手机管理,备份软件 http://w…

MySQL · myrocks · MyRocks之memtable切换与刷盘

概述 MyRocks的memtable默认是skiplist,其大小和个数分别由参数write_buffer_size和max_write_buffer_number控制。数据写入时先写入active memtable, 当active memtable写满时,active memtable会转化为immutable memtable. immutable memtable数据是不会…

强化学习简介

by Thomas Simonini通过托马斯西蒙尼(Thomas Simonini) Reinforcement learning is an important type of Machine Learning where an agent learn how to behave in a environment by performing actions and seeing the results.强化学习是机器学习的一种重要类型&#xff0…

android 无法接收广播_别告诉我你不认识Android中广播接收者(二)

前面我们了解了什么是广播接收者与广播接收者的创建,这一次我们要接着继续去了解广播接收者的相关知识,这些知识包括广播接收者的注册、自定义广播与广播的类型。当我们学习完广播接收者之后,该如何才能让它起到作用呢?还有广播接…

hic染色体构想_了解微服务:从构想到起点

hic染色体构想by Michael Douglass迈克尔道格拉斯(Michael Douglass) 了解微服务:从构想到起点 (Understanding Microservices: From Idea To Starting Line) Over the last two months, I have invested most of my free time learning the complete ins-and-outs…

Linux-find命令应用举例-按时间筛选和删除文件

find参数说明: find有很多参数是以动作首字母时间的方式用于按访问、改变、更新时间来筛选文件。 动作表达: a(last accessed) 最近一次访问时间 c(last changed) 最近一次改变时间 m(last modified) 最近一次修改时间注意此上的c和m的区别,…