Keras 'Tensor' 对象没有属性 'ndim'

Keras 'Tensor' object has no attribute 'ndim'

我正在尝试实现孪生网络(通过使用三元组损失方法)。我就是不能让它训练。经过多次尝试,我想我的问题出在生成器上(我在生成器中准备输入数据流进行训练),但到目前为止我无法定位问题。帮助! :)

这是我的模型定义(它基于 ResNet50)。

model = ResNet50(weights='imagenet')
model.layers.pop()
for layer in model.layers:
    layer.trainable = False
x = model.get_layer('flatten_1').output
model_out = Dense(128, activation='sigmoid',  name='model_out')(x)
new_model = Model(inputs=model.input, outputs=model_out)

这里我定义要训练的模型:

anchor_in = Input(shape=(224, 224, 3))
positive_in = Input(shape=(224, 224, 3))
negative_in = Input(shape=(224, 224, 3))

anchor_out = new_model(anchor_in)
positive_out = new_model(positive_in)
negative_out = new_model(negative_in)

merged_vector = concatenate([anchor_out, positive_out, negative_out], axis=-1)
# Define the model to be trained
siamese_model = Model(inputs=[anchor_in, positive_in, negative_in],
                      outputs=merged_vector)
siamese_model.compile(optimizer=Adam(lr=.001), loss=triplet_loss)

能够训练模型。我需要用生成器为它提供数据,我是这样定义它的:

(请注意,我故意在每个文件夹中只放 1 张图片只是为了开始。如果可以的话,我稍后会增加每个文件夹中的 # 图片。)

def generator_three_imgs():
    train_path = r'C:\Users\jon\Desktop\AI_anaconda\face_recognition\dataset\train\E'
    generator1 = ImageDataGenerator()
    generator2 = ImageDataGenerator()
    generator3 = ImageDataGenerator()
    anchor_train_batches = generator1.flow_from_directory(train_path+'\Ed_A', target_size=(224, 224), batch_size=1)
    positive_train_batches = generator2.flow_from_directory(train_path+'\Ed_P', target_size=(224, 224), batch_size=1)
    negative_train_batches = generator3.flow_from_directory(train_path+'\Ed_N', target_size=(224, 224), batch_size=1)
    while True:
        anchor_imgs, anchor_labels = anchor_train_batches.next()
        positive_imgs, positive_labels = positive_train_batches.next()
        negative_imgs, negative_labels = negative_train_batches.next()
        concat_out = concatenate([anchor_out, positive_out, negative_out], axis=-1)
        yield ([anchor_imgs, positive_imgs, negative_imgs], 
               concat_out)

最后,我尝试按如下方式训练模型:

siamese_model.fit_generator(generator_three_imgs(),
                            steps_per_epoch=1, epochs=15, verbose=2)

通过给出以下错误消息立即失败:

Epoch 1/15
Found 1 images belonging to 1 classes.
Found 1 images belonging to 1 classes.
Found 1 images belonging to 1 classes.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-23-7537b4595917> in <module>()
      1 siamese_model.fit_generator(generator_three_imgs(),
----> 2                             steps_per_epoch=1, epochs=15, verbose=2)

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
     89                 warnings.warn('Update your `' + object_name +
     90                               '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
   2228                     outs = self.train_on_batch(x, y,
   2229                                                sample_weight=sample_weight,
-> 2230                                                class_weight=class_weight)
   2231 
   2232                     if not isinstance(outs, list):

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training.py in train_on_batch(self, x, y, sample_weight, class_weight)
   1875             x, y,
   1876             sample_weight=sample_weight,
-> 1877             class_weight=class_weight)
   1878         if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
   1879             ins = x + y + sample_weights + [1.]

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
   1478                                     output_shapes,
   1479                                     check_batch_axis=False,
-> 1480                                     exception_prefix='target')
   1481         sample_weights = _standardize_sample_weights(sample_weight,
   1482                                                      self._feed_output_names)

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training.py in _standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
     74         data = data.values if data.__class__.__name__ == 'DataFrame' else data
     75         data = [data]
---> 76     data = [np.expand_dims(x, 1) if x is not None and x.ndim == 1 else x for x in data]
     77 
     78     if len(data) != len(names):

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training.py in <listcomp>(.0)
     74         data = data.values if data.__class__.__name__ == 'DataFrame' else data
     75         data = [data]
---> 76     data = [np.expand_dims(x, 1) if x is not None and x.ndim == 1 else x for x in data]
     77 
     78     if len(data) != len(names):

AttributeError: 'Tensor' object has no attribute 'ndim'

也许有人在这方面有更多经验..?


我发现我在上面粘贴了错误的数据。但这仍然不能解决问题。 Daniel Möller 在下面建议的解决方案解决了这个问题。

上面生成器函数的内容有错别字。更正后的(包括下面 Daniel 的建议)如下所示:

def generator_three_imgs(batch_size=1):
    train_path = r'C:\Users\sinthes\Desktop\AI_anaconda\face_recognition\dataset\train\E'
    generator1 = ImageDataGenerator()
    generator2 = ImageDataGenerator()
    generator3 = ImageDataGenerator()
    anchor_train_batches = generator1.flow_from_directory(train_path+'\Ed_A', target_size=(224, 224), batch_size=batch_size)
    positive_train_batches = generator2.flow_from_directory(train_path+'\Ed_P', target_size=(224, 224), batch_size=batch_size)
    negative_train_batches = generator3.flow_from_directory(train_path+'\Ed_N', target_size=(224, 224), batch_size=batch_size)
    while True:
        anchor_imgs, anchor_labels = anchor_train_batches.next()
        positive_imgs, positive_labels = positive_train_batches.next()
        negative_imgs, negative_labels = negative_train_batches.next()
        concat_out = np.concatenate([anchor_labels, positive_labels, negative_labels], axis=-1)
        yield ([anchor_imgs, positive_imgs, negative_imgs], 
               concat_out)

是的,您的生成器正在使用 keras 函数(用于张量)来连接 numpy 数据。

使用numpy.concatenate([anchor_labels, positive_labels, negative_labels], axis=-1)