Как обучить сочетание изображения и данных в CNN с помощью ImageAugmentation в TFlearn

Я хотел бы обучить сверточную нейронную сеть в Tflearn-Tensorflow, используя сочетание изображений (информация о пикселях) и данных. Поскольку у меня небольшое количество изображений, мне нужно использовать увеличение изображения, чтобы увеличить количество образцов изображений, которые я передаю в сеть. Но это означает, что я могу передавать данные изображения только в качестве входных данных, а данные, не относящиеся к изображению, нужно добавлять на более позднем этапе, предположительно до полносвязного слоя. Я не могу понять, как это сделать, так как кажется, что я могу только сообщить сети, какие данные использовать, когда я вызываю model.fit({'input': ), и я не могу передать конкатенацию обоих типов data там как input_data вызывает непосредственно увеличение изображения. Есть ли какая-либо конкатенация, которую я могу выполнить на промежуточном этапе, чтобы добавить дополнительные данные или какие-либо другие альтернативы, которые позволят мне использовать ImageAugmentation и данные, не относящиеся к изображениям, которые мне нужны для обучения сети? Мой код с некоторыми комментариями ниже. Большое спасибо.

import tensorflow as tf
import tflearn
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.estimator import regression

#px_train:pixel data, data_train: additional data 
px_train, data_train, px_cv, data_cv, labels_train, labels_cv = prepare_data(path, filename)

img_aug = ImageAugmentation()
img_aug.add_random_flip_leftright()
img_aug.add_random_rotation(max_angle = 89.)
img_aug.add_random_blur(sigma_max=3.)
img_aug.add_random_flip_updown()
img_aug.add_random_90degrees_rotation(rotations = [0, 1, 2, 3])

#I can only pass image data here to apply data_augmentation 
convnet = input_data(shape = [None, 96, 96, 1], name = 'input', data_augmentation = img_aug)

convnet = conv_2d(convnet, 32, 2, activation = 'relu')
convnet = max_pool_2d(convnet, 2)                                   

convnet = conv_2d(convnet, 64, 2, activation = 'relu')
convnet = max_pool_2d(convnet, 2)                                   

convnet = tf.reshape(convnet, [-1, 24*24*64])    
#convnet = tf.concat((convnet, conv_feat), 1)
#If I concatenated data like above, where could I tell Tensorflow to assign the variable conv_feat to my 'data_train' values?

convnet = fully_connected(convnet, 1024, activation = 'relu')
convnet = dropout(convnet, 0.8)

convnet = fully_connected(convnet, 99, activation = 'softmax')
convnet = regression(convnet, optimizer = 'adam', learning_rate = 0.01, loss = 'categorical_crossentropy', name = 'labels')

model = tflearn.DNN(convnet)

#I can't add additional 'input' labels here to pass my 'data_train'. TF gives error.
model.fit({'input': np.array(px_train).reshape(-1, 96, 96, 1)}, {'labels': labels_train}, n_epoch = 50, validation_set = ({'input': np.array(px_cv).reshape(-1, 96, 96, 1)}, {'labels': labels_cv}), snapshot_step = 500, show_metric = True, run_id = 'Test')

person Brisa    schedule 13.03.2017    source источник


Ответы (1)


Если вы посмотрите документацию для метода model.fit: http://tflearn.org/models/dnn/ . Чтобы указать несколько входных данных для model.fit, вам просто нужно передать их в виде списка, т.е. model.fit([X1, X2], Y). Таким образом, X1 передается первому имеющемуся у вас слою input_data, а X2 передается второму слою input_data.

Если вы хотите объединить разные слои, вы можете взглянуть на слой слияния в Tflearn: http://tflearn.org/layers/merge_ops/

Редактировать 1:

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

import tensorflow as tf
import tflearn
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.estimator import regression
from tflearn.layers.merge_ops import merge
from tflearn.data_augmentation import ImageAugmentation

img_aug = ImageAugmentation()
img_aug.add_random_flip_leftright()
img_aug.add_random_rotation(max_angle = 89.)
img_aug.add_random_blur(sigma_max=3.)
img_aug.add_random_flip_updown()
img_aug.add_random_90degrees_rotation(rotations = [0, 1, 2, 3])

convnet = input_data(shape = [None, 96, 96, 1], data_augmentation = img_aug)
convfeat = input_data(shape = [None, 120])

convnet = conv_2d(convnet, 32, 2, activation = 'relu')
convnet = max_pool_2d(convnet, 2)                                   

convnet = conv_2d(convnet, 64, 2, activation = 'relu')
convnet = max_pool_2d(convnet, 2)                                   

# To merge the layers they need to have same dimension
convnet = fully_connected(convnet, 120) 
convnet = merge([convnet, convfeat], 'concat')

convnet = fully_connected(convnet, 1024, activation = 'relu')
convnet = dropout(convnet, 0.8)

convnet = fully_connected(convnet, 99, activation = 'softmax')
convnet = regression(convnet, optimizer = 'adam', learning_rate = 0.01, loss = 'categorical_crossentropy', name = 'labels')

model = tflearn.DNN(convnet)

# Give multiple inputs as a list
model.fit([np.array(px_train).reshape(-1, 96, 96, 1), np.array(data_train).reshape(-1, 120)], 
           labels_train, 
           n_epoch = 50, 
           validation_set = ([np.array(px_cv).reshape(-1, 96, 96, 1), np.array(data_cv).reshape(-1, 120)], labels_cv), 
           snapshot_step = 500, 
           show_metric = True, 
           run_id = 'Test')
person Nicki Skafte    schedule 13.03.2017
comment
Привет Ники, спасибо за ваш ответ, но не могли бы вы быть более конкретным? Когда я добавляю еще один слой input_data: conv_feat = input_data(shape = [None, 120], name = 'input'), я получаю сообщение об ошибке: не удалось транслировать входной массив из формы (792,96,96,1) в форму ( 792). Кажется, он пытается переформатировать данные из первых input_data в форму вторых input_data, а не выбирать второй элемент списка из model.fit, который теперь: model.fit({'input': [ np.array(px_train).reshape(-1, 96, 96, 1), np.array(data_train).reshape(-1, 120)]},... - person Brisa; 13.03.2017
comment
Я попытался отредактировать свой ответ так, чтобы он включал пример того, что я пытался объяснить :) - person Nicki Skafte; 14.03.2017
comment
Большое спасибо, Ники, это работает! :) Также я обнаружил, что конкатенация входных данных тоже работает: convnet = tf.concat((convnet, conv_feat), 1) если мы удалим тег name = 'input' из input_data(...). Только когда я удалил его, Tensorflow выбрал оба входа из model.fit({'input': [X1, X2]},...). - person Brisa; 14.03.2017
comment
Это хорошо, но я использую Keras. Я не могу найти способ использовать этот аргумент data_augmentation в функции ввода. Кто-нибудь делал это в Керасе? Любая помощь будет оценена по достоинству. Спасибо - person Nib; 27.07.2017