精华内容
参与话题
问答
  • 深度学习kNN算法

    2020-10-29 15:57:59
    class kNN: def __init__(self): pass def fit(self, x_train, y_train): self.xtr = x_train self.ytr = y_train def predict(self, k, dis, x_test): assert dis == 'E' or dis == 'M' num_te.
    import numpy as np
    
    
    class kNN:
        def __init__(self):
            pass
    
        def fit(self, x_train, y_train):
            self.xtr = x_train
            self.ytr = y_train
    
        def predict(self, k, dis, x_test):
            assert dis == 'E' or dis == 'M'
            num_test = x_test.shape[0]  # 测试样本数量
            labelist = []
            # 使用欧式距离公式做为距离数量
            if dis == 'E':
                for i in range(num_test):
                    distances = np.sqrt(np.sum(((self.xtr - np.tile(x_test[i], (self.xtr.shape[0], 1))) ** 2), axis=1))
                    nearest_k = np.argsort(distances)  # 根据下标排序
                    topK = nearest_k[:k]  # 按照K值进行切片
                    classCount = {}  # 创建一个空字典
                    for i in topK:
                        classCount[self.ytr[i]] = classCount.get(self.ytr[i], 0) + 1
                    sortclassCount = sorted(classCount.items(), key=operator.itemgetter(1))
                    labelist.append(sortclassCount)
                return np.array(labelist)
            # 使用曼哈顿公式作为距离公式
            if dis == 'M':
                for i in range(num_test):
                    # 行相加
                    distances = np.sum(np.abs(self.xtr - np.tile(x_test[i], (self.xtr.shape[:0], 1))), axis=1)
                    nearest_k = np.argsort(distances)
                    topK = nearest_k[:k]
                    classCount = {}
                    for i in topK:
                        classCount[self.ytr[i]] = classCount.get(self.ytr[i], 0) + 1
                    sortedclassCount = sorted(classCount.items(), key= operatory.itemgetter(1))
                    labelist.append(sortedclassCount[0][0])
                return np.array(labelist)
    展开全文
  • 先来看深度学习的代码: # 由于发现使用KNN算法对于facebook地区的分类实在是缓慢 # 因此尝试使用深度学习的方法 import tensorflow as tf import numpy as np import pandas as pd from sklearn.model_selection ...

    先来看深度学习的代码:

    # 由于发现使用KNN算法对于facebook地区的分类实在是缓慢
    # 因此尝试使用深度学习的方法
    import tensorflow as tf
    import numpy as np
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    
    
    data = pd.read_csv("./train.csv")
    # print(data)
    # 2. 基本的数据处理
    # 1) 缩小数据范围
    data = data.query("x<2.5 & x>2 & y<1.5 & y>1.0")
    
    # time是时间戳,因此我们要把时间转换为我们能够理解的年月日时分秒
    time_value = pd.to_datetime(data["time"], unit='s')  #转换为正常的时间了
    # print(type(time_value))     #<class 'pandas.core.series.Series'>
    date = pd.DatetimeIndex(time_value)   #转换为年月日时分秒
    # 因为对我们有用的也就是日期、星期几、小时
    data['day'] = date.day
    data["weekday"] = date.weekday
    data["hour"] = date.hour
    
    # 去掉签到次数比较少的地点,分组聚合的方法
    place_count = data.groupby("place_id").count()["row_id"]   # 相当于获得了一个地点id签到了多少次,返回一个series
    # 过滤掉小于等于三次的:使用布尔索引,之前讲过,用自身过滤自身------place_count[place_count > 3]
    # 则data.index返回一个index类型的行索引列表,data.index.values返回的是行索引组成的ndarray类型。
    data_final = data[data["place_id"].isin(place_count[place_count > 3].index.values)]
    
    # 筛选特征值和目标值
    x = data_final[['x', 'y', 'accuracy', 'day', 'weekday', 'hour']]
    y = data_final['place_id']
    
    
    y = pd.get_dummies(y)
    long = len(y.columns.values)
    # print("y:\n", len)    # 事实证明此案例就950个地址
    # 划分数据集
    x_train, x_test, y_train, y_test = train_test_split(x, y)
    
    # # 特征工程: 标准化,注意训练集和测试集要做同样的手脚
    # transfer = StandardScaler()
    # x_train = transfer.fit_transform(x_train)
    # # 注意测试集不要用fit_transform,因为测试集需要用训练集的平均值和标准差
    # x_test = transfer.transform(x_test)
    
    
    x_train = x_train.values.astype(np.float32)
    x_train = x_train.reshape(-1, 6)
    y_train = y_train.values.astype(np.float32)
    y_train = y_train.reshape(-1, long)
    x_test = x_test.values.astype(np.float32)
    x_test = x_test.reshape(-1, 6)
    y_test = y_test.values.astype(np.float32)
    y_test = y_test.reshape(-1, long)
    # print("y_train", y_train)
    
    
    tfx = tf.placeholder(tf.float32, [None, 6], "inputx")
    tfy = tf.placeholder(tf.float32, [None, long], "inputy")
    
    # 输入神经网络进行模型训练,感觉网络结构不太行
    
    l1 = tf.layers.dense(tfx, 128, tf.nn.relu, name="l1")
    l2 = tf.layers.dense(l1, 128, tf.nn.relu, name="l2")
    l3 = tf.layers.dense(l2, 128, tf.nn.relu, name="l3")
    out = tf.layers.dense(l3, long, name="l4")
    prediction = tf.nn.softmax(out, name="pred")
    
    
    # print("prediction:", prediction)
    print("out的尺寸", out.shape)
    loss = tf.losses.softmax_cross_entropy(onehot_labels=tfy, logits=out)
    accuracy = tf.metrics.accuracy(          # return (acc, update_op), and create 2 local variables
        labels=tf.argmax(tfy, axis=1), predictions=tf.argmax(out, axis=1))[1]
    opt = tf.train.GradientDescentOptimizer(learning_rate=0.0001)
    train_op = opt.minimize(loss)
    
    sess = tf.Session()
    sess.run(tf.group(tf.global_variables_initializer(), tf.local_variables_initializer()))
    
    accuracies, steps = [], []
    for t in range(400000):
        # training
        batch_index = np.random.randint(len(x_train), size=1)    # 生成32个随机数,返回array数组
        # print("batch_index:\n", batch_index)
        sess.run(train_op, {tfx: x_train[batch_index], tfy: y_train[batch_index]})  # 注意feeddict可以不用了
        # if t % 400 == 0:
        #     print("x_train[batch_index]:\n", x_train[batch_index])
        #     print("y_train[batch_index]:\n", y_train[batch_index])
        #     print("out:\n", sess.run(out, {tfx: x_train[batch_index], tfy: y_train[batch_index]}))
    
        if t % 50 == 0:
            # testing
            acc_, pred_, loss_ = sess.run([accuracy, prediction, loss], {tfx: x_test, tfy: y_test})
            # print("prediction:", pred_)
            accuracies.append(acc_)
            steps.append(t)
            print("Step: %i" % t, "| Accurate: %.2f" % (acc_ * 100), "| Loss: %.2f" % loss_,)
            
    
    

    效果特别不好,刚开始两万步准确率才能到1%
    加入标准化以后准确率直接是0%
    因此得出一个结论就是,分类类别太多,深度学习不太好用(此案例分类类别共950个)
    可能是水平还不到位
    因此决定用K近邻算法,但是准确率又不太高:

    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.model_selection import GridSearchCV
    
    
    # 1.获取数据
    data = pd.read_csv("./train.csv")
    
    # 2. 基本的数据处理
    
    # 1) 缩小数据范围
    data = data.query("x<2.5 & x>2 & y<1.5 & y>1.0")
    
    # 2) 处理时间特征
    # data["time"]
    time_value = pd.to_datetime(data["time"], unit='s')  #转换为正常的时间了
    date = pd.DatetimeIndex(time_value)   #转换为年月日时分秒,以符合我们的习惯
    
    data['day'] = date.day
    data["weekday"] = date.weekday
    data["hour"] = date.hour
    # 3) 去掉签到次数比较少的地点,分组聚合的方法
    place_count = data.groupby("place_id").count()["row_id"]   #data.groupby("place_id").count()相当于统计place_id出现的次数
    
    # 过滤掉小于等于三次的:使用布尔索引,之前讲过,用自身过滤自身
    # place_count[place_count > 3].head()
    # 只取data中只含有过滤掉的place_id的行
    data_final = data[data["place_id"].isin(place_count[place_count > 3].index.values)]
    
    
    
    #筛选特征值和目标值
    x = data_final[['x', 'y', 'accuracy', 'day', 'weekday', 'hour']]
    y = data_final['place_id']
    
    #划分数据集
    x_train, x_test, y_train, y_test = train_test_split(x, y)
    
    
    
    
    #3.特征工程: 标准化,注意训练集和测试集要做同样的手脚
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    #注意测试集不要用fit_transform,因为测试集需要用训练集的平均值和标准差
    x_test = transfer.transform(x_test)
    
    #4.KNN算法预估器
    estimator = KNeighborsClassifier()
    
    # 加入网格搜索与交叉验证,上面括号里的n_neighbors=3没必要了
    # 参数准备
    param_dict = {"n_neighbors": [3,5,7,9]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)  #3折
    estimator.fit(x_train, y_train)
    
    #5.模型评估
    #方法一:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("比对真实值和预测值:\n", y_predict == y_test)
    
    #方法二:计算准确率
    accuracy = estimator.score(x_test, y_test)
    print("准确率为:\n", accuracy)
    
    # 因为这个例子中加入了网格搜索,因此可以调用方法查看最佳参数
    # 包括最佳参数、最佳结果、最佳估计器、每一步的交叉验证结果
    
    print("最佳参数k:\n", estimator.best_params_)
    print("最佳结果:\n", estimator.best_score_)   #也就是打十折的最佳准确率,是验证集而不是测试集的结果
    print("最佳估计器:\n", estimator.best_estimator_)
    print("交叉验证结果:\n", estimator.cv_results_)    #看不出什么门道
    

    如果仅仅用缩小范围的这些样本,准确率k=3的时候最好,为30%-40%之间,跟猜差不多
    如果跑全部样本,只采用k=3的话,跑了十二分钟都没跑完,就不看了
    因为是kaggle的案例
    平时做一些小的样本分析还是可以的

    展开全文
  • 文章目录引言人脸数据获取处理图片读取到并数组中调用opencv内置函数进行人脸识别knn算法进行人脸识别使用Dense层神经网络进行人脸识别 引言 人脸识别和人脸检测不同,人脸检测时检测到人脸位置,而人脸识别是基于...

    引言

    人脸识别和人脸检测不同,人脸检测时检测到人脸位置,而人脸识别是基于人脸数据库,进行一些识别操作如识别某一个人像是数据库中的哪个标签。

    需要说明的是,使用knn和Dense层的神经网络作为人脸识别算法只是我的尝试,在实际的使用中基本不使用这两种算法的。同时,经过实际测试,这样得到的结果极不准确,甚至可以说毫无效果(苦笑)。


    人脸数据获取

    进行人脸识别首先要有人脸数据库,我们可以用opencv调用摄像头,进行人脸检测,并将人脸灰度图片写入到(200, 200)的pgm文件作为我们的人脸数据库。

    code

    import cv2
    
    def generate():
        face_cascade = cv2.CascadeClassifier( # haar级联文件-人脸
            './cascades/haarcascade_frontalface_default.xml'
        )
        camera = cv2.VideoCapture(0)
        count = 0
    
        while True:
            ret, frame = camera.read()
            frame = cv2.flip(frame, 1)  # 翻转为正常角度
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #转灰度处理
            faces = face_cascade.detectMultiScale(gray, 1.3, 5) # 识别
    
            for (x, y, w, h) in faces:
                img = cv2.rectangle( # 画框图
                    frame, (x, y), (x + w, y + h), (255, 0, 0), 2
                )
                # cv2.putText(
                #     img, 'name', (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2
                # )
                f = cv2.resize(gray[y: y+h, x: x+w], (200, 200)) # 统一大小
                cv2.imwrite('./data/at/name/%s.pgm' % str(count), f) # 将人脸数据写入到pgm文件中
                count += 1
            if count == 200:
                break
    
            cv2.imshow('camera', frame)
            if cv2.waitKey(int(1000 / 12)) & 0xff == ord("q"): # 等待q键
                break
    
        camera.release()
        cv2.destroyAllWindows()
        return
    
    if __name__ == '__main__':
        generate()
    

    处理图片读取到并数组中

    这个代码是读取数据的模块,在后面的代码中多次调用以获取数据
    将上一步存储的图片数据转化为可处理的numpy数组,提供了两种相似的接口函数。

    read_images 为普通的读取到灰度的pgm图片返回的数组
    read_images_binary 是将pgm图片进行了二值化处理得到的数组数据

    返回的数据类型为 list, list, dict
    分别为 图片数据、图片标签、标签和人名的映射字典

    import os, sys, re
    import cv2
    import numpy as np
    
    def read_images(path, sz=None): # 读取自己的图片数据库
        c = 0
        X, y = [], []
        dic = {}
        for dirname, dirnames, filenames in os.walk(path): # 遍历文件夹下文件
            for subdirname in dirnames:
                subject_path = os.path.join(dirname, subdirname)
                # print("subdirname = ", dirname)
                # print("subject_path = ", subject_path)
                for filename in os.listdir(subject_path):
                    if filename[-4:] != '.pgm': # 如果文件不是pgm文件,那么跳过
                        continue
                    filepath = os.path.join(subject_path, filename) # 生成完整的文件名
                    # print(filepath)
                    im = cv2.imread(os.path.join(subject_path, filename), \
                                    cv2.IMREAD_GRAYSCALE) # 读取pgm图片
                    # print(np.shape(im))
                    # 改变大小
                    if sz is not None:
                        im = cv2.resize(im, (200, 200)) # 调整图片大小
    
                    X.append(np.asarray(im, dtype=np.uint8))
                    y.append(c)
                # print(re.findall(r'./data/at/(.*)', subject_path))
                dic[c] = re.findall(r'./data/at/(.*)', subject_path)[0]
                c = c + 1
        # print("c = ", c)
        # print(X)
        return [X, y], dic
    
    def read_images_binary(path, sz=None): # 读取自己的图片数据库
        c = 0
        X, y = [], []
        dic = {}
        for dirname, dirnames, filenames in os.walk(path): # 遍历文件夹下文件
            for subdirname in dirnames:
                subject_path = os.path.join(dirname, subdirname)
                # print("subdirname = ", dirname)
                # print("subject_path = ", subject_path)
                for filename in os.listdir(subject_path):
                    if filename[-4:] != '.pgm': # 如果文件不是pgm文件,那么跳过
                        continue
                    filepath = os.path.join(subject_path, filename) # 生成完整的文件名
                    # print(filepath)
                    im = cv2.imread(os.path.join(subject_path, filename), \
                                    cv2.IMREAD_GRAYSCALE) # 读取pgm图片
                    ret, im = cv2.threshold(im, 120, 255, cv2.THRESH_BINARY)
                    if sz is not None:
                        im = cv2.resize(im, (200, 200)) # 调整图片大小
    
                    X.append(np.asarray(im, dtype=np.uint8))
                    y.append(c)
                # print(re.findall(r'./data/at/(.*)', subject_path))
                dic[c] = re.findall(r'./data/at/(.*)', subject_path)[0]
                c = c + 1
        # print("c = ", c)
        # print(X)
        return [X, y], dic
    

    调用opencv内置函数进行人脸识别

    内置的三种人脸识别函数

    model = cv2.face.EigenFaceRecognizer_create() # 这个版本的opencv名字改了,和书上的有点不一样
    model = cv2.face.LBPHFaceRecognizer_create(1, 8, 8, 90)
    model = cv2.face.FisherFaceRecognizer_create()
    

    调用opencv-python提供的这三种人脸识别函数,发现效果都不好。人脸总是检测错误,准确率极低,要它何用?(不知道是不是我使用姿势不太正确)于是我催生出自己实现人脸识别算法那的念头。

    观察框出的人脸,觉得一个人的人脸图片,单单框出了人脸,那应该相似度很高啊。类似于手写数字识别,简单的knn算法可以达到很高的正确率,那么是不是可以用knn较好的解决这个问题。

    实践出来的结果是:不是的。

    code

    import cv2
    import numpy as np
    from PIL import Image, ImageDraw, ImageFont
    from getData import read_images
    
    def cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img)
        fontText = ImageFont.truetype(
            "SimHei.ttf", textSize, encoding="utf-8")
        draw.text((left, top), text, textColor, font=fontText)
        return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    
    def face_rec(): # 人脸识别
    
        [X, y], label2name = read_images('./data/at')
        print("label2name:", label2name)
        print(np.shape(X))
        print("label2name = ", label2name)
        print(np.shape(X))
        # print("y = ", y)
        y = np.asarray(y, dtype=np.int32)
    
        # 调用人脸识别函数生成模型
        # model = cv2.face.EigenFaceRecognizer_create() # 这个版本的opencv名字改了,和书上的有点不一样
        model = cv2.face.LBPHFaceRecognizer_create(1, 3, 8, 8)
        model.train(np.asarray(X), np.asarray(y)) # 训练
        camera = cv2.VideoCapture(0)
        face_cascade = cv2.CascadeClassifier( # 分类器检测人脸
            './cascades/haarcascade_frontalface_default.xml'
        )
        while True:
            read, img = camera.read()
            img = cv2.flip(img, 1)  # 翻转为正常角度
            faces = face_cascade.detectMultiScale(img, 1.3, 5)
            for (x, y, w, h) in faces:
                img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
                gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                roi = gray[x: x+2, y: y+h]
                roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
                params = model.predict(roi) # 预测
                print(params) # 返回 (图片标签, 置信度)
                if params[0] >= 0:
                    name = label2name[params[0]]
                else:
                    name = "未知"
                print("检测到%s" % name)
                print("label: %s, Confidence: %.2f" % (params[0], params[1]))
                img = cv2ImgAddText(img, name, x, y - 20, (255, 255, 0), 20)
                # cv2.putText(img, name, (x, y - 20),
                #             cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2) # putText只能写上ascii中的部分字符, 呵呵
            # print(img)
    
            cv2.imshow('camera', img)
            if cv2.waitKey(1000 // 12) & 0xff == ord("q"):
                break
        cv2.destroyAllWindows()
    
    if __name__ == "__main__":
        face_rec() # 人脸识别
    

    knn算法进行人脸识别

    简单的knn模板

    knn 实现

    import numpy as np
    import matplotlib.pyplot as plt
    from getData import read_images
    
    def knn(xtest, data, label, k): # xtest为测试的特征向量,data、label为“训练”数据集,k为设定的阈值
    #     print(xtest.shape)
    #     print(label.shape)
        exp_xtest = np.tile(xtest, (len(label), 1)) - data
        sq_diff = exp_xtest**2
        sum_diff = sq_diff.sum(axis=1)
        distance = sum_diff**0.5
        # print(distance)
        sort_index = distance.argsort()
        classCount = {}
        for i in range(k):
            one_label = label[sort_index[i]]
            classCount[one_label] = classCount.get(one_label, 0) + 1
        sortedClassCount = sorted(classCount.items(), key = lambda x:x[1], reverse=True)
        print(distance.sum())
        print(classCount)
        print(sortedClassCount)
        return sortedClassCount[0][0]
    
    def main():
        [X, y], label2name = read_images('./data/at/')
        print(np.shape(X))
        X = np.array(X)
        Xx = X.reshape(X.shape[0], 40000)
        xdata, label = Xx, y
        result = knn(np.array(xdata[67]), xdata, label, 3)
        print("result = ", label2name[result])
        return result
    
    if __name__ == '__main__':
        main()
    

    调用knn的主体部分

    import cv2
    import numpy as np
    from PIL import Image, ImageDraw, ImageFont
    from getData import read_images_binary
    from knn import knn
    
    
    def cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img)
        fontText = ImageFont.truetype(
            "SimHei.ttf", textSize, encoding="utf-8")
        draw.text((left, top), text, textColor, font=fontText)
        return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    
    def face_rec(): # 人脸识别
    
        [X, y], label2name = read_images_binary('./data/at')
        X = np.array(X)
        Xx = X.reshape(X.shape[0], 40000)
        xdata, label = Xx, y
    
        y = np.asarray(y, dtype=np.int32)
        face_cascade = cv2.CascadeClassifier( # 分类器检测人脸
            './cascades/haarcascade_frontalface_default.xml'
        )
        videoCapture = cv2.VideoCapture(0)
        while True:
            read, img = videoCapture.read()
            img = cv2.flip(img, 1)
            faces = face_cascade.detectMultiScale(img, 1.3, 5)
            for (x, y, w, h) in faces:
                img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
                gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                roi = gray[x: x+2, y: y+h]
                roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
                roi = np.array(roi).reshape(40000, )
                result = knn(roi, xdata, label, 3)
                print(result) # 返回结果的标签
                name = label2name[result]
                print("检测到%s" % name)
                img = cv2ImgAddText(img, name, x, y - 20, (255, 255, 0), 20)
            cv2.imshow('camera', img)
            if cv2.waitKey(1000 // 12) & 0xff == ord("q"):
                break
        cv2.destroyAllWindows()
    
    if __name__ == "__main__":
        face_rec() # 人脸识别
    

    使用Dense层神经网络进行人脸识别

    简单的神经网络多分类器实现(效果不好,大概是数据太少,每个人只有200张(200, 200) 的pgm图片数据。

    调用keras的高级API,搭积木一样的建立神经网络。

    即使是这么少的数据,训练一次的时间也要好几分钟。调参调了好久,关键是调不出效果啊~

    from getData import read_images, read_images_binary
    import numpy as np
    from tensorflow.keras import models
    from tensorflow.keras import layers
    
    def to_onehot(y): # 将标签转化为独热码oen-hot
        print("max of y = ", np.max(y))
        onehots = np.zeros((len(y), np.max(y) + 1), dtype=np.float)
        for i in range(len(y)):
            onehots[i][y[i]] = 1.0
        print("shape of onehots : ", np.shape(onehots))
        return onehots
    
    def get_model_dense(size=(200, 200)): # 设置一个全连接层网络,返回模型,未训练
        model = models.Sequential([
            layers.Dense(16, activation='relu', input_shape=((40000, ))),
            layers.Dense(16, activation='relu'),
            layers.Dense(16, activation='relu'),
            layers.Dense(4, activation='softmax')
        ])
        model.compile(
            optimizer='rmsprop',
            loss='categorical_crossentropy',
            metrics=['accuracy']
        )
        return model
    
    def k_fold_validation(train_data, train_targets):
        k = 4
        num_val_samples = len(train_data) // k
        num_epochs = 5
        all_scores = []
    
        for i in range(k):
            print('processing fole # ', i)
            val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples]
            val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples]
    
            partial_train_data = np.concatenate(
                [train_data[:i * num_val_samples],
                train_data[(i + 1) * num_val_samples:]],
                axis=0
            )
            partial_train_targets = np.concatenate(
                [train_targets[:i * num_val_samples],
                 train_targets[(i + 1) * num_val_samples:]],
                axis = 0
            )
            model = get_model_dense()
            model.fit(
                partial_train_data,
                partial_train_targets,
                epochs=num_epochs,
                batch_size=3
            )
            '''
            model5开始,对图片进行了阈值为120的图片二值化处理
            model6调整了参数(防止过拟合),从64调成16
            model7加了一层
            '''
            model.save('dense_model_7.h5')
            val_mse, val_mae = model.evaluate(val_data, val_targets)
            all_scores.append(val_mae)
    
    def main():
        [X, y], label2name = read_images_binary('./data/at/') # 调用人脸数据
        X = np.array(X).reshape(len(X), 40000) / 255
        y = to_onehot(np.array(y))
        index = np.arange(len(X))
        np.random.shuffle(index) # 生成打乱的索引
        print("index = ", index)
        X = X[index] # 得到打乱的数据
        y = y[index]
        print(X)
        print(y)
        print(X.shape)
        print(y.shape)
        k_fold_validation(X, y)
    
    
    if __name__ == "__main__":
        main()
    

    主体部分

    import cv2
    import numpy as np
    from PIL import Image, ImageDraw, ImageFont
    from getData import read_images
    from knn import knn
    from tensorflow.keras import models
    
    
    def cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img)
        fontText = ImageFont.truetype(
            "SimHei.ttf", textSize, encoding="utf-8")
        draw.text((left, top), text, textColor, font=fontText)
        return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    
    def face_rec(): # 人脸识别
    
        [X, y], label2name = read_images('./data/at')
        print("label2name: ", label2name)
        X = np.array(X)
        Xx = X.reshape(X.shape[0], 40000)
        xdata, label = Xx, y
    
        y = np.asarray(y, dtype=np.int32)
        face_cascade = cv2.CascadeClassifier( # 分类器检测人脸
            './cascades/haarcascade_frontalface_default.xml'
        )
        videoCapture = cv2.VideoCapture(0)
    
        model = models.load_model('dense_model_6.h5')
    
        while True:
            read, img = videoCapture.read()
            img = cv2.flip(img, 1)
            faces = face_cascade.detectMultiScale(img, 1.3, 5)
            for (x, y, w, h) in faces:
                img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
                gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                roi = gray[x: x+2, y: y+h]
                roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
                roi = np.array(roi).reshape(40000, )
                prediction = model.predict(np.array([roi]))
                # print(np.shape(roi))
                print("dnn predict result :", prediction)
                index = np.argmax(prediction) # 最大值所在的索引
                name = label2name[index]
                print("检测到%s" % name)
                img = cv2ImgAddText(img, name, x, y - 20, (255, 255, 0), 20)
            cv2.imshow('camera', img)
            if cv2.waitKey(1000 // 12) & 0xff == ord("q"):
                break
        cv2.destroyAllWindows()
    
    if __name__ == "__main__":
        face_rec() # 人脸识别
    

    一些小知识点

    opencv putText无法写中文

    putText()不能直接写上中文,那就用PIL库曲线救国了。下面是一个demo。

    #coding=utf-8
    #中文乱码处理
    
    import cv2
    import numpy
    from PIL import Image, ImageDraw, ImageFont
    
    def cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img)
        fontText = ImageFont.truetype(
            "SimHei.ttf", textSize, encoding="utf-8")
        draw.text((left, top), text, textColor, font=fontText)
        return cv2.cvtColor(numpy.asarray(img), cv2.COLOR_RGB2BGR)
    
    img = cv2.imread('./test.png')
    img = cv2ImgAddText(img, "你好世界", 140, 60, (255, 255, 0), 20)
    cv2.imshow('image', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    二值化图片

    使用cv2.threshold()函数,设置cv2.THRESH_BINARY参数进行二值化。可以设置阈值。

    import cv2
    import numpy as np
    
    img = cv2.imread('test.jpg')
    # img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.imwrite('test.jpg', cv2.Canny(img, 50, 120))
    cv2.imshow('canny', cv2.imread('test.jpg'))
    ret, img = cv2.threshold(img, 110, 255, cv2.THRESH_BINARY)
    cv2.imshow('binary', img)
    cv2.waitKey()
    cv2.destroyAllWindows()
    

    路径目录测试

    由于代码文件和图片文件中间隔了两个文件夹,且图片所在文件夹名称代表图片标签名称,所以如何遍历文件夹,读取到有用的信息是个技术活。

    import os
    
    path = './data'
    for dirname, dirnames, filenames in os.walk(path):
        for subdirname in dirnames:
            subject_path = os.path.join(dirname, subdirname)
            # print(subject_path)
            for filename in os.listdir(subject_path):
                if filename[-4:] == '.pgm':
                    filepath = os.path.join(subject_path, filename)
                    print(filepath)
    

    np.random.shuffle() 测试

    np.random.shuffle() 能够将某一迭代对象进行打乱。
    会直接改变传递给他的对象,而不会返回值,需要注意。

    用这个函数,生成索引的随机排列,可以很方便的得到打乱的数据和标签,从而更好的进行训练。

    import numpy as np
    
    a = range(0, 10)
    print(a)
    print(type(a[9]))
    print(np.array(a))
    index = np.array(a)
    np.random.shuffle(index)
    print(index)
    
    index = np.arange(7)
    print(index)
    

    keras保存和恢复模型

    from tensorflow.keras import models
    model.save('dense_model_7.h5')
    model = models.load_model('dense_model_6.h5')
    就不用每次都重新训练了。

    展开全文
  • 深度学习-KNN原理

    2020-07-18 10:12:28
    KNN 分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中文档总数为n,那么KNN 的分类时间复杂度为O(n)。 基本原理 基于统计的方法 来进行样本点分类判别 对于未知类别属性数据集中的点:...

    K-NN是一种非常简单的算法

    概述:


    KNN 算法本身简单有效,它是一种lazy-learning 算法。


    分类器不需要使用训练集进行训练,训练时间复杂度为0。


    KNN 分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中文档总数为n,那么KNN 的分类时间复杂度为O(n)。

     

    基本原理

    基于统计的方法 来进行样本点分类判别

    对于未知类别属性数据集中的点:

    1.计算已知类别数据集中的点与当前点的距离
    2.按照距离依次排序
    3.选取与当前点距离最小的K个点
    4.确定前K个点所在类别的出现概率
    5.返回前K个点出现频率最高的类别作为当前点预测分类。

    存在的问题

    K 值的选择,距离度量和分类决策规则是该算法的三个基本要素


    问题:该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K 个邻居中大容量类的样本占多数


    解决:不同的样本给予不同权重项

    如何计算图像之间的距离

    代码示例

    1.选取超参数的正确方法是:将原始训练集分为训练集和验证集,我们在验证集上尝试不同的超参数,最后保留表现最好那个


    2.如果训练数据量不够,使用交叉验证方法,它能帮助我们在选取最优超参数的时候减少噪音。


    3.一旦找到最优的超参数,就让算法以该参数在测试集跑且只跑一次,并根据测试结果评价算法。


    4.最近邻分类器能够在CIFAR-10上得到将近40%的准确率。该算法简单易实现,但需要存储所有训练数据,并且在测试的时候过于耗费计算能力


    5.最后,我们知道了仅仅使用L1和L2范数来进行像素比较是不够的,图像更多的是按照背景和颜色被分类,而不是语义主体分身。用于分类任务效果是不满意的.

    1.预处理你的数据:对你数据中的特征进行归一化(normalize),让其具有零平均值(zero mean)和单位方差(unit variance)。


    2.如果数据是高维数据,考虑使用降维方法,比如PCA


    3.将数据随机分入训练集和验证集。按照一般规律,70%-90% 数据作为训练集


    4.在验证集上调优,尝试足够多的k值,尝试L1和L2两种范数计算方式。

     

     

    展开全文
  • knn 第一个学习的深度学习算法

    千次阅读 2016-12-04 22:34:07
    在几经摸索下,终于用python开始写下了自己的第一个机器学习算法KNN 这是一个分类算法,可以通过已有标签,判断一个输入的事物是不是已知的标签,其实这个算法算是入门级的,用来练手刚刚好 写完以后觉得,机器...
  • 深度学习与计算机视觉系列(2)_图像分类与KNN

    万次阅读 多人点赞 2015-11-20 17:16:17
    图像分类问题这是很久以前就引起关注的一类图像相关问题。 对于一张输入的图片,要判定它属于给定的一些标签/类别中的哪一个。看似很简单的一个问题,这么多年却一直是计算机视觉的一个核心问题。...
  • inputs: X: A numpy array of shape(num_test, D) containing test data. Returns: dists: A numpy array of shape(num_test, num_train) where dists[i, j] is the Euclidean distance between the ith test ...
  • 当前在knn.ipynb 里面的box 15 Now implement the function. predict_labels and run the code below: 现在执行classifier.predict_labels 这个函数。运行下面的代码来预测labels we use k = 1 (which is Nea...
  • 《机器学习实战》kNN #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/4/5 16:58 # @Author : HJH # @Site : # @File : kNN.py # @Software: PyCharm from numpy import * import operator fro.....
  • 深度学习分类算法系列之 -KNN

    千次阅读 2018-07-26 20:33:46
    先看一个实例来体会一下什么叫做KNN。已知一堆数据a和一堆数据0,然后有一个未知数据c,要判断c到底属于a还是0.如果是1NN,就找到离C最近的数据,离哪一个最近,就判断c属于哪一类。如果利用3NN,如下图所示,以c为...
  • 1 基本概念 Cover和Hart在1968年提出了最初的... 输入基于实例的学习instance-based learning ,懒惰学习lazy learning 2 例子:   对最后一个未知电影类型进行归类    对上图实例进行转化为特征向量  ...
  • 原文链接:https://blog.csdn.net/ywx1832990/article/details/84175277 Kmeans 与 kNN 虽然都是以 K 打头,但却是两类算法——kNN 为监督学习中的分类算法,而 Kmeans 则是非监督学习中的聚类算法
  • 参考:https://blog.csdn.net/xundh/article/details/73611249 包括算法解释、代码和数据集。
  • Kmeans 与 kNN 虽然都是以 K 打头,但却是两类算法——kNN 为监督学习中的分类算法,而 Kmeans 则是非监督学习中的聚类算法;二者相同之处:均利用近邻信息来标注类别。 Kmeans 是聚类算法中最为简单、高效的。 核心...
  • #!python from numpy import * import operator from os import listdir def createDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0.1,0.1],[0.2,0.1]]) labels = ['A','A','B','B'] return group,...
  • 深度学习基础(一)——KNN与SVM

    千次阅读 2017-09-28 23:33:12
    1,上午继续看书,主要看了深度学习的发展历程以及主要技术介绍 2,中午思考了决策树算法中的数据准备阶的矩阵装换,将类似Excel数据表格的形式数据转换为0-1矩阵  数据大致格式为:表头为特征向量名称以及输出...
  • 这是一个使用knn把特征向量进行分类的demo。 Knn算法的思想简单说就是:看输入的sample点周围的k个点都属于哪个类,哪个类的点最多,就把sample归为哪个类。也就是说,训练集是一些已经被手动打好标签的数据,knn会...

空空如也

1 2 3 4 5 ... 20
收藏数 438
精华内容 175
关键字:

knn深度学习