人工智能的起源
图灵测试
1956年,达特茅斯会议,人工智能诞生
主要分支介绍
1.计算机视觉
eg:人脸识别
2.自然语言处理
语音识别
语义识别
3.机器人
人工智能必备三要数
数据
算法
计算力
gpu、cpu
gpu – 计算密集型
cpu – IO密集型
机器学习是人工智能的一个实现途径
深度学习是机器学习的一个方法发展而来
人工智能 > 机器学习 > 深度学习
数据
自动分析获得模型
预测
从数据中自动分析获得模型,并利用模型对未知数据进行预测
1.获得数据
2.数据基本处理
3.特征工程
4.机器学习(模型训练)
5.模型评估
对数据进行缺失值,去除异常值等处理
1.定义
把数据转化为机器更容易识别的数据
2.为什么需要特征工程
数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限
3.包含内容
特征提取
特征预处理
特征降维
选择合适的算法对模型进行训练
对训练好的模型进行评估
1.监督学习 – 有特征值,有目标值
目标值连续 – 回归
目标值离散 – 分类
2.无监督学习 — 仅有特征值
聚类
关联规则
3.半监督学习
有特征值,但是一部分数据有目标值,一部分没有
4.强化学习
动态过程,上一步数据的输出是下一步数据的输入
四要素:agent,action,environment,reward
1.分类模型评估
准确率
精确率
召回率
F1-score
AUC指标
2.回归模型评估
均方根误差 root mean squared error RMSE
相对平方误差 relative squared error RSE
平均绝对误差 mean absolute error MAE
相对绝对误差 relative absolute error RAE
决定系数 coefficient of determination
3.拟合
欠拟合
过拟合
microsoft开发的,可视化的机器学习模型搭建平台。
1.jupyter定义
开源的科学计算平台
类比ipython
可以运行代码,可以做笔记
文件按后缀.ipynb
使用:jupyter notebook
2.jupyter和pycharm对比
jupyter – 探索性数据,一边分析,一边运行
pycharm – 适合逻辑性强的操作(web)
3.jupyter两种模式
编辑模式 – 直接点击进去,可以进行编写代码,做笔记
命令模式 – 通过快捷键,操作,eg:添加一行
4.快捷键
通用:
shift + enter,执行本单元代码,并跳转到下一单元
ctrl + enter,执行本单元代码,留在本单元
命令模式:
Y,cell切换到code模式
M,cell切换到markdown模式
A,在当前cell的上面添加cell
B,在当前cell的下面添加cell
双击D,删除当前cell
编辑模式:
和常规方式一样
官网:https://matplotlib.org/
import matplotlib.pyplot as plt
import random
# 生成数据
x = range(60)
y_bj = [random.uniform(10,15) for i in x]
y_sh = [random.uniform(15,20) for i in x]
# 1.创建画布
plt.figure(figsize=(20,8),dpi=100)
figsize参数可以指定绘图对象的宽度和高度,单位为英寸。
dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80。
# 2.绘制图像
plt.plot(x,y_bj,label = "beijing")
plt.plot(x,y_sh,label = "shanghai")
# 2.1添加x,y轴刻度
y_ticks = range(40)
x_ticks_labels = ["11点{}分".format(i) for i in x] # 可能不显示中文,需要安装语言包
plt.yticks(y_ticks[::5])
plt.xticks(x[::5],x_ticks_labels[::5])
# plt.xticks(x_ticks_labels[::5]) # 第一个参数必须是数字
# 2.2添加网格
plt.grid(True,linestyle = "--",alpha=1) # linestyle:绘制网格的方式 alpha:透明度
# 2.3添加描述
plt.xlabel("time",fontsize = 20)
plt.ylabel("temperature")
plt.title("一小时温度变化图",fontsize = 10)
# 2.4 显示图例
plt.legend(loc="best") # best:显示的最好位置,0
# 3.显示图像
plt.show()
# 生成数据
x = range(60)
y_bj = [random.uniform(10,15) for i in x]
y_sh = [random.uniform(15,20) for i in x]
# 1.创建画布
fig,axes = plt.subplots(nrows=1 ,ncols=2,figsize=(20,8),dpi=100)
# 2.绘制图像
axes[0].plot(x,y_bj,label = "beijing")
axes[1].plot(x,y_sh,label = "shanghai")
# 2.1添加x,y轴刻度
y_ticks = range(40)
x_ticks_labels = ["11点{}分".format(i) for i in x] # 可能不显示中文,需要安装语言包
axes[0].set_xticks(x[::5])
axes[0].set_yticks(y_ticks[::5])
axes[0].set_xticklabels(x_ticks_labels[::5])
axes[1].set_xticks(x[::5])
axes[1].set_yticks(y_ticks[::5])
axes[1].set_xticklabels(x_ticks_labels[::5])
# 2.2添加网格
axes[0].grid(True,linestyle = "--",alpha=1) # linestyle:绘制网格的方式 alpha:透明度
axes[1].grid(True,linestyle = "--",alpha=1) # linestyle:绘制网格的方式 alpha:透明度
# 2.3添加描述
axes[0].set_xlabel("time",fontsize = 20)
axes[0].set_ylabel("temperature")
axes[0].set_title("beijing温度变化图",fontsize = 10)
axes[1].set_xlabel("time",fontsize = 20)
axes[1].set_ylabel("temperature")
axes[1].set_title("shanghai温度变化图",fontsize = 10)
# 2.4 显示图例
axes[0].legend(loc="best") # best:显示的最好位置,0
axes[1].legend(loc="best") # best:显示的最好位置,0
# 3.显示图像
plt.show()
1.图像保存
plot.savafig(‘path’,dpi=300)
注意:图像保存一定要做到show前面。因为show会释放figure资源
2.添加x轴,y轴刻度
plt.xticks(x,**kwargs) X:要显示的刻度值
plt.yticks(y,*kwargs) y:要显示的刻度值 Y:
注意:第一个参数必须是数字,如果不是数字,需要进行值替换。
3.添加网格
plt.grid(True,linestyle = “–”,alpha=1)
linestyle:绘制网格的方式 alpha:透明度
4.添加描述信息
plt.xlabel(“time”,fontsize = 20)
plt.ylabel(“temperature”)
plt.title(“一小时温度变化图”,fontsize = 10)
5.多次plot
直接绘制
6.显示图例
plt.legend()
注意:需要显示之前,声明plot里面的具体label值
7.多个坐标系图像显示
fig,axes = plt.subplots(nrows = 1,ncols = 2)
nrows – 几行
ncols – 几列
注意:有些方法需要添加set_
8.折线图应用场景
1.表述数据变化
2.绘制一些数学图像
# 0.数据准备
x = [0,243,324,123,3124]
y = [213,321,634,23,312]
# 1.创建画布
plt.figure(figsize=(20,8),dpi=100)
# 2.绘制图像(散点图)
plt.scatter(x,y)
# 3.图像展示
plt.show()
# 0.数据准备
movie_name = ["weq","eq","demo"]
x = range(len(movie_name))
y = [213,312,314]
# 1.创建画布
plt.figure(figsize=(20,8),dpi=100)
# 2.绘制图像(柱状图)
plt.bar(x,y,color = ['b','r'],width=0.5)
# 2.1 x轴
plt.xticks(x,movie_name,fontsize=20)
# 2.2网格
plt.grid()
# 2.3标题
plt.title("sdad")
# 3.图像展示
plt.show()
开源的python科学计算库,用于快速处理任意维度的数组,Numpy中,存储对象是ndarray(N维数组)。
np.array(list/tuple)
内存块风格 – 一体式存储
支持并行化运算 – 向量化运算
效率高于纯python代码 – 底层使用了C,内部释放了GIL。
import random
import time
import numpy as np
a= []
for i in range(1000000):
a.append(random.random())
# 通过%time魔法方法,查看当前行的代码运行一次所花费的时间
%time sum1 = sum(a)
b = np.array(a)
%time sum2 = np.sum(b)
0.创建
score = np.array([[80,89,86],
[23,123,13]],dtype = np.float32)
1.ndarray的属性
属性名字 属性解释
ndarray.shape 数组维度的元组
ndarray.ndim 数组维度
ndarray.size 数组中的元素数量
ndarray.itemsize 一个数组元素的长度(字节)
ndarray.dtype 数组元素的类型
2.ndarray的形状
np.array()
3.ndarray的类型
bool
Int
float
str
…
注意:若不指定,整数默认int64,小数默认float64
生成0和1的数组
np.ones(shape[,dtype,order])
np.ones_like(a[,dtype,order,subok])
np.zeros(shape[,dtype,order])
np.zeros_like(a[,dtype,order,subok])
e.g: zero = np.zeros([3,4])
从现用的数组中生成
np.array – 深拷贝
np.asarray – 浅拷贝
生成固定范围的数组(产生连续的序列)
np.linspace(start,stop,num,endpoint)
num:要生成的等间隔样例数量,默认为50
endpoint:序列中是否包含stop值,默认为ture
np.arange(start,stop,step,dtype)
step:每隔多少生成数据
np.logspace(start,stop,num)
生成以10的n次幂的数据
生成随机数组
1.生成均匀分布随机数
np.random.uniform(low=0.0,high=1.0,size=None)
size = 数量
2.生成正态分布随机数
np.random.normal(loc=0.0,scale=1.0,size=None)
loc = 此概率分布的均值
scale = 此概率分布的标准差
均值 – 图形的左右位置
方差 – 图像是痩,还是胖
值越小,图形越瘦高,数据越集中
值越大,图形越矮胖,数据越分散
数组名[0:2,0:3]
直接索引
二维数组:先对行进行索引,在对列进行索引。
高维数组:从宏观到微观。
1.数组对象.reshape([5,4]) : 5行2列(先拉直,再重排)
不进行行列互换,产生新变量
reshape(-1,1):变成向量例:(16,) --> (16,1)
2.数组对象.resize([-1,2]) : 不知道几行,但是2列
不进行行列互换,对原值进行修改
3.数组对象.T
进行行列互换,产生新变量
数组对象.astype(type)
e.g:array.astype(np.int32)
转化为byte:
arr.tostring()
np.unique(array)
sum(0/1)
0:表示按照列求和
1:表示按照行求和
大于,小于直接进行判断。
赋值:满足要求,直接进行赋值。
e.g:
stock_c>1
stock_c[stock>1] = 2
np.all(condition): 所有元素都满足条件才返回True
np.any(condition): 只要有一个元素满足条件就返回True
np.where(condition,first,second):
满足要求,赋值第一个值,否则赋值第二个值
np.logical_and(cond1,cond2) : 都满足
np.logical_or(cond1,cond2): 满足一个
Min
Max
midian -- 中位数
mean -- 均值
std --标准差
var -- 方差
argmax -- 最大值下标
argmin -- 最小值下标
1.矩阵和向量
矩阵:理解-二维数组
向量:理解-一维数组
2.加法和标量乘法
加法:对应位置相加
乘法:标量和每个位置的元素相乘
3.矩阵向量(矩阵)乘法
[m行 , n列] * [n行 , l列] = [m行 , l列]
4.矩阵乘法性质
满足结合律,不满足交换律
5.单位矩阵
对角线为1,其他位置为0的矩阵
6.逆矩阵
矩阵a* 矩阵b = 单位矩阵
那么a和b就互为逆矩阵
7.转置(T)
行列互换
1.数组和数字是直接可以进行运算
2.数组和数组:
需要满足广播机制
维度相同。
shape对应位置为1
3.矩阵乘法api
np.dot – 点乘
np.matmul --矩阵相乘
注意: 两者之间在进行矩阵相乘时候,没有区别。
但是,dot支持矩阵和数字相乘。
开源的数据挖掘库
用于数据探索
封装了matplotlib,Numpy
import Pandas as pd
Series 1维 带有标签的同结构类型数组。
DataFrame 2维 表格结构,带有标签,大小可变,且可以包含异构的数组。
注:一个DataFrame中可以包含若干个Series。
1.创建DataFrame(字典结构)
pd.DataFrame(ndarray,index,columns,…)
ndarray: np数据结构
index:行索引值
columns:列索引值
2.创建日期
pd.date_range(start=None,end=None,periods=None,freq=‘B’)
start – 开始日期
end – 结束日期
periods – 时间跨度,时间天数
freq – 统计时间方式,递进单位,默认1天,‘B’默认略过周末。
3.DataFrame介绍 – 类比二维数组
1 dataframe属性
对象.shape
对象.index
对象.columns
对象.values
对象.T
对象.head(n): 看前几行
对象.tail(n): 默认后5行
2 dataframe设置索引
修改行列索引:
必须整行或者整列去进行修改
重设索引
对象.reset_index(drop=False): drop默认为False,不删除原来的索引值。
设置新索引:
对象.set_index(keys=[],drop=True)
keys:列索引名作为索引
drop:默认为True,删除原来的索引
如果设置索引是两个的时候就是multiIndex
4.MultiIndex和panel – 类比三维数组
1 MultiIndex
对象.index
对象.index.names
2 panel – 已经弃用,了解
直接没法进行查看里面的值,需要通过索引获取
5.Series – 一维数组
1 创建
pd.Series(ndarray,list/dictionary)
通过ndarray创建
指定索引创建
通过字典创建
2 属性
对象.index
对象.values
1.索引操作
1. 直接 – 先列后行
2. 对象.loc[行,列] – 先行后列,通过行和列的索引来访问数据。":“表示连续,”[]"表示枚举。包首包尾
3. 对象.iloc[] – 先行后列,索引值的下标。包首不包尾。
4. 对象.ix[] – 先行后列,混合索引
2.赋值操作
对close列进行重新赋值
1.对象[“close”] =1
2.对象.close = 1
3.排序
1.dataframe
对象.sort_values(by,ascending=True)
单个键或者多个键进行排序,默认升序。
by – 按照什么排序
ascending – 升降序
对象.sort_index()
注意:by这个参数可以接受多个值,优先按照第一个索引排序,如果相同,按照后面的。
2.Series
对象.sort_values()
对象.sort_index()
1.算术运算
对象.add(n)
直接使用方法,add,sub …
也可以用符号
2.逻辑运算
逻辑运算符号 < 、>、| 、 &
直接判断
逻辑运算函数
对象.query(“expr”)
expr:查询字符串
对象.isin([])
3.统计函数
对象.describe()
统计函数
Sum
mean
…
mode – 众数(出现次数最多的数)
idxmax – 最大值的索引
idxmin – 最小值的索引
4.累计统计函数
函数 作用
cumsum 计算前1/2/3/…/n个数的和
cummax 计算前1/2/3/…/n个数的最大值
cummin 计算前1/2/3/…/n个数的最小值
cumprod 计算前1/2/3/…/n个数的积
5.自定义运算
apply(func,axis=)
func – 自己定义的函数
axis 按行还是按列计算
对象.plot(x=None,y=None,kind=“line”)
kind –
line – 折线图
bar
barh – 条形图旋转
hist
pie
scatter
plt.show()
1.csv
读取 – pd.read_csv(filepath_or_buffer,usecols=[,])
filepath_or_buffer: 文件路径
usecols – 需要读取的列名
存储 – 对象.to_csv(path_or_buf=None,conlumns,mode=‘w’,index = True)
mode:"w"重写,"a"追加
conlumns – 保存哪列
index : 是否保存索引
2.hdf
读取 – pd.read_hdf()
写入 – 对象.to_hdf()
注意:保存文件是xxx.h5
3.json
读取 – pd.read_json(path_or_buf=None,orient=None,typ=‘frame’,line=False)
orient – 按照什么方式进行读取或者写入(‘split’,‘records’,‘index’,‘columns’,‘values’)
lines – 是否按照行读取和写入
typ – 指定转换成的对象类型series或dataframe
写入 – 对象.to_json(path_or_buf=None,orient=None,line=False)
orient – 按照什么方式进行读取或者写入(‘split’,‘records’,‘index’,‘columns’,‘values’)
lines – 是否按照行写入
4.推荐使用hdf
压缩方式,读取效率快。
压缩后,节省空间。
支持跨平台。
判断数据是否为NaN:
np.any(pd.isnull(movie)) # 里面如果有一个缺失值,就返回True
np.all(pd.notnull(movie)) # 里面如果有一个缺失值,就返回False
处理方式:
存在缺失值,并且是np.nan:
1.删除存在缺失值的:data = movie.dropna(axis=“rows”)
注:不会修改原数据,需要接受返回值
2.替换缺失值,fillna(value=“”,inplace=True)
value:替换成的值
inplace:True:会修改原数据,False:不替换修改原数据,生成新的对象
不是缺失值nan,有默认标记的
对象.replace(to_replace=,value=)
to_replace – 替换前的值
value – 替换后的值(np.NaN)
1.什么是数据离散化
把一些数据分到某个区间,最后用不同的符号或者数字表达式
2.数据离散化api
pd.qcut() – 把数据大致分为数量相等的几类
pd.cur() – 指定分组间隔
数量统计:
对象.value_counts()
3.one-hot编码
就是把数据转换为0,1统计类型
别名:哑变量,热独编码
api:
pd.get_dummies()
pd.concat()
axis=
pd.merge()
left – 左表
right – 右表
on – 指定键
how – 按照什么方式进行拼接
1.什么交叉表,透视表
就是探索两列数据之间的占比关系
2.交叉表:pd.crosstab()
返回具体数量的统计
3.透视表:对象.pivot_table([],index=[])
返回占比情况
对象.groupby(key,as_index)
key – 按照什么去分组
as_index – 是否发生结构变化
注意:如果抛开聚合,去说分组,没有意义。
现在说的机器视觉(machine vision)一般指计算机视觉(computer vision),简单来说就是研究如何使机器看懂东西,就是指使用摄影机和电脑代替人眼对目标进行是被、跟踪和测量等机器视觉,并进一步做图形处理,使电脑处理成为更适合人眼观察或传送给仪器检测的图像。
计算机视觉:
语义感知:
分类 Classification(物体、属性、场景等)
检测 Detection(物体、行人、人脸等)
识别 Recognition(物体、人)
分割 Segmentation
检索 Retrieval
语言 Language
几何属性:
3D建模
双目视觉
增强现实
图像处理:
空间域处理:
点运算 (HE、CLAHE)
形态学运算(膨胀、腐蚀)
临域运算(卷积、金字塔)
频率域处理:
傅里叶变换
小波变换
opencv是一个的跨平台库,可以运行在 Linux、Windows 和 Mac OS 操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时也提供了python接口,实现了图像处理和计算机视觉方面的很多通用算法。
Gray Bradsky于1999年开发,2000年发布
c++、python、java、js
跨平台
pip install opencv-python
pip install opencv-contrib-python
模块 | 介绍 |
---|---|
core | 核心模块,是定义基本数据结构的模块,也包括库中所有其他模块使用的基本函数 |
imgproc | 图像处理模块,包括图像滤波、几何图像变换、颜色空间变换和直方图 |
imgcodecs | 图像文件读写 |
highgui | 高级GUI,提供UI功能的接口,可以执行以下操作:创建和操作可以显示的窗口、将滑动条添加到窗口、键盘命令和处理鼠标事件等 |
videoio | 视频I/O,视频捕获和视频编解码器的接口 |
video | 视频分析模块,包括背景减法、运动估计和目标跟踪算法 |
calib3d | 摄像机标定和三维重建,包括基本的多视点几何算法、立体匹配算法、目标姿态估计、单摄像机和立体摄像机标定以及三维重建 |
features2d | 二维特征框架,该模块包括特征检测器、描述符和描述符匹配器 |
objdetect | 目标检测,检测预定义类的对象和实例(例如,人脸、眼睛、人和汽车) |
dnn | 深度神经网络(Deep neural network, DNN)模块,本模块包含以下内容:用于创建新层的API、一组预定义的常用层、从层构造和修改神经网络的API、从不同深度学习框架加载序列化网络模型的功能等 |
ml | 机器学习库(Machine Learning Library, MLL)是一组可用于分类、回归和聚类目的的类和方法 |
flann | 快速近似近邻库(Fast Library for Approximate Nearest Neighbors, FLANN)是一组非常适合快速近邻搜索的算法,用于多维空间中的聚类和搜索 |
photo | 计算摄影,提供一些计算摄影的函数 |
stitching | 图像拼接,实现了一个自动拼接全景图像的拼接流水线 |
shape | 形状距离和匹配模块,可用于形状匹配、检索或比较 |
superres | 超分辨率,包含一组可用于提高分辨率的类和方法 |
videostab | 视频稳定,包含一组用于视频稳定的类和方法 |
viz | 三维可视化工具,用于显示与场景交互的小部件 |
import cv2
# 创建窗口
# cv2.namedWindow('window', cv2.WINDOW_AUTOSIZE)
cv2.namedWindow('window', cv2.WINDOW_NORMAL)
# 更改窗口的大小
cv2.resizeWindow("window", 800, 600)
# 展示名字为window的窗口
cv2.imshow('window', 0)
# 等待按键
# 0表示接收任意按键,如果给其他的整数,表示等待按键的时间,单位是毫秒
key = cv2.waitKey(0)
# key是int 型,最少都是16位,但是ascii码是8位
# ord()是python中计算ascii的值的函数q
if key & 0xFF == ord("q"):
print("准备销毁窗口")
cv2.destroyAllWindows()
import cv2
import matplotlib.pyplot as plt
# 默认是按照彩色图片来读取的(0是灰度)
# pic 的数据格式是numpy的ndarray
pic = cv2.imread('./1.jpg')
# 发现matplotlib显示的图片和真实的图片颜色不一样,因为opencv读进来的图片数据的通道不是默认的(RGB),
# 而是BGR,所以一般opencv读进来的图片不要用别的方式去展示,比如matplotlib
# 用opencv自己的方式去展示
# plt.imshow(pic)
# plt.imshow(pic[:, :, ::-1])
# plt.show()
def cv_show(name, img):
cv2.imshow(name, img)
key = cv2.waitKey(0)
if key & 0xFF == ord('q'):
print("销毁窗口")
cv2.destroyAllWindows()
import cv2
# VideoCapture可以捕获摄像头,用数字来表示不同的设备,比如0,1(打开失败不会报错);如果是文件直接指定路径。
video = cv2.VideoCapture("../1.mp4")
# 检查是否打开正确
if video.isOpened():
# 读一帧数据,返回标记和这一帧数据,True表示读到了数据,False表示没读到数据。
op, frame = video.read()
else:
op = False
while op:
op, frame = video.read()
if frame is None:
break
if op:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('ret', gray)
# 假如一个视频是30帧,那么每张图片间隔1000//30毫秒(只能是整数)
if cv2.waitKey(10) & 0xFF == 27:
break
video.release()
cv2.destroyAllWindows()
cap = cv2.VideoCapture(0)
# fource = cv2.VideoWriter_fourcc(*'mp4v')
fource = cv2.VideoWriter_fourcc(*'XVID')
# 创建videowriter
# vw = cv2.VideoWriter('output.mp4',fource,30,(640,480))
vw = cv2.VideoWriter('output.avi', fource, 30, (640, 480))
while cap.isOpened():
ret,frame = cap.read()
if not ret:
break
# 写入每一帧图片
vw.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
vw.release()
cv2.destroyAllWindows()
import cv2
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 300, 200)
img = cv2.imread("./1.jpg")
while True:
cv2.imshow('img', img)
key = cv2.waitKey(0)
if key & 0xFF == ord('q'):
break
elif key & 0xFF == ord("s"):
cv2.imwrite("./2.png", img)
else:
print(key)
cv2.destroyAllWindows()
.cv.line(img,start,end,color,thickness,linetype,shift) # 绘制直线
thickness:线条宽度
linetype: 线型-1,4,5,16 默认是8
shift:坐标缩放比例,可不写
.cv.circle(img,centerpoint,r,color,thickness) # 绘制圆形
.cv.rectangle(img,leftupper,rightdown,color,thickness) # 绘制矩形
.cv.putText(img,text,station,font,fontsize,color,thickness,cv.LINE_AA) # 向图像中添加文字
# opencv是没有办法直接绘制中文的。需要用到第三方库:pip install pillow
#创建一张全白的图片用来绘制中文
img = np.full((200,200,3),fill_value=255,dtype=np.uint8)
from PIL import ImageFont,ImageDraw,Image
fontpath = "C:\Windows\Fonts\....."
#设置字体的颜色
b,g,r,a = 0,255,0,0
#设置字体大小
font = ImageFont.truetype(fontpath,15)
#将numpy array的图片格式转为PIL的图片格式
img_pil = Image.fromarray(img)
#创建画板
draw = ImageDraw.Draw(img_pil)
#在图片上绘制中文
draw.text((10,150),"绘制中文",font=font,fill=(b,g,r,a))
#将图片转为numpy array的数据格式
img = np.array(img_pil)
cv2.imshow("img",img)
.cv2.ellipse(img,中心点,长宽的一半,角度,从哪个角度开始,从哪个角度结束,颜色…) # 画椭圆
.cv2.polylines(img,[pts],boolean_isclosed,color,thickness) # 画多边形(pts多边形的点集ndarray,必须是int32,且pts是3维的例:np.array([(…,…),(.,.)],np.int32)
.cv2.fillPoly(img,[pts],color) # 填充多边形,一定是闭合的。
注意
:
1.左上角是原点
2.y轴向下,x轴向右
3.单位:像素点
def mouse_callback(event, x, y, flags, userdata):
"""
对窗口上的鼠标动作做出响应,函数名可以随便取,但是参数必须时5个。
:param event:鼠标事件
:param x:鼠标的x坐标
:param y:鼠标的y坐标
:param flags:鼠标的组合案件
:param userdata:用户数据
:return:
"""
print(event, x, y, flags, userdata)
# 调用鼠标的回调函数
cv2.setMouseCallback('mouse', mouse_callback, 'userdata')
获取并修改图像中的像素点
img是ndarray,通过行列坐标来获取相应的值并修改。
其中行对应y轴,列对应x轴。
图像属性
shape,size,dtype
import cv2
import numpy as np
# 创建窗口
cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)
cv2.resizeWindow('trackbar', 640, 480)
# 定回调函数
def callback(value):
pass
# 创建trackbar
cv2.createTrackbar('R', 'trackbar', 0, 255, callback)
cv2.createTrackbar('G', 'trackbar', 0, 255, callback)
cv2.createTrackbar('B', 'trackbar', 0, 255, callback)
# 创建一个背景图片
img = np.zeros((480, 640, 3), np.uint8)
while True:
# 获取当前tracker的值
r = cv2.getTrackbarPos('R', 'trackbar')
g = cv2.getTrackbarPos('G', 'trackbar')
b = cv2.getTrackbarPos('B', 'trackbar')
# 改变背景图颜色
img[:] = [b, g, r]
cv2.imshow('trackbar', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
HSV
hue:色相,即色彩。
saturation:饱和度,颜色接近光谱色的程度。(混合)
value(Brightness):明度,颜色明亮的程度。(黑色控制)
HSL
hue:色相,即色彩。
saturation:饱和度,颜色纯度。(稀释)
Lightness(Brightness):明度。(黑白控制)
YUV
考虑到人类的感知能力,减低色度的带宽。
最大的优点就是占用极少的带宽。
index = cv2.getTrackbarPos('curcolor','color',0,2,callback)
colorspaces=[cv2.COLOR_BGR2GRAY,cv2.COLOR_BGR2BGRA,cv2.COLOR_BGR2HSV]
cvt_img = cv2.cvtColor(img,colorspaces[index])
mat是opencv在c++语言中用来表示图像数据的一种数据结构,在python中转化为numpy的ndarray。
img2 = img.view() # 浅拷贝
img3 = img.copy() # 深拷贝
cv2.imshow('img',np.hstack((img2,img3))) # 水平堆叠显示
cv2.imshow('img',np.vstack((img2,img3))) # 垂直堆叠显示
b,g,r = cv2.split(img) # 分割通道
b[10:100,10:100] =255 # 修改一些颜色
img2 = cv2.merge((b,g,r)) # 合并通道
import cv2
img1 = cv2.imread("../1.jpg")
img2 = cv2.imread("../img.png")
print(img1.shape)
print(img2.shape)
# 在加法之前需要把图片的形状变得完全一致才行。长宽相同,通道数一样
new_img1 = img1[:483, :500]
new_img2 = img2[:483, :500]
# add的规则就是两个图对应位置的元素相加,如果超过255,全部变成255
# 图片和单个数字运算,每个数都会和100进行加法运算,相当于%256 # img1 +=100
new_img = cv2.add(new_img1, new_img2)
# 减 subtract 相应位置元素相减,减完小于0,统一变成0
new_img2 = cv2.subtract(new_img1, new_img2)
# 乘 multiply
new_img3 = cv2.multiply(new_img1, new_img2)
# 除 divide
new_img4 = cv2.divide(new_img1, new_img2)
cv2.imshow("img", new_img)
if cv2.waitKey(1) & 0xFF == ord('q'):
cv2.destroyAllWindows()
# 图像的融合
# 不是简单的加法了,相当于拿图片做了线性运算,new_img = img1*w1 + img2*w2 + bias
import cv2
img1 = cv2.imread("../1.jpg")
img2 = cv2.imread("../img.png")
new_img1 = img1[:483, :500]
new_img2 = img2[:483, :500]
new_img = cv2.addWeighted(new_img1, 0.3, new_img2, 0.7, 0)
opencv中的逻辑运算就是对应位置元素进行与或非,异或。
opencv中的非,0反过来是255。
import cv2
import numpy as np
img1 = cv2.imread("../1.jpg")
img2 = cv2.imread("../img.png")
# 变成相同形状的图片
img1 = img1[:483, :500]
img2 = img2[:483, :500]
# 非操作。相当于(255-img1)
img1_not = cv2.bitwise_not(img1)
# 与操作,按位与
img_and = cv2.bitwise_and(img1,img2)
# 或操作,按位或
img_or= cv2.bitwise_or(img1,img2)
# 异或,按位异或
img_xor= cv2.bitwise_xor(img1,img2)
cv2.imshow('not', np.hstack((img2,img1, img_xor)))
resize(src,src, dsize, dst=None, fx=None, fy=None, interpolation=None)
src: 要缩放的图片
dsize: 缩放之后的图片大小,元组和列表示均可
dst: 可选参数,缩放之后的输出图片
fx,fy: 可选参数,x轴和y轴的缩放比,及宽度和高度的缩放比
interpolation:插值算法
INTER_NEAREST:邻近插值,速度快,效果差。
INTER_LINEAR:双线性插值,使用原图中的4个点进行插值,默认。
INTER_CUBIC:三次插值,原图中的16个点。
INTER_AREA:区域插值,效果最好,计算时间最长。
import cv2
import numpy as np
img1 = cv2.imread("../1.jpg")
img2 = cv2.imread("../img.png")
# 把图片变成一样尺寸并展示,不用切片
new_img1 = cv2.resize(img1, (500, 483))
new_img2 = cv2.resize(img2, (500, 483))
print(img1.__sizeof__()) # 查看字节
# 按照x,y轴的比例进行缩放
new_img3 = cv2.resize(img1,dsize=None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)
cv2.imshow("img", np.hstack((new_img1, img2)))
cv2.waitKey(0)
cv2.destroyAllWindows()
flip(src,flipCode)
flipcode = 0 上下翻转
flipcode > 0 左右翻转
flipcode < 0 上下+左右翻转
import cv2
import numpy as np
img1 = cv2.imread("../1.jpg")
new_img1 = cv2.flip(img1, flipCode=-1)
cv2.imshow("img", np.hstack((img1, new_img1)))
cv2.waitKey(0)
cv2.destroyAllWindows()
rotate(img,rotatecode)
cv2.rotate_90_clockwise 90度顺时针
cv2.rotate_180 180度
cv2.rotate_90_counterclockwise 90度逆时针
import numpy as np
import cv2
img1 = cv2.imread("../1.jpg")
h, w, ch = img1.shape
# 变换矩阵,最少是float32位
M = np.float32([[1, 0, 200], [0, 1, 0]]) # 左移200px
# 平移,注意opencv中是先宽度,后高度
new_img2 = cv2.warpAffine(img1, M, dsize=(w, h))
cv2.imshow('img', np.hstack((img1, new_img2)))
cv2.waitKey(0)
cv2.destroyAllWindows()
img1 = cv2.imread("../1.jpg")
h, w, ch = img1.shape
# 获取变换矩阵
# 规定时逆时针旋转
M = cv2.getRotationMatrix2D((w/2,h/2),45,1)
new_img1 = cv2.warpAffine(img1,M,(w,h))
cv2.imshow('img', np.hstack((img1, new_img1)))
cv2.waitKey(0)
cv2.destroyAllWindows()
透视变换就是将一种坐标系变换成另一种坐标系,简单来说可以把一张“斜”的图变“正”。
降噪
图像卷积就是卷积核在图像上按行滑动像素时不断的相乘求和的过程。
padding
卷积之后图片的长宽会变小,如果要保持图片大小不变,我们需要在图片周围填充0,padding指的就是填充的0的圈数。
计算padding的圈数
输入体积大小 H1W1D1
四个超参数:
filter数量k
filter大小f
步长s
零填充大小p
输出体积大小h2w2d2
h2 = (h1-f+2p)/s +1
w2 = (w1-f+2p)/s +1
d2 = k
为什么都是奇数?
1.根据上面padding的计算公式,如果要保持图片大小不变,采用偶数卷积核的话,将会出现补零为小数的情况
2.奇数维度的过滤器有中心,便于指出过滤器的位置,即opencv卷积中的锚点。
img1 = cv2.imread("../1.jpg")
# kernel = np.ones((5, 5), np.float32)/25
# 尝试其他的卷积核,突出轮廓
# kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
# kernel = np.array([[-2, 1, 0], [-1, 1, 1], [0, 1, 2]]) # 浮雕效果
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]) # 锐化
new_img1 = cv2.filter2D(img1, -1, kernel)
cv2.imshow("img", np.hstack((img1, new_img1)))
方盒滤波
boxfilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None)
ksize:卷积核大小,例如(5,5)
normalize = True时,a=1/(w*h)滤波器的宽高。
normalize = false时,a=1。
一般情况都是用normalize = true,这时方盒滤波等价于均值滤波。
均值滤波
blur(src, ksize, dst=None, anchor=None, borderType=None)
符合高斯分布(也叫正态分布)的数据的概率密度函数。
假设有一个数组[1556789],取其中的中间值(即中位数)作为卷积后的结果值即可,中值滤波对胡椒噪音(椒盐噪音)效果明显。
双边滤波对于图像的边缘信息能有更好的保存。其原理是一个与空间距离相关的高斯函数与一个灰度距离相关的高斯函数相乘。
边缘检测
边缘时像素值发生跃迁的位置,是图像的显著特征之一,再图像特征提取,对象检测,模式识别等方面都有重要的作用。
# x轴方向梯度,获取的是垂直边缘
dx = cv2.Sobel(img, cv2.CV_64F, dx=1, dy=0, ksize=5)
dy = cv2.Sobel(img, cv2.CV_64F, dx=0, dy=1, ksize=5)
# 可利用nump的加法,直接整合两张图
# dst = dx + dy
# 也可以利用opencv的加法
dst = cv2.add(dx, dy)
cv2.imshow("img", np.hstack((dx, dy, dst)))
# x轴方向梯度,获取的是垂直边缘
dx = cv2.Scharr(img, cv2.CV_64F, dx=1, dy=0)
dy = cv2.Scharr(img, cv2.CV_64F, dx=0, dy=1)
# 可利用nump的加法,直接整合两张图
# dst = dx + dy
# 也可以利用opencv的加法
dst = cv2.add(dx, dy)
cv2.imshow("img", np.hstack((dx, dy, dst)))
img = cv2.imread("../1.jpg")
dst = cv2.Laplacian(img,-1,ksize=3)
cv2.imshow("img", np.hstack((img, dst)))
Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
最优边缘检测的三个主要评价标准
Canny边缘检测的一般步骤
1.去噪:边缘检测容易收到噪声影响,在进行边缘检测前通常需要进行去噪,一般用高斯滤波去除噪音。
2.计算梯度:对平滑后的图像采用sobel算子计算梯度和方向
3.非极大值抑制(NMS)
- 在获取了梯度和方向后,遍历图像,去除所有不是边界的点。
- 实现方法:逐个遍历像素点,判断当前像素点是否是周围像素点中具有相同方向梯度的最大值。
4.滞后阈值
img = cv2.imread("../1.jpg")
# 阈值越小,细节越丰富,绘制的边缘越精细
img1 = cv2.Canny(img, 100, 200)
img2 = cv2.Canny(img, 64, 128)
cv2.imshow("img", np.hstack((img1, img2)))
指一系列处理图像形状特征的图像处理技术。
img = cv2.imread("../1.jpg")
# 二值化操作是对灰度图像操作,将图片变成灰度图片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 返回两个结果,一个是阈值,另一个是处理后的图片
ret, dst = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("img", np.hstack((gray, dst)))
img = cv2.imread("../1.jpg")
# 二值化操作是对灰度图像操作,将图片变成灰度图片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 自适应阈值二值化只返回一个值,即二值化之后的结果
dst = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,3,0)
cv2.imshow("img", np.hstack((gray, dst)))
腐蚀操作也是用卷积核扫描图像,只不过腐蚀操作的卷积核一般都是1,如果卷积核内所有像素点都是白色,那么锚点即为白色。
img = cv2.imread("../1.jpg")
kernel = np.ones((3,3),np.uint8)
dst = cv2.erode(img,kernel,iterations=2)
cv2.imshow("img", np.hstack((img, dst)))
opencv 提供了获取卷积核的api,不需要我们手工创建卷积核。
img = cv2.imread("../1.jpg")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.erode(img, kernel, iterations=2)
cv2.imshow("img", np.hstack((img, dst)))
膨胀时腐蚀的相反操作,基本原理是只要保证卷积核的锚点是非0值,周边无论是0还是非0值,都变成非0值。
img = cv2.imread("../1.jpg")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.dilate(img, kernel, iterations=2)
cv2.imshow("img", np.hstack((img, dst)))
# 开运算 = 腐蚀 + 膨胀
# 开运算提供了另一种去除噪声的思路
img = cv2.imread("../1.jpg")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel,iterations=2)
cv2.imshow("img", np.hstack((img, dst)))
# 闭运算 = 膨胀 + 腐蚀
# 闭运算可以去除图形内部的噪声
img = cv2.imread("../1.jpg")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel,iterations=2)
cv2.imshow("img", np.hstack((img, dst)))
# 注意调节kernel大小以获得更清晰的边缘
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel,iterations=2)
cv2.imshow("img", np.hstack((img, dst)))
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel,iterations=1)
cv2.imshow("img", np.hstack((img, dst)))
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
dst = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel,iterations=1)
cv2.imshow("img", np.hstack((img, dst)))
图形轮廓是具有相同颜色或灰度的连续点的曲线。
注意点:
- 为了检测的准确性,需要先对图形进行二值化或Canny操作。
- 画轮廓时辉修改输入的图像,如果之后想继续使用原始图像,应该将原始图像存储到其他变量中。
findContours(image, mode, method, contours=None, hierarchy=None, offset=None)
RETR_CCOMP = 3,按照树型存储轮廓,从小到大,从右到左。
drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
contourArea(contour, oriented=None)
arcLength(curve, closed)
import cv2
img = cv2.imread("../1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化,注意有两个返回值,阈值和结果
ret, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
# 轮廓查找,新版本返回两个结果,轮廓和层级
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 打印轮廓,contours时list,不是ndarray,里面放的时ndarray,每个ndarray表示一个contour
print(contours)
# 绘制轮廓
# 绘制轮廓会直接修改原图
# 如果想保持原图不变,建议copy一份
img_copy = img.copy()
cv2.drawContours(img_copy, contours, -1, (0, 0, 255), 1)
# cv2.imshow("img",img)
# cv2.imshow("img_copy",img_copy)
# 计算轮廓面积和周长
area = cv2.contourArea(contours[1]) # 面积
perimeter = cv2.arcLength(contours[1], closed=True) # 周长
cv2.waitKey(0)
cv2.destroyAllWindows()
findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP函数对该多边形曲线做适当近似,这就是轮廓的多边形逼近。
approxPolyDP就是以多边形去逼近轮廓,采用的是Douglas-Peucker算法;DP算法原理比较简单,核心就是不断找多变形最远的点加入形成新的多边形,直到最短距离小于指定的精度。
# 使用多边形逼近,近似m模拟轮廓
approx = cv2.approxPolyDP(contours[1], 5, closed=True)
# approx本质上就是一个轮廓数据
# 画出多边形逼近的轮廓
cv2.drawContours(img_copy, [approx], 0, (0, 255, 0), 2)
cv2.imshow("img_copy", img_copy)
人脸检测
:在一张图像中判断是否存在人脸并找出人脸所在的位置。
人脸识别
:在人脸检测的基础上收集人脸数据集合进行处理保存信息,将输入人脸与保存的信息进行对比校验,得到的是其中某个人脸。
特征值
:以某种特定规则对输入源进行处理得到具有唯一性质量化的值,在人脸识别中特征值的提取有HOG-方向梯度直方图,HAAR-like特征,LBP-局部二进制模式三种方法。
分类器
:根据特征值界定输入事物是否属于某种类别的过滤条件组合,未知类别的算聚类器,弱分类器的正确率高于随机分类(50%),强分类器:能满足预期分类并且正确率很高的分类器。
Adaboost
:迭代算法,同一个训练集合下训练多个弱分类器,把弱分类器迭代组合成一个强分类器。
级联分类器
:将多个同类型的分类器列联合起来进行推算整合以得到符合目标的最终分类器的方法。
1.准备数据,分析数据,对数据进行预处理,归一化处理
。
2.划分训练集和测试集。
3.计算未知样本和每个训练集样本的距离。
4.设定参数,k值。
5.将距离升序排列。
6.选取距离最小的k个点。
7.统计前k个最近邻样本点所在类别出现的次数。
8.多数表决,选择出现频率最大的类别作为未知样本的类别。
def knn(inx, dataset, labels, k):
"""
knn算法分类器
:param inx:未知样本(测试集)
:param dataset:训练样本的特征矩阵(训练集)
:param labels:训练集分类标签向量
:param k:选择距离最小的k个点
:return:分类结果
"""
dist = (((dataset - inx) ** 2).sum(1)) ** 0.5 # 欧氏距离:计算未知样本和每个训练集样本的距离
sorted_dist = dist.argsort() # 从小到大,返回原序列的索引
class_count = {}
for i in range(k): # 计算类型出现的次数
vote_lable = labels[sorted_dist[i]]
class_count[vote_lable] = class_count.get(vote_lable, 0) + 1
max_type = 0
max_count = -1
for key, value in class_count.items():
if value > max_count:
max_type = key
max_count = value
return max_type
0-1标准化、Z-score标准化、sigmoid压缩法等等
0-1标准化公式:
normalization = x- min / max -min
def autoNorm(dataset):
minvals = dataset.min(0)
maxvals = dataset.max(0)
normaldataset = np.zeros (dataset.shape)
normaldataset = (dataset-minvals) / (maxvals-minvals)
return normaldataset
距离最接近的数据点称为支持向量(support vector)。支持向量定义的沿着分隔线的区域成为间隔(margin)。
目标:找到一个超平面,使得它能够尽可能多的将两类数据点正确的分开,同时使分来的两类数据点距离分类面最远。
scikit-learn是基于python语言的机器学习工具。
1.导入库:from sklearn import svm
2.模型定义: model = svm.SVC()
3.模型函数: model.fit(trainingMat,hwlabels)
4.模型测试:classifierresult = model.predict(vectorundertest)
互斥且完备:每一个实例都被有且仅有一条路径和规则覆盖
信息增益直接以信息熵为基础,计算当前划分对信息熵所造成的变化。
划分选择的各种准则虽然对决策树的尺寸有较大影响,但对泛化性能的影响很有限。
例如信息增益于基尼指数产生的结果,仅在约2%的情况下不同。
剪纸方法和程度对决策树泛化性能的影响更为显著。
剪枝是决策树防止过拟合的手段
在数据带噪时甚至可能将泛化性能提升25%。
轴平行分类
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
研究和测度两个或两个以上变量之间关系的方法有回归分析和相关分析。
相关分析:研究两个或两个以上随机变量之间线性依存关系的紧密程度。通常用相关系数表示,多元相关时用复相关系数表示。
回归分析:研究某一随机变量(因变量)与其他一个或几个普通变量(自变量)之间的数量变动的关系。
import numpy as np
import pandas as pd
income = [20, 40, 20, 30, 10, 10, 20, 20, 20, 30]
production = [30, 60, 40, 60, 30, 40, 40, 50, 30, 70]
df = pd.DataFrame({'income':np.array(income),'production':np.array(production)})
print(df)
print(df.corr()) # 相关系数
print(df["income"].corr(df['production']))
lr = linear_model.LinearRegression()
lr. fit(x,y)
print(lr.coef_)
print(lr.intercept_)
梯度下降法(Gradient descent)是一个最优化算法,通常也称为最速下降法。1874年由著名的数学家柯西给出。
函数变化最快的方向就是函数的梯度方向。
批量梯度下降法、随机梯度下降算法(Stochastic gradient descent,SGD)
聚类目的在将相似的事务归类。
聚类分析又称为“同质分组”或者“无监督的分类”,指把一组数据分成不同的“簇”,每簇中的数据相似而不同簇间的数据则距离较远。
簇内文档之间应该彼此相似
簇间文档之间差异大
无监督意味着没有已标注好的数据集。
k-均值聚类算法中的每个簇都定义为其质心向量。
划分准则:使得所有文档到其所在簇的质心向量的平方和最小。
通过以下两步来实现目标优化:
重分配(reassignment):将每篇文档分配给离它最近的簇
重计算(recomputation):重新计算每个簇的质心向量
from sklearn.cluster import KMeans
....
model = KMeans(n_cluster=4) # K类,4类
model.fit(dataset)
print(model.cluster_centers_) # 打印中心
plt.scatter(dataset[:,0],dataset[:,1],c=model.labels_)
自底向上方法(合并):开始时,将每个样本作为单独的一个组;然后,依次合并相近的样本或组,直至所有样本或组被合并为一个组或者达到终止条件为止。
代表算法:AGNES算法
自顶向下方法(分裂)
代表算法:DIANA算法
关键问题:如何定义簇相似度
多个指标降为少数几个综合指标的过程在数学上叫降维。
满足以下条件:
每个主成分的系数平方和为1.
主成分之间相互独立,即无重叠的信息。
主成分的方差依次递减,重要性依次递减。
广义:
人工神经网络(artificial neural networks)也简称为审计网络或称作连接模型,是对人脑或自然神经网络若干基本特性的抽象和模拟,以大量的具有相同结构的简单单元的连接,来模拟人类大脑的结构和思维方式的一种可实现的物理系统,可通过计算机程度来模拟实现。
单层感知机:模型中的激活函数多采用符号函数,因此输出值为二值量,主要用于简单模式分类。
多层感知机:模型通过感知器的组合以及采用s型激活函数,可输出值为0-1之间的连续值,可实现输入到输出的任意非线性映射。
bp神经网络 = 多层感知机 + 反向误差传播(back propagation)学习(训练)算法即模型训练或者说连接权重的调整采用反向传播学习算法。
1.特征自动学习
2.层次网络结构
3.深层网络结构
自动编码机就是一种尽可能复现输入信号的神经网络。
第一步:采用自下而上的无监督学习 — wake-sleep算法。
第二步:自顶向下的监督学习
卷积:
局部特征提取
训练中进行参数学习
每个卷积核提取特定模式的特征
卷积神经网络训练的是----卷积核的参数
池化(下采样):
降低数据维度,避免过拟合
增强局部感受野
提高平移不变性
-全连接:
特征提取到分类的桥梁
官网:https://keras.io/
基于python的深度学习库
keras是一个用python编写的高级神经网络API,它能够以tensorflow,cntk,或者theano作为后端运行。
-运行简单而快速的原型设计(用户友好,高度模块化,可扩展性)
-同时支持卷积神经网络和循环神经网络,以及两者的组合
-在CPU和GPU上无缝运行。
# 安装
pip install keras
pip install tensorflow / pip install theano
# keras.jsonw文件 修改配置文件的后端
"floatx":"float32",
"epsilon":"1e-07",
"backend":"tensorflow",
"image_data_format":"channels_last"
from os import listdir
from keras.utils.np_utils import to_categorical
from keras.models import Model
from keras.layers import Input, Dense, Flatten, Dropout
from keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
from keras.models import load_model
import matplotlib.pyplot as plt
import numpy as np
def img2vector(filename):
returnVect = np.zeros((32, 32))
fr = open(filename)
for i in range(32):
lineStr = fr.readline()
for j in range(32):
returnVect[i, j] = int(lineStr[j])
return returnVect
# 9.模型复现
seed = 42
np.random.seed(seed) # 固定随机种子,使得模型训练结果可以复现
# 2.数据读取
hwlabels = []
trainingfilelist = listdir("trainingDigits")
m = len(trainingfilelist)
trainingmat = []
for i in range(m):
filenamestr = trainingfilelist[i]
filestr = filenamestr.split('.')[0]
classnumstr = int(filestr.split("_")[0])
hwlabels.append(to_categorical(classnumstr, 10)) # 独热编码(one-hot enconding) 从一维变成10维
trainingmat.append(img2vector('trainingDigits/%s' % filenamestr))
trainy = np.array(hwlabels)
trainx = np.array(trainingmat)
print(trainx.shape)
# 将三维的ndarray变成4维的
trainx = trainx.reshape((trainx.shape[0],
trainx.shape[1],
trainx.shape[2],
1))
print(trainx.shape)
# 3.建立模型
inp = Input(shape=(32, 32)) # 输入层
x = Flatten(name='flatten')(inp) # 将输入“压平”,即把多维的输入一维化,常用在从其他层到全连接层的过渡。
x = Dense(400, activation="relu", name="dense-1")(x) # 全连接层
x = Dropout(0.2, name="dropout-1")(x) # 删除一些连接,防止过拟合
x = Dense(10, activation="softmax", name="recognition")(x) # 全连接层
model = Model(inp, x)
# 4.模型编译与显示
model.compile(optimizer='adam',
loss='mse',
metrics=['accuracy'])
# optimizer:优化器
# SGD:随机梯度下降优化器
# RMSprop:均方根传播优化器,通常是训练循环神经网络RNN的不错选择
# AdaGrad:适应性梯度优化器,每一个参数保留一个学习率以提升在稀疏梯度上的性能
# Adam:自适应矩估计优化器,同时获得了AdaGrad和RMSProp算法的优点。
# loss:损失函数(目标函数)
# mse:均方根误差
# metrics:评价指标(评价函数和损失含数相似,只不过评价函数的结果不会用于训练过程中)
model.summary()
# # 5.模型训练
# # 8.保存和加载模型
modelfilepath = "model.best.hdf5" # 存入模型的名称
checkpoint = ModelCheckpoint(modelfilepath, monitor="val_accuracy", verbose=1, save_best_only=True, mode="max") # 保存最好的
earlypoint = EarlyStopping(monitor="val_accuracy", patience=20, verbose=1, mode="auto") # 没有变化自动停止训练
reduce_lr = ReduceLROnPlateau(monitor="val_loss", factor=0.1, patience=10, verbose=1, mode="auto", min_delta=0.00001,
cooldown=0, min_lr=0) # 学习率自动调整
history = model.fit(trainx, trainy, validation_split=0.1, epochs=100, batch_size=32,
callbacks=[checkpoint, earlypoint, reduce_lr]) # 设置验证集比例,迭代次数,样本批次大小
# testmodel = load_model(modelfilepath) # 加载训练好的模型
# 6.模型测试
testFileList = listdir('testDigits')
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)
testVector = []
testVector.append(vectorUnderTest)
testX = np.array(testVector)
classifierResult = np.argmax(model.predict(testX))
print(u"DNN得到的辨识结果是: %d, 实际值是: %d" % (classifierResult, classNumStr))
if classifierResult != classNumStr: errorCount += 1.0
print("\n辨识错误数量为: %d" % errorCount)
print("\n辨识率为: %f %" % ((1 - errorCount / float(mTest)) * 100))
# 7.绘制学习曲线
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()
# # 加深网络模型
# relu函数是目前比较火的一个激活函数,函数公式:f(x) = max(0,x)
# 相比sigmod函数与tanh函数有以下几个优点
# 1.客服梯度消失的问题
# 2.加快训练速度
# 缺点:
# - 输入负数,则完全不激活,relu函数死掉
# - relu函数输出要么是0,要么是正数,也就是relu函数不是以0为中心的函数。
from keras.layers import Input, Dense, Flatten, Dropout, Conv2D, MaxPool2D
from os import listdir
from keras.utils.np_utils import to_categorical
from keras.models import Model
from keras.layers import Input, Dense, Flatten, Dropout
from keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
from keras.models import load_model
import matplotlib.pyplot as plt
import numpy as np
def img2vector(filename):
returnVect = np.zeros((32, 32))
fr = open(filename)
for i in range(32):
lineStr = fr.readline()
for j in range(32):
returnVect[i, j] = int(lineStr[j])
return returnVect
# 9.模型复现
seed = 42
np.random.seed(seed) # 固定随机种子,使得模型训练结果可以复现
# 2.数据读取
hwlabels = []
trainingfilelist = listdir("trainingDigits")
m = len(trainingfilelist)
trainingmat = []
for i in range(m):
filenamestr = trainingfilelist[i]
filestr = filenamestr.split('.')[0]
classnumstr = int(filestr.split("_")[0])
hwlabels.append(to_categorical(classnumstr, 10)) # 独热编码(one-hot enconding) 从一维变成10维
trainingmat.append(img2vector('trainingDigits/%s' % filenamestr))
trainy = np.array(hwlabels)
trainx = np.array(trainingmat)
# 建立模型
inp = Input(shape=(32, 32, 1))
x = Conv2D(50, (5, 5), padding='valid', strides=(1, 1), activation='relu', name='conv-1')(inp)
x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid', name='pool-1')(x)
x = Conv2D(50, (3, 3), padding='valid', strides=(1, 1), activation='relu', name='conv-2')(x)
x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid', name='pool-2')(x)
x = Conv2D(30, (3, 3), padding='valid', strides=(1, 1), activation='relu', name='conv-3')(x)
x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid', name='pool-3')(x)
x = Dropout(0.2, name='dropout-1')(x)
x = Flatten(name='flatten')(x)
x = Dense(10, activation='softmax', name='recognition')(x)
model = Model(inp, x)
# 模型编译与显示
model.compile(optimizer='adam',
loss='mse',
metrics=['accuracy'])
model.summary()
modelfilepath = "model.best.hdf5" # 存入模型的名称
checkpoint = ModelCheckpoint(modelfilepath, monitor="val_accuracy", verbose=1, save_best_only=True, mode="max") # 保存最好的
earlypoint = EarlyStopping(monitor="val_accuracy", patience=30, verbose=1, mode="auto") # 没有变化自动停止训练
reduce_lr = ReduceLROnPlateau(monitor="val_loss", factor=0.1, patience=10, verbose=1, mode="auto", min_delta=0.00001,
cooldown=0, min_lr=0) # 学习率自动调整
history = model.fit(trainx, trainy, validation_split=0.1, epochs=100, batch_size=32,
callbacks=[checkpoint, earlypoint, reduce_lr]) # 设置验证集比例,迭代次数,样本批次大小
testFileList = listdir('testDigits')
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)
testVector = []
testVector.append(vectorUnderTest)
testX = np.array(testVector)
testX = testX.reshape((testX.shape[0],testX.shape[1],testX.shape[2],1))
classifierResult = np.argmax(model.predict(testX))
print(u"CNN得到的辨识结果是: %d, 实际值是: %d" % (classifierResult, classNumStr))
if classifierResult != classNumStr: errorCount += 1.0
print("\n辨识错误数量为: %d" % errorCount)
print("\n辨识率为: %f %" % ((1 - errorCount / float(mTest)) * 100))
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()
精确率:查到准不准
precision = tp/(tp+fp)
召回率:查的全不全
recall = tp/(tp+fn)
准确率:
ACC = (tp+tn)/(tp+tn+fp+fn)
平均准确率(average precision,AP):
pr曲线下的面积,这里的average,等于是对precision进行取平均。
数据增强策略:
官网:https://pytorch.org/get-started/locally/