使用Keras进行三元组损失训练时崩溃

我正在尝试实现一个简单的面部识别应用程序,但已经几天被一个问题困扰了。希望有在这方面更有经验的人能提供帮助。希望如此。

这是我的程序:

import tensorflow as tf#from keras.applications.vgg16 import VGG16from keras.applications.resnet50 import ResNet50, preprocess_inputfrom keras.preprocessing import image#import PIL#from PIL import Imagefrom keras.models import Modelfrom keras.layers import Dense, Input, subtract, concatenate, Lambda, add, maximumfrom keras import backend as Kfrom keras.preprocessing.image import ImageDataGeneratorfrom keras.optimizers import Adamimport numpy as npdef identity_loss(y_true, y_pred):    return K.mean(y_pred - 0 * y_true)def triplet_loss(inputs, dist='euclidean', margin='maxplus'):    anchor, positive, negative = inputs    positive_distance = K.square(anchor - positive)    negative_distance = K.square(anchor - negative)    if dist == 'euclidean':        positive_distance = K.sqrt(K.sum(positive_distance, axis=-1, keepdims=True))        negative_distance = K.sqrt(K.sum(negative_distance, axis=-1, keepdims=True))    elif dist == 'sqeuclidean':        positive_distance = K.sum(positive_distance, axis=-1, keepdims=True)        negative_distance = K.sum(negative_distance, axis=-1, keepdims=True)    loss = positive_distance - negative_distance    if margin == 'maxplus':        loss = K.maximum(0.0, 1 + loss)    elif margin == 'softplus':        loss = K.log(1 + K.exp(loss))    return K.mean(loss)model = ResNet50(weights='imagenet')model.layers.pop()x = model.get_layer('flatten_1').outputmodel_out = Dense(128, activation='relu',  name='model_out')(x)model_out = Lambda(lambda  x: K.l2_normalize(x,axis=-1))(model_out)new_model = Model(inputs=model.input, outputs=model_out)anchor_input = Input(shape=(224, 224, 3), name='anchor_input')pos_input = Input(shape=(224, 224, 3), name='pos_input')neg_input = Input(shape=(224, 224, 3), name='neg_input')encoding_anchor   = new_model(anchor_input)encoding_pos      = new_model(pos_input)encoding_neg      = new_model(neg_input)loss = Lambda(triplet_loss)([encoding_anchor, encoding_pos, encoding_neg])siamese_network = Model(inputs  = [anchor_input, pos_input, neg_input],                         outputs = loss)siamese_network.compile(optimizer=Adam(lr=.00001), loss=identity_loss)#########################   For reading img path info - start ##########train_path1 = '/home/cesncn/Desktop/github_projects/face_recog_proj_with_triplet_loss/training_img_pairs.csv'TRAIN_INPUT_PATHS = [train_path1]RECORD_DEFAULTS_TRAIN = [[0], [''], [''], ['']]def decode_csv_train(line):   parsed_line = tf.decode_csv(line, RECORD_DEFAULTS_TRAIN)   anchor_path = parsed_line[1]   pos_path  = parsed_line[2]   neg_path    = parsed_line[3]   return anchor_path, pos_path, neg_path#########################   For reading img path info - end ##########batch_size = 16filenames = tf.placeholder(tf.string, shape=[None])dataset = tf.data.Dataset.from_tensor_slices(filenames)dataset = dataset.flat_map(lambda filename: tf.data.TextLineDataset(filename).skip(1).map(decode_csv_train))dataset = dataset.shuffle(buffer_size=1000)dataset = dataset.batch(batch_size)iterator = dataset.make_initializable_iterator()next_element = iterator.get_next()init_global_var = tf.global_variables_initializer() with tf.Session() as sess:    sess.run(init_global_var)    nr_epochs = 5    for i in range(0, nr_epochs):        print("\nnr_epoch: ", str(i), "\n")        sess.run(iterator.initializer, feed_dict={filenames: TRAIN_INPUT_PATHS})        while True:            try:              anchor_path, pos_path, neg_path = sess.run(next_element)              anchor_imgs = np.empty((0, 224, 224, 3))              pos_imgs = np.empty((0, 224, 224, 3))              neg_imgs = np.empty((0, 224, 224, 3))              for j in range (0, len(anchor_path)):                  anchor_img = image.load_img(anchor_path[j], target_size=(224, 224))                  anchor_img = image.img_to_array(anchor_img)                  anchor_img = np.expand_dims(anchor_img, axis=0)                  anchor_img = preprocess_input(anchor_img)                  anchor_imgs = np.append(anchor_imgs, anchor_img, axis=0)                  pos_img = image.load_img(pos_path[j], target_size=(224, 224))                  pos_img = image.img_to_array(pos_img)                  pos_img = np.expand_dims(pos_img, axis=0)                  pos_img = preprocess_input(pos_img)                  pos_imgs = np.append(pos_imgs, pos_img, axis=0)                  neg_img = image.load_img(neg_path[j], target_size=(224, 224))                  neg_img = image.img_to_array(neg_img)                  neg_img = np.expand_dims(neg_img, axis=0)                  neg_img = preprocess_input(neg_img)                  neg_imgs = np.append(neg_imgs, neg_img, axis=0)              # HERE IT CRASHES WHEN I CALL THE FIT FUNCTION! ! !              siamese_network.fit([anchor_imgs, pos_imgs, neg_imgs],                                   batch_size = batch_size,                                  epochs = 1,                                   verbose = 2)             except tf.errors.OutOfRangeError:              print("Out of range error triggered (looped through training set 1 time)")              break

