Как добавить больше слоев к существующей модели (например, обучаемая модель машинного приложения)?

#machine-learning #computer-vision #keras-layer #conv-neural-network #image-classification

#машинное обучение #компьютерное зрение #keras-layer #conv-нейронная сеть #изображение-классификация

Вопрос:

Я пытаюсь использовать модель Google из обучаемого машинного приложения https://teachablemachine .withgoogle.com / добавив еще несколько слоев перед выходными слоями. Когда я переучиваю модель, всегда возвращается эта ошибка:

Ошибка значения: ввод 0 слоя dense_25 несовместим со слоем: ожидаемая ось -1 входной формы должна иметь значение 5, но полученный ввод с формой [20, 512]

Вот мой подход:

введите описание изображения здесь

При повторном обучении модели возвращается ошибка:

введите описание изображения здесь

Если я переобучу модель без добавления новых слоев, она работает нормально. Кто-нибудь может посоветовать, в чем проблема?

Ответ №1:

ОБНОВЛЕННЫЙ ОТВЕТ

если вы хотите добавить слои между двумя слоями для предварительно обученной модели, это не так просто, как добавление слоев с помощью метода add . если это будет сделано, это приведет к неожиданному поведению

анализ ошибки:

если вы скомпилируете модель, как показано ниже (как вы указали):

 model.layers[-1].add(Dense(512, activation ="relu"))
model.add(Dense(128, activation="relu"))
model.add(Dense(32))
model.add(Dense(5))
  

вывод сводки модели :

 Model: "sequential_12"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
sequential_9 (Sequential)    (None, 1280)              410208    
_________________________________________________________________
sequential_11 (Sequential)   (None, 512)               131672    
_________________________________________________________________
dense_12 (Dense)             (None, 128)               768       
_________________________________________________________________
dense_13 (Dense)             (None, 32)                4128      
_________________________________________________________________
dense_14 (Dense)             (None, 5)                 165       
=================================================================
Total params: 546,941
Trainable params: 532,861
Non-trainable params: 14,080
_________________________________________________________________
  

здесь все выглядит хорошо, но при ближайшем рассмотрении :

 for l in model.layers:
  print("layer : ", l.name, ", expects input  of shape : ",l.input_shape)
  

вывод :

 layer :  sequential_9 , expects input  of shape :  (None, 224, 224, 3)
layer :  sequential_11 , expects input  of shape :  (None, 1280)
layer :  dense_12 , expects input  of shape :  (None, 5) <-- **PROBLEM**
layer :  dense_13 , expects input  of shape :  (None, 128)
layer :  dense_14 , expects input  of shape :  (None, 32)
  

ПРОБЛЕМА здесь в том, что dense_12 ожидает ввода формы (None, 5), но он должен ожидать ввода формы (None, 512) поскольку мы добавили плотную (512) в sequential_11, возможной причиной может быть добавление слоев, подобных указанным выше, которые могут не обновлять некоторые атрибуты, такие как форма вывода sequential_11, поэтомуво время прямого прохождения происходит несоответствие между выводом sequential_11 и вводом слоя dense_12 (в вашем случае dense_25)

возможный обходной путь :

на ваш вопрос «добавление слоев между sequential_9 и sequential_11», вы можете добавить столько слоев, сколько захотите, между sequential_9 и sequential_11, но всегда убедитесь, что форма вывода последнего добавленного слоя должна соответствовать форме ввода, ожидаемой sequential_11. в данном случае это 1280.

код :

 sequential_1 = model.layers[0] # re-using pre-trained model
sequential_2 = model.layers[1]

from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Model

inp_sequential_1 = Input(sequential_1.layers[0].input_shape[1:])
out_sequential_1 = sequential_1(inp_sequential_1)

#adding layers in between sequential_9 and sequential_11
out_intermediate = Dense(512, activation="relu")(out_sequential_1)
out_intermediate = Dense(128, activation ="relu")(out_intermediate)
out_intermediate = Dense(32, activation ="relu")(out_intermediate)

# always make sure to include a layer with output shape matching input shape of sequential 11, in this case 1280
out_intermediate = Dense(1280, activation ="relu")(out_intermediate)

output = sequential_2(out_intermediate) # output of intermediate layers are given to sequential_11 

final_model = Model(inputs=inp_sequential_1, outputs=output)
  

вывод сводки модели:

 Model: "functional_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_5 (InputLayer)         [(None, 224, 224, 3)]     0         
_________________________________________________________________
sequential_9 (Sequential)    (None, 1280)              410208    
_________________________________________________________________
dense_15 (Dense)             (None, 512)               655872    
_________________________________________________________________
dense_16 (Dense)             (None, 128)               65664     
_________________________________________________________________
dense_17 (Dense)             (None, 32)                4128      
_________________________________________________________________
dense_18 (Dense)             (None, 1280)              42240     
_________________________________________________________________
sequential_11 (Sequential)   (None, 5)                 128600    
=================================================================
Total params: 1,306,712
Trainable params: 1,292,632
Non-trainable params: 14,080
  

Комментарии:

1. спасибо за ваше время. Я последовал вашему совету, к сожалению, он вернул другую ошибку.

2. Он вернул другую ошибку: —-> 4 ввода = Ввод (модель. layers[0].input_shape[0]) 296 ‘для ввода, а не для обоих одновременно.’) 297 если значение batch_input_shape равно None, shape равно None, а tensor равно None: —> 298 увеличьте значение ошибки (‘Пожалуйста, укажите для ввода либо shape ‘299’, либо tensor аргумент. Обратите внимание, что ‘ 300 ‘ shape не включает в себя ошибку batch ‘ ValueError: пожалуйста, укажите для ввода либо shape аргумент, либо tensor аргумент. Обратите внимание, что shape это не включает измерение пакета.

3. о, я забыл. layer.input_shape возвращает первую ось как None, которая представляет переменный размер пакета. не включая это, ошибка будет исправлена.

4. Это работает, но разрушает исходную архитектуру модели. Давайте вернемся к исходной модели выше, возможно ли добавить несколько слоев между sequential_9 и sequential_11, не разрушая ее архитектуру? Вы можете получить модель по ссылке github ниже: github.com/seansothey/Research_Project/blob/main /…

5. Потрясающе!!! Это работает, действительно ценю ваше время. Еще один вопрос, причина добавления плотного слоя 1280 перед выводом позже, заключается в том, чтобы следовать оригинальной архитектуре, потому что ожидается, что sequential_11 будет связан с 1280 единицами. Я прав?