第一天:
1.概述:
从数据中自动分析获得规律(模型),并利用规律对未知数据进行预测
2.数据集:
1.从历史数据获取规律,这些历史数据是怎么的格式?
机器学习的数据:文件csv(数据库的性能瓶颈,读取速度不行,格式不符合)
2.读取工具:pandas (一个数据读取非常方便以及基本的处理格式的工具)(dataFrame格式:通过行索引和列索引补全缺失值和数据转换,重复值不需要进行去重 )
3.numpy:释放了GIL,是真正的多线程
4.可用的数据集:scikit-learn、kaggle、UCI
5.数据集数据的结构组成:特征值+目标值(目标值就是你要最终要分辨的是什么 )
房子面积 房子位置 房子楼层 房子朝向 目标值 #特征目录
数据1 80 9 3 0 80
数据2 100 9 5 1 120
数据3 80 10 3 0 100
注:有些数据集可以没有目标值
6.sklearn:对于特征的处理提供了强大的接口(当特征值不满足机器学习的的算法需求时,那就要对特征进行处理,比如字符串不符合计算需求)
3.数据的特征工程:将原始数据转换为更好的代表预测模型的潜在问题的特征的工程,从而提高了对未知数据的的预测准确性
1.scikit-learn(sklearn):直接调用函数就可以对特征值进行特征分析 (安装scikit-learn需要Numpy,pandas库)
2.特征抽取:文本、字符串等等不能用于计算的数据进行转换,转换为数据(进行特征值化,为了让计算机更好的去理解数据)
3.特征抽取的API:
1.sklearn.feature_extraction
1.对字典数据进行特征值化:类: sklearn.feature_extraction.DictVectorizer(sparse=False/ture) (类对象示例化之后会有方法)
字典数据抽取:把字典中一些类别数据,分别进行转换成特征
1.方法: DictVectorizer.fit_trabsform(X) X:字典或者保护字典的迭代器,返回值为sparse矩阵 (即把一个字典的数据转换为一个数据)
DictVectorizer.inverse_trabsform(X) X:array数据或者sparse矩阵,返回值为转换之前的数据格式
DictVectorizer.get_feature_name() 返回类别名称
DictVectorizer.trabsform(X) 按照原先的标准转换
2.例子: from sklearn.feature_extraction import DictVectorizer
def dictvec():
#字典数据抽取
dict = DictVectorizer()#类对象示例化,括号里的sparse=False/ture的值就决定了返回的转换后的数据为数组还是矩阵
#调用对象方法,参数为字典
data=dict.fit_transform([{‘city’:‘北京’,‘temperature’:100}, {‘city’:‘上海’,‘temperature’:60}, {‘city’:‘深圳’,‘temperature’:40}]) #data 就是把字典转换后的数据
print(data)
print(dict.get_feature_name())
return None
if __name__=="__main__":
//调用dictvec()
dictvec()
#print(data)执行结果 sparse矩阵
(0,1) 1.0
(0,3) 100.0
(1,0) 1.0
(1,3) 60.0
(2,2) 1.0
(2,3) 30.0
print(dict.get_feature_name())执行结果
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60]
[ 0. 0. 1. 30.]]
2.对数组数据进行特征值化:先要转换为字典数据,再对字典数据进行特征转换
3.对文本数据进行特征值化:类 :sklearn.feature_extraction.text.CountVectorizer(sparse=False/ture) (类对象示例化之后会有方法)
统计文章中所有的词,特征目录重复的词只看作一次,在词的列表里面进行统计每个词出现的次数,单个字母不统计
2.例子: from sklearn.feature_extraction import CountVectorizer
def dictvec():
#对文本进行特征值化
cv = CountVectorizer()#类对象示例化,括号里的sparse=False/ture的值就决定了返回的转换后的数据为数组还是矩阵
#调用对象方法
data=cv.fit_transform(["gkjdsjdajsd","jklfjakfjakj"]
print(data) #这个的结果是一个sparse矩阵
print(dict.get_feature_name())#生成一个特征目录,词的列表
print(data.toarry())#把一个sparse矩阵转换为一个数组
return None
if __name__=="__main__":
//调用dictvec()
dictvec()
3.例子:对中文文本进行特征值化,中文的文章时,要进行分词,把中文文本转换为以词来分开的列表,才能提取出特征目录
1.jieba 分词,返回的是词语发生器
from sklearn.feature_extraction import CountVectorizer
import jieba
def cutword():
con1=jieba.cut("姐姐噶快就是大家圣诞节")
con2=jieba.cut("解放军安居房卡夫卡见附件是的房间")
#转换成列表
content1=list(con1)
content2=list(con2)
#把列表转换成字符串,这个字符串就是以字符串来隔开
c1=' '.join(content1)
c2=' '.join(content2)
return c1,c2;
def hanziverc():
c1,c2 = cutword()
cv = CountVectorizer()
data=cv.fit_transform([c1,c2])
print(data) #这个的结果是一个sparse矩阵
print(dict.get_feature_name())#生成一个特征目录,词的列表
print(data.toarry())#把一个sparse矩阵转换为一个数组
return None
if __name__=="__main__":
hanziverc()
4.tf-idf分析问题:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中出现很少,则认为此词或短语具有很好的类别区分能力,适合用来分类,用以评估一个词对于一个文件或一个词料库中的其中一份文件的重要程度
1. tf(term frequency:词的频率);idf(inverse document frequency:逆文档频率);
2.log(总文档数量/该词出现的文档数量):输入的数值越小,结果越小
3.tf*idf:重要性程度
4.类:sklearn.feature_extraction.text.TfidfVectorizer
TfidfVectorizer(stop_words=None,...)
返回词的权重矩阵
1.TfidfVectorizer.fit_transform(X)
X:文本或包含文本字符串的可迭代对象
2.TfdfVectorizer.inverse_transform(X)
X:array数组或者sparase矩阵
返回值:转换之前的数据格式
3.TfidfVectorzer.get_feature_names()
返回值:单词列表
4.特征预处理:对数据进行处理,将数据转换成算法要求的数据
sklearn特征预处理API:sklearn.preprocessing
多个特征同等重要的时候,进行归一化,使某一个特征不会对结果造成很大的影响(把所有重要的值转换到同一标准下面来进行比较)
1.数值型数据:标准缩放(归一化、标准化、缺失值)
1.归一化:对原始数据进行变换把数据映射到(默认[0,1])之间
1.公式:X'=(x-min)/(max-min) X"=X'*(mx-mi)+mi
注:作用于每一列。max为一列的最大值,min为一列的最小值,那么X"为最终的结果,mx,mi分别为指定区间默认值mx为1,mi为0
2.归一化API:示例化:sklearn.preprocessing.MinMaxScaler
1.MinMaxScaler(feature_range=(0,1)...) #每个特征缩放到给定范围(默认0,1)
2.MinMaxScaler.fit_transform(X)
X:numpy arry格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array
3.步骤:示例化MinMaxScaler、通过fit_transform转换
3.示例:
from sklearn.preprocessing import MinMaxScaler
def mm():
mm=MinMaxScaler(feature_range=(0,1) )
data=mm.fit_transform([[90,2,10,40],[90,2,10,40],[90,2,10,40],[90,2,10,40]])
print(data)
return None
if __name__=="__main__":
mm()
2.标准化:对原始数据进行变换到均值为0,方差为1范围内
类:sklearn.preprocessing.StandardScaler
1.公式:X'=(x-mean)/u u=方差的开根号
注:作用于每一列,mean为平均值,u为标准差
2.标准化API:示例化:StandardScaler(...) #处理之后每列来说所有的数据聚集在均值0附近方差为1
1.StandardScaler.fit_transfom(x) #进行标准化
X:numpy array格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array
2.StandardScaler.mean()
原始数据中每列特征的平均值
3.StandardScaler.std()
原始数据每列特征的方差
3.示例:
from sklearn.preprocessing import StandardScalerr
def mm():
std=StandardScaler
data=std.fit_transfom([[90,2,10,40],[90,2,10,40],[90,2,10,40],[90,2,10,40]])
print(data)
return None
if __name__=="__main__":
mm()
3.缺失值:
示例化:sklearn.preprocessing.Imputer
1.对缺失值删除:如果每列或者行数据缺失值达到一定的比例,建议放弃整行或整列
2.对缺失值插补:可以通过缺失值每行或者每列的平均值、中位数来填充
3.缺失值的API:
1.Imputer(missing_values='NaN',strategy='mean',axis=0) #完成缺失值插补
missing_values:指定缺失值的位置
strategy:填补的方法:平均值还是中位数
axis:指定用缺失值的行或列来进行填补
2.Imputer.fit_transform(X) #调用函数完成填补
X:numpy arry:格式的数据[n_samples,n_features]
放回值:转换后的形状相同array
4.示例:
from sklearn.preprocessing import Imputer
import numpy as np
def im():
im=Imputer(missing_values='NaN',strategy='mean',axis=0)
data=im.fit_transfom([[1,2],[np.nan,3],[7,6]])
print(data)
return None
if __name__=="__main__":
mm()
2.类别型数据:one-hot编码(转换为以字典,然后对字典进行抽取,前面额方法)
3.时间类型:时间的切分
5.数据降维:维度指特征的数量(把特征的数量减少),把一些对结果影响不大的特征进行舍去
1.特征选择:
1.特征选择的原因:冗余:部分特征的相关度高,容易消耗计算机性能;噪声:部分特征对预测结果有影响
2.主要方法1:Filter(过滤式):VarianceThreshold;Embedded(嵌入式):正则化、决策树;Wrapper(包裹式)
1.Filter(过滤式):VarianceThreshold(根据方差的大小进行过滤)
类:sklearn.feature_selection.VarianceThreshole
1.方差很小或为0时,就表明该 特征的数据都一样或差不多,该降维
2.API:示例化:VarianceThreshole(threshold=0.0) #删除所有低方差的特征,threshold=0.0为想要删除得方差得大小
1,VarianceThreshole.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
放回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有相同值得特征
3.示例:
from sklearn.feature_sekection import VarianceThreshold
import numpy as np
def var():
var=VarianceThreshole(threshold=0.0)
data=var.fit_transfom([[0,2,0,3],[0,1,4,3],[0,1,1,3]])
print(data)
return None
if __name__=="__main__":
var()
3.主要方法2:神经网络
4.主要方法3:PCA主成分分析(特征数量达到上百时,采用这一个):数据维数压缩,尽可能降低原数据的维数(复杂度),只损失少量信息,可以削减回归分析或聚类 分析中特征得数量
类:sklearn.decomposition.PCA
1.API:示例化PCA(n_components=None) #将数据分解为较低维数空间(n_components为小数时人为可控指定保留特征数量的占比,即90%时,指定保留90%的信息;为整数时人为指定保留多少个特征数量)
1.PCA.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
放回值:转换后指定维度的array
2.示例:
from sklearn.decomposition import PCA
def pca():
pca=PCA(n_components=0.9)
data=pca.fit_transfom([[2,8,4,5],[6,3,0,8],[5,4,9,1]])
print(data)
return None
if __name__=="__main__":
pca()
4.机器学习开发流程
1.数据类型
1.离散型数据(全部是整数)、连续性数据(在某一个范围内可以任取一个数):离散型是区间内不可分的,连续性在区间内可分
2.机器学习的算法分类:
1.监督学习(预测目标值,数据有特征值+目标值)(输入数据,有特征有标签,即有标准答案)
1.分类(目标值离散数据):k-近邻算法、贝叶斯分类、决策树与随机森林、逻辑回归、神经网络
2.回归(目标值连续数据):线性回归、岭回归
3.用于标注:隐马尔可夫模型
2.无监督学习(只有特征值)(输入数据有特征无标签,即无标准答案)
聚类:k-means
3.机器学习的开发流程
1.找数据
2.原始数据
1.建立模型(模型+算法+数据):根据数据类型划分应用种类
3.数据基本处理:如pd去处理数据(缺失值,合并表。。。。)
· 4.特征工程:对特征进行处理(重要)
5.找算法:对于的分类问题或回归问题的算法
6.模型评估,判定效果
7.上线使用:以API形式提供
第二天:
监督学习:
1.skleaen数据集
1.数据集的划分
1.训练集(75%)用来训练建立模型,测试集(25%)用来评估模型
2.数据集划分API:类:sklearn.model_selection.train_test_split
2.sklearn数据集API介绍
类:sklearn.datasets.load_iris()
1.datasets.load_()
获取小规模数据集,数据包含在datasets里
2.datasets.fetch_(data_home=None)
获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是~/scikit_learn_data/
load和fetch返回的数据类型datasets.base.bunch(字典格式)
1,data:特征数据数组,是[n_samples * n_features]的二维numpy.ndarray数据
2.标签数据,是n_samlpesd的唯一numpy.ndarray数组
3.DSCR:数据描述
4.feature_names:特征名(新闻数据,手写数字,回归数据集没有)
5.target_names:标签名
3.示例:
from sklearn.datasets import load_iris
li = load_iris()
print(li.data) #获取特征值
print(li.target) #获取目标值
print(li.DESCR) #打印描述
3.数据集进行分割(把数据集随机分割成训练集和测试值)
类:sklearn.model_selection.train_test_split(*arrays,**options)
1.x 数据集的特征值
2.y 数据集的目标值
3.test_size 测试集的大小,一般为float
4.random_state 随机数种子,不同的种子会造成不同的随机采样结果,相同的种子采样结果相同
5.return 训练集特征值,测试机特征值,训练标签,测试标签(默认随机去取)
示例:
3.示例:
from sklearn.datasets import load_iris
from sklearn.model_selction import train_test_split
li = load_iris()
print(li.data) #获取特征值
print(li.target) #获取目标值
print(li.DESCR) #打印描述
x_train,x_test,y_tarin,y_test=train_test_split(li.data,li.targt,test_size_=0.25) #得到的是分割后的x_train训练值的特征值、x_test我i测试集的特征值(y有一样),test_size_=0.25为测试值的占比
4.用于分类的大数据集
sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’) #用于加载数据集
subset:'train(训练集)‘或者’test(测试集)’,‘all(数据集)’,可选,选择要加载的数据集
datasets.clear_data_home(data_home=None)#清除目录下的数据
示例:
from sklearn.datasets import load_iris,fetch_20newsgroups
from sklearn.model_selction import train_test_split
li=load_iris()
news=fetch_20newsgroups(subset=‘all’) #获取所有的文章
print(news.data)
print(news.target)
5.回归数据集
1.sklearn.datasets.load_boston() #加载并返回波士顿数据集
2.sklearn.datasts.load_diabets() #加载和返回糖尿病数据集
示例:
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.model_selction import train_test_split
lb=load_boston()
print(lb.data) #获取特征值
print(lb.target) #获取目标指
print(lb.DESCR)
2.转换器和估计器
转换器
1.fit_transform():输入数据直接转换
估计器 estimator
1.用于分类的估计器
1.sklearn.neighbors k-近邻算法
2.sklearn.naive_bayes 贝叶斯
3.sklearn.linear_model.LogisticRegression 逻辑回归
4.sklearn.tree 决策数与随机森林
2.用于回归的估计器
1.sklearn.linear_model.LinearRegression 线性回归
2.sklearn.linear_model.Ridge 岭回归
3.流程
1.调用fit(x_train,y_train) #传入训练集特征值和训练集目标值建立模型
2.输入测试集的数据,评估模型
1.y_predict=predict(x_test) #把测试集的特征值输入就会输出一个目标指值
2.输出预测的准确率:score(x_test,y_test)
3.分类算法:
数据的处理:
1.对象.query() #缩小数据集的范围
2.处理日期的数据
pd.to_datatime() #转换时间格式
pd.DatatimeIndex() #把时间的年月日的数据转换为字典的数据
3.增加分割的日期数据
4.删除没用的日期数据
对象.drop()
5.将某一个特征值的数值少于n的删除
place_count=data.groupby(‘place_id’).count()
tf=place_count[place_count.row_id>3].reset_index()
data = data[data[place_id].isin(tf.place_id)]
1.k-近邻算法:通过你的“邻居"来推断出你的类别(需要调参数k)(目标值离散)
1.定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别
2.两个样本的距离:如:a(a1,a2,a3),b(b1,b2,b3) x=(a1-b1)2+(a2-2)2+(a3-b3)^2的开方(相似的样本,特征之间的值应该都是相近的)
3.k-近邻算法需要做标准化处理
4.API:sklearn.neighbors.KNeifhborsClassifier(n_neighbors=5,algorithm=‘auto’)
n_neighbors: init,可选(默认为5),k_neighbors查询默认使用的邻居数 #找到最近的几个邻居
algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用与计算最邻近的算法:'ball_tree’将会使用ballTree,'kd_tree’将时用KDTree。'auto’将尝试根据传递给fit方法的值来决定最适合的算法
分类是在K个样本中取最相似的比例,相似的比例大,则认为属于这个类别,所以k的取值也会影响结果
5.示例(利用k-近邻算法进行的模型训练流程):
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.model_selction import train_test_split
from sklearn,neighbors import KNeighborsClassifier
import pandas as pd
· from.sklearn.preprocessing import StandarScaler
def knncls():
data=pd.read_csv(“数据集的目录”) #读取数据集
#处理数据
#1.缩小数据(一些没有意义或数据很小的特征去除),筛选一定范围内的特征值
data=data.query("特征值1>数值1&特征值1<数值2&特征值2>..&特征值2<..") #按照条件来进行筛选
#2.处理时间的数据
time_value=pd.to_datatime(data['time'],unit='s')
print(time_value)
#把日期格式转换为字典格式
time_value=pd.DatetimeIndex(time_value) #转换为字典格式就可以任意获取年月日分等等
#构造一些特征(添加一些特征到data里)
data['day']=time_value.day #添加新的特征值day,并把从字典获取到的日赋给day
data['hour']=time_value.hour
data['weekday']=time_value.weekday
#把时间戳特征删除
data=data.drop(['time'],axis=1) #按列删除
5.将某一个特征值的数值少于n的删除
place_count=data.groupby('place_id').count()
tf=place_count[place_count.row_id>3].reset_index()
data = data[data[place_id].isin(tf.place_id)]
#取出数据当中的特征值和目标值
y=data['place_id']
x=data.drop(['place_id'],axis=1)
#进行数据的分割训练值和测试集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
#特征工程(标准化),对训练集和测试机集的特征进行标准化
std=standardScaler()
x_train= std.fit_transform(x_train)
x_test= std.fit_transform(x_test)
#进行算法流程,k-近邻算法
knn=KNeighborsClassifier(n_neighbors=5) #n_neighbors=5为取K值
#fit,输入建立模型
knn.fit(x_train,y_train) #输入训练值,这里会得出一个训练模型
#得出预测结果
y_predict=knn.predict(x_test)
print(y_predict)
#得出准确率
print(knn.score(x_test,y_test))
6. K很小:容易受异常点影响
K很大:容易受K值数量波动
2.朴素贝叶斯分类算法(概率思想,不需要调参,以最大的概率来分类,前提:特征之间相互独立,进行文本分类)(目标值离散)
贝叶斯算法用来预测文档分类是可结合tf-idf的词的重要性,训练 集误差大,结果不好
1.联合概率:所有条件都同时成立 P(A,B)=P(A)*P(B)
2,条件概率:事件A在另一个事件B已经发生的条件下发生的概率 P(A|B)=P(B|A)P(A)/P(B) 特性:P(A1,A2|B)=P(A1|B)P(A2|B)
3.P(科技|文档1)=x,P(娱乐|文档1)=y,比较x,y,那个大就属于那个类别
4.贝叶斯公式:P(A|B)=P(B|A)P(A)/P(B) P(A|F1,F2...)=P(F1,F2..|A)P(A)/P(F1,F2...)
1.B为给定文档的特征值(频数统计,预测文档提供),A为文档类别
2.P(A)为每一个文档类别的概率(某文档类别数/总文档数量)
3. P(B|A)为给定类别下特征(被预测文档中出现的词)的概率
计算方法:训练文档中去计算
1.P(F1|C)=Ni/N Ni为该F1词在A类别所有文档中出现的次数 N为所属类别C下的文档所有词出现的次数和
4.P(F1,F2...)为预测文档中每一个词的概率
5.如果词频列表里面有很多出现次数都为0,很可能计算结果都为零
解决方法:拉普拉斯平滑系数
P(F1|C)=(Ni+a)/(N+am) a为指定的系数一般为1,m为训练文档中统计出的特征词个数
5.API:类:sklearn.naive_bayes.MultinomialINB(alpha=1.0) #alpha为拉普拉斯平滑系数
6.示例
1.加载20类新闻呢数据,并进行分割
2.特征抽取(每篇文章都变成了一个词的重要性列表)
3.朴素贝叶斯estimator流程进行预估
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.model_selction import train_test_split
from sklearn.naive_bayes import MultinomialINB
from skearn.feature_extracton.text import TfidfVectorizer
def naviebayes()
news=fetch_20newsgroups(subset='all') #获取说有的数据
#进行数据分割,分割成训练集红外测试集
x_train,x_test,y_train,y_test=train_test_split(news.data,nws.target,test_size=0.25)
#对数据集进行特征抽取,即用tf-idf对文档中的词变为一个列表
tf=TfidfVectorizer()
#对训练集进行转换,对此列表进行词的重要性统计['a','b','c','d'],即返回词的权重比
x_train=tf.fit_transform(x_train)
print(tf.get_feature_names())
#把预测文档也转换为词的重要性列表,这里的统计是以训练集统计出来的['a','b','c','d']来对预测文档进行统计
x_test=tf.transform(x_test)
#进行朴素贝叶斯算法预测
mlt=MultinomialINB(alpha=1.0)
mlt.fit(x_train,y_train) #输入训练集进行贝叶斯计算,这里会的出一个训练模型
y_predict=mlt.predict(x_test) #得出预测文档结果
print(y_predict)
print(mlt.score()) #得出准确率
return None
3.精确率与召回率
1.精确率:预测结果为正例样本中真实为正例的比例(查的准)
2.召回率:真实为正例的样本中预测结果为正例的比例(查得全,对正样本得区分能力)
API:sklearn.metrics.classification_report(y_true,y_pred,target_name=None)
y_true:真实目标指
y_pred:估计器预测目标值
target_name:目标类别名称
return:每一个类别精确率与召回率
4.交叉验证和网格搜索
1.交叉验证(包含训练集和验证集):把所有得数据分词n等分
2.网格搜索:有很多参数是需要用手动指定得(如k-近邻算法中得k值),这种叫超参数,但是手动过程繁琐,所以需要对模型预设几种超参数组合,每组超参数都采用交叉验证来进行评估,最后选出参数组合建立模型
如模型1为k=3,用10折交叉验证来得出10个交叉模型得平均值,k=5也是样,最后比较交叉模型得平均值,得到k=?时得最优参数
当超参数不止一个时且相互影响,则两个超参数进行两两组合进行网格搜索
3.交叉验证和网格搜索API:类:sklearn.model_selection.GridSearchCV
1.sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)
对估计器得指定参数进行详尽搜索
1.estimator:估计器对象
2.param_grid:估计器参数(dict){"n_neigbors":[1,3,5]} #给多个参数,一个一个去搜,取一个最好的
3.cv:指定几折交叉验证
4.fit:输入训练数据
5.score:准确率
结果分析
1.best_score_:在交叉验证中验证得最好结果
2.best_estimator_:最好得参数模型
3.cv_results_:每次交叉验证后得测试集准确率结果和训练集准确率结果
2.示例
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.model_selction import train_test_split ,GridSearchCV
from sklearn.naive_bayes import MultinomialINB
from skearn.feature_extracton.text import TfidfVectorizer
def naviebayes()
#这里会进行一些数据分割和特征抽取
#使用K-近邻算法
knn=KNeighborsClassififier(n_neighbors=)
#构造一些参数的值
、 param={“n_neighbors”:[3,5,10]}
#进行网格搜索
gc=GridSearchCV(knn,param_grid=param,cv=10)
#进行交叉运算
git.fit(x_train,y_train)
#预测准确率
print(gc.score(x_test,y_test))
#每一个超参数每次交叉验证的结果
print(gc.best_estimator)
#在交叉验证中最好的结果
print(gc.best_score_)
#选择最好的模型
print(gc.best_estimator_)
return None
5.决策数(目标值离散)
1. 类似与程序设计中的条件分支结构if-then
2.H=-(p1logp1+p2logp2+...+pxlogpx)
H为信息熵,单位为比特(信息熵越少越好)
公式:H(x)=P(x)logP(x)的求和
信息和消除不确定性是相联系的
3.决策树的划分依据之一---信息增益(一个特征条件对整个的信息熵的减少程度)
就是知道一个特征值对结果影响的大小,越大,则认为熵减越大,则在决策的时候用处就越大,那这个特征值就越早进行判断
1.特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)(H(D)为总信息熵的大小)与特征A给定条件下D的信息条件熵H(D|A)之差:g(D,A)=H(D)-H(D|A)
2.计算看图
3.决策树的分类就是根据信息熵的大小来分类的
4.把信息增益最大的定义为最具有特征且作为第一个特征分类,以此类推
4.决策树的划分其他依据:
1.ID3:信息增益最大准则
2.C4.5:信息增益比,最大准则
3.CART:
回归树:平凡误差最小
分类数:基尼系数,最小的准则,在sklearn中可以选择划分的原则
5.决策树API:
class sklearn.tree.DecisionTreeClassifier(criterion='gini',max_depth=None,random_state=None)
1.决策树分类器
2.criterion:默认是‘gini系数’,也可以选择信息增益的熵‘entropy’(选择以基尼系数)
3.max_depth:数的深度大小
4.random_state:随机数种子
method:
decision_path:返回决策树的路径
sklearn.tree.export_graphviz() #该函数能够导出DOT格式
sklearn.tree.export_graphviz(estimator,out_file='tree.dot',feature_names=[","])
1.将dot文件转换为pdf\png
安装graphviz sudo apt-get install graphviz
6.示例:
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.model_selction import train_test_split ,GridSearchCV
from sklearn.naive_bayes import MultinomialINB
from sklearn.tree import DecisionTreeClassifier
from skearn.feature_extracton.text import TfidfVectorizer
from sklearn.feature_extraction import DictVectorizer
def decision():
#获取数据
titan=pd.read_csv("数据网址")
#处理数据,找出特征值和目标值(从多个特征值取出最有用的特征值)
x=titan[['pclass','age','sex']] #取出特征值
y=titan['survived'] #取出目标值
#缺失值填补处理
x['age'].fillna(x['age'].mean(),inplace=True)
#分割数据集到训练集和测试集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
#特征工程对数据进行处理(当特征值为类别时,该类特征值的数据就用one-hot编码)
dict=DictVectorizer(sparse=False)
x_train=dict.fit_transform(x_train.to_dict(orient="records"))
x_test=dict.fit_transform(x_test.to_dict("records"))
#用决策树进行预测
dec.=DecisionTreeClassifier(max_depth=5)
dec.fit(x_train,y_train) #这里会得出一个训练模型
#预测的准确率
print(dec.score(x_test,y_test))
#导出决策树
sklearn.tree.export_graphviz(estimator,out_file='./tree.dot',feature_names=['年龄'....])
return None
6.集成学习方法---随机森林(处理具有高维特征的输入样本,而且不需要降维)(目标值离散)
1.集成学习方法:建立几个模型组合来解决单一预测问题,它的工作原理是生成多个分类器/模型,各自独立的学习和做出预测,这些预测最后结合成单预测
2.随机森林:是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定(由结果同样的数多决定)
例如:如果你训练了5个树,其中有4个树的结果是true,1个数的结果是false,那么最终的结果会是true
3.随机森林建立多个决策树的过程
1.单个树的建立过程(多个决策树的建立也是和下面的步骤一样):N个样本,M个特征
1.随机在N个样本当中选择一个样本,重复N次 ,这样抽取的样本可能重复
2.随机在M个特征当中选出m<M个特征 m取值
随机抽取又返回,这样是为了保证多个决策树的样本和特征都不一样
4.随机森林API:
类:class sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion='gini',max_depth=None,bootstrap=True,random_state=None)
1.n_estimators:integer,optional(default=10) 森林里树木数量
2.criterion:string,可选(default="gini")分割特征的测量方法
3.max_depth:integer或None,可选(默认=无) 树的最大深度
4.bootstrap:boolean,option(default=True)是否在构建树时使用放回抽样
5.max_features="",每个决策树的最大特征数量
auto/sqrt/log2/None
5.示例:
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.model_selction import train_test_split ,GridSearchCV
from sklearn.naive_bayes import MultinomialINB
from sklearn.tree import DecisionTreeClassifier
from skearn.feature_extracton.text import TfidfVectorizer
from sklearn.feature_extraction import DictVectorizer
from class sklearn.ensemble import RandomForestClassifier
def decision()
#获取数据
titan=pd.read_csv("数据网址")
#处理数据,找出特征值和目标值(从多个特征值取出最有用的特征值)
x=titan[['pclass','age','sex']] #取出特征值
y=titan['survived'] #取出目标值
#缺失值填补处理
x['age'].fillna(x['age'].mean(),inplace=True)
#分割数据集到训练集和测试集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
#特征工程对数据进行处理(当特征值为类别时,该类特征值的数据就用one-hot编码)
dict=DictVectorizer(sparse=False)
x_train=dict.fit_transform(x_train.to_dict(orient="records"))
x_test=dict.fit_transform(x_test.to_dict("records"))
#随机森林预测(超参数调优)
rf=RandomForestClassifier()
param={"n_estimators":[120,200,300,1200],"max_depth":[5,8,15,20]}#建立参数字典
#网格搜索与交叉验证(进行超参数调优)
gc=GridSearchCV(rf,param_grid=param,cv=2)
gc.fit(x_train,y_train)
print(gc.score(x_test,y_test)) #查看准确率
print(gc.best_params) #查看最优参数模型
return None
if __name__=="__main__":
decision()
7.回归算法---线性回归分析(目标值连续,数据可以是线性数据,也可以是非线性数据)
1.寻找一种能预测的趋势(最终训练得出来的结果就是得到权重和偏置)
2.线性关系:
1一个特征:在二维空间中,呈直线关系(y=kx+b;b为偏置),对于单个特征的情况更加通用;在三维中,特征值,目标值呈平面关系
2.多个特征:y=k1*x1+k2*x2+...+b
3.线性关系模型:一个通过属性(属性即特征)的线性组合来进行预测的函数,f(x)=w1*x1+w2*x2+...++wx*xx+b
w为权重,b称为偏置项
3.线性回归:线性回归通过一个或者多个自变量(自变量即特征值)与应变量(因变量即目标值)之间进行建模的回归分析,其中可以为一个或多个自变量之间的线性组合(线性回归的一种)
1.一元线性回归:涉及到的变量只有一个
2.多元线性回归:涉及到的变量两个或两个以上
3.通用公式:h(w)=w0+w1*x1+w2*x2+...=wT *x
其中w,x为矩阵: [w0] [1]
w=[w1] ,x=[x1] 矩阵是大多数算法的计算基础[矩阵必须是二维]
[w2] [x2]
矩阵相乘的条件:(m行,I列)*(I行,n列)=(m行,n列)
a=[[1,2,3,4],[5,6,7,8],[2,3,7,9]] 表示3行4列 ;b=[[2],[2],[2],[2]] 表示4行1列
4.特征值与权重的一种组合来预测结果
5.损失函数(即误差大小)
1.线性回归也会又误差,但线性回归可以不断的去减少误差
2.yi为第i个训练本的真实值,hw(xi)为第i个训练样本特征值组合预测函数
3.总损失定义:
J(a)=(hw(x1)-y1)^2+(hw(x2)-y2)^2+...+(hw(xm)-ym)^2
=(hw(xi)-yi)^2的i=1到m的求和(即就是误差的平方相加)
4.h(w)=w0+w1*x1+w2*x2+...=wT *x 使误差值最小,就是要找到最小损失对于的w值
寻找最优化的w值的方法
1.最小二乘法值正规方程w=(xT*x)^(-1)*xTy x为特征值矩阵,y为目标值矩阵,xT为矩阵的转置,(xT*x)^(-1)为逆矩阵
2.最小二乘法之梯度下降(算法的本质就是在计算的过程中不断的去迭代原有的值)
以单变量中的w0,w1为例
公式看图
6.线性回归正规方程、梯度下降API
1.sklearn.linear_model.LinearRegression() #正规方程
coef_:回归系数
2.sklearn.linear_model.SGDRegressor() #梯度下降
coef_:回归系数
回归系数据数最终求出来的w值
7.回归性能评估
1.(均分误差(Mean Squared Error)MSE)评价机制
公式看图:
2.sklearn回归评价API
类:sklearn.metrics.mean_squared_error
1.mean_squared_error(y_true,y_pred)
均分误差回归损失
y_ture:真实值
y_pred:预测值
return:浮点数结果
8.示例:
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.linear_model import LinearRegression,SGDRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
def mylinear():
#获取数据
lb=load_boston()
#分割数据集到训练集和测试集
x_train,x_test,y_train,y_test=train_test_split(lb.data,lb.target,test_size=0.25)
#进行标准化处理,特征值和目标值都必须进行标准化处理,特征值和目标值分开标准化
std_x=StandardScaler()
x_train=std_x.fit_transform(x_train)
x_test=std_x.transform(x_test)
std_y=StandardScaler()
y_train=std_y.fit_transform(x_train.reshape(-1,1))#目标值一般为一维的,矩阵运算要规定是二维的,reshape(-1,1)转换为二维的
y_test=std_y.transform(x_test)
#estimator预测
#正规方程求解方式预测结果
lr=LinearRegression()
lr.fit(x_train,y_train)
print(lr.coef_) #打印权重
#预测测试集的房子价格
y_lr_predict=std_y.inverse_transform(lr.predict(x_test)) #把得出来的结果进行反标准化
#用梯度下降来寻找最佳的权值
y_sqd_predict =SGDRegressor()
print(lr.coef_)
return None
if __name__=="__main__":
4.过拟合和欠拟合也会影响预测
1.过拟合:一个载训练集数据上能获得比其他假设更好的拟合,但载训练数据外的数据集上也不能很好的拟合数据(模型过于复杂)
1.解决方法:进行特征选择,消除关联性很大的特征
正则化:a0+a1x+a2x^2+a3x^3+s4x^4//正则化就是不断的把a3,a4的权重不断减少,减少到0(尽量减小高次项的特征),越小的参数说明模型越简单,不容易产生过拟合现象
L2正则化:Ridge岭回归:带有正则化的线性回归,解决过拟合
交叉验证:只是能知道是不是过拟合
2.欠拟合:一个载训练集数据上不能获得比其他假设更好的拟合,但载训练数据外的数据集上也不能很好的拟合数据(模型过于复杂)
8.Ridge岭回归:带有正则化的线性回归
1.API:sklearn.linear_model.Ridge(alpha=1.0)
具有L2正则化的线性最小二乘法
alpha:正则化力度(这就是要调优的过程)
coef_:回归系数
9.模型的保存于加载:一个模型训练好之后,就可以直接用来使用,而不是再次训练
API:from sklearn.externals import joblib
1.保存模型:joblib.dump(lr,'保存test.pkl文件目录') //test.pkl是保存格式,为二进制文件,lr为调用预测算法的lr=LinearRegression()
2.加载模型:model=joblib.load('test.pkl文件目录')
使用:y_predict=model.predict(x_test) #直接用来预测结果
10.逻辑回归(二分类算法,解决二分类问题,线性回归转换为分类问题,得出概率值):线性回归的式子作为逻辑回归的输入
1.输入:Z(w)=w0+w1*x1+w2*x2+...=wT *x(单个样本)
2.sigmoid函数可以将线性回归的输入转换为Y坐标0~1之间的某一个值,输入于Y坐标相交的地方就是0.5,映射到0~1之间的值就是概率值
3.公式看图
4.损失函数:公式看图
5.损失值可以理解为信息熵大小(目的是为了减少信息熵的大小)
6.损失函数:均方误差(不存在多个局部最低点)只有一个最小值
对数似然损失:多个局部最小值
7.解决办法(梯度下降求解):1.多次随机初始化,多次比较最小值结果
2.求解过程中,调整学习率
API(自带正则化):sklearn.linear_model.LogisticRegreesion(penalty='l2',C=1.0) #penalty为正则化,以l2的形式正则化,C为正则化的力度
Logistic回归分类器
coef_:回归系数
1.二分类的分类的类别:哪个类别少,判定概率值是这个类别
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.linear_model import LinearRegression,SGDRegressor,Ridge,LogisticRegreesion
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error ,classificaton_report
import pandas as pd
import numpu as np
def logistic():
#读取数据
#如果数据的列没有列名,就要构造列名
column=['列名','列名','列名']
data=pd.read_csv("数据网址",names=column) #获取数据时直接加上列名
#对缺失值进行处理
data=data.replace(to_replace='?',value=np.nan) #替换掉?的值
data=data.dropna() #删除数据
#进行数据分分割
x_train,x_test,y_tarin,y_test=train_test_split(data[column[1:10]],data[column[10]],test_size=0.25)#分割出特征值[1:10],#分割出目标值第11列
#进行标准化处理,分类问题时的目标值不用标准化处理
std=StandarScalar()
x_train=std.fit_transform(x_train)
x_test=std.transform(x_test)
#进行逻辑回归预测
lg=LogisticRegreesion(c=1.0)
lg.fit(x_train,y_train)
y_predict=lg.score(x_test,y_test) #预测
lg.score(x_test,y_test) #准确率
#召回率
,classificaton_report (y_test,y_predict,labels=[2,4],target_name=["良性","恶性"])
return None
非监督学习:softmax方法(当数据没有目标值时,据类要做在分类之前,在预测类别)
1.特点: 只有特征值,没有目标值
通过特征值来分类(不知道类别的个数K,K就是一个超参数)
2.过程:K=3
1.随机抽取3个样本,当作三个类别的中心点(k1,k2,k3)
2.计算剩余的其余点到这个中心点的距离(a,b,c)
3.从中选出距离最近的一个点作为自己的标记,形成一个族群
4.分别计算这个三个族群的平均值,把三个平均值与之前的三个旧中心点相比较,如果相同:结束据类;如果不相同:把三个平均值当作新的中心点,重复第二步
1.Kmeans:均值聚类
1.API:sklearn.cluster.KMeans(n_clusters=8,init='k-means++')
n_clusters:开始的据类中心数量(即把样本分成多少个类别)
init='k-means++'
labels_:默认标记的类型,可以和真实值比较(不是值比较)
2.示例:
km=KMeans(n_clusters=4)
Km.fit(x) #x为样本数
predict=km.predict(x) #进行分类
3.据类的评估标准:轮廓系数
1.计算公式:SCi=(bi-ai)/max(bi,ai)
2.i为已聚类数据中的样本,bi为i到其他族群的所有样本的距离最小值,ai为i到本身的距离平均值
3.最终计算出所有样本点的轮廓系数平均值
4.标准:外部族群之间的距离最大化,族群之内样本之间的距离最小化
5.过程:对于每一个样本
1.计算族群1到自身类别的点距离的平均值ai
2.计算族群1分别到族群2,族群3所有的点的距离,求出平均值b1,b2取出最小的值当作bi
3.计算族群1的轮廓系数,轮廓系数为-1到1之间,越靠近1越好
4.理想:bi>>ai SCi=1 ,bi<<ai SCI=-1 API:sklearn.metrics.sillhouette_score(X,labels)
API:sklearn.metrics.sillhouette_score(X,labels)
计算所有样本的平均值论轮廓系数
X:特征值
labels:被聚类标记的目标值
例:
API:sklearn.metrics.sillhouette_score(x,predict)
4.采用迭代式算法,直观易懂并且非常实用
缺点:容易收敛到局部(多次聚类)
深度学习:图像识别,自然语言处理,聊天对话系统等等
GPU:图像处理显卡,在程序中只要一行代码就可以使用GPU
4.Tensorflow(深度学习框架),为计算密集型
1.整个结构(tensoflow运行有依赖性)
tensor:张量(代表数据),椭圆形
operation(op):专门运算操作节点,所有操作都是一个op,正方形
图(graph):你的整个程序的结构,图
绘画:运算程序的图
2.图:图默认已经注册,一组表示tf.Operation计算单位的对象和tf.Tensor表示操作之间流动的数据单元的对象
1.获取调用:
1.tf.get_default_graph() #获取图
2.op、sess或者tensor的graph属性
例:下面就是定义的一张图
import tensorflow as tf
a=tf.constant(5.0)
b=tf.constant(6.0) #tf.Operation
sum1=tf.add(a,b) #tf.Operation
print(sum1)
with tf.Session() as sess:
print(sess.run(sum1))
#获取图
1.print(sees.run(sum1))
2.print(a.graph)
3.print(sum1.graph)
4.print(sess.graph)
2.图是用来给程序分配内存,程序所有的操作都是在该内存中
3.图的创建(上下交环境,一张图中包含了一组op和tensor)
1.tf.Graph()
2.使用新创建的图
g=tf.Graph()
with g.as_default():
a=tf.constant(1.0)
assert c.graph is g
3.op有那些:看图
1.只要使用tensorflow的API定义的函数和类都是op
4.tensor(张量):就是指代的是数据
op就是一个载体,tensor就是被载体
3.会话:
1.tf.Session() #开启会话,一次只能运行一个图结构
运行TensorFlow操作图的类,使用默认注册的图(可以指定运行的图)
指定图运行:tf.Session(graph=)
2.会话资源
会话可能拥有很多资源,如tf.Variable,tf.QueueBase和tf.ReaderBase,会话结束后需要进行资源释放
3. sess=tf.Session() sess.run(…)#启动整个图 sess.close()#回收图,释放内存
4.使用上下文管理器
with tf.Session() as sess:
sess.run(…)
5.config=tf.ConfigProto(log_device_placement=True) #为tf.Session的参数,可以看到图里所有的资源
6.交互式:tf.InteractiveSession() #开启交互式会话,
7.eval():只要有会话的上下文环境,就可以使用eval
1.tensorflow:
1.前端系统:定义程序的图的结构
2.后端系统:运算图结构
2.会话相当于桥梁的作用,把图和操作系统或硬件结合起来
1.运行图结构,解析图
2.分配资源计算
3.掌握资源(如变量资源的生命周期,队列,线程)
3.会话的run方法:
run(fetches,feed_dict=None)
运行ops和计算tensor
嵌套列表,元组 如:seess.run([a,b,sum1])对的,sess.run(a,b,sum1)为错的
namedtuple,dict或OrderedDict(从装载的运算符也能运行(不是op或tensor不能运行),即默认给运算符重载成op类型)
feed_dict允许调用者覆盖图中指定张量的值,能提供给placeholder使用
训练模型的数不固定时,这个参数可以实时的提供数据去训练,
placeholder是一个占位符,feed_dict为字典,在运行的时候才提供数据
使用:
1.样本固定 如:两行三列
plt=tf.placeholder(tf.float32(类型),[2,3]#两行三列(形状))
sess.run(plt,feed_dict={plt:[[1,2,3],[4,5,6]]#两行三列})
2.样本不固定
plt=tf.placeholder(tf.float32(类型),[None,None])
sess.run(plt,feed_dict={plt:[[1,2,3],[4,5,6],[...]]#这里填补的时候随便填})
返回值异常
RuntimeError:如果它Session处于无效状态(例如已关闭)
TypeError:如果fetches或feed_dict键是不适合类型。
ValueError:如果fetches或feed_dict键无效或引用Tensor不存在
Tensorflow Feed操作
意义:在程序执行的时候,不确定输入的是什么,提前占个坑
语法:placeholder提供占位符,run时候通过feed_dict指定参数
4.张量(tensor),张量的数组为tensor类型(和numpy的数组差不多,numpy的数组类型为ndarray类型,tensorflow依赖numpy)
1.张量的阶和数据的类型
1.阶
0阶:纯量,只有大小
1阶:向量,只有大小和方向
2阶:矩阵,数据表
3阶:3阶张量,数据立体 如:[2,3,4]即2张3行4列的表
n阶:
2.Tensorflow基本的数据格式
看图
常用:tf.float32和tf.int32、tf.uint8
3.张量的属性:
graph 张量所属的默认图
op 张量的操作名
name 张量的字符串描述
shape 张量的形状(一维的形状可能会不认,所以要进行形状的改变)
1.动态形状和静态形状:改变形状在于有没有生成一个新的张量数据,有则动,无则静
静态形状:
创建一个张量,初始状态的形状
tf.Tensor.get_shape():获取静态形状
tf.tensor.set_shape():更新Tensor对象的静态形状,通常用于在不能直接推断的情况下,不能跨纬度修改
动态形状:
一种描述原始张量在执行过程中的一种形状(动态变化)
tf.reshape:创建一个具有不同动态形状的新张量,可以跨纬度修改
2.转换静态形状时,1阶到1阶,2阶到2阶,不能跨阶数改变形状
3.对于已经固定或者设置静态形状的张量/变量,不能再次设置静态形状
4.tf.reshape()动态创建新张量时,元素个数不能不匹配
3.一个类型化的N维度数据(tf.Tensor)
4.三部分,名字,形状,数据类型
2.张量的操作
1.生成固定值张量:
1.tf.zeros(shape,dtype=tf.float32,name=None)
创建所有元素设置为零的张量,此操作返回一个dtype具有形状shape和所有元素设置为零的类型的张量
如:zero=tf.zero([3,4],tf.float32)
2.tf.zero_like(tensor,dtype=tf.float32,name=None)
给tensor定张量(),此操作返回tensor与所有元素设置为零相同的类型和形状的张量
3.tf.ones(shape,dtype=tf.float32,name=None)
创建一个所有元素设置为1的张量,此操作返回一个类型的张量,dtype形状shape和所有元素设置为1
4.tf.ones_like(tensor,dtype=None,name=None)
给tensor定张量(),此操作返回tensor与所有元素设置为1相同类型和形状的张量
5.tf.fill(dims,value,name=None)
创建一个填充了标量值得张量,此操作创建一个张量得形状dims并填充它value
6.tf.constant(value,dtype=None,shape=None,name='Const')
创建一个常数张量
2.生成随机张量
1.tf.truncated_normal(shape,mean=0.0,stddev=1.0,dtype=tf.float32,seed=None,name=None)
从截断得正态分布中输出随机值,和tf.random_normal()一样,但是所有数字都不超过两个标准差
2.tf.random_norma(shape,mean=0.0,stddec=1.0,dtype=tf.float32,seed=None,name=None)
从正态分布中输出随机值,有随机正态分布得数字组成得矩阵
mean为平均值,stddec为标准差
3.张量的变换
1.tf.string_to_number(string_tensor,out_type=None,name=None)
2.tf.to_double(x,name='ToDouble')
3.tf.to_float(x,name='ToFloat')
4.tf.to_bfloat16(x,name='ToBFloat16')
5.tf.to_int32(x,name='ToInt32')
6.tf.to_int64(x,name='ToInt64')
7.tf.cast(x,dtype,name=None)#万能转换
如:a=tf.cast([[1,2,3],[4,5,6]],tf.float32)
4.张量的形状和变换
可以用于确定张量的形状并更改张量的形状
1.tf.shape(input,name=None)
2.tf.size(input,name=None)
3.tf.rank(input,name=None)
4.tf.reshape(tensor,shape,name=None)
5.tf.squeeze(input,squeeze_dims=None,name=None)
6.tf.expand_dims(input,dims,name=None)
切片和矿展(如把两个数据拼接在一块)
tf.concat(values,axis,name='concat'),axis为0时按行合并
如: a=[[1,2,3],[4,5,6]]
b=[[7,8,9],[10,11,12]]
c=tf.concat([a,b],axis=0)
c.eval为查看
5.变量(变量也是一种op,可以变化的,是一种特殊的变量,能够进行存储持久化,它的值就是张量,默认被训练)
1.变量的创建(当定义一个变量op的时候,一定要在会话当中去运行初始化)
tf.Variable(initial_value=None,name=None,trainable=True)
创建一个带值initial_value得新变量
如:var=tf.Variable(tf.random_normal([2,3],mean=0.0,stddev))
显示初始化:tf.global_variables_initializer()
如: int_op=tf.global_variables_initializer()
运行初始化op:sess.run(init_op)
assign(value)
为变分配一个新值,返回新值
eval(session=None)
计算并返回此变量的值
name属性表示变量名字
6.可视化学习tensorflow
1.数字序列化-events文件(八图结构序列化成事件events文件)
tensorBoard通过读取TensorFlow的事件文件来运行
2.tf.sunmmary.FileWriter('/tmp/tensorflow/summary/test/',graph=)
返回filewrite,写入事件文件到指定目录(最好用绝对路径),以提供给tensorboard使用
把,graph指定的图写入到事件文件当中
filewriter=tf.sunmmary.FileWriter("...")
3.开启
tensorboard --logdir="/tmp/tensorflow/summary/test"
一般浏览器打开为127.0.0.1:6006
4.符号意义
看图
5.API:
矩阵运算:tf.matmul(x,w)
平方:tf.square(error)
均值:tf.reduce_mean(error)
梯度下降优化: tf.train.GradientDescentOptimizer(learning_rate)
learning_rate:学习率,手动指定
method:
minimize(loss):最小优化损失
return:放回梯度下降op(op要运行)
例: 使用tensorflow实现一个简单的线性回归案例
线性回归回顾:权重与特征值相乘相加的和(w1x1+w2x2+w3x3+......+偏置,这个公式用矩阵实现)
算法:线性回归 策略:均方误差 优化:梯度下降
1.准备数据:特征和目标值
2.建立模型:随机初始化准备权重w(有几个特征就有几个权重),一个偏置b
得出模型:y_predict=x1w1+x2w2+.....+b(模型的参数必须用变量定义,不能用张量)
3.求损失函数,即误差,用均方误差求误差loss
4.梯度下降降去优化损失过程,已有API,只要指定学习率,最终得到最终的权重和偏置
def myregression():
#自实现一个线性回归预测
#准备数据 特征值x[100,1](100个样本,1个特征),目标值y[100](目标值为100个)
#数据用张量定义(用最简单的一个权重和一个偏置)
x=tf.random_normal([100,1],mean=1.75,stddev=0.5,name="x_data") #随机生成特征值
#定义一个线性回归的真实值,最后与预测值相比
y_ture = tf.matmul([x,[0.7]])+0.8
#建立线性回归模型:一个权重,一个偏置,y=xw+b
#把权重和偏置进行初始化,用变量初始化,随机指定一个值,即让它从某个点求损失,然后再这个点用梯度下降求优化
trainable参数:指定这个变量能否跟着梯度下降一起优化
weight=tf.Variable(tf.random_normal([1,1],mean=0.0,stddev=1.0),name="w",trainable=true)
bias=tf.Variable(tf.random_normal(0.0,name="b") #偏置初始化为0.0
#建立模型:
y_predict=tf.matmul(x,weight)+bias
#建立损失函数,求得是均方误差
loss=tf.reduce_mean(tf.square(y-true-y_predict))
#梯度下降优化损失
#学习率不能提太高,一般为小数
train_op=tf.train.GradientDescentOptimizer(0.1).minimze(loss)
#定义一个初始化变量的op
init_op=tf.global_variables_initializer()
#通过会话运行程序:
with tf.Session() as sess:
#初始化变量
sess.run(init_op)
#打印随机最先初始化的权重和偏置
print(weight.evel(),bias.evel())
#运行优化,循环优化
for i in rang(100):
sess.run(train_op)
print(weight.evel(),bias.evel())
return None
if __name__ =="__main__":
myregression()
6.梯度爆炸/梯度消失(以指数增加)
在极端情况下,权重的值变得非常大,以至于溢出,导致NaN值
解决:
重新设计网络
调整学习率
使用梯度截断(在训练过程中检查和限制梯度的大小)
使用激活函数
7.作用域
1.tensorflow变量作用域:,以下由示例
tf.variable_scope(<scope_name>)创建指定名字的变量作用域
2.在后台显示程序:首先建立事件文件
filewriter=tf.summary.Filewriter("路径",graph=sess.graph#指定传图进去)
例:
def myregression():
with tf.variable_scope("data"): #建立data作用域
#自实现一个线性回归预测
#准备数据 特征值x[100,1](100个样本,1个特征),目标值y[100](目标值为100个)
#数据用张量定义(用最简单的一个权重和一个偏置)
x=tf.random_normal([100,1],mean=1.75,stddev=0.5,name="x_data") #随机生成特征值
#定义一个线性回归的真实值,最后与预测值相比
y_ture = tf.matmul([x,[0.7]])+0.8
with tf.variable_scope("mode"):
#建立线性回归模型:一个权重,一个偏置,y=xw+b
#把权重和偏置进行初始化,用变量初始化,随机指定一个值,即让它从某个点求损失,然后再这个点用梯度下降求优化
trainable参数:指定这个变量能否跟着梯度下降一起优化
weight=tf.Variable(tf.random_normal([1,1],mean=0.0,stddev=1.0),name="w",trainable=true)
bias=tf.Variable(tf.random_normal(0.0,name="b") #偏置初始化为0.0
#建立模型:
y_predict=tf.matmul(x,weight)+bias
with tf.variable_scope("loss"):
#建立损失函数,求得是均方误差
loss=tf.reduce_mean(tf.square(y-true-y_predict))
with tf.variable_scope("optimizer"):
#梯度下降优化损失
#学习率不能提太高,一般为小数
train_op=tf.train.GradientDescentOptimizer(0.1).minimze(loss)
#定义一个初始化变量的op
init_op=tf.global_variables_initializer()
#通过会话运行程序:
with tf.Session() as sess:
#初始化变量
sess.run(init_op)
#打印随机最先初始化的权重和偏置
print(weight.evel(),bias.evel())
#运行优化,循环优化
for i in rang(100):
sess.run(train_op)
print(weight.evel(),bias.evel())
return None
if __name__ =="__main__":
myregression()
8.增加变量显示:观察模型的参数、损失值等变量的变化
1.收集变量,一般卸载会话之前
tf.summary.scalar(name=",tensor):
收集对于损失函数和准确率等单值变量,name为变量名字,tensor为值
rf.summary.histogram(name=",tensor)收集高纬度的变量参数
tf.summary.image(name=",tensor)收集输入的图片张量能显示图片
如:tf.summary.scalar("losses",loss)#losses为在后台看到的名字
rf.summary.histogram("weights",weight)
2.合并变量写入事件文件,在会话运行之前做
merged=tf.summary.merge_all()
运行合并:summary=sess.run(merged)#每次迭代都需运行
添加:FileWriter.add_summary(summary,i),表示第几次的值
如:
#定义合并tensor的op
merged=tf.summary.merge_all()
#运行op
summary=sess.run(merged)
#写入后台
FileWriter.add_summary(summary,i)
9.模型保存和加载
saver=tf.train.Saver(var_list=None,max_to_keep=5) #建立保存模型op
var_list:指定将要保存和还原的变量。它可以作为一个dict或一个列表传递
max_to_keep:指示要保留的最近检查点文件的最大数量。创建新文件时,会删除较旧的文件,如果无或0,则保留所有检查点文件。默认为5(即保留最新的5个检查点文件)
例:
saver.save(sess,'路径') #模型的保存
saver.restoore(sess,'路径') #模型的加载
保存文件格式:checkpoint文件
例:
saver =tf.train.Saver() #在会话前建立op
saver.save(sess,'路径') #在会话画中或会话后 保存模型
if os.path.exists("路径") #判断模型路径是否存在
saver.restoore(sess,'路径') #在回话中加载模型
10.自定义命令行参数(即在运行的时候也可以修改参数)
1.tf.app.flags,它支持应用从命令行接受参数,可以用来指定集群配置,在tf.app.flags下面有各种定义参数的类型
DEFINE_string(flag_name,default_value,docstring)
DEFINE_integer(flag_name,default_value,docstring)
DEFINE_boolean(flag_name,default_value,docstring)
DEFINE_float(flag_name,default_value,docstring)
2.tf.app.flags,在flags有一个FLAGS标志,它在程序程序中可以调用到我们前面具体定义的flag_name
3.通过tf.app.run()启动main(argv)函数
步骤:
1.首先定义有那些参数需要在运行时候指定
2.程序当中获取定义命令行参数
例:
#传进来的第一个参数:名字、默认值、说明
tf.app.flags.DEFINE_integer("max_step",100,"模型训练的步数")
#模型目录
tf.app.flags.DEFINE_string("model_dir","","模型加载路径")
#定义获取命令行参数的名字
FLAGS=tf.app.flags.FLAGS
def myregression():
with tf.variable_scope("data"): #建立data作用域
#自实现一个线性回归预测
#准备数据 特征值x[100,1](100个样本,1个特征),目标值y[100](目标值为100个)
#数据用张量定义(用最简单的一个权重和一个偏置)
x=tf.random_normal([100,1],mean=1.75,stddev=0.5,name="x_data") #随机生成特征值
#定义一个线性回归的真实值,最后与预测值相比
y_ture = tf.matmul([x,[0.7]])+0.8
with tf.variable_scope("mode"):
#建立线性回归模型:一个权重,一个偏置,y=xw+b
#把权重和偏置进行初始化,用变量初始化,随机指定一个值,即让它从某个点求损失,然后再这个点用梯度下降求优化
trainable参数:指定这个变量能否跟着梯度下降一起优化
weight=tf.Variable(tf.random_normal([1,1],mean=0.0,stddev=1.0),name="w",trainable=true)
bias=tf.Variable(tf.random_normal(0.0,name="b") #偏置初始化为0.0
#建立模型:
y_predict=tf.matmul(x,weight)+bias
with tf.variable_scope("loss"):
#建立损失函数,求得是均方误差
loss=tf.reduce_mean(tf.square(y-true-y_predict))
with tf.variable_scope("optimizer"):
#梯度下降优化损失
#学习率不能提太高,一般为小数
train_op=tf.train.GradientDescentOptimizer(0.1).minimze(loss)
#定义一个初始化变量的op
init_op=tf.global_variables_initializer()
saver =tf.train.Saver() #在会话前建立op
#通过会话运行程序:
with tf.Session() as sess:
#初始化变量
sess.run(init_op)
#打印随机最先初始化的权重和偏置
print(weight.evel(),bias.evel())
if os.path.exists("路径") #判断模型路径是否存在
saver.restoore(sess,'路径') #在回话中加载模型
#运行优化,循环优化
for i in rang(FLAGS.max_step):
sess.run(train_op)
print(weight.evel(),bias.evel())
saver.save(sess,'路径') #在会话画中或会话后 保存模型
return None
if __name__ =="__main__":
myregression()
#运行:day_04.py --max_step=500 --model_dir= "路径"
11.线程队列于IO操作(不用numpy)
1.队列和线程(tensorflow中的多线程是一个真正的多线程,是真正的并行)
1.线程和线程之间的通信同过队列来实现
2.队列与队列管理器(实现线程之间的同步)
1.Q=tf.FIFOQueue(capacity,dtypes,name='fifo_queue'):创建一个以先进先出队列,按顺序出队列的队列
capacity:队列的大小,整数。可能存储在此队列中的元素数量的上限
dtypes:指定队列类型,DType对象列表。长度dtypes必须等于每个队列元素中的张量数,dtype的类型形状,决定了后面进队列元素形状
method
depueue(name=None) #出队列
enqueue(vals,name=None) #入队列
enqueue(vals,name=name=None);#vals列表或者元组
返回一个队列操作
size(name=None)
en_q=Q.enqueue_many([[0.1,0.2,0.3], ]) #往队列中写数据
data=Q.dequeue()#从队列中取数据
sess.run(enq_many)#在会话中初始化队列
2.tf.RandomShuffleQueue随机出队列
3.队列管理器
tf.train.QueueRunner(queue,enqueue_ops=None)#创建线程,创建一个QueueRunner
queue: A Queue
enqueue_ops:添加线程的队列操作列表#[]*2,指定两个线程,列表里为线程将要做的操作
create_threads(sess,coord=None,start=False) #启动线程
创建线程来运行给定会话的入队操作
start:布尔值,如果True启动线程;如果False调用者必须调用start()启动线程
coord:线程协调器,后面线程管理需要用到
return :线程的示例
当数据量很大时,入队操作从硬盘中读取数据,放入内存中,主线程需要等待入队操作完成,才能进行训练,会话里可以运行多个线程,实现异步读取
例:
Q=tf.FIFOQueue(1000,tf.float32)
var=tf.Variable(0.0)
data=tf.assign_add(var,tf.constant(1.0)) #自加1
en_q=Q.enqueue(data)
qr=tf.train.QueueRunner(Q, enqueue_ops=[en_q]*2)#创建两个个线程里把var++
#初始化变量op
init_op=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op) #初始化变量
threads=qr.create_threads(sess,start=True) #启动子线程
for i in range(300):
print(sess.run(Q.dequeue()))
3.线程和协调器(用来管理线程)
tf.train.Corrdinator():线程协调员,实现一个简单的机制来协调一组线程的终止
request_stop():子线程是否要停止
should_stop()检查是否要求停止
join(threads=None,stop_grace_period_secs=120)
等待线程终止
return:线程协调员示例
例:
Q=tf.FIFOQueue(1000,tf.float32)
var=tf.Variable(0.0)
data=tf.assign_add(var,tf.constant(1.0)) #自加1
en_q=Q.enqueue(data)
qr=tf.train.QueueRunner(Q, enqueue_ops=[en_q]*2)#创建两个个线程里把var++
#初始化变量op
init_op=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op) #初始化变量
#开启线程管理器
coord=tf.train.Coordinator()
threads=qr.create_threads(sess,coord=coord,start=True) #启动子线程
for i in range(300):
print(sess.run(Q.dequeue()))
#回收
coord.request_stop()
coord.join(threads)
2.文件读取
1.文件读取流程
1.构造一个文件队列(把数据的路径+文件名写入队列)
2.构建文件阅读器,对读取队列内容(read)
默认只读取一个样本,默认csv文件中读取一行,二进制文件中的读取指定一个样本的bytes,图片文件中按一行一行读取
3.解码(decode)
4.批处理
2.文件读取API
1.tf.train.string_input_producer(string_tensor,shuffle=True)#,用于构造文件路径将输出字符串(例如文件名)输入到管道队列
string_tensor:含有文件名的1阶张量(列表,列表里有文件的路径和名字)
num_epochs:过几遍数据,默认无限过数据
return:具有输出字符串的队列
2.文件阅读器
1.class tf.TextLineReader
阅读文本文件逗号分隔值(CSV)格式,默认按行读取
return: 读取器示例
2.tf.FixedLengthRecordReader(record_bytes)
要读取每个记录是固定数量字节的二进制文件
record_bytes:整数,指定每次读取的字节数
return:读取器示例
3.tf.TFRecordReader
读取TfRecords文件
有一个共同的读取方法:
read(file_queue):从队列中指定数量内容
返回一个Tensors元组(key文件名字,value默认的内容(行,字节))
3.文件读取API-文件内容解码器
1.tf.decode_csv(records,record_defaults=None,field_delim=None,name=None)#将CSV转换为张量,与tf.TextLineReader搭配使用
records:tensor型字符串,每一个字符串是csv中的记录行
field_delim:默认分隔符“,”
record_defaults:指定每一个样本的每一列的类型,指定默认值,参数决定了所得张量的类型,并设置了一个值,在输入字符串中缺少使用默认值,如
2.tf.decode_raw(bytes,out_type,little_endian=None,name=None)
将字节转换为一个数字向量表示,字节为一字符串类型的张量,与函数tf.FixedLengthRecordReader搭配使用,二进制读取为uint8格式
4.批处理
1.tf.train.batch(tensors,batch_size,num_threads=1,capacity=32,name=None)
读取指定大小(个数)的张量
tensors:可以是包含张量的列表
batch_size:从队列中读取的批处理大小
num_threads:进入队列中元素的最大数量
return tensors
2.tf.train.shuffle_batch(tensors,batch_size,capacity,min_after_dequeue,num_threads=1)
乱序读取指定大小(个数)的张量
min_after_dequeue:留下队列里的张量个数,能够保持随机打乱
3.CSV文件读取案例
1.先找到文件,构造一个列表
2.构造文件队列
3.构造阅读器,读取队列内容(一行)
4.解码内容
5.批处理
例:
import tensorflow as tf
import os
def csvread(filelist):#这个任务只有子线程能用
#构造文件队列
file_queue=tf.train.string_input_producer(filelist)
#构造阅读器读取队列数据(按一行)
reader=tf.TextLineReader()
key,value=reader.read(file_queue)
#对每行内容进行解码
records=[["None"],["None"]]
example,label=tf.decode_csv(value,record_defaults=records)
#想要读取多个数据,批处理
example_batch,label=tf.train.batch([example,label,batch_size=9,num_threads=1,capacity=9])
return example_batch,label
if __name__ == "__main__":
#找到文件,放入列表,路径加名字放到列表中
file_name=os.listdir("路径1")
filelist=os.path.join("路径1",file) for file in file_name #把路径和名字拼接
example,label=csvread(filelist)
with tf.Session() as sess:
#定义一个线程协调器
coord= tf.train.Coordinator()
#开启读文件的线程
tf.train.start_queue_runners(sess,coord=coord)
#打印读取的内容
sess.run([example,label])
print(sess.run([example,label]))
#回收子线程
coord.request_stop()
coord.join(threads)
3.图片处理和读取
图片存储类型:uint8
矩阵计算:float32
1.图片基本知识
1.有多少个像素点就有多少个特征值
2.黑白:单通道,某一个像素点只有一个值(为灰度值0-255)
3.彩色:三通道,某一个像素点有RGB三个值组成
3.如何用张量来表达像素特征
[100,120000]:有100张图片,每张图片有120000个像素点
4.图像数字化三要素
1.长度
2.宽带
3.通道数
1.一通道:灰度值
2.三通道:RGB
张量表示
指定3-D张量:[height,width,channels](长度,宽带,通道数)
例:一个图片有120000个像素:[200,200,3](120000=200*200*3)
4.每一个样本必须保持特征值数量一样
1.把所有的图片样本统一成同一特征数量(即长宽一样)
2.图像基本操作:
1.增加图片数据的统一性
2.所有图片转换为指定大小
3.缩小图片数据量,防止增加开销
3.图像基本操作API
1.tf.image.resize_images(images,size)#缩小和放大图片(不是切片)
images:4-D形状[batch,height,width,channels]或3-D形状的张量[height,width,channels]的图片数据
batch:为批量(表示多少张)
size:1-D int32张量:new_height,new_width,图像的新尺寸
放回4-D格式或者3-D格式
4.图像读取API
1.构造一个列表
2.构造图片队列
3.构造阅读器,读取队列内容(一张)
4.解码内容
5.批处理(多个样本)
API:
图像读取器
1.tf.WholeFileReader
将文件的全部内容作为值输出的读取器
return:读取器示例
方法:read(file_queue):输出将是一个文件名(key)和该文件的内容(值)
图像解码器
1.tf.image.decode_jpeg(contents)
将JPEG编码的图像解码为uint3张量
return:uint8张量,3-D形状[height,width,channels]
tf.image.decode_png(contents)
将PNG编码的图像解码为uint8或uint16张量
return:张量类型,3-D形状[height,width,channels]
5.图像读取示例
import tensorflow as tf
import os
def picread(filelist): #这个任务只有子线程能用
#filelist:文件路径+名字列表
#1.构造文件队列
file_queue=tf.train.string_input_producer(filelist)
#2.构造阅读器去读取图片的内容(默认读取一张图片)
reader=tf.WholeFileReader(); #类示例化
key,value=reader.read(file_queue)
#3.对读取的图片数据进行解码
image=tf.image.decode_jpeg(value)#结果shape=(?,?,?)
#4.处理图片的大小,统一大小
image_resize=tf.image.resize_images(image,[200,200])
image_resize.set_shape([200,200,3]) #设定形状
#5.进行批处理(批处理的时候,形状必须先设定好)
image_batch=tf.train.batch([image_resize],batch_size=20,num_threads=1,capacity=20)
return image_batch
if __name__ == "__main__":
file_name=os.listdir("图片路径")
filelist=[os.path,join("图片路径",file)] for file in file_name] #把图片路径和图名字整合起来
example_batch,label_batch=picread(filelist)
with tf.Session() as sess:
#定义一个线程协调器
coord=tf.train.Coordinator()
#开启读文件的线程
threads=tf.train.start_queue_runners(sess,coor=coord)
#运行op
sess.run([imae_batch])
#回收子线程
coord.request_stop()
coord.join(threads)
4.二进制文件读取(案例:CIFAR-10二进制数据读取)
按照指定样本的字节进行读取
1.二进制文件读取API
文件阅读(根据文件格式来选取)
class tf.TextLineReader
阅读文本文件逗号分隔符(CSV)格式,默认按行读取
return :读取器示例
tf.FixedLengthRecordReader(record_bytes)
要读取每一个记录是固定数量的字节的二进制文件
record_bytes:整型,指定每次读取的字节数
return:读取器示例
tf.TFRecordReader
读取TfRcords文件
有一个共同读取的方法(上面的都是类)
read(file_queue):从队列中指定数量内容
返回一个Tensors元组(key文件名字,value默认的内容(行,字节))
案例:读取二进制文件转换为张量
2.二进制文件解码器
tf.decode_csv(records,recoard_defafaults=None,field_delim=None,name=None)
将CSV转换为张量,与tf.TextLineReader搭配使用
records:tensor型字符串,每一个字符串是csv中的记录行
field_delim:默认分隔符","
record_defaults:参数决定了所得的张量类型,并设置一个值在输入字符串中缺少使用默认值
tf.decord_raw(bytes,out_type,little_endian=None,name=None)
将字节转换为一个数字向量表示,字节为一字符串类型的张量,与函数tf.FixedLengthRecordReader搭配使用,二进制读取为uint8格式
例:
#定义cifar的数据等命令行参数
FLAGS= tf.app.flages.FLAGS
tf.app.flags.DEFINE_string("目录","路径","文件目录")
#定义一个类
class Cifaread(object)
#完成读取二进制文件,写进tfrecords,读取tfrecords
def __init__(self,filelist):
#文件列表
self.file_list=filelist
#定义读取的图片的一些属性
self.height=32
self.width=32
self.channel=3
#二进制文件每张图片的字节
self.image_bytes=1
self.image_bytes=self.height*self.width*self.channel
self.bytes=self.label_bytes+self.image_bytes
def read_and_decode(self):
#1.构造文件队列
file_queue=tf.train.string_input_producer(self.file_list)
#2.构造二进制文件读取器,读取内容,每个样本的字节数
reader=tf.FixedLengthRecordReader(self.bytes)
key,value=reader.read(file_queue)
#3.解码内容
label_image=tf.decord_raw(value,tf.uint8)
#4.分割出图片和标签数据,切出特征值和目标值
label=tf.slice(label_image,[0], [self.label_bytes])
image=tf.slice(label_image,[self.label_bytes],[self.image_bytes])
#5.对图片的特征数据进行形状的改变[3072]-->[32,32,3]
image_reshape=tf.reshape(image,[self.height,self.width,self.channel])
#6.批处理数据
image_batch,label_batchl=tf.train.batch([image_reshape,label],batch_size=10,num_threads=1,capacity=1)
return None
if __name__=="__main__":
file_name=os.listdir("FLAGS.cifar_dir")
filelist=[os.path.join("路径",file) for file in file_name in file_name if file[-3:]=="bin" ] #把以bin结尾的文件都拿出来
cf=CifarRead(filelist)
image_batch,label_barch=cf.read_and_decode()
with tf.Session() as sess:
coord=tf.train.Coordinator()
threads=tf.train.start_queue_runners(sess,coord=coord)
coord.request_stop()
coord.join(threads)
5.tfrecords文件读取与存储(tensorflow自带的文件格式,也是一种二进制文件)
方便移动和存储,为了将二进制数据和标签(训练的类别标签)数据存储在同一个文件中
文件格式:*.tfrecords
写入文件内容:Example协议块(类字典的格式,即数据可以键值)
即就是是把解码出来的特征值和目标值用来类字典的文件来存储
对于每一个样本,都要构造example协议块
TFRecords存储
1.建立TFRecord存储器
tf.python_io.TFRecord(path)
写入tfrecords文件
path:TFRecord文件的路径
return:写文件
method
write(record):向文件中写入一个example
close():关闭文件写日期
注:字符串为一个序列化的Example,Example.SerializeToString()
2.构造每一个样本的Example协议快
1.tf.train.Example(features=None)
写入tfrecords文件
features:tf.train.Features类型的特征示例
return:example格式协议块
2.tf.train.Features(feature=None)
构建每个样本的信息键值对
feature:字典数据。key为要保存的名字
value为tf.train.Feature实例
return:Features类型
3.tf.train.Feature(**options)
**options:例如
bytes_list=tf.train.BytesList(value=[Bytes])
int64_list=tf.train.Int64List(value=[Value])
存储类型
4.tf.train.Int64List(value=[Value])
5.tf.train.BytesList(value=[Bytes])
6.tf.train.FloatList(value=[value])
3.TFRecords读取方法
同文件读取流程,中间需要解析过程
1.解析TFRecords的example协议内存块
2.tf.parse_single_example(serialized,features=None,name=None)
1.解析一个单一的Example原型
2.serialized:标量字符串Tensor,一个序列化的Example
3.features:dict字典数据,键位读取的名字,值位FixedLenFeature
4.return: 一个键值对组成的字典,键为读取的名字
3.tf.FixedLenFeature(shape,dtype)
1.shape:输入数据的形状,一般不指定,为空列表
2.dtype:输入数据类型,与存储进文件的类型要一致
类型只能是float32,int64,string
4.tfrecord文件阅读器
根据文件格式,选择对应的文件阅读器
1.class tf.TextLineReader
阅读文本文件逗号分隔值(CSV)格式,默认按行读取
return: 读取器示例
2.tf.FixedLengthRecordReader(record_bytes)
要读取每个记录是固定数量字节的二进制文件
record_bytes:整型,指定每次读取的字节数
return:读取器示例
3.tf.TFRecordReader
读取TfRecords文件
有一个共同读取方法
read(file_queue):从队列中指定数量内容
返回一个Tensors元组(key文件名字,value默认的内容(行,字节))
#定义cifar的数据等命令行参数
FLAGS= tf.app.flages.FLAGS
tf.app.flags.DEFINE_string("目录1","路径1","文件目录")
tf.app.flags.DEFINE_string("目录2","路径2","文件目录")
#定义一个类
class Cifaread(object)
#完成读取二进制文件,写进tfrecords,读取tfrecords
def __init__(self,filelist):
#文件列表
self.file_list=filelist
#定义读取的图片的一些属性
self.height=32
self.width=32
self.channel=3
#二进制文件每张图片的字节
self.image_bytes=1
self.image_bytes=self.height*self.width*self.channel
self.bytes=self.label_bytes+self.image_bytes
def read_and_decode(self):
#1.构造文件队列
file_queue=tf.train.string_input_producer(self.file_list)
#2.构造二进制文件读取器,读取内容,每个样本的字节数
reader=tf.FixedLengthRecordReader(self.bytes)
key,value=reader.read(file_queue)
#3.解码内容
label_image=tf.decord_raw(value,tf.uint8)
#4.分割出图片和标签数据,切出特征值和目标值
label=tf.slice(label_image,[0], [self.label_bytes])
image=tf.slice(label_image,[self.label_bytes],[self.image_bytes])
#5.对图片的特征数据进行形状的改变[3072]-->[32,32,3]
image_reshape=tf.reshape(image,[self.height,self.width,self.channel])
#6.批处理数据
image_batch,label_batchl=tf.train.batch([image_reshape,label],batch_size=10,num_threads=1,capacity=1)
return None
def write_to_tfrecord(self,image_batch,label_batch)
#将解码后的图的特征值和目标值存储进tfrecords
#image_batch:图片的特征值
#label_batch:图片的目标值
#1.构造一个tfrecord存储器
tf.python_io.TFRecord("FLAGS.cifar_tfrecords")
#2.循环将所欲样本写入,每张图片样本都要构造example协议
for i in rang(10):
#取出第i张图片数据的特征值和目标值
image=image_batch[i].eval().tostring #eval用来获取张量,不然获取的就是类型,并把张量转换为字符串
label=label_batch[i].eval()[0]
#构造一个样本的example
example=tf.train.Example(features=tf.train.Features(feature={
"image":tf.train.Features(bytes_List=tf.train.BytesList(value=[image])),
"label":tf.train.Features(int64_list=tf.train.Int64List(value=[label]))
}))
#写入单独的样本
writer.write(example.SerializeToString())
#关闭
writer.close()
return None
def read_from_tfrecords(self):
#1.构造文件队列
file_queue=tf.train.string_input_producer([FLAGS.cifar_tfrecords])
#2.构造文件阅读器,读取内容example,value=一个样本的序列化example
reader=tf.TFRecordReader()
key,value=reader.read(file_queue)
#3.解析example
features=tf.parse_single_example(value,features={
"image":tf.FixedLenFeature([],tf.string),
"label":tf.FixedLenFeature([],tf.sint64),
})
#4.解码内容,如果读取的内容是string类型需要解码,int64等等不需要解码
image=tf.decode_raw(features["image"],tf.uint8)
label=tf.cast(features["label"],tf,int32)
#固定图片形状
tf.reshape(image,[self.height,self.width,self.channel])
#5.进行批处理
image_batch,label_batch=tf.train.batch([image_reshape,label],batch_size=10,num_threads=1,capacity=10)
return None
if __name__=="__main__":
file_name=os.listdir("FLAGS.cifar_dir")
filelist=[os.path.join("路径",file) for file in file_name in file_name if file[-3:]=="bin" ] #把以bin结尾的文件都拿出来
cf=CifarRead(filelist)
image_batch,label_barch=cf.read_and_decode()
with tf.Session() as sess:
coord=tf.train.Coordinator()
threads=tf.train.start_queue_runners(sess,coord=coord)
#存储进tfrecords文件
cf.write_to_tfrecords(image_batch,label_batch)#里面有evel,只能在这里运行
coord.request_stop()
coord.join(threads)
5.神经网络:
5.1 神经网络基础
1.感知机(似于线性回归,不过是用来解决分类问题类)
1.有n个输入数据,通过权重与数据之间的计算和,比较激活函数效果,得出输出
有一个阈值,大于阈值做什么,小于阈值做什么
w1x1+w2x2+w3x3+w4x4+…+n=y
y>阈值 为一个分类
y<阈值 为一个分类
2.很容易解决与、或问题
3.单个感知机解决不了的问题,可以在加一个,就会设置两个阈值等等,就可以解决复杂的分类问题
2.神经网络(也称人工神经网络ANN)
1.基础神经网络:单层感知器,线性神经网络,BP神经网络,Hopfield神经网络等
2.进阶神经网络:玻尔兹曼机,受限玻尔兹曼机,递归神经网络等等
3.深度神经网络:深度置信网络,卷积神经网络,循环神经网络,LSTM神经网络等等
定义:感知机——更名——>神经元——>多个神经元——>神经网络
不同的结构解决不同的问题
特点:
1.输入向量的维度和输入神经元的个数相同
2.每个连接都有权重
3.同一层神经元之间没有连接
4.由输入层,隐层,输出层组成
5.第N层(最后一层)与第N-1层(最后一层的前一层)的所有神经元连接,也叫全连接层
6.全连接层为输出
组成:
1.结构:神经网络中权重,神经元等等
2.激活函数
3.学习规则:学习规则指定了网络中的权重如何随着时间推进而调整(方向传播算法)
例:
神经网络:多分类
某一个样本输入——>得出属于全部类别的每一个概率(有多少个类别,输出就有多少)
比较输出概率的大小
3.神经网络的API模块(类)
1.tf.nn:提供神经网络相关操作的支持,包括卷积操作(conv),池化操作(pooling),归一化、loss、分类操作、embedding、RNN、Evalution
2.tf.layers:主要提供的高层的神经网络,主要和卷积相关的,对tf.nn的进一步封装
3.tf.contrib:tf.contrib.layers提供狗将计算图中的网络层、正则化、摘要操作、是构建计算图的高级操作,但是tf.contrib包不稳定以及一些实验代码
5.2浅层人工神经网络模型(输入到输出之间只有一层神经网络)
1.softMax回归:
1.用来处理从全连接层输出的值,把输出的值转化为属于一个一个类别概率
2.公式:看图
1.计算概率值
2.所有类别的概率值相加都等于1
3.类别要经过one_hot编码
2.神经网络衡量损失(神经网络交叉熵损失,进化版的信息熵)
1.公式:看图
2.衡量两两之间的损失熵的差异大小
3.每一个样本都有一个交叉熵损失
3.神经网络优化:反向传播算法(其实就是梯度下降)
1.正向传播经过交叉熵损失计算,通过交叉熵损失计算来使用反向传播算法来不断跟新前面的权重
5.3神经网络实现手写数字识别(直接用全连接层,中间不用其他隐层)
1.全连接-从输入到直接输出的API
特征加权
1.tf.matmul(a,b,name=None)+bisa
return:全连接结果,供交叉损失运行
不需要激活函数(因为是最后的输出)
2.softMax计算、交叉熵(一个函数计算概率值有计算了交叉熵)
1.tf.nn.softmax_cross_entropy_with_logits(labels=None,logits=None,name=None)
计算logits和label之间的交叉损失熵
labels:标签值(真实值)
logits:样本加权之后的值
return:返回损失值列表
求所有的样本的损失,然后求平均值
2.损失值列表平均值计算
tf.reduce_mean(input_tensor)
计算张量的尺寸的元素平均值
3.其他方法–损失下降API
1.tf.train.GradientDescentOptimizer(learning_rate)#梯度下降优化
learning_rate:学习率
minimize(loss):最小化损失
return:梯度下降op
3.one-hot API介绍
tf.one_hot(indices,depth,on_value=None,off_value=None,axis=None,dtype=None,name=None)
indices:在热编码中位置,即数据集标签
depth:张量的深度,即类别数
4.获取数据API
1.类:from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets(FLAGS.data_dir,one_hot=Ture)
2.获取数据的特征值
1.mnist.train.images()#获取全部图片的特征值
2.mnist.train.next_batch()#批次获取数据,包括特征和目标值(自己指定)
5.准确率计算
1.equal_list=tf.equal(tf.argmax(y,1),tf.argmax(y_label,1))
y为预测值
y_label为真实值
2.accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
6.步骤:单(全连接层)实现手写数字识别
特征值[None,784] 目标值[None,0]
1.准备数据
2.定义数据占位符,实现自己定义用多少个样本来训练
3.建立模型:y_predict=tf.matmul(x,w)+b
即随机初始化权重(784*10个)和偏置(10个)
4.得出预测结果,计算损失
loss:平均样本损失
5.梯度下降优化
学习率 优化步数
6.模型评估(计算准确率)
例:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
FLAGS=tf.app.flags.FLAGS
tf.app.flags.DEFINE_interger("is_train",1,"指定程序是预测还是训练")
def full_connected():
#获取真实的数据
mnist=input_data.read_data_sets("路径",one_hot=True)
#1.建立数据占位符,在运行是实时提供训练集 x[None,784]特征值 y_true[None,10]
with tf.variable_scope("data"): #定义作用域
#1.建立数据占位符
x=tf.placeholder(tf.float32,[None,784])
y_true=tf.placeholder(tf.int32,[None,10])
#2.建立全连接层的神经网络w[784,10] b[10]
with tf.variable_scope("fc_model"):
#1.随机初始化权重和偏置
weight=tf.Variable(tf.random_normal([780,10],mean=0.0,stddev=1.0,name="w")
bias=tf.Variable(tf.constant(0.0,shape=[10])
#2.预测None个样本的输出结果matrix[None,784]*[784,10]+[10]=[None,10]
y_predict=tf.matmul(x,weight)+bias
#3.计算交叉熵损失,求出所有样本的损失,然后求平均值
with tf.variable_scope("soft_cross")
#求平均交叉熵损失
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
#4.梯度下降求出损失
with tf.variable_scope("optimizer"):
1.tf.train.GradientDescentOptimizer(0.1).minimize(loss)
#5.计算准确率
with tf.variable_scope(acc)
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predoct,1))
#equal_list 得出None样本
accurcy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
#收集单个数字值变量,用于后台显示
tf.summary.scalar("losses",loss)
tf.summary.scalar("acc",accuracy)
#高纬度变量收集
tf.summary.histogram("weightes",weight)
tf.summary.histogram("biases",bias)
#6.定义一个初始化变量的op
init_op=tf.global_variables_initializer()
#定义一个合并变量的op
merged=tf.tf.summary.merge_all()
#创建一个saver
saver=tf.train.Saver()
#7.开启会话训练
with tf.Session() as sess:
#初始化变量
sess.run(init_op)
#建立events文件,然后写入
filewriter=tf.summary.Filewriter("目录",graph=sess.graph)
if FLAGS.is_train==True:#is_train为1旧训练
#迭代步数训练,更新参数预测
for i in range(2000):
#取出真实存在的特征值和目标值
mnist_x,mnist_y=mnist.train.next_batch(50)
sess.run(train_op,fee_dict{x:mnist_x, y_true:mnist_y})
#写入每部训练的值
summary=sess.run(merged,feed_dict={x:mnist_x,y_true:mnist_y})
print("训练%d步,准确率为:%f"%(i,sess.run(accuracy,feed_dict={x:mnist_x, y_true:mnist_y)))
#在训练结束后保存模型
saver.save(sess,"保存路径(路径中要包含名字)")
else:#否则就用保存模型来预测
#加载模型
saver.restore(sess,"模型目录")
for i in rang(100)
#每次预测一张图
x_test,y_test=mnist.test.next_batch(1)
print("第%张图片,手写数字目标是%d,预测结果是:%d" %(
i,
tf.argmax(y_test,1).eval(),
tf.argmax(sess.run(y_predict,feed_dict={x:x_test,y_true:y_test}),1)
))
return None
if __name__=="__main__"
full_connected()
5.3卷积神经网络介绍以及卷积层结构
深度学习网络与更常见的单一隐藏层神经网络的区别在于深度,深度学习网络中,每一个节点层在前一层输出的基础上学习识别一组特定的特征。随着神经网络深度增加,节点所能识别的特征也就越来越复杂
在输入和全连接层之间可以加很多层,自己加多少层和每一次加多少也是不确定的,所有卷积神经网络就可以知道加多少层,指定了每一层加多少
尽量减少最后一层全连接层的数量
卷积神经网络的错误了很低
1.基本组成:输入层、隐藏层、输出层。而卷积神经网络的特点在于隐藏层分为卷积层和池化层(pooling layer,又叫下采样层)
卷积层:通过在原始图像上平移来提取特征
池化层:通过特征后稀疏参数来减少学习的参数,降低网络的复杂度,(最大池化和平均池化)
2.卷积神经网络结构:
1.卷积层过滤器(观察窗口,即里面装的就是权重)
1.个数
2.大小(11,33,55 (奇数)),即观察窗口的大小也就是权重的个数
3.步长(一般选择1为步长),即观察窗口移动
4.零填充
卷积核在提取特征映射时的动作称之为零填充,由于移动步长不一定能整出整张图的像素宽度,其中有两种方式,SAME和VALID
1.SAME:越过边缘取样,取样的面积和输入图像的像素宽度一致
2.VALID:不越过边缘提取,取样的面积小于输入人的图像的像素宽度
5.卷积层输出深度、输出宽度
1.深度由过滤器个数决定
2.输出宽度
以图片为例
结论:就是观察完成之后得出的观察后的特征,就是一张简化版的特征表(对于黑白图片就是只有1张表,彩色图片有3张表,过滤器同时要有3个)
以识别图片为例:过滤器就是观察窗口(观察窗口就是权重),被观察窗口观察的像素点都会与窗口中的权重做线性回归得出一个结果1,整个图片还没有观察完,整个窗口就会移动,再次观察,得出结果2,一直把图片观察完成,最后得出一个结论1
并不限定一个人去观察,可以使用多个过滤器去观察,每一个过滤器把一个样本观察完都会得出一个结论,多个过滤器就会由结论1、结论2、结论3等等
移动越过图片大小:
1.不越过,直接停止观察(图片未观察完成)
2.直接越过(越过的部分用零填充),把图片观察完成旧停止,往下观察
6.公式:
1.输入体积大小H1W1D1
2.四个超参数
1.Filter数量K
2.Filter大小F
3.步长S
4.零填充大小P
3.输出体积大小H2W2D2(H2W2为每一个Filter观察出的样本特征大小,D2为多少个Filter观察出的样本)
1.H2=(H1-F+2P)/S+1
2.W2=(W1-F+2P)/S+1
3.D2=K
7.卷积层的API
1.tf.nn.conv2d(input,filter,strides=,name=None)
计算给定4-D input和filter张量的2维卷积
input:给定的输入张量,具有[batch,heigth,width,channel],类型为float32,64
filter:指定过滤器的大小,[filter_height,filter_width,in_channels,out_channels]
strides:strides=[1,stride,stride,1],步长(四个参数,表示上下左右移动的步长都为1)
padding:“SAME”,“VALID”,使用的填充算法的类型,使用“SAME”。其中“VALID”表示滑动超出部分舍弃,"SAME"表示填充,使得变化后height,width一样大
2.激活函数(激活层)
1.新的激活函数-Relu(以前为sigmoid)
f(x)=max(0,u),如果u<=0,f(x)就为0,如果u>0,f(x)=u
以图片为例:
使图片的像素没有0以下的值
2.为什么要激活函数(一定要)
增加激活函数就相当于增加了网络非线性分割的能力
3.为什么不用sigmoid
1.反向传播求激活函数误差梯度时,计算量相对大,而采用Relu激活函数,整个过程的计算节省很多
2.对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度爆炸的情况
4.激活函数API(把卷积得出的结论输入到激活函数就可以得出一个结果)
1.tf.nn.relu(features,name=None)
features:卷积后加上偏置的结果
return:结果
3.池化层(Pooling),理解为相似的特征区域用一个特征来表示
1.池化层主要的作用是特征提取,通过去掉Feature Map中不重要的样本,进一步减少参数数量,池化层的方法很多,最常用的是Max Pooling。22,2步长
2.可以有很多卷积层,从卷积层输出的数据可以非常大,最后再经过多个池化层把数据缩小
3.池化层API:
1.tf.nn.max_pool(value,ksize=,strides=,padding=,name=None)
输入上执行最大池数
value:4-D Tensor形状[batch,height,width,channels]
ksize:池化窗口大小,[1,ksize,ksize,1]
strides:步长大小,[1,strides,strides,1]
padding:“SAME”,“VALID”,使用的填充算法的类型,使用"SAME"
4.池化得到的数据多少可以用卷积层的计算公式来算
5.出来的数据放到全连接层进行预测
4.全连接层
1.前面的卷积和池化相当于做特征工程,后面的全连接相当于做特征加权,最后的全连接层在整个卷积神经网络中起到"分类器"的作用
注:在大型网络当中会有一个droupout层(减少过拟合)
5.4卷积神经网络识别手写数字
1.卷积层、激活层、池化层加多少:特征多的时候直接用googlenet来设计卷积神经网络
2.特征比较少的:自己设计卷积神经网络
3.设计卷积神经网络:
1.第一个卷积层:
卷积:32个filter,55大小,strides1,padding=“SAME”(输入为4维数据,输入:[None,28,28,1],偏置有32个,输出:[None,28,28,32])
激活:不改变形状,输出:[None,28,28,32]
池化:22,strides2,padding=“SAME”(输入:[None,28,28,32],输出:[None,14,14,32])
2.第二个卷积层:
卷积: 64个filter,55大小,strides1,padding=“SAME”(输入为4维数据,输入:[None,14,14,32],偏置有64个,输出:[None,14,14,64])
激活:不改变形状,输出:[None,14,14,64]
池化:22,strides2,输入:[None,14,14,64] 输出:[None,7,7,64]
3.全连接层FC: 输入:[None,7764] 权重[7764,10],偏置有10个, 输出:[None,10]
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#定义一个初始化权重的函数
def weight_variables(shape)
w=tf.Variable(tf.random_normal(shape=shape,mean=0.0,stddev=1.0))
return w
#定义一个初始化偏置的函数
def bias_variables(shape)
b=tf.Variable(tf.constant(0.0,shape=shape))
return b
#自定义的卷积模型
def model():
#1.建立数据占位符,在运行是实时提供训练集 x[None,784]特征值 y_true[None,10]
with tf.variable_scope(“data”): #定义作用域
#1.建立数据占位符
x=tf.placeholder(tf.float32,[None,784])
y_true=tf.placeholder(tf.int32,[None,10])
#第一个大卷积层(卷积551(一个人观察一张55),32个人,步长1)、激活、池化)
with tf.variable_scope(“conv1”):
#随机初始化权重
w_conv1=weight_variables([5,5,1,32])
#随机初始化偏置,32个偏置
b_conv1=bias_variables[32]
#对样本x进行形状的改变[None,784] [None,28,28,1]
x_reshape=tf.reshape(x,[-1,28,28,1])
#卷积层
relu1=tf.nn.conv2d(x_reshape,w_conv1,srides=[1,1,1,1],padding=“SAME”)+b_conv1
#激活层
x_relu1=tf.nn.relu(relu1)
#池化层
x_pool1=tf.nn.max_pool(x_relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding=“SAME”)
#第二个大卷积层(卷积5*5*32(一个人观察32张5*5),64个人,步长1)、激活、池化)
with tf.variable_scope("conv1"):
#随机初始化权重
w_conv2=weight_variables([5,5,32,64])
#随机初始化偏置,64个偏置
b_conv2=bias_variables[64]
#卷积层
relu2=tf.nn.conv2d(x_pool1,w_conv2,srides=[1,1,1,1],padding="SAME")+b_conv2
#激活层
x_relu2=tf.nn.relu(relu2)
#池化层
x_pool2=tf.nn.max_pool(x_relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
#全连接层(得出类别的概率值)
with tf.variable_scope("fc"):
#随机初始化权重和偏置
w_fc=weight_variables([7*7*64,10])
b_fc=bias_variables([10])
#修改形状
x_fc_reshape=tf.reshape(x_poo2,[-1,7*7*64])
#进行矩阵运算得出每个样本的结果
y_predict=tf.matmul(x_fc_reshape,w_fc)+b_fc
return x,y_true,y_predict
def conv_fc():
#获取真实的数据
mnist=input_data.read_data_sets("路径",one_hot=True)
#用一个函数定义模型,得出输出
x,y_true,y_predict=model()
#计算交叉熵损失,求出所有样本的损失,然后求平均值
with tf.variable_scope("soft_cross")
#求平均交叉熵损失
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
#梯度下降求出损失,深度学习的学习率都是很小的
with tf.variable_scope("optimizer"):
1.tf.train.GradientDescentOptimizer(0.0001).minimize(loss)
#计算准确率
with tf.variable_scope(acc)
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predoct,1))
#equal_list 得出None样本
accurcy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
#定义一个初始化变量的op
init_op=tf.global_variables_initializer()
#开启会话运行
with tf.Session() as sess:
sess.run(init_op)
#迭代步数训练,更新参数预测
for i in range(2000):
#取出真实存在的特征值和目标值
mnist_x,mnist_y=mnist.train.next_batch(50)
sess.run(train_op,fee_dict{x:mnist_x, y_true:mnist_y})
#写入每部训练的值
print("训练%d步,准确率为:%f"%(i,sess.run(accuracy,feed_dict={x:mnist_x, y_true:mnist_y)))
return None
if __name__ =="__main__":
conv_fc()
4.GoogleNet(数据量较大时使用)
库:
from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_base
5.5 验证码识别案例