как cambine CNN и RNN или emblendding? - PullRequest
0 голосов
/ 17 мая 2019

Я новичок в искусственном интеллекте и пытаюсь объединить сверточные нейронные сети и рекуррентные нейронные сети или встраивание.
Если в качестве входных данных у нас есть две данные, первая из которых является изображением, а другая - текстом, изображение соответствует изображению продукта, а текст соответствует его описанию, а выходными данными является проверка соответствия продукта описанию или нет.

Для этого я уже собрал набор данных, в котором у меня есть изображение и описание в формате JSON, у меня даже есть код Embedding и CNN, но я не знаю, как их объединить, чтобы решить эту проблему.

На изображении ниже вы можете увидеть модель, которую я пытаюсь разработать:

Markdown model

Для CNN я использую Resnet v2

def lr_schedule(epoch):

    lr = 1e-3
    if epoch > 180:
        lr *= 0.5e-3
    elif epoch > 160:
        lr *= 1e-3
    elif epoch > 120:
        lr *= 1e-2
    elif epoch > 80:
        lr *= 1e-1
    print('Learning rate: ', lr)
    return lr

def resnet_layer(inputs,
                 num_filters=16,
                 kernel_size=3,
                 strides=1,
                 activation='relu',
                 batch_normalization=True,
                 conv_first=True):

    conv = Conv2D(num_filters,
                  kernel_size=kernel_size,
                  strides=strides,
                  padding='same',
                  kernel_initializer='he_normal',
                  kernel_regularizer=l2(1e-4))

    x = inputs
    if conv_first:
        x = conv(x)
        if batch_normalization:
            x = BatchNormalization()(x)
        if activation is not None:
            x = Activation(activation)(x)
    else:
        if batch_normalization:
            x = BatchNormalization()(x)
        if activation is not None:
            x = Activation(activation)(x)
        x = conv(x)
    return x


def resnet_v2(input_shape, depth):

    if (depth - 2) % 9 != 0:
        raise ValueError('depth should be 9n+2 (eg 56 or 110 in [b])')
    # Start model definition.
    num_filters_in = 16
    num_res_blocks = int((depth - 2) / 9)

    inputs = Input(shape=input_shape)
    # v2 performs Conv2D with BN-ReLU on input before splitting into 2 paths
    x = resnet_layer(inputs=inputs,
                     num_filters=num_filters_in,
                     conv_first=True)

    # Instantiate the stack of residual units
    for stage in range(3):
        for res_block in range(num_res_blocks):
            activation = 'relu'
            batch_normalization = True
            strides = 1
            if stage == 0:
                num_filters_out = num_filters_in * 4
                if res_block == 0:  # first layer and first stage
                    activation = None
                    batch_normalization = False
            else:
                num_filters_out = num_filters_in * 2
                if res_block == 0:  # first layer but not first stage
                    strides = 2    # downsample

            # bottleneck residual unit
            y = resnet_layer(inputs=x,
                             num_filters=num_filters_in,
                             kernel_size=1,
                             strides=strides,
                             activation=activation,
                             batch_normalization=batch_normalization,
                             conv_first=False)
            y = resnet_layer(inputs=y,
                             num_filters=num_filters_in,
                             conv_first=False)
            y = resnet_layer(inputs=y,
                             num_filters=num_filters_out,
                             kernel_size=1,
                             conv_first=False)
            if res_block == 0:
                # linear projection residual shortcut connection to match
                # changed dims
                x = resnet_layer(inputs=x,
                                 num_filters=num_filters_out,
                                 kernel_size=1,
                                 strides=strides,
                                 activation=None,
                                 batch_normalization=False)
            x = keras.layers.add([x, y])

        num_filters_in = num_filters_out

    # Add classifier on top.
    # v2 has BN-ReLU before Pooling
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = AveragePooling2D(pool_size=8)(x)
    y = Flatten()(x)
    # Instantiate model.
    model = Model(inputs=inputs, outputs=y)
    return model

depth = 3 * 9 + 2
batch_size = 8
epochs = 200
num_classes = 10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
input_shape = x_train.shape[1:]
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
#x_train_mean = np.mean(x_train, axis=0)
#x_train -= x_train_mean
#x_test -= x_train_mean
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
print('y_train shape:', y_train.shape)

y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

save_dir = os.path.join(os.getcwd(), 'saved_models')
model_name = 'a101.h5'
if not os.path.isdir(save_dir):
    os.makedirs(save_dir)
filepath = os.path.join(save_dir, model_name)

checkpoint = ModelCheckpoint(filepath=filepath, monitor='val_acc', verbose=1, save_best_only=True)
lr_scheduler = LearningRateScheduler(lr_schedule)

model_image = resnet_v2(input_shape=input_shape, depth=depth)

model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.001), metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_test, y_test), shuffle=True, 
          callbacks=[checkpoint, lr_scheduler])

Для встраивания это мой код (он работает отлично):

class A101Dataset(Dataset):
   def __init__(self, json_file, images_dir, transform=None):
       self.fb_model = gensim.models.KeyedVectors.load_word2vec_format('./cc.tr.300.vec', encoding='utf-8')

       self.data = []
       with open(json_file, encoding='utf-8') as f:
           raw = json.load(f)
           for item in raw:
               for img in item['images']:
                   img_path = f'./Dataset/a101/images/{img}'
                   self.data.append((img_path, item['product_name']))
       self.transform = transform

   def __len__(self):
       return len(self.data)

   def __getitem__(self, idx):

       img_path, product_name = self.data[idx]

       words = product_name.split()
       sent_vec = np.mean([self.fb_model[w] for w in words], axis=0)
       print(sent_vec.shape)
#         image = io.imread(img_path)
       image = cv2.imread(img_path)
#         image = Image.open(img_path)
       sample = {'image': image, 'sent_vec': sent_vec}

       if self.transform:
           sample['image'] = self.transform(sample['image'])

       return sample

dataset = A101Dataset(json_file='./Dataset/a101/a101.json', images_dir='./Dataset/a101/images/')

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

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