1. 程式人生 > >Keras 最新《面向小數據集構建圖像分類模型》

Keras 最新《面向小數據集構建圖像分類模型》

網絡 ict regular n) val sent rom link prepare

本文地址: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.jpg dog002.jpg ... cats/ cat001.jpg cat002.jpg ... validation/ dogs/ dog001.jpg dog002.jpg ... cats/ cat001.jpg cat002.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, 150 top_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 = 16 def save_bottlebeck_features(): datagen = ImageDataGenerator(rescale=1. / 255) # build the VGG16 network model = 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.jpg
            dog002.jpg
            ...
        cats/
            cat001.jpg
            cat002.jpg
            ...
    validation/
        dogs/
            dog001.jpg
            dog002.jpg
            ...
        cats/
            cat001.jpg
            cat002.jpg
            ...
```
‘‘‘

# thanks sove bug @http://blog.csdn.net/aggresss/article/details/78588135

from 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, 150

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 = 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) # bug

model = 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 bug
    layer.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.
# lets 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 訓練神經網絡 《顯卡就是開發板》

Keras 最新《面向小數據集構建圖像分類模型》