Эффективные способы извлечения функций из предварительно обученной cnn

Есть ли более эффективный способ извлечения функций из набора данных, как показано ниже:

def extract_features(directory, sample_count):
    features = np.zeros(shape=(sample_count, 6, 6, 512))
    labels = np.zeros(shape=(sample_count, 6))

    generator = 
    ImageDataGenerator(rescale=1./255).flow_from_directory(directory, 
    target_size=(Image_Size, Image_Size), batch_size = batch_size, 
    class_mode='categorical')

    i = 0

    print('Entering for loop...');

    for inputs_batch, labels_batch in generator:
        features_batch = conv_base.predict(inputs_batch)
        features[i * 20 : (i + 1) * 20] = features_batch
        labels[i * 20 : (i + 1) * 20] = labels_batch
        i += 1
        print(i);

        if (i * 20) >= sample_count:
            break

    return features, labels

Из-за размера моего набора данных этот процесс занимает довольно много времени, и я хотел знать, есть ли лучший способ сделать это?

Заранее спасибо :)

Полный код:

from keras import layers
from keras import models
from keras import losses
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
from keras.applications.vgg16 import VGG16

import matplotlib.pyplot as plt
import numpy as np

Train_DIR = '/Users/eoind/food/train'
Test_DIR = '/Users/eoind/food/test'
Validation_DIR = '/Users/eoind/food/validation'

Image_Size = 200 # Size of input images to be scaled to 
Train_Samples = 6000
Validation_Samples = 3000
Test_Samples = 3000

num_epochs = 30
batch_size = 20
steps_per_epoch = Train_Samples/batch_size

conv_base = VGG16(weights='imagenet', include_top=False, input_shape= 
(Image_Size, Image_Size, 3))

conv_base.summary()

print('Conv_Base Summary');

def extract_features(directory, sample_count):
    features = np.zeros(shape=(sample_count, 6, 6, 512))
    labels = np.zeros(shape=(sample_count, 6))

    generator = 
    ImageDataGenerator(rescale=1./255).flow_from_directory(directory, 
    target_size=(Image_Size, Image_Size), batch_size = batch_size, 
    class_mode='categorical')

    i = 0

    print('Entering for loop...');

    for inputs_batch, labels_batch in generator:
        features_batch = conv_base.predict(inputs_batch)
        features[i * 20 : (i + 1) * 20] = features_batch
        labels[i * 20 : (i + 1) * 20] = labels_batch
        i += 1
        print(i);
    
        if (i * 20) >= sample_count:
            break
    
    return features, labels

train_features, train_labels = extract_features(Train_DIR, Train_Samples)
validation_features, validation_labels = extract_features(Validation_DIR, 
Validation_Samples)
test_features, test_labels = extract_features(Test_DIR, Test_Samples)

print('Extracting Features');

train_features = np.reshape(train_features, (Train_Samples, 6 * 6 * 512))
validation_features = np.reshape(validation_features, (Validation_Samples, 6 * 
6 * 512))
test_features = np.reshape(test_features, (Test_Samples, 6 * 6 * 512))

print('Reshaping Features');

model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_dim=6 * 6 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

model.summary()

print('Model Summary');

model.compile(optimizer=optimizers.RMSprop(lr=1e-4),
              loss=losses.categorical_crossentropy,
              metrics=['acc'])

print('Compiling Model');

hist = model.fit(train_features, train_labels,
                 steps_per_epoch = steps_per_epoch,
                 epochs = num_epochs,
                 batch_size = batch_size,
                 verbose = 1,
                 validation_data = (validation_features, validation_labels))

print('Fitting Model');

train_loss=hist.history['loss']
val_loss=hist.history['val_loss']
train_acc=hist.history['acc']
val_acc=hist.history['val_acc']
xc=range(num_epochs)

fig1=plt.figure(1,figsize=(7,5))
plt.plot(xc,train_loss)
plt.plot(xc,val_loss)
plt.xlabel('Number of Epochs')
plt.ylabel('Loss')
plt.title('Training Loss Vs. Validation Loss')
plt.grid(True)
plt.legend(['Training', 'Validation'])
plt.style.use(['classic'])
fig1.savefig('loss.png')

fig2=plt.figure(2,figsize=(7,5))
plt.plot(xc,train_acc)
plt.plot(xc,val_acc)
plt.xlabel('Number of Epochs')
plt.ylabel('Accuracy')
plt.title('Training Accuracy Vs. Validation Accuracy')
plt.grid(True)
plt.legend(['Training', 'Validation'], loc='upper left')
plt.style.use(['classic'])
fig2.savefig('acc.png')

model.save('food_pretrained.h5') # Save model

Вывод консоли iPython

Layer (type)                 Output Shape              Param #   
=================================================================
input_19 (InputLayer)        (None, 200, 200, 3)       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 200, 200, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 200, 200, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 100, 100, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 100, 100, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 100, 100, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 50, 50, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 50, 50, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 50, 50, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 50, 50, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 25, 25, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 25, 25, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 25, 25, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 25, 25, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 12, 12, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 12, 12, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 12, 12, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 12, 12, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 6, 6, 512)         0         
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
Conv_Base Summary
Found 6000 images belonging to 6 classes.
Entering for loop...
1
2
3
4
5
6
7
8
9
10
11
12...

Я не уверен, чего вы ожидаете, если набор данных большой и вы используете графический процессор, вам нечего делать, кроме как просто дождаться обработки всего набора данных. В любом случае это займет меньше времени, чем обучение модели на наборе данных.

Dr. Snoopy 11.04.2018 15:16
0
1
704
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я скажу нет, не думаю, что есть более эффективный способ. Вычисления должны происходить, и они особенно медленны для процессора. Лучшее, что вы можете сделать, - это избежать повторных вычислений, преобразовав набор данных, сохранив массивы, а затем загружая их каждый раз при обучении.

Я проходил через то же самое, пока не сломался и не купил графический процессор ... и с тех пор моя жизнь стала намного менее напряженной. Я настоятельно рекомендую вложить деньги даже в 1050, если вы не можете себе позволить ничего другого. Возможно, вам придется выяснить, как справиться с ограниченной памятью графического процессора, но это упростит вам жизнь.

Другие вопросы по теме