caffe ensemble(模型融合+adaboost)

本文介绍如何在Caffe中实现模型融合及Adaboost集成学习的方法。通过模型融合可以创建ensemble模型,而Adaboost则通过集成多个弱分类器提高预测准确性。
部署运行你感兴趣的模型镜像

方法一:模型融合(生成fuse_modelfusion_train_val.prototxt(更改层名/直接将各自的ip1层 concat))   

Caffe中并没有直接用于融合的官方工具,这介绍一个简单有效的土办法,用融合模型进行ensemble

https://github.com/frombeijingwithlove/dlcv_for_beginners/tree/master/random_bonus/multiple_models_fusion_caffe

http://www.cnblogs.com/frombeijingwithlove/p/6683476.html

方法二:adaboost(集成)   (写出ensemble层(前提各模型层名不一样)

参考:http://blog.youkuaiyun.com/u014114990/article/details/51005316

ensemble_accuracy_layer.cpp 

Softmax 层和 accuracy 层的配置文件如下:

layer {  
  name: "3_prob"  
  type: "Softmax"  
  bottom: "3_ip2"  
  top: "3_prob"  
}  
  
layer {  
  name: "1_accuracy"  
  type: "Accuracy"  
  bottom: "1_prob"  
    bottom: "label"  
  top: "1_accuracy"  
  include {  
    phase: TEST  
  }  
} 

ensemble 层配置函数如下:

layer {
  name: "ensemble
  type: "Esemble"
  bottom: "prob1"
  bottom: "prob2" 
  bottom: "prob3" 
  bottom: "label"
  top: "ensemble_accuracy"
  include { 
     phase: TEST
  }
}

先训练弱分类器,用弱分类器的模型即可,如果把caffe训练好的模型当弱分类器,只需要调用caffe,使用该模型即可,不需要重新训练该弱分类器。

下面代码是调用caffe训练的模型,使用adaboost弱分类器。 这里主要使用了sklearn 库。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: Tairui Chen

import numpy as np
import os
import sys
import argparse
import glob
import time
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.ensemble import AdaBoostClassifier, BaggingClassifier

import caffe

g_rnd = np.random.randint(100000)

def create_weighted_db(X, y, weights, name='boost'):
    X = X.reshape(-1, 3, 32, 32)
    train_fn = os.path.join(DIR, name + '.h5')

    dd.io.save(train_fn, dict(data=X,
                              label=y.astype(np.float32),
                              sample_weight=weights), compress=False)
    with open(os.path.join(DIR, name + '.txt'), 'w') as f:
        print(train_fn, file=f)


class CNN(BaseEstimator, ClassifierMixin):
    def __init__(self):
        pass

    def get_params(self, deep=False):
        return {}

    def fit(self, X, y, sample_weight=None):
        global g_seed
        global g_loop
        if sample_weight is None:
            sample_weight = np.ones(X.shape[0], np.float32)
            print('Calling fit with sample_weight None')
        else:
            sample_weight *= X.shape[0]
            print('Calling fit with sample_weight sum', sample_weight.sum())

        #sample_weight = np.ones(X.shape[0], np.float32)

        #II = sample_weight > 0
        #X = X[II]
        #y = y[II]
        #sample_weight = sample_weight[II]

        #sample_weight = np.ones(X.shape[0])
        w = sample_weight
        #sample_weight[:10] = 0.0
        #w[:1000] = 0.0
        #w = sample_weight
        #w0 = w / w.sum()
        #print('Weight entropy:', -np.sum(w0 * np.log2(w0)))
        print('Weight max:', w.max())
        print('Weight min:', w.min())
        #import sys; sys.exit(0)

        self.classes_ = np.unique(y)
        self.n_classes_ = len(self.classes_)

        # Set up weighted database
        create_weighted_db(X, y, sample_weight)

        #steps = [(0.001, 2000, 2000)]
        steps = [(0.001, 0.004, 60000), (0.0001, 0.004, 5000), (0.00001, 0.004, 5000)]
        #steps = [(0.00001, 10000, 10000), (0.000001, 5000, 15000), (0.0000001, 5000, 20000)]
        #steps = [(0.001, 10000, 10000)]
        #steps = [(0.001, 200, 1000)]

        name = os.path.join(CONF_DIR, 'adaboost_{}_loop{}'.format(g_rnd, g_loop))
        bare_conf_fn = os.path.join(CONF_DIR, 'boost_bare.prototxt')
        conf_fn = os.path.join(CONF_DIR, 'solver.prototxt.template')
        #bare_conf_fn = 'regaug_bare.prototxt'
        #conf_fn = 'regaug_solver.prototxt.template'

        net, info = train_model(name, conf_fn, bare_conf_fn, steps,
                                seed=g_seed, device_id=DEVICE_ID)

        loss_fn = 'info/info_{}_loop{}.h5'.format(g_rnd, g_loop)
        dd.io.save(loss_fn, info)
        print('Saved to', loss_fn)

        g_loop += 1

        print('Classifier set up')

        self.net_ = net

    def predict_proba(self, X):
        X = X.reshape(-1, 3, 32, 32)
        #X = X.transpose(0, 2, 3, 1)
        prob = np.zeros((X.shape[0], self.n_classes_))

        M = 2500
        for k in range(int(np.ceil(X.shape[0] / M))):
            y = self.net_.forward_all(data=X[k*M:(k+1)*M]).values()[0].squeeze(axis=(2,3))
            prob[k*M:(k+1)*M] = y

        T = 30.0

        eps = 0.0001

        #prob = prob.clip(eps, 1-eps)

        log_prob = np.log(prob)
        print('log_prob', log_prob.min(), log_prob.max())
        #log_prob = log_prob.clip(min=-4, max=4)
        new_prob = np.exp(log_prob / T)
        new_prob /= dd.apply_once(np.sum, new_prob, [1])

        return new_prob

    def predict(self, X):
        prob = self.predict_proba(X)
        return prob.argmax(-1)


train_data = np.load('G:/EDU/_SOURCE_CODE/chainer/examples/cifar10/data/train_data.npy')
train_labels = np.load('G:/EDU/_SOURCE_CODE/chainer/examples/cifar10/data/train_labels.npy')

model_path = 'cifar10/' # substitute your path here
# GoogleNet
net_fn   = model_path + 'VGG_mini_ABN.prototxt'
param_fn = model_path + 'cifar10_vgg_iter_120000.caffemodel'

caffe.set_mode_cpu()
net = caffe.Classifier(net_fn, param_fn,
                       mean = np.float32([104.0, 116.0, 122.0]), # ImageNet mean, training set dependent
                       channel_swap = (2,1,0)) # the reference model has channels in BGR order instead of RGB


def preprocess(net, img):
    return np.float32(np.rollaxis(img, 2)[::-1]) - net.transformer.mean['data']


for i in range(10):
	img = train_data[i].transpose((1, 2, 0)) * 255
	img = img.astype(np.uint8)[:, :, ::-1]
	end = 'prob'
	h, w = img.shape[:2]
	src, dst = net.blobs['data'], net.blobs[end]
	src.data[0] = preprocess(net, img)
	net.forward(end=end)
	features = dst.data[0].copy()
 
 
X = train_data
y = train_labels
X *= 255.0
mean_x = X.mean(0)
X -= mean_x

te_X= np.load('G:/EDU/_SOURCE_CODE/chainer/examples/cifar10/data/test_data.npy')
te_y = np.load('G:/EDU/_SOURCE_CODE/chainer/examples/cifar10/data/test_labels.npy')

create_weighted_db(te_X, te_y, np.ones(te_X.shape[0], dtype=np.float32), name='test')  

clf = AdaBoostClassifier(base_estimator=CNN(), algorithm='SAMME.R', n_estimators=10,
                                 random_state=0)
clf.fit(X.reshape(X.shape[0], -1), y)

for i, score in enumerate(clf.staged_score(X.reshape(X.shape[0], -1), y)):
                print(i+1, 'train score', score)

for i, score in enumerate(clf.staged_score(te_X.reshape(te_X.shape[0], -1), te_y)):
                print(i+1, 'test score', score)


您可能感兴趣的与本文相关的镜像

AutoGPT

AutoGPT

AI应用

AutoGPT于2023年3月30日由游戏公司Significant Gravitas Ltd.的创始人Toran Bruce Richards发布,AutoGPT是一个AI agent(智能体),也是开源的应用程序,结合了GPT-4和GPT-3.5技术,给定自然语言的目标,它将尝试通过将其分解成子任务,并在自动循环中使用互联网和其他工具来实现这一目标

import glob import os import matplotlib.pyplot as plt import numpy as np from PIL import Image from sklearn.ensemble import AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier class AdaboostFaceDetector: def __init__(self): # 使用sklearn的决策树作为基础分类器 self.boost_classifier = None @staticmethod def extract_haar_features(image, bbox): """提取类Haar特征""" x, y, w, h = bbox # 确保边界框在图像范围内 height, width = image.shape x = max(0, min(x, width - 1)) y = max(0, min(y, height - 1)) w = min(w, width - x) h = min(h, height - y) face_roi = image[y:y + h, x:x + w] if face_roi.size == 0: return np.zeros(100) # 调整大小为固定尺寸 face_roi_resized = np.array(Image.fromarray(face_roi).resize((20, 20))) # 计算类Haar特征(简化版本) features = [] for i in range(5, 20, 5): for j in range(5, 20, 5): # 确保索引不越界 if i + 5 <= 20 and j + 5 <= 20: # 水平和垂直方向的矩形特征 region1 = face_roi_resized[j - 5:j, i - 5:i] region2 = face_roi_resized[j - 5:j, i:i + 5] region3 = face_roi_resized[j:j + 5, i - 5:i] h_feature = np.sum(region1) - np.sum(region2) v_feature = np.sum(region1) - np.sum(region3) features.extend([h_feature, v_feature]) # 如果特征数量不足,用0填充 while len(features) < 100: features.append(0.0) return np.array(features[:100]) def prepare_training_data(self, image_paths, annotations): """准备训练数据""" features = [] labels = [] for img_path, annotation in zip(image_paths, annotations): try: # 使用PIL加载图像 image = np.array(Image.open(img_path).convert('L')) # 转换为灰度 except Exception as e: print(f"无法加载图像 {img_path}: {e}") continue height, width = image.shape # 使用真实标注作为正样本 for (x, y, w, h) in annotation: feature = self.extract_haar_features(image, (x, y, w, h)) features.append(feature) labels.append(1) # 正样本 # 生成负样本(非人脸区域) for _ in range(5): # 每个图像生成5个负样本 x = np.random.randint(0, width - 50) y = np.random.randint(0, height - 50) w = np.random.randint(20, min(100, width - x)) h = np.random.randint(20, min(100, height - y)) # 确保不是真实的人脸区域 is_face = False for fx, fy, fw, fh in annotation: if abs(x - fx) < 50 and abs(y - fy) < 50: is_face = True break if not is_face: feature = self.extract_haar_features(image, (x, y, w, h)) features.append(feature) labels.append(0) # 负样本 return np.array(features), np.array(labels) def train(self, image_paths, annotations): """训练Adaboost分类器""" print("准备训练数据...") features, labels = self.prepare_training_data(image_paths, annotations) if len(features) == 0: print("未提取到有效特征,请检查数据路径") return print(f"训练数据形状: {features.shape}") print(f"标签分布: {np.bincount(labels)}") # 使用Adaboost分类器 self.boost_classifier = AdaBoostClassifier( DecisionTreeClassifier(max_depth=3), n_estimators=50, learning_rate=1.0, random_state=42 ) print("开始训练Adaboost分类器...") self.boost_classifier.fit(features, labels) print("训练完成!") def detect_faces(self, image): """检测图像中的人脸""" if self.boost_classifier is None: print("请先训练分类器!") return [] # 转换为灰度图像 if len(image.shape) == 3: gray = np.array(Image.fromarray(image).convert('L')) else: gray = image height, width = gray.shape detected_faces = [] # 多尺度滑动窗口检测 scales = [0.5, 0.75, 1.0, 1.25, 1.5] for scale in scales: w_size = int(50 * scale) h_size = int(50 * scale) step_size = max(10, int(20 * scale)) # 动态步长 for y in range(0, height - h_size, step_size): for x in range(0, width - w_size, step_size): bbox = (x, y, w_size, h_size) feature = self.extract_haar_features(gray, bbox) # 使用Adaboost分类器预测 try: prediction = self.boost_classifier.predict([feature])[0] confidence = np.max(self.boost_classifier.predict_proba([feature])) if prediction == 1 and confidence > 0.7: detected_faces.append((x, y, w_size, h_size, confidence)) except Exception: continue # 跳过预测失败的情况 # 非极大值抑制 return self.non_max_suppression(detected_faces) def non_max_suppression(self, faces): """非极大值抑制""" if len(faces) == 0: return [] # 按置信度排序 faces_sorted = sorted(faces, key=lambda x: x[4], reverse=True) keep = [] while faces_sorted: current = faces_sorted.pop(0) keep.append(current) faces_sorted = [face for face in faces_sorted if self.iou(current[:4], face[:4]) < 0.3] return keep @staticmethod def iou(box1, box2): """计算交并比""" x1, y1, w1, h1 = box1 x2, y2, w2, h2 = box2 xi1 = max(x1, x2) yi1 = max(y1, y2) xi2 = min(x1 + w1, x2 + w2) yi2 = min(y1 + h1, y2 + h2) inter_area = max(0, xi2 - xi1) * max(0, yi2 - yi1) box1_area = w1 * h1 box2_area = w2 * h2 union_area = box1_area + box2_area - inter_area return inter_area / union_area if union_area > 0 else 0 class TemplateMatchingDetector: """模板匹配人脸检测器""" def __init__(self): self.templates = self.generate_face_templates() @staticmethod def generate_face_templates(): """生成简单的人脸模板""" templates = [] # 创建椭圆模板(模拟人脸形状) for size in [20, 30, 40]: template = np.zeros((size, size)) center_x, center_y = size // 2, size // 2 radius_x, radius_y = size // 3, size // 2 for i in range(size): for j in range(size): if ((i - center_x) / radius_x) ** 2 + ((j - center_y) / radius_y) ** 2 <= 1: template[i, j] = 1.0 templates.append(template) return templates def detect_faces(self, image): """使用模板匹配检测人脸""" if len(image.shape) == 3: gray = np.array(Image.fromarray(image).convert('L')) else: gray = image detected_faces = [] height, width = gray.shape # 归一化图像 gray_normalized = (gray - np.mean(gray)) / (np.std(gray) + 1e-8) for template in self.templates: t_height, t_width = template.shape # 滑动窗口 for y in range(0, height - t_height, 10): for x in range(0, width - t_width, 10): # 提取窗口 window = gray_normalized[y:y + t_height, x:x + t_width] if window.shape != template.shape: continue # 计算相关性 correlation = np.sum(window * template) if correlation > 5.0: # 经验阈值 detected_faces.append((x, y, t_width, t_height, correlation)) # 非极大值抑制 return self.non_max_suppression(detected_faces) @staticmethod def non_max_suppression(faces): """非极大值抑制""" if len(faces) == 0: return [] faces_sorted = sorted(faces, key=lambda x: x[4], reverse=True) keep = [] while faces_sorted: current = faces_sorted.pop(0) keep.append(current) # 计算IoU并过滤重叠的检测框 faces_sorted = [face for face in faces_sorted if TemplateMatchingDetector.iou(current[:4], face[:4]) < 0.3] return keep @staticmethod def iou(box1, box2): """计算交并比""" x1, y1, w1, h1 = box1 x2, y2, w2, h2 = box2 xi1 = max(x1, x2) yi1 = max(y1, y2) xi2 = min(x1 + w1, x2 + w2) yi2 = min(y1 + h1, y2 + h2) inter_area = max(0, xi2 - xi1) * max(0, yi2 - yi1) box1_area = w1 * h1 box2_area = w2 * h2 union_area = box1_area + box2_area - inter_area return inter_area / union_area if union_area > 0 else 0 class SkinColorDetector: """基于肤色的人脸检测器""" def __init__(self): # 定义肤色范围(HSV空间) self.lower_skin = np.array([0, 20, 70], dtype=np.uint8) self.upper_skin = np.array([20, 255, 255], dtype=np.uint8) def detect_faces(self, image): """使用肤色信息检测人脸""" if len(image.shape) == 2: # 如果是灰度图,转换为RGB rgb_image = np.stack([image] * 3, axis=-1) else: rgb_image = image # 转换为HSV颜色空间 hsv_image = np.array(Image.fromarray(rgb_image).convert('HSV')) # 创建肤色掩码 skin_mask = np.zeros(hsv_image.shape[:2], dtype=np.uint8) for i in range(3): channel_mask = (hsv_image[:, :, 0] >= self.lower_skin[0]) & \ (hsv_image[:, :, 0] <= self.upper_skin[0]) & \ (hsv_image[:, :, 1] >= self.lower_skin[1]) & \ (hsv_image[:, :, 1] <= self.upper_skin[1]) & \ (hsv_image[:, :, 2] >= self.lower_skin[2]) & \ (hsv_image[:, :, 2] <= self.upper_skin[2]) skin_mask = skin_mask | channel_mask # 寻找连通区域 from scipy import ndimage labeled_array, num_features = ndimage.label(skin_mask) detected_faces = [] for i in range(1, num_features + 1): # 获取当前区域的坐标 points = np.where(labeled_array == i) if len(points[0]) > 0: y_min, y_max = np.min(points[0]), np.max(points[0]) x_min, x_max = np.min(points[1]), np.max(points[1]) w = x_max - x_min h = y_max - y_min # 过滤太小或太大的区域 if 20 < w < 200 and 20 < h < 200 and 0.5 < w / h < 2.0: confidence = len(points[0]) / (w * h) # 密度作为置信度 detected_faces.append((x_min, y_min, w, h, confidence)) return detected_faces class FaceDetectionEvaluator: """人脸检测评估器""" def __init__(self): self.detectors = { 'Adaboost': AdaboostFaceDetector(), 'Template_Matching': TemplateMatchingDetector(), 'Skin_Color': SkinColorDetector() } def load_wider_face_dataset(self, data_path, num_images=20): """加载WIDER FACE数据集(简化版本)""" image_paths = [] annotations = [] # 假设数据目录结构 images_dir = os.path.join(data_path, 'images') annotations_dir = os.path.join(data_path, 'annotations') if os.path.exists(images_dir): # 获取图像文件 image_files = glob.glob(os.path.join(images_dir, '*.jpg'))[:num_images] image_files.extend(glob.glob(os.path.join(images_dir, '*.png'))[:num_images]) for img_file in image_files: image_paths.append(img_file) # 加载对应的标注文件 base_name = os.path.splitext(os.path.basename(img_file))[0] ann_file = os.path.join(annotations_dir, base_name + '.txt') if os.path.exists(ann_file): annotations.append(self.load_annotation(ann_file)) else: annotations.append([]) else: # 生成模拟数据用于演示 print("使用模拟数据进行演示...") for i in range(num_images): # 创建模拟图像路径 image_paths.append(f'simulated_image_{i}.jpg') # 生成随机的人脸标注 annotations.append(self.generate_random_annotations()) return image_paths, annotations @staticmethod def load_annotation(ann_file): """加载标注文件""" annotations = [] try: with open(ann_file, 'r') as f: for line in f: parts = line.strip().split() if len(parts) >= 4: x, y, w, h = map(int, parts[:4]) annotations.append((x, y, w, h)) except Exception as e: print(f"无法加载标注文件 {ann_file}: {e}") return annotations @staticmethod def generate_random_annotations(): """生成随机的人脸标注(用于演示)""" num_faces = np.random.randint(1, 5) annotations = [] for _ in range(num_faces): x = np.random.randint(0, 400) y = np.random.randint(0, 400) w = np.random.randint(50, 150) h = np.random.randint(50, 150) annotations.append((x, y, w, h)) return annotations @staticmethod def calculate_iou(box1, box2): """计算两个边界框的IoU""" x1, y1, w1, h1 = box1 x2, y2, w2, h2 = box2 xi1 = max(x1, x2) yi1 = max(y1, y2) xi2 = min(x1 + w1, x2 + w2) yi2 = min(y1 + h1, y2 + h2) inter_area = max(0, xi2 - xi1) * max(0, yi2 - yi1) box1_area = w1 * h1 box2_area = w2 * h2 union_area = box1_area + box2_area - inter_area return inter_area / union_area if union_area > 0 else 0 def evaluate_detector(self, detector, image_paths, ground_truths, iou_threshold=0.5): """评估检测器性能""" all_precisions = [] all_recalls = [] for img_path, gt_boxes in zip(image_paths, ground_truths): if not os.path.exists(img_path) and img_path.startswith('simulated'): # 对于模拟图像,创建一个随机图像 image = np.random.randint(0, 255, (500, 500, 3), dtype=np.uint8) else: try: image = np.array(Image.open(img_path)) except Exception as e: print(f"无法加载图像 {img_path}: {e}") continue # 检测人脸 detected_faces = detector.detect_faces(image) # 计算精度和召回率 if len(gt_boxes) == 0 and len(detected_faces) == 0: precision = 1.0 recall = 1.0 elif len(gt_boxes) == 0: precision = 0.0 recall = 0.0 elif len(detected_faces) == 0: precision = 0.0 recall = 0.0 else: # 匹配检测结果和真实标注 true_positives = 0 used_gt = set() for det_face in detected_faces: det_box = det_face[:4] max_iou = 0 best_gt_idx = -1 for i, gt_box in enumerate(gt_boxes): if i in used_gt: continue iou_val = self.calculate_iou(det_box, gt_box) if iou_val > max_iou: max_iou = iou_val best_gt_idx = i if max_iou >= iou_threshold and best_gt_idx != -1: true_positives += 1 used_gt.add(best_gt_idx) precision = true_positives / len(detected_faces) if len(detected_faces) > 0 else 0 recall = true_positives / len(gt_boxes) if len(gt_boxes) > 0 else 0 all_precisions.append(precision) all_recalls.append(recall) # 计算平均精度 mean_precision = np.mean(all_precisions) mean_recall = np.mean(all_recalls) ap_score = np.mean(all_precisions) # 简化的AP计算 return mean_precision, mean_recall, ap_score, all_precisions, all_recalls @staticmethod def plot_pr_curves(results): """绘制PR曲线""" plt.figure(figsize=(10, 8)) for detector_name, result in results.items(): precisions = result['precisions'] recalls = result['recalls'] # 排序以便绘制PR曲线 sorted_indices = np.argsort(recalls) sorted_recalls = np.array(recalls)[sorted_indices] sorted_precisions = np.array(precisions)[sorted_indices] plt.plot(sorted_recalls, sorted_precisions, marker='.', label=f'{detector_name} (AP={result["ap"]:.3f})') plt.xlabel('Recall') plt.ylabel('Precision') plt.title('Precision-Recall Curve - Face Detection Algorithms') plt.legend() plt.grid(True) plt.xlim([0, 1]) plt.ylim([0, 1]) plt.savefig('pr_curve_comparison.png', dpi=300, bbox_inches='tight') plt.show() def visualize_detections(self, image_paths, ground_truths, max_images=5): """可视化检测结果""" num_detectors = len(self.detectors) fig, axes = plt.subplots(num_detectors, max_images, figsize=(15, 3 * num_detectors)) if num_detectors == 1: axes = [axes] for i, (detector_name, detector) in enumerate(self.detectors.items()): for j in range(min(max_images, len(image_paths))): img_path = image_paths[j] gt_boxes = ground_truths[j] if not os.path.exists(img_path) and img_path.startswith('simulated'): # 创建模拟图像 image = np.random.randint(0, 255, (500, 500, 3), dtype=np.uint8) else: try: image = np.array(Image.open(img_path)) except Exception: continue # 检测人脸 detected_faces = detector.detect_faces(image) # 绘制图像 if num_detectors > 1: ax = axes[i][j] else: ax = axes[j] ax.imshow(image) # 绘制真实标注(绿色) for x, y, w, h in gt_boxes: rect = plt.Rectangle((x, y), w, h, fill=False, edgecolor='g', linewidth=2, label='Ground Truth') ax.add_patch(rect) # 绘制检测结果(红色) for x, y, w, h, confidence in detected_faces: rect = plt.Rectangle((x, y), w, h, fill=False, edgecolor='r', linewidth=2, label='Detection') ax.add_patch(rect) ax.set_title(f'{detector_name}\nGT: {len(gt_boxes)}, Det: {len(detected_faces)}') ax.axis('off') # 只在第一列添加标签 if num_detectors > 1: axes[i][0].set_ylabel(detector_name, rotation=90, size='large') plt.tight_layout() plt.savefig('detection_visualization.png', dpi=300, bbox_inches='tight') plt.show() def main(): """主函数""" print("Lab_1: 基于Adaboost组合分类器的人脸检测") # 初始化评估器 evaluator = FaceDetectionEvaluator() # 加载数据 print("加载WIDER FACE数据集...") data_path = './WIDER_FACE' # 修正拼写 image_paths, annotations = evaluator.load_wider_face_dataset(data_path, num_images=20) print(f"成功加载 {len(image_paths)} 张图像") # 训练Adaboost分类器 print("\n训练Adaboost分类器...") adaboost_detector = evaluator.detectors['Adaboost'] adaboost_detector.train(image_paths, annotations) # 评估所有检测器 print("\n评估人脸检测算法...") results = {} for detector_name, detector in evaluator.detectors.items(): print(f"\n评估 {detector_name}...") precision, recall, ap, precisions, recalls = evaluator.evaluate_detector( detector, image_paths, annotations ) results[detector_name] = { 'precision': precision, 'recall': recall, 'ap': ap, 'precisions': precisions, 'recalls': recalls } print(f"{detector_name} 结果:") print(f" 平均精度: {precision:.3f}") print(f" 平均召回率: {recall:.3f}") print(f" AP: {ap:.3f}") # 绘制PR曲线 print("\n绘制PR曲线...") evaluator.plot_pr_curves(results) # 可视化检测结果 print("\n可视化检测结果...") evaluator.visualize_detections(image_paths, annotations, max_images=5) # 输出优化建议 print_optimization_suggestions(results) def print_optimization_suggestions(results): """输出优化建议""" print("\n" + "=" * 50) print("优化和方法改进思路") print("=" * 50) print("\n1. 基于评估结果的改进方向:") best_ap = max(results.values(), key=lambda x: x['ap']) best_detector = [name for name, res in results.items() if res['ap'] == best_ap['ap']][0] print(f" 当前最佳检测器: {best_detector} (AP: {best_ap['ap']:.3f})") for name, res in results.items(): if name != best_detector: improvement = best_ap['ap'] - res['ap'] print(f" {name} 需要提升 {improvement:.3f} 来达到最佳性能") print("\n2. 技术优化建议:") print(" a. 特征提取优化:") print(" - 实现更复杂的Haar-like特征") print(" - 添加LBP特征或HOG特征") print(" b. 分类器优化:") print(" - 调整Adaboost参数(学习率、弱分类器数量)") print(" - 尝试不同的基础分类器") print(" c. 检测策略优化:") print(" - 实现更高效的多尺度检测") print(" - 改进非极大值抑制算法") print(" d. 数据增强:") print(" - 增加旋转、缩放、亮度变换") print(" - 生成更多困难负样本") print("\n3. 扩展功能:") print(" - 添加人脸关键点检测") print(" - 实现人脸识别功能") print(" - 添加实时视频检测功能") if __name__ == "__main__": main()上述代码中读取WIDER FACE数据集的片段是哪一个
最新发布
11-29
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值