Мы обучили несколько нейронных сетей, распознающих написанные от руки цифры, предсказывающих цены на жилье или различающих кошек и собак, тогда возникает проблема, как использовать эти обученные сети, мне нужно переобучить каждую проблемную сеть? Поскольку программисты не очень любят делать повторяющиеся вещи, ответ должен заключаться в том, что колеса уже есть.
Давайте сначала представим набор данных ImageNet. Здесь нельзя не упомянуть известного китайского ученого в области искусственного интеллекта Ли Фейфея.
Примерно в 2005 году Ли Фейфэй закончила свою докторскую карьеру и занялась академическими исследованиями. До этого она осознала проблему. До этого люди пытались максимально оптимизировать алгоритм, думая, что независимо от того, какие данные, пока Алгоритм достаточно хорош, его можно решить. Чтобы принимать лучшие решения, Ли Фейфэй осознает ограниченность этой проблемы. Бывает, что она все еще активистка. Она хочет сделать чрезвычайно огромный набор данных, набор данных, который описывает все объекты в мире как можно больше, скачивайте картинки и дайте Аннотировать картинку просто и скучно. Конечно, эта работа позже была размещена на краудсорсинговой платформе Amazon. Бесчисленное количество людей по всему миру участвовало в этом великом проекте. было 14 197 122 изображения (одна тысяча четыреста 10 000), 21 841 категория. В процессе этой разработки люди также обнаружили, что этот набор данных принес гораздо больший успех, чем ожидалось, и даже предложение глубоких сверточных нейронных сетей, которые сейчас считаются наиболее перспективными, имеет отношение к ImageNet. Я забыл, кто сказал: «Один только этот набор данных может дать Ли Фейфею место в области науки о данных». Можно ли сказать, что этот набор данных все еще открывает новые горизонты. (Однажды я слушал речь Ли Фейфэй в аудитории, и теперь я думаю об этом и чувствую себя очень взволнованным, она действительно полна энтузиазма).
Основываясь на этом наборе данных, можем ли мы обучить некоторые сети?В обычных условиях нам не нужно тратить время на обучение сети? Ответ - да, и такие модели есть в Керасе, или встроенные.Керас так хорошо вас понимает, так что милости просим, мы просто воспользуемся, спасибо!
Извлечение признаков
Сверточная нейронная сеть, которую мы использовали ранее, разделена на две части.Первая часть представляет собой сверточный продукт, состоящий из объединяющего слоя и сверточного слоя, а вторая часть — классификатор.Смысл извлечения признаков заключается в том, что первая часть остается неизменной. ., изменяя вторую часть.
Почему это возможно? Ранее мы объясняли, как работают нейронные сети, что очень похоже на когнитивный процесс человеческого мозга, помните? Давайте посмотрим на исходную картинку.
Мы видим, что изображение сетевого распознавания имеет иерархическую структуру. Например, сетевой уровень в начале используется для распознавания изображений или сборки строк. Это общее и похожее, поэтому мы можем использовать его повторно. Последние классификаторы часто определяются в соответствии с конкретными задачами, например, распознавание глаз кошек или собак — это не то же самое, что распознавание ножек стола, поэтому чем он совершеннее, тем он более универсален. Многие встроенные модели в Keras можно загрузить напрямую.Если вы их не загрузите, они будут загружены автоматически при использовании:
https://github.com/fchollet/deep-learning-models/releases
Давайте возьмем пример использования VGG16 для идентификации кошек или собак.Объяснения на этот раз относительно просты и объяснялись ранее, поэтому они помещены в комментарии к коду:
#!/usr/bin/env python3
import os
import time
import matplotlib.pyplot as plt
import numpy as np
from keras import layers
from keras import models
from keras import optimizers
from keras.applications import VGG16
from keras.preprocessing.image import ImageDataGenerator
def extract_features(directory, sample_count):
# 图片转换区间
datagen = ImageDataGenerator(rescale=1. / 255)
batch_size = 20
conv_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(150, 150, 3))
conv_base.summary()
features = np.zeros(shape=(sample_count, 4, 4, 512))
labels = np.zeros(shape=(sample_count))
# 读出图片,处理成神经网络需要的数据格式,上一篇文章中有介绍
generator = datagen.flow_from_directory(
directory,
target_size=(150, 150),
batch_size=batch_size,
class_mode='binary')
i = 0
for inputs_batch, labels_batch in generator:
print(i, '/', len(generator))
# 提取特征
features_batch = conv_base.predict(inputs_batch)
features[i * batch_size: (i + 1) * batch_size] = features_batch
labels[i * batch_size: (i + 1) * batch_size] = labels_batch
i += 1
if i * batch_size >= sample_count:
break
# 特征和标签
return features, labels
def cat():
base_dir = '/Users/renyuzhuo/Desktop/cat/dogs-vs-cats-small'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
# 提取出的特征
train_features, train_labels = extract_features(train_dir, 2000)
validation_features, validation_labels = extract_features(validation_dir, 1000)
# 对特征进行变形展平
train_features = np.reshape(train_features, (2000, 4 * 4 * 512))
validation_features = np.reshape(validation_features, (1000, 4 * 4 * 512))
# 定义密集连接分类器
model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_dim=4 * 4 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))
# 对模型进行配置
model.compile(optimizer=optimizers.RMSprop(lr=2e-5),
loss='binary_crossentropy',
metrics=['acc'])
# 对模型进行训练
history = model.fit(train_features, train_labels,
epochs=30,
batch_size=20,
validation_data=(validation_features, validation_labels))
# 画图
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.show()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
if __name__ == "__main__":
time_start = time.time()
cat()
time_end = time.time()
print('Time Used: ', time_end - time_start)
Немного случайно, что здесь не слишком много следов переобучения, на самом деле могут быть скрытые опасности переобучения, в этом случае требуется улучшение данных, что то же самое, что и раньше, но отличие здесь в том, что используется встроенная модель, и параметры модели нужно заморозить.Мы не хотим менять обученную модель.Конкретный код ключа записывается следующим образом:
conv_base.trainable = False
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
Выше приведен один из методов повторного использования модели. Мы используем модель как она есть. В нашей следующей статье будет представлен еще один метод тонкой настройки модели.
Впервые опубликовано из публичного аккаунта: РАИС