Как добавить еще один слой в предварительно загруженную сеть? - PullRequest
1 голос
/ 01 ноября 2019

Я загружаю нейронную сеть с помощью tenorflow и colab notbook от Google. И я хочу удалить полностью связанный слой выходного слоя и добавить еще один полностью связанный только с одним нейроном, и я хочу заморозить другие слои и обучить только этот добавленный выходной слой. Я использую tf.keras.application.MobileNetV2, и я использую mledu- datasets/cats_and_dogs.

Я имею serarch в API-интерфейсе tenorflow и тестировал методы для добавления, но я не добился успеха. Мой код следующий:

<code>
Original file is located at
    https://colab.research.google.com/drive/16VdqQFBfY_jp5-5kRQvWQ0Y0ytN9W1kN

https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/images/classification.ipynb#scrollTo=3f0Z7NZgVrWQ

This tutorial follows a basic machine learning workflow:

1.   Examine and understand data
2.   Build an input pipeline
3.   Build the model
4.   Train the model
5.   Test the model
6.   Improve the model and repeat the process

## Import packages

Let's start by importing the required packages. The `os` package is used to read files and directory structure, NumPy is used to convert python list to numpy array and to perform required matrix operations and `matplotlib.pyplot` to plot the graph and display images in the training and validation data.
"""

from __future__ import absolute_import, division, print_function, unicode_literals

"""Import Tensorflow and the Keras classes needed to construct our model."""

# try:
#   # %tensorflow_version only exists in Colab.
#   %tensorflow_version 2.x
# except Exception:
#   pass

import tensorflow as tf

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator

import os
import numpy as np
import matplotlib.pyplot as plt

import keras
from keras import backend as K
from keras.layers.core import Dense, Activation
from keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from keras.preprocessing import image
from keras.models import Model
from keras.applications import imagenet_utils
from keras.layers import Dense,GlobalAveragePooling2D
from keras.applications import MobileNet
from keras.applications.mobilenet import preprocess_input
from IPython.display import Image
from keras.optimizers import Adam

"""## Load data
Begin by downloading the dataset. This tutorial uses a filtered version of Dogs vs Cats dataset from Kaggle. Download the archive version of the dataset and store it in the "/tmp/" directory.
"""

_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'

path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)

PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')

"""The dataset has the following directory structure:

<pre>
<b>cats_and_dogs_filtered</b>
|__ <b>train</b>
    |______ <b>cats</b>: [cat.0.jpg, cat.1.jpg, cat.2.jpg ....]
    |______ <b>dogs</b>: [dog.0.jpg, dog.1.jpg, dog.2.jpg ...]
|__ <b>validation</b>
    |______ <b>cats</b>: [cat.2000.jpg, cat.2001.jpg, cat.2002.jpg ....]
    |______ <b>dogs</b>: [dog.2000.jpg, dog.2001.jpg, dog.2002.jpg ...]