当我调用函数siamese_network.fit(…)时,它会崩溃并给出以下错误,这对我来说完全没有意义!!

---------------------------------------------------------------------------AttributeError                            Traceback (most recent call last)<ipython-input-16-65401d04281c> in <module>()     61                                   batch_size = batch_size,     62                                   epochs = 1,---> 63                                   verbose = 2)      64      65               #siamese_network.fit({'anchor_input': anchor_imgs, 'pos_input': pos_imgs, 'neg_input': neg_imgs},~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)   1628             sample_weight=sample_weight,   1629             class_weight=class_weight,-> 1630             batch_size=batch_size)   1631         # Prepare validation data.   1632         do_validation = False~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)   1485         sample_weights = [_standardize_weights(ref, sw, cw, mode)   1486                           for (ref, sw, cw, mode)-> 1487                           in zip(y, sample_weights, class_weights, self._feed_sample_weight_modes)]   1488    1489         if check_array_lengths:~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/keras/engine/training.py in <listcomp>(.0)   1484                                                    self._feed_output_names)   1485         sample_weights = [_standardize_weights(ref, sw, cw, mode)-> 1486                           for (ref, sw, cw, mode)   1487                           in zip(y, sample_weights, class_weights, self._feed_sample_weight_modes)]   1488 ~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/keras/engine/training.py in _standardize_weights(y, sample_weight, class_weight, sample_weight_mode)    538     else:    539         if sample_weight_mode is None:--> 540             return np.ones((y.shape[0],), dtype=K.floatx())    541         else:    542             return np.ones((y.shape[0], y.shape[1]), dtype=K.floatx())AttributeError: 'NoneType' object has no attribute 'shape'

有人知道如何解决这个问题吗?


回答:

我尝试了三元组损失函数的几种变体。上面版本只是其中一种尝试…

无论如何,在上面的版本中,问题似乎是这样的:

这是我创建和编译模型的方式:

siamese_network = Model(inputs  = [anchor_input, pos_input, neg_input],                         outputs = loss)siamese_network.compile(optimizer=Adam(lr=.00001), loss=identity_loss)

显然,我在这里说模型有一个输出,称为“loss”。

后来当我训练模型时,我在fit函数中将y设置为null。这是一个大错误。

z = [0]    # ADDED LINEsiamese_network.fit(x = [anchor_imgs, pos_imgs, neg_imgs],                     y = z     # ADDED LINE                    batch_size = batch_size,                    epochs = 1,                     verbose = 2) 

这个修复解决了问题。

我选择回答这个问题而不是删除它。希望这能帮助那些可能有类似问题的人..

附注:如果在Keras中没有设置y,它默认设置为NULL。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注