2017-11-17 38 views
0

我是Keras和Tensorflow的新手。我正在使用深度学习来开展面部识别项目。我使用此代码(输出softmax图层)将输入主题的类标签作为输出获得,并且我的100个类的自定义数据集的准确率为97.5%。如何使用keras和tensorflow后端将密集层的输出作为一个numpy数组?

但是现在我对特征向量表示感兴趣,所以我想通过网络传递测试图像并在softmax(最后一层)之前从激活的密集层提取输出。我提到了Keras的文档,但似乎没有任何效果。任何人都可以请帮助我如何从密集层激活提取输出并保存为一个numpy数组?提前致谢。

class Faces: 
    @staticmethod 
    def build(width, height, depth, classes, weightsPath=None): 
     # initialize the model 
     model = Sequential() 
     model.add(Conv2D(100, (5, 5), padding="same",input_shape=(depth, height, width), data_format="channels_first")) 
     model.add(Activation("relu")) 
     model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2),data_format="channels_first")) 

     model.add(Conv2D(100, (5, 5), padding="same")) 
     model.add(Activation("relu")) 
     model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), data_format="channels_first")) 

     # 3 set of CONV => RELU => POOL 
     model.add(Conv2D(100, (5, 5), padding="same")) 
     model.add(Activation("relu")) 
     model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2),data_format="channels_first")) 

     # 4 set of CONV => RELU => POOL 
     model.add(Conv2D(50, (5, 5), padding="same")) 
     model.add(Activation("relu")) 
     model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2),data_format="channels_first")) 

     # 5 set of CONV => RELU => POOL 
     model.add(Conv2D(50, (5, 5), padding="same")) 
     model.add(Activation("relu")) 
     model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), data_format="channels_first")) 

     # 6 set of CONV => RELU => POOL 
     model.add(Conv2D(50, (5, 5), padding="same")) 
     model.add(Activation("relu")) 
     model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), data_format="channels_first")) 

     # set of FC => RELU layers 
     model.add(Flatten()) 
     #model.add(Dense(classes)) 
     #model.add(Activation("relu")) 

     # softmax classifier 
     model.add(Dense(classes)) 
     model.add(Activation("softmax")) 

     return model 

ap = argparse.ArgumentParser() 
ap.add_argument("-l", "--load-model", type=int, default=-1, 
    help="(optional) whether or not pre-trained model should be loaded") 
ap.add_argument("-w", "--weights", type=str, 
    help="(optional) path to weights file") 
args = vars(ap.parse_args()) 


path = 'C:\\Users\\Project\\FaceGallery' 
image_paths = [os.path.join(path, f) for f in os.listdir(path)] 
images = [] 
labels = [] 
name_map = {} 
demo = {} 
nbr = 0 
j = 0 
for image_path in image_paths: 
    image_pil = Image.open(image_path).convert('L') 
    image = np.array(image_pil, 'uint8') 
    cv2.imshow("Image",image) 
    cv2.waitKey(5) 
    name = image_path.split("\\")[4][0:5] 
    print(name) 
    # Get the label of the image 
    if name in demo.keys(): 
     pass 
    else: 
     demo[name] = j 
     j = j+1 
    nbr =demo[name] 

    name_map[nbr] = name 
    images.append(image) 
    labels.append(nbr) 
print(name_map) 
# Training and testing data split ratio = 60:40 
(trainData, testData, trainLabels, testLabels) = train_test_split(images, labels, test_size=0.4) 

trainLabels = np_utils.to_categorical(trainLabels, 100) 
testLabels = np_utils.to_categorical(testLabels, 100) 

trainData = np.asarray(trainData) 
testData = np.asarray(testData) 

trainData = trainData[:, np.newaxis, :, :]/255.0 
testData = testData[:, np.newaxis, :, :]/255.0 

opt = SGD(lr=0.01) 
model = Faces.build(width=200, height=200, depth=1, classes=100, 
        weightsPath=args["weights"] if args["load_model"] > 0 else None) 

model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) 
if args["load_model"] < 0: 
    model.fit(trainData, trainLabels, batch_size=10, epochs=300) 
(loss, accuracy) = model.evaluate(testData, testLabels, batch_size=100, verbose=1) 
print("Accuracy: {:.2f}%".format(accuracy * 100)) 
if args["save_model"] > 0: 
    model.save_weights(args["weights"], overwrite=True) 

for i in np.arange(0, len(testLabels)): 
    probs = model.predict(testData[np.newaxis, i]) 
    prediction = probs.argmax(axis=1) 
    image = (testData[i][0] * 255).astype("uint8") 
    name = "Subject " + str(prediction[0]) 
    if prediction[0] in name_map: 
     name = name_map[prediction[0]] 
    cv2.putText(image, name, (5, 20), cv2.FONT_HERSHEY_PLAIN, 1.3, (255, 255, 255), 2) 
    print("Predicted: {}, Actual: {}".format(prediction[0], np.argmax(testLabels[i]))) 
    cv2.imshow("Testing Face", image) 
    cv2.waitKey(1000) 

回答

0

参见https://keras.io/getting-started/faq/我怎样才能获得的中间层的输出?

您需要通过为定义添加“名称”参数来命名要输出的图层。如.. model.add(Dense(xx, name='my_dense'))
然后,您可以定义一个中间模型,并通过执行类似运行...

m2 = Model(inputs=model.input, outputs=model.get_layer('my_dense').output) 
Y = m2.predict(X) 
+0

我得到这样的输出: *张量( “dense_1/BiasAdd:0”,形状=( ?,442),dtype = float32)* 但我需要打印一个numpy数组,它是输入图像的一个特征表示。 – TheBiometricsGuy

+0

在上面的例子中,X需要是一个numpy数组(即真实数据)。 keras model.predict()函数通过Tensorflow图处理该数据并返回一个numpy数组。 “张量”类型是用于创建图形的内部变量。你不应该看到这是来自model.predict()的输出 – bivouac0

相关问题