. После извлечения его содержимого назначьте переменные с правильным путем к файлу для набора обучения и проверки. "" "train_dir = os.path.join (PATH, 'train') validation_dir = os.path.join (PATH, 'validation') train_cats_dir = os.path.join (train_dir, 'cats') # каталог с нашим обучениемcat pictures train_dogs_dir = os.path.join (train_dir, 'dogs') # каталог с нашими изображениями обучающих собак validation_cats_dir = os.path.join (validation_dir, 'cats') # каталог с нашими валидационными изображениями cat validation_dogs_dir = os.path. присоединиться к каталогу (validation_dir, 'dogs') # с нашими изображениями собак для проверки "" "### Понимание данных Давайте посмотрим, сколько изображений с кошками и собаками находится в каталоге для обучения и проверки:" "" num_cats_tr = len (os. listdir (train_cats_dir)) num_dogs_tr = len (os.listdir (train_dogs_dir)) num_cats_val = len (os.listdir (validation_cats_dir)) num_dogs_val = len (os.listdir (validation__in_________in__t__t__t__t__t= )_Num_Num_Tum)'Всего изображений дрессировки кошек:', num_cats_tr) print ('Всего изображений дрессировки собак:', num_dogs_tr) print ('Всего валидацийín cat cat: ', num_cats_val) print (' Всего изображений для валидации собак: ', num_dogs_val) print ("-") print ("Всего обучающих изображений:", total_train) print ("Всего валидационных изображений:", total_val) """ Для удобства настройте переменные, которые будут использоваться при предварительной обработке набора данных и обучении сети. "" "Batch_size = 32 эпох = 15 IMG_HEIGHT = 160 IMG_WIDTH = 160" "" ### Подготовка данных Отформатируйте изображения в соответствующие предварительно-процессированные тензоры с плавающей запятой перед подачей в сеть: 1. Считайте образы с диска. 2. Расшифруйте содержимое этих изображений и преобразуйте его в правильный формат сетки в соответствии с их содержимым RGB. 3. Преобразуйте их в тензоры с плавающей точкой. 4. Измените тензоры от 0 до 255 до значений от 0 до 1, так как нейронные сети предпочитают работать с небольшими входными значениями. К счастью, все эти задачи можно выполнить с помощью класса `ImageDataGenerator`, предоставленного` tf.keras`. Он может читать изображения с диска и предварительно обрабатывать их в соответствующие тензоры. Он также настроит генераторы, которые преобразуют эти изображения в пакеты тензоров, что полезно при обучении сети. "" "train_image_generator = ImageDataGenerator (rescale = 1. / 255) # Генератор для наших данных обучения validation_image_generator = ImageDataGenerator (rescale = 1. / 255) # Генератор для наших данных проверки" "" После определения генераторов для обучающих и проверочных изображений,метод `flow_from_directory` загружает изображения с диска, применяет масштабирование и изменяет размеры изображений до требуемых размеров." "" train_data_gen = train_image_generator.flow_from_directory (batch_size = batch_size, directory = train_dir, shuffle = True, target_size = (IMG_HID) (IMG)), class_mode = 'binary') val_data_gen = validation_image_generator.flow_from_directory (batch_size = batch_size, directory = validation_dir, target_size = (IMG_HEIGHT, IMG_WIDTH), class_mode = 'binary') "images" "Vi # Visualize trainingсуммируйте обучающие изображения, извлекая серию изображений из обучающего генератора (в данном примере это 32 изображения), а затем наносите на пятерку пять изображений с помощью `matplotlib`. "" "sample_training_images, _ = next (train_data_gen)" "" Функция `next` возвращает пакет из набора данных. Возвращаемое значение функции `next` имеет вид` (x_train, y_train) `, где x_train - это обучающие функции, а y_train - его метки. Откажитесь от меток, чтобы визуализировать только обучающие изображения. "" "# Эта функция будет отображать изображения в виде сетки с 1 строкой и 5 столбцами, где изображения размещены в каждом столбце. Def plotImages (images_arr): fig, axes = plt.subplots (1, 5, figsize = (20,20)) оси = axes.flatten () для img, ax в zip (images_arr, axes): ax.imshow (img) ax.axis ('off') plt. ight_layout () plt.show () plotImages (sample_training_images [: 5]) "" "## Создание модели Модель состоит из трех блоков свертки с максимальным слоем пула в каждом из них. Существует полностью связанный слой с 512 юнитами, который активируется функцией активации `relu`. Модель выводит вероятности класса на основе двоичной классификации с помощью функции активации `sigmoid`. "" "# model = Sequential ([# Conv2D (16, 3, заполнение = 'same', активация = 'relu', input_shape = (IMG_HEIGHT, IMG_WIDTH, 3)), # MaxPooling2D (), # Conv2D (32, 3, padding = 'same', активация = 'relu'), # MaxPooling2D (), # Conv2D (64, 3, padding = 'same', активация = 'relu'), # MaxPooling2D (), # Flatten (), #Dense (512, активация = 'relu'), # Dense (1, активация = 'sigmoid') #]) "" "Carregando o modelo o modelo` keras.applications.MobileNetV2`, compesos treinados para base imagenet e semas camadas totalmente conectadas. "" "# из импорта keras.layers Input # input_tensor = Input (shape = (IMG_HEIGHT, IMG_WIDTH, 32)) модель = tf.keras.applications.mobilenet_v2.MobileNetV2 (input_shape = (IMG_HEIGHT, IMG_WIDTH, 3), alpha = 1.0, include_top = False, weights = 'imagenet', input_tensor = None, pooling = 'max', classes = 2) model.trainable = False

Я ожидаю добавить полностьюподключенный слой в сети, но он вообще не добавляется.

1 Ответ

1 голос
/ 01 ноября 2019

Допустим, вы загружаете предварительно обученного MobileNetV2:

model = tf.keras.applications.mobilenet_v2.MobileNetV2()

. Вы можете проверить, как выглядит ваша модель, с помощью model.summary():

...
__________________________________________________________________________________________________
out_relu (ReLU)                 (None, 7, 7, 1280)   0           Conv_1_bn[0][0]
__________________________________________________________________________________________________
global_average_pooling2d (Globa (None, 1280)         0           out_relu[0][0]
__________________________________________________________________________________________________
Logits (Dense)                  (None, 1000)         1281000     global_average_pooling2d[0][0]
==================================================================================================
Total params: 3,538,984
Trainable params: 3,504,872
Non-trainable params: 34,112
__________________________________________________________________________________________________

Теперь, если хотите,отбросить свой последний слой ФК и создать еще один с одним нейроном. Это делается так:

penultimate_layer = model.layers[-2]  # layer that you want to connect your new FC layer to 
new_top_layer = tf.keras.layers.Dense(1)(penultimate_layer.output)  # create new FC layer and connect it to the rest of the model
new_model = tf.keras.models.Model(model.input, new_top_layer)  # define your new model

Теперь, если вы проверите с помощью new_model.summary(), вы увидите, что ваша новая модель была создана правильно.

...
__________________________________________________________________________________________________
out_relu (ReLU)                 (None, 7, 7, 1280)   0           Conv_1_bn[0][0]
__________________________________________________________________________________________________
global_average_pooling2d (Globa (None, 1280)         0           out_relu[0][0]
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 1)            1281        global_average_pooling2d[0][0]
==================================================================================================
Total params: 2,259,265
Trainable params: 2,225,153
Non-trainable params: 34,112
__________________________________________________________________________________________________

Наконец, чтобы заморозить веса всех слоев до последнего, просто выполните:

for layer in new_model.layers[:-2]:
    layer.trainable = False
...