1. Машина опорных векторов SVM
1. Принцип SVM
В машинном обучении контролируемые модели обучения машин опорных векторов и связанные с ними алгоритмы обучения могут быть проанализированы для классификации данных и регрессионного анализа. Учитывая набор обучающих примеров, каждый из которых помечен как принадлежащий к одному или другому из двух классов, обучающий алгоритм SVM строит модель, которая присваивает новые примеры тому или иному классу, что делает его невероятностным бинарным линейным классификатором (хотя такие методы поскольку существует масштабирование Платта для использования SVM в настройках вероятностной классификации). Модель SVM предназначена для представления этих примеров в виде карты точек в пространстве, чтобы разделить примеры каждого класса как можно большим кажущимся разрывом. Затем новые примеры сопоставляются с тем же пространством и предсказываются, что они принадлежат к классу в зависимости от того, на какую сторону они попадают.
Например, у нас на столе два цветных шара и мы хотим их разделить.
Берем палочку и кладем на стол, красиво получается?
Пришли какие-то шлюхи и положили на стол еще шаров, это сработало, но один из шаров был не с той стороны, теперь может быть место получше, чтобы положить палку.
SVM пытается разместить стержень в наилучшем положении, оставляя как можно больше зазора с обеих сторон стержня.
Теперь, когда шлюха возвращается, палка все еще остается хорошим местом.
В наборе инструментов SVM есть еще один, более важный трюк. Шлюха увидела, как хорошо ты обращаешься с палкой, поэтому она бросает тебе новый вызов.
В мире нет ни одной клюшки, которой можно было бы забить мяч, так что же делать? Конечно, вы поворачиваете стол! Подбросить мяч в воздух. Затем, используя свои профессиональные навыки ниндзя, вы берете лист бумаги и просовываете его между шарами.
Теперь суки стоят и наблюдают за мячом, и кажется, что их яйца разделены какими-то кривыми линиями.
После этого скучные взрослые называют эти шарики «данными», палочки «классификатором», трюк с максимальным зазором — «оптимизацией», таблицу — «кернеллингом», а бумажку — «гиперплоскостью».
2. Параметры SVM opencv
Реализация машин опорных векторов представлена в OpenCV 3.3, а именно в классе cv::ml::SVM, который объявлен в файле include/opencv2/ml.hpp и реализован в модулях/ml/src/. В файле svm.cpp файл, он поддерживает как две классификации, так и мультиклассификацию, регрессию и т. д. Реализация SVM в OpenCV происходит из библиотеки libsvm. в:
(1), класс cv::ml::SVM: наследуется от cv::ml::StateModel, а cv::ml::StateModel наследуется от cv::Algorithm;
(2), функция создания: статическая, для создания объекта SVM используется новый SVMImpl;
(3), функция setType/getType: установить/получить тип формулы SVM, включая C_SVC, NU_SVC, ONE_CLASS, EPS_SVR, NU_SVR, используемый для указания классификации, регрессии и т. д., по умолчанию C_SVC;
(4), функция setGamma/getGamma: установка/получение параметра γ функции ядра, значение по умолчанию равно 1;
(5), функция setCoef0/getCoef0: установка/получение параметра coef0 функции ядра, значение по умолчанию равно 0;
(6), функция setDegree/getDegree: установка/получение параметра степени функции ядра, значение по умолчанию равно 0;
(7), функция setC/getC: установка/получение параметра C задачи оптимизации SVM, значение по умолчанию равно 0;
(8), функция setNu/getNu: установка/получение параметра υ задачи оптимизации SVM, значение по умолчанию равно 0;
(9), функция setP/getP: установка/получение параметра ε задачи оптимизации SVM, значение по умолчанию равно 0;
(10), функция setClassWeights/getClassWeights: применяется к SVM::C_SVC, установка/получение весов, значение по умолчанию пусто cv::Mat;
(11), функция setTermCriteria/getTermCriteria: установить/получить условие завершения итерации при обучении SVM, значение по умолчанию — cv::TermCriteria(cv::TermCriteria::MAX_ITER + TermCriteria::EPS,1000, FLT_EPSILON);
(12), функция setKernel/getKernelType: установка/получение типа функции ядра SVM, включая CUSTOM, LINEAR, POLY, RBF, SIGMOID, CHI2, INTER, значение по умолчанию — RBF;
(13), функция setCustomKernel: инициализация функции ядра CUSTOM;
(14), функция trainAuto: обучать SVM с оптимальными параметрами;
(15), функция getSupportVectors/getUncompressedSupportVectors: получить все опорные векторы;
(16), функция getDecisionFunction: функция решения;
(17), функция getDefaultGrid/getDefaultGridPtr: создание сетки параметров SVM;
(18), функция сохранения/загрузки: сохранение/загрузка обученной модели, поддержка форматов xml, yaml, json;
(19), функция обучения/прогнозирования: используется для обучения/прогнозирования, все используют базовый класс StatModel.
Исходная ссылка: http://bytesizebio.net/2014/02/05/support-vector-machines-explained-well/
Ссылка на формулу: https://en.wikipedia.org/wiki/Support_vector_machine
Ссылка на параметр SVM: https://docs.opencv.org/master/d1/d2d/classcv_1_1ml_1_1SVM.html
Пример
svm_type() — указывает тип SVM:
параметр:
- C_SVC: C представляет штрафной коэффициент, и чем больше C, тем больше штраф за неправильную классификацию.
- NU_SVC: то же, что и C_SVC.
- ONE_CLASS: метка класса не требуется, используется для оценки плотности и кластеризации опорных векторов.
- EPSILON_SVR: -нечувствительная функция потерь, для точек выборки существует область, которая не дает значения потерь для целевой функции, то есть -полоса.
- NU_SVR: Поскольку EPSILON_SVR необходимо заранее определить параметры, в некоторых случаях бывает непросто выбрать подходящие параметры. А NU_SVR умеет автоматически рассчитывать параметры.
kernel_type() - тип ядра SVM:
параметр:
- LINEAR: линейная функция ядра (линейное ядро)
- POLY: функция полиномиального ядра (полиномиальное ядро)
- RBF: радиальная базисная функция
- SIGMOID: Нелинейная функция ядра функции действия нейронов (Sigmoid tanh)
- ПРЕДВАРИТЕЛЬНО ВЫЧИСЛЕННАЯ: функция ядра, определяемая пользователем.
train()
параметр:
- Образцы InputArray, обучающие образцы
- int layout, набор текста, параметры: ROW_SAMPLE, каждая обучающая выборка представляет собой строку выборок, COL_SAMPLE, каждая обучающая выборка занимает столбец выборок
- Ответы InputArray, вектор ответа, связанный с обучающими выборками
getDecisionFunction()
параметр:
- int i, индекс решающей функции. Если решаемой задачей является регрессия, 1-классовая или 2-классовая классификация, то будет только одна решающая функция и индекс всегда должен быть равен 0. В противном случае в случае N-классовой классификации будет N(N- 1)/2 решающая функция.
- Выходной массив альфа, Необязательный выходной вектор альфа-весов, соответствующих различным опорным векторам. В случае линейного SVM все альфа равны 1.
- OutputArray svidx, необязательный выходной вектор индексов опорных векторов в матрице опорных векторов. В случае линейных SVM каждая решающая функция состоит из одного «сжатого» опорного вектора.
import cv2
import numpy as np
import matplotlib.pyplot as plt
#1 准备data
rand1 = np.array([[155,48],[159,50],[164,53],[168,56],[172,60]])
# 女生身高和体重数据
rand2 = np.array([[152,53],[156,55],[160,56],[172,64],[176,65]])
# 男生身高和体重数据
# 2 建立分组标签,0代表女生,1代表男生
label = np.array([[0],[0],[0],[0],[0],[1],[1],[1],[1],[1]])
# 3 合并数据
data = np.vstack((rand1,rand2))
data = np.array(data,dtype='float32')
# 4 训练
# ml 机器学习模块 SVM_create() 创建
svm = cv2.ml.SVM_create()
# 属性设置
svm.setType(cv2.ml.SVM_C_SVC) # svm type
svm.setKernel(cv2.ml.SVM_LINEAR) # line
svm.setC(0.01)
# 训练
result = svm.train(data,cv2.ml.ROW_SAMPLE,label)
# 预测
pt_data = np.vstack([[167,55],[162,57]]) #0 女生 1男生
pt_data = np.array(pt_data,dtype='float32')
print(pt_data)
(par1,par2) = svm.predict(pt_data)
print(par2)
результат:
[[167. 55.]
[162. 57.]]
[[0.]
[1.]]
2. Особенности свиней
Функция гистограммы ориентированного градиента (HOG) — это дескриптор функции, используемый для обнаружения объектов в компьютерном зрении и обработке изображений. Он строит функции, вычисляя и подсчитывая гистограммы направления градиента локальных областей изображения. Функция Hog в сочетании с классификатором SVM широко используется для распознавания изображений, особенно для обнаружения пешеходов с большим успехом. Напомним, что метод обнаружения пешеходов с помощью HOG+SVM был предложен французским исследователем Далалем в CVPR в 2005 году. Хотя постоянно предлагалось множество алгоритмов обнаружения пешеходов, в основном они основаны на идее HOG+SVM.
Процесс реализации алгоритма извлечения признаков HOG:
Метод извлечения функции HOG заключается в том, чтобы сделать изображение (цель или окно сканирования, которое вы хотите обнаружить):
1) Оттенки серого (видим изображение как трехмерное изображение x, y, z (оттенки серого));
2) Используйте метод Гамма-коррекции для стандартизации цветового пространства входного изображения (нормализация); цель состоит в том, чтобы отрегулировать контрастность изображения, уменьшить влияние локальных теней и изменений освещения в изображении, а также подавить интерференцию шума. ;
3) Вычислить градиент (включая размер и направление) каждого пикселя изображения, в основном для сбора информации о контурах, при этом еще больше ослабляя интерференцию освещения.
4) Разделите изображение на маленькие ячейки (например, 6*6 пикселей/ячейка);
5) Подсчитайте гистограмму градиента каждой ячейки (количество различных градиентов), чтобы сформировать дескриптор каждой ячейки;
6) Каждая из нескольких ячеек формируется в блок (например, 3*3 ячейки/блок), и дескрипторы признаков всех ячеек в блоке соединяются последовательно, чтобы получить дескриптор признака HOG блока.
7) Объедините дескрипторы признаков HOG всех блоков в образе изображения, чтобы получить дескриптор признаков HOG изображения (цель, которую вы хотите обнаружить). Это последний вектор признаков, который можно использовать для классификации.
Исходная ссылка: https://blog.csdn.net/liulina603/article/details/8291093
3. Примеры
HOGDescriptor()
параметр:
- Размер win_size=Размер(64, 128), чтобы определить размер окна.
- Размер block_size=Размер(16, 16), размер блока, в настоящее время поддерживает только Размер(16, 16)
- Size block_stride=Size(8, 8), размер скользящего шага блока, размер поддерживает только размер, кратный размеру ячейки.
- Размер cell_size=Размер(8, 8), размер ячейки, в настоящее время поддерживает только Размер(8, 8).
- int nbins=9, количество ячеек гистограммы (количество урн для голосования), в настоящее время каждая ячейка поддерживает только 9.
- double win_sigma=DEFAULT_WIN_SIGMA, параметр окна фильтра Гаусса.
- двойной порог_L2hys=0,2, нормализованное сжатие внутриблочного типа нормализации гистограммы L2-Hys
- bool gamma_correction=true, будет ли гамма-коррекция
- nlevels=DEFAULT_NLEVELS, максимальное количество окон обнаружения
Положительный образец:
Отрицательный образец:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 第一步:确定标准
PosNum = 820
# 正样本个数
NegNum = 1931
# 负样本个人
winSize = (64,128)
# 一个窗口(win)的大小是64x128
blockSize = (16,16)
# 每个块的大小是16x16
blockStride = (8,8)
# 每个块的步长是8x8
# 一个窗口有((64-16)/8+1)*((128-16)/8+1) = 7*15 = 105个块(block)
cellSize = (8,8)
# 每个胞元的大小是8x8
# 一个块(block)有 (16/8)*(16/8) = 4胞元(cell)
nBin = 9
# 一个胞元有 9 个bin,表示每一个胞元对应的向量就是9维
# 窗口对应的一维特征向量维数n = 105 * 4 * 9 = 3780
# hog+svm检测行人,最终的检测方法是最基本的线性判别函数,wx + b = 0,刚才所求的3780维向量其实就是w,而加了一维的b就形成了opencv默认的3781维检测算子
# 第二步:创造一个HOG描述子和检测器
hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nBin)
# 第三步:启动SVM分离器
svm = cv2.ml.SVM_create()
# 第四步:计算Hog
featureNum = int(((128-16)/8+1)*((64-16)/8+1)*4*9)
# 窗口对应的一维特征向量维数n
featureArray = np.zeros(((PosNum+NegNum),featureNum),np.float32)
# 创建Hog特征矩阵
labelArray = np.zeros(((PosNum+NegNum),1),np.int32)
# 创建标签矩阵
# 给图片样本打标签,正样本是1,负样本是-1
for i in range(0,PosNum):
fileName = 'pos/'+str(i+1)+'.jpg'
# 导入正样本图片
img = cv2.imread(fileName)
hist = hog.compute(img,(8,8))
# 每个hog特性的维数是3780
for j in range(0,featureNum):
featureArray[i,j] = hist[j]
# featureArray装载hog特征, [1,:]代表hog特征1, [2,:]代表hog特征2
labelArray[i,0] = 1
# 正样本的label是 1
for i in range(0,NegNum):
fileName = 'neg/'+str(i+1)+'.jpg'
img = cv2.imread(fileName)
hist = hog.compute(img,(8,8))
for j in range(0,featureNum):
featureArray[i+PosNum,j] = hist[j]
labelArray[i+PosNum,0] = -1
# 负样本的label是 -1
# SVM属性设置
svm.setType(cv2.ml.SVM_C_SVC)
# SVM模型类型:C_SVC表示SVM分类器,C_SVR表示SVM回归
svm.setKernel(cv2.ml.SVM_LINEAR)
# 核函数类型: LINEAR:线性核函数(linear kernel),POLY:多项式核函数(ploynomial kernel),RBF:径向机核函数(radical basis function),SIGMOID: 神经元的非线性作用函数核函数(Sigmoid tanh),PRECOMPUTED:用户自定义核函数
svm.setC(0.01)
# SVM类型(C_SVC/ EPS_SVR/ NU_SVR)的参数C,C表示惩罚因子,C越大表示对错误分类的惩罚越大
# 第六步:训练函数
ret = svm.train(featureArray,cv2.ml.ROW_SAMPLE,labelArray)
# 第七步:检测 (1、创建myhog,参数myDeteect)
alpha = np.zeros((1),np.float32)
# 权重的可选输出向量
rho = svm.getDecisionFunction(0,alpha)
# 检索决策函数。
print(rho)
print(alpha)
alphaArray = np.zeros((1,1),np.float32)
supportVArray = np.zeros((1,featureNum),np.float32)
resultArray = np.zeros((1,featureNum),np.float32)
alphaArray[0,0] = alpha
resultArray = -1*alphaArray*supportVArray
myDetect = np.zeros((3781),np.float32)
for i in range(0,3780):
myDetect[i] = resultArray[0,i]
myDetect[3780] = rho[0]
# myDetect是3781维,其中3780维来自resultArray,最后一维来自rho
myHog = cv2.HOGDescriptor()
myHog.setSVMDetector(myDetect)
# 第八步:导入待检测图片的加载
imageSrc = cv2.imread('Test2.jpg',1)
# 加载待检测图片
objs = myHog.detectMultiScale(imageSrc,0,(8,8),(32,32),1.05,2)
# 检测图片
x = int(objs[0][0][0])
y = int(objs[0][0][1])
w = int(objs[0][0][2])
h = int(objs[0][0][3])
# 原始坐标(x,y),宽w,高h
# 第九步:绘制展示
cv2.rectangle(imageSrc,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('dst',imageSrc)
cv2.waitKey(0)
Изображения, которые необходимо обнаружить:
результат:
(0.19296025963377925, array([[1.]]), array([[0]], dtype=int32))
[0.]