Есть ли более эффективный способ извлечения функций из набора данных, как показано ниже:
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
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...
Я скажу нет, не думаю, что есть более эффективный способ. Вычисления должны происходить, и они особенно медленны для процессора. Лучшее, что вы можете сделать, - это избежать повторных вычислений, преобразовав набор данных, сохранив массивы, а затем загружая их каждый раз при обучении.
Я проходил через то же самое, пока не сломался и не купил графический процессор ... и с тех пор моя жизнь стала намного менее напряженной. Я настоятельно рекомендую вложить деньги даже в 1050, если вы не можете себе позволить ничего другого. Возможно, вам придется выяснить, как справиться с ограниченной памятью графического процессора, но это упростит вам жизнь.
Я не уверен, чего вы ожидаете, если набор данных большой и вы используете графический процессор, вам нечего делать, кроме как просто дождаться обработки всего набора данных. В любом случае это займет меньше времени, чем обучение модели на наборе данных.