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