-2

so I've been working on this facial identification project. It's for my science fair and I'm in the phase where I'm trying to get data graphs, plots, and visualizations. I've got it to work to some extent, but it's not consistent (in terms of execution).

The thing is, sometimes the code works, sometimes it'll give me an error. For some context, the error is with Numpy append(). I have a variable I want to append data to but when it doesn't work the error is AttributeError: 'numpy.ndarray' object has no attribute 'append'

#Although the results aren't as expected, this can make for a good demo in ISEF
#The whole refresh after a face is detected is cool and can be used to show how different faces cluster

# Numerical computation requirements
import numpy as np 
from numpy import linalg, load, expand_dims, asarray, savez_compressed, append
from numpy.linalg import norm
import pandas as pd

# Plotting requirements
import matplotlib
from matplotlib import pyplot as plt
import matplotlib.patheffects as PathEffects
from matplotlib.animation import FuncAnimation as ani
import seaborn as sb

# Clustering requirements
import sklearn
from sklearn.cluster import KMeans
from sklearn.manifold import TSNE
from sklearn.preprocessing import scale

# Miscellaneous requirements
import os
import cv2
from PIL import Image
from mtcnn.mtcnn import MTCNN
from keras.models import load_model
from scipy.spatial.distance import squareform, pdist

# Initialize RNG seed and required size for Facenet
seed = 12345678
size = (160,160)

# Required networks
facenet = load_model('facenet_keras.h5')
fd = MTCNN()

# Initialize Seaborn plots
sb.set_style('darkgrid')
sb.set_palette('muted')
sb.set_context('notebook', font_scale=1.5, rc={'lines.linewidth': 2.5})

# Matplotlib animation requirements?
plt.style.use('fivethirtyeight')
fig = plt.figure()

# Load embeddings
data = load('jerome only npz/jerome embeddings.npz')
Data_1 = data['arr_0']

Dataset = []

for array in Data_1:
    Dataset.append(np.expand_dims(array, axis=0))

# Create cluster
cluster = KMeans(n_clusters=2, random_state=0).fit(Data_1)

y = cluster.labels_
z = pd.DataFrame(y.tolist())

faces = list()

def scatter(x,colors):
    palette = np.array(sb.color_palette('hls', 26))

    plot = plt.figure()
    ax = plt.subplot(aspect='equal')
    # sc = ax.scatter(x[:,0],x[:,1], lw =0, s=120, c=palette[colors.astype(np.int)])
    sc = ax.scatter(x[:,0],x[:,1], lw =0, s=120)
    labels = []

    return plot , ax, sc, labels

def detembed():
    cam = cv2.VideoCapture(0)
    _,frame = cam.read()
    info = fd.detect_faces(frame)
    if info != []:
        for i in info:
            print("*****************    FACE DETECTED *************************************************")
            x,yc,w,h = i['box']
            x,y = abs(x), abs(yc)
            w,h = abs(w), abs(h)
            xx, yy = x+w, yc+h
            #cv2.rectangle(frame, (x,y), (xx,yy), (0,0,255),2)
            face = frame[yc:yy, x:xx]
            image = Image.fromarray(face)
            image = image.resize(size)
            arr = asarray(image)

            arr = arr.astype('float32')
            mean, std = arr.mean(), arr.std()
            arr = (arr - mean) / std
            samples = expand_dims(arr, axis=0)
            faces.append(samples)
        #cv2.imshow('Camera Feed', frame)

while True:
    detembed()
    embeddings = Dataset
    if not faces:
        continue
    else:
        for face in faces:
            embeds = facenet.predict(face)
            #switch these if conflicts arise
            embeddings.append(embeds)
            embeddings = asarray(embeddings)

            embeddings = embeddings[:,0,:]

    cluster = KMeans(n_clusters=2, random_state=0).fit(Data_1)
    y = cluster.labels_

    points = TSNE(random_state=seed).fit_transform(embeddings)

    # here "y" dictates the color of the plots depending on the kmeans algorithm
    scatter(points,y)
    graph = ani(fig, scatter, interval=20)
    fcount = len(embeddings)
    plt.text(0,0,'{} points'.format(fcount))
    plt.show()

    # reset embeddings var to initial dataset
    Dataset = np.delete(Dataset, fcount - 1,0)
    embeddings = Dataset

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.release()
cv2.destroyAllWindows

Note that I am not a talented programmer; this code was botched from some example I found online. I had to pick up Python as I went along with this project. I do have a background in C, so I would say I get the basics of code logic.

Please help. I'm getting really desperate; the science fair is getting closer and I am a high schooler with no ML mentor. I live on an island (Guam) with no machine learning practitioners (not even in the university), so I turn to Stackoverflow.

Jerome Ariola
  • 135
  • 1
  • 11
  • The error is quite self-explanatory. Try to replace `embeddings.append(embeds)` by `np.append(embeddings, embeds)` – Théo Rubenach Mar 02 '20 at 11:27
  • Lists have an append method, numpy arrays do not. There is a np.append function, but I discourage its use. It's often used wrong. – hpaulj Mar 02 '20 at 11:35
  • If you start with a list, do an append, then change it to an array, the list append will no longer work. – hpaulj Mar 02 '20 at 11:58

1 Answers1

0

There's no issue with NumPy's append(). Here(3rd statement) you're trying to append a value to Numpy array without using NumPy's np.append().

Dataset.append(np.expand_dims(array, axis=0))

embeddings = Dataset

embeddings.append(embeds)

Since Datasets contain Numpy array after running the first statement, embeddings will also be a NumPy array and hence the operation fails whenever the execution comes here.

A simple fix would be to use this:

np.append(embeddings, embeds)

Or this,

embeddings = list(Dataset)

Hope that helps.

Raghul Raj
  • 1,428
  • 9
  • 24