#python #tensorflow #conv-neural-network
#python #tensorflow #conv-нейронная сеть
Вопрос:
Я работаю с медицинскими данными и пытаюсь построить модель TF с 2 входами.
-Первый вход представляет собой массив numpy, содержащий данные о нескольких пациентах. Некоторые тесты регулярно выполняются для каждого пациента (например, проверка веса пациента). Они будут появляться несколько раз в моем массиве.
-Второй — это изображение легких пациента.
Предположим, у меня есть 2 пациента по имени Боб и Джин. Боб был протестирован 3 раза, а Жан был протестирован 2 раза. У меня будет 3 строки в массиве для Боба и 2 строки для Джин. Но для каждого пациента у меня есть только одно изображение. Итак, в моем DataGenerator мне придется использовать это изображение 3 раза для каждой строки.
Мой первый ввод будет выглядеть так:
['Name', 'Age', 'Weight']
['Bob', 54, 80]
['Bob', 55, 81]
['Bob', 52, 79]
['Jean', 40, 90]
['Jean', 41, 88]
И второй, подобный этому:
Bob_img = 'Array representing the image of Bob lungs'
Jean_img = 'Array representing the image of Jean lungs'
[Picture_array]
[Bob_img]
[Bob_img]
[Bob_img]
[Jean_img]
[Jean_img]
Я хочу создать CNN для обработки изображения, а затем объединить выходные данные CNN с массивом numpy.
В моем втором вводе есть повторение изображений. Он использует много оперативной памяти и выполняет одно и то же вычисление в CNN несколько раз. Итак, я хотел бы знать, есть ли какой-либо способ ее оптимизировать?
Модель более сложная, чем в следующем коде, но у вас должна быть идея с ней.
image_input = K.Input(shape=(512, 512, 60,), name="img_input")
x = tf.keras.layers.Conv2D(filters=64, kernel_size=(3, 3), padding='same', activation='relu')(image_input)
x = tf.keras.layers.Conv2D(filters=64, kernel_size=(3, 3), padding='same', activation='relu')(x)
x = tf.keras.layers.MaxPool2D(pool_size=(2,2),strides=(2,2))(x)
cnn_output = tf.keras.layers.Flatten()(x)
numpy_input = K.Input(shape=(10,), name="numpy_input")
x = tf.keras.layers.concatenate([cnn_output, numpy_input], axis=1)
x = tf.keras.layers.Dense(32, activation='relu')(x)
x = tf.keras.layers.Dense(1, activation='relu')(x)
output= tf.keras.layers.Dense(1)(x)
model = K.Model(inputs=[image_input, numpy_input], outputs=output)
Построение модели:
tf.keras.utils.plot_model(model, show_shapes=True)
Комментарии:
1. Что вы подразумеваете под «Во-вторых, повторение образа «Пациента» каждый раз, когда он появляется, потребляет память»? Было бы полезно, если бы вы могли подробнее рассказать о своей проблеме.
2. @ShubhamPanchal Я отредактировал сообщение. Скажите мне, понятно ли это.
3. Понятия «У каждого «пациента» может быть несколько строк» и «повторение изображения «Пациента» каждый раз, когда он появляется, потребляет память» неясны, можете ли вы дать более подробную информацию.
4. @TouYou Я обновил сообщение. Тесты регулярно проводятся для каждого пациента. Каждый тест будет отображаться как строка в моем массиве. Изображение уникально для каждого пациента. Для каждой строки пациента я использую это изображение. Повторение этого изображения использует слишком много оперативной памяти. И изображение вычисляется несколько раз по CNN.
5. image_input = K.Input(форма = (512, 512, 60,) вы имели в виду форму = (512, 512, 60) с 60 каналами?
Ответ №1:
Наконец-то найден ответ: можно реализовать обучение с нуля. Затем решение состоит в том, чтобы перенаправить CNN, затем дополнить прямой проход CNN табличным вводом и применить прямой проход второй части NN. Наконец, мне просто нужно применить обратное распространение. Я поместил ссылку на руководство по написанию обучения с нуля здесь. И мой код, если он может быть полезен:
epochs = 1
for epoch in range(epochs):
print("nStart of epoch %d" % (epoch,))
j=0
# Iterate over the batches of the dataset.
for [X1, X2], Y in generator:
# Open a GradientTape to record the operations run
# during the forward pass, which enables auto-differentiation.
with tf.GradientTape() as tape:
# Forward pass for CNN
out_imgs = CNN(X2)
# Replicate the forward pass in the same order than the numpy array
patients = X1.loc[:, 'Patient'].unique()
X_imgs = np.empty([X1.shape[0], out_imgs.shape[1]])
for i in range(len(patients)):
X_imgs[np.where(X1['Patient']==patients[i])] = out_imgs.numpy()[i]
# Concatenate the forward pass with the numpy array
inp_mlp = [tf.keras.layers.concatenate([0.1*X_imgs, np.asarray(X1[temp_SELECTED_COLUMNS])], axis=1)]
# Forward pass of the second part of the layer
for layer in model.layers[-3:]:
inp_mlp.append(layer(inp_mlp[-1]))
# Calculate loss
loss = model.compiled_loss(tf.constant(Y), inp_mlp[-1], regularization_losses=model.losses)