Как я могу вставить скалярное значение и двоичное значение в слой (последний слой) в кератах? - PullRequest
0 голосов
/ 23 мая 2019

Я пытаюсь изменить сеть , которая реализована здесь .Эта сеть использует рентгеновские снимки images в качестве входных данных и классифицирует их по 14 категориям (13 типов заболеваний и не обнаружены).Сеть не учитывает возраст и пол пациента в качестве входных данных.Поэтому я хочу предоставить этой информации и сеть.Короче говоря, на последних 3 слоях сеть выглядит следующим образом:

bn (BatchNormalization)         (None, 7, 7, 1024)   4096        conv5_block16_concat[0][0]       
__________________________________________________________________________________________________
avg_pool (GlobalAveragePooling2 (None, 1024)         0           bn[0][0]                         
__________________________________________________________________________________________________
predictions (Dense)             (None, 14)           14350       avg_pool[0][0]  

Итак, что я сделал до сих пор, так это следующее: я просто выталкиваю последний плотный слой, используя model_vgg16.layers.pop().

Тогда, как указано, сеть превращается в:

bn (BatchNormalization)         (None, 7, 7, 1024)   4096        conv5_block16_concat[0][0]       
__________________________________________________________________________________________________
avg_pool (GlobalAveragePooling2 (None, 1024)         0           bn[0][0] 

Я знаю, что могу добавить слой, используя:

new_layer = Dense(14, activation='softmax', name='my_dense')

inp = model.input
out = new_layer(model.layers[-1].output)

model2 = Model(inp, out)

Но я не знаю, как добавить слой, которыйберет входные данные из предыдущего слоя вместе с 1 скалярным значением (age [0: 100]) и одним двоичным значением пол [0: 1].

Итак Как добавить последний слой, который принимаетвходные данные из предыдущего слоя вместе с 1 скалярным значением и 1 двоичным значением?

Редактировать: Базовая модель, которую я использую, - DenseNet121.Некоторые заключительные слои выглядят следующим образом: DenseNet121 some of the last layers

EDIT Способ загрузки модели следующий:

cp = ConfigParser()
cp.read(config_file)

# default config
output_dir = cp["DEFAULT"].get("output_dir")
base_model_name = cp["DEFAULT"].get("base_model_name")
class_names = cp["DEFAULT"].get("class_names").split(",")
image_source_dir = cp["DEFAULT"].get("image_source_dir")
image_dimension = cp["TRAIN"].getint("image_dimension")

output_weights_name = cp["TRAIN"].get("output_weights_name")
weights_path = os.path.join(output_dir, output_weights_name)
best_weights_path = os.path.join(output_dir, f"best_{output_weights_name}")
model_weights_path = best_weights_path

model_factory = ModelFactory()
model = model_factory.get_model(
    class_names,
    model_name=base_model_name,
    use_base_weights=False,
    weights_path=model_weights_path)

Сейчасмодель в переменной model.Затем, как предложено, я делаю

x = model.output
flat1 = Flatten()(x)

и получаю эту ошибку:

ValueError: вход 0 несовместим со слоем flatten_27: ожидается min_ndim = 3, найдено ndim = 2

Когда я повторяю то же самое после удаления последнего слоя, используя model.layers.pop()

Я все еще получаю ту же ошибку?Хотя я потратил пару часов, я не могу решить эту проблему.Так как это можно сделать?

Ответы [ 3 ]

1 голос
/ 24 мая 2019

попробуйте

from keras.applications.densenet import DenseNet121
from keras.layers import Dense, GlobalAveragePooling2D,concatenate

input_image = Input(shape=(224, 224, 3))
# normalize age
input_age_and_gender = Input(shape=(2,))
base_model = DenseNet121(input_tensor=input_image, weights='imagenet', include_top=False)
x = base_model.output
encoded_image = GlobalAveragePooling2D()(x)
out = concatenate([encoded_image,input_age_and_gender])
output = Dense(14, activation='softmax')(out)
model = Model([input_image,input_age_and_gender],output)
1 голос
/ 23 мая 2019

У вас может быть модель с несколькими входами.

Так что вместо использования это :

img_input = Input(shape=input_shape)

base_model = base_model_class(
    include_top=False,
    input_tensor=img_input,
    input_shape=input_shape,
    weights=base_weights,
    pooling="avg")
x = base_model.output
predictions = Dense(len(class_names), activation="sigmoid", name="predictions")(x)
model = Model(inputs=img_input, outputs=predictions)

Я не уверен, как там выглядит ваша base_model . НО ради этого проверьте следующее, где первый вход мнимый, а форма второго входа должна быть формой вашего age_gender_df.values:

input1 = Input(shape=(64,64,1))
conv11 = Conv2D(32, kernel_size=4, activation='relu')(input1)
pool11 = MaxPooling2D(pool_size=(2, 2))(conv11)
conv12 = Conv2D(16, kernel_size=4, activation='relu')(pool11)
pool12 = MaxPooling2D(pool_size=(2, 2))(conv12)
flat1 = Flatten()(pool12)
# INSTEAD OF THE ABOVE INPUT I WROTE YOU CAN USE YOUR BASE MODEL

input2 = Input(shape=(2,2)) # HERE THIS SHOULD BE THE SHAPE OF YOUR AGE/GENDER DF
layer = Dense(10, activation='relu')(input2)
flat2 = Flatten()(layer)

merge = concatenate([flat1, flat2])
# interpretation model
hidden1 = Dense(10, activation='relu')(merge)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(14, activation='linear')(hidden2)
model = Model(inputs=[input1, input2], outputs=output)

Резюме

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_30 (InputLayer)           (None, 64, 64, 1)    0                                            
__________________________________________________________________________________________________
conv2d_23 (Conv2D)              (None, 61, 61, 32)   544         input_30[0][0]                   
__________________________________________________________________________________________________
max_pooling2d_23 (MaxPooling2D) (None, 30, 30, 32)   0           conv2d_23[0][0]                  
__________________________________________________________________________________________________
conv2d_24 (Conv2D)              (None, 27, 27, 16)   8208        max_pooling2d_23[0][0]           
__________________________________________________________________________________________________
input_31 (InputLayer)           (None, 2, 2)         0                                            
__________________________________________________________________________________________________
max_pooling2d_24 (MaxPooling2D) (None, 13, 13, 16)   0           conv2d_24[0][0]                  
__________________________________________________________________________________________________
dense_38 (Dense)                (None, 2, 10)        30          input_31[0][0]                   
__________________________________________________________________________________________________
flatten_23 (Flatten)            (None, 2704)         0           max_pooling2d_24[0][0]           
__________________________________________________________________________________________________
flatten_24 (Flatten)            (None, 20)           0           dense_38[0][0]                   
__________________________________________________________________________________________________
concatenate_9 (Concatenate)     (None, 2724)         0           flatten_23[0][0]                 
                                                                 flatten_24[0][0]                 
__________________________________________________________________________________________________
dense_39 (Dense)                (None, 10)           27250       concatenate_9[0][0]              
__________________________________________________________________________________________________
dense_40 (Dense)                (None, 10)           110         dense_39[0][0]                   
__________________________________________________________________________________________________
dense_41 (Dense)                (None, 14)           154         dense_40[0][0]                   
==================================================================================================
Total params: 36,296
Trainable params: 36,296
Non-trainable params: 0

Визуализация:

enter image description here

EDIT:

В вашем случае я полагаю, что модель должна выглядеть следующим образом:

img_input = Input(shape=input_shape)

base_model = base_model_class(
    include_top=False,
    input_tensor=img_input,
    input_shape=input_shape,
    weights=base_weights,
    pooling="avg")
x = base_model.output
flat1 = Flatten()(x)

input2 = Input(shape=(2,2)) # HERE THIS SHOULD BE THE SHAPE OF YOUR AGE/GENDER DF
layer = Dense(10, activation='relu')(input2)
flat2 = Flatten()(layer)

merge = concatenate([flat1, flat2])
# interpretation model
hidden1 = Dense(10, activation='relu')(merge)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(14, activation='linear')(hidden2)
model = Model(inputs=[img_input, input2], outputs=output)
0 голосов
/ 27 мая 2019

Проблема решается путем сначала удаления последнего слоя (слоя прогнозирования) с помощью

model_original.layers.pop()

Затем определения другой модели, которая является копией исходной модели, за исключением последнего слоя

model2 = keras.Model(model_original.input, model_original.layers[-1].output)

после этого определяется вход, в который входит возраст

age = layers.Input(shape=(1,))

Далее, возраст и последний слой предыдущегоопределенная сеть объединяется с использованием

x = model2.output concatenated = layers.concatenate([x, age])

На последнем шаге после объединения добавляется слой прогнозирования для завершения сети

output = Dense(14, activation='linear')(concatenated) model3 = keras.Model(inputs=[model_original.input, age], outputs=output)

Итак, финальные слои дизайна выглядят так: final design

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...