CS231N Assignment5 图像分类练习
CS231N Assignment5 图像分类练习
Begin
本文主要介绍CS231N系列课程的第五项作业,利用图像的其他特征取完成一个图像训练。
这里采用的使Hog特征和HSV特征作为图像的特征,然后利用我们前面学习的几种方法做训练。
另外由于这里没有调用CS231N课程的库(我懒....没有去弄),就用了我们图像课上的OPENCV
的库去获取特征。
课程主页:网易云课堂CS231N系列课程
语言:Python3.6
系统:Windows10
________________________________________________
注意:加入你没有安装OPENCV的话,参考我的如下帖子去安装即可,包括拓展包也有说明~~~
_________________________________________________
好了,其实这个作业简单,已经没有什么东西了~~~
emmm,算法在前几章节已经写过了
1、读取图像数据
读取图像数据和之前代码一致~~~
#step1 数据裁剪 #数据量太大,我们重新整理数据,提取一部分训练数据、测试数据、验证数据 num_training = 49000#训练集数量 num_validation = 1000#验证集数量 num_test = 1000#测试集数量 num_dev = 500 Data = load_CIFAR10() CIFAR10_Data = './' X_train,Y_train,X_test,Y_test = Data.load_CIFAR10(CIFAR10_Data)#load the data #从训练集中截取一部分数据作为验证集 mask = range(num_training,num_training + num_validation) X_val = X_train[mask] Y_val = Y_train[mask] #训练集前一部分数据保存为训练集 mask = range(num_training) X_train = X_train[mask] Y_train = Y_train[mask] #训练集数量太大,我们实验只要一部分作为开发集 mask = np.random.choice(num_training,num_dev,replace = False) X_dev = X_train[mask] Y_dev = Y_train[mask] #测试集也太大,变小 mask = range(num_test) X_test = X_test[mask] Y_test = Y_test[mask] print(X_train[0].shape) a = np.array(X_train[5]).astype('uint8') print(a.shape)
2、数据预处理
数据预处理就是训练前对数据进行一定处理,我们要提取图像的特征,一般HOG特征我们
需要它变为灰度图像,因为HOG要的是它的梯度,无需三个通道颜色值。所以我们先灰度化
需要使用OPENCV的cvtColor函数,色彩通道的转换,第一个参数传入图像数据,第二个参
传入转换形式BGR2GRAY是BGR格式转为灰度格式。
gray_train[i]=cv.cvtColor(X_train[i].astype('uint8'),cv.COLOR_BGR2GRAY)
我们仅对训练集和验证集做了转换,如下:
################################ #获取灰度图像 gray_train = np.zeros((X_train.shape[0],X_train.shape[1],X_train.shape[2])) gray_val = np.zeros((X_val.shape[0],X_val.shape[1],X_val.shape[2])) for i in range(X_train.shape[0]): gray_train[i]=cv.cvtColor(X_train[i].astype('uint8'),cv.COLOR_BGR2GRAY) print(gray_train.shape) for i in range(X_val.shape[0]): gray_val[i]=cv.cvtColor(X_val[i].astype('uint8'),cv.COLOR_BGR2GRAY)
接下来需要获取它的HOG特征,此时我们用了CV的HOG类,先声明一个类~~
hog = cv.HOGDescriptor((32,32), (8,8), (4,4), (4,4), 9, 1)
类中前四个参数是size,后两个是int对于hog的具体介绍,在本文就不介绍了,
后续我专门写个图像的帖子介绍。我简述一下,第一个是窗口大小,第二个是块
的大小,第三个是块每次移动的位移量,第四个是胞的大小,第五个参数是每个
包内统计的梯度方向的类数。首先,包是在块里面的8*8的块可以容纳4个包,会
计算4个包的梯度数据,每个包会统计9个方向的数据,这样就4*9=36个,然后
块每次移动(4,4)这样就在一个窗口里会出现7*7个块,故一共81*36=1764个。
~~~~~~~~~~~emmmm这么理解先
你可以参考下这个人解释的在看看
http://blog.sina.com.cn/s/blog_48e673350102vcv8.html
这样呢,我们声明了一个类,并且声明一个矩阵,向量维度是1764存储HOG特征。
################################### #获取HOG特征 hog = cv.HOGDescriptor((32,32), (8,8), (4,4), (4,4), 9, 1) hist_train = np.zeros((gray_train.shape[0],1764)) hist_val = np.zeros((gray_val.shape[0],1764))
然后,接下来要计算hog特征了,此时用到类的computer函数,传入三个参数,图像,
图像的大小,窗口的单位移动量。也就是说窗口还要再图像里面移动,可以知道hog
特征又增大了,这里由于我们图像比较小我们就不移动窗口了。
for i in range(gray_train.shape[0]): histt = hog.compute(gray_train[i].astype('uint8'),(32,32),(0,0)) hist_train[i] = histt.reshape((-1,)) for i in range(gray_val.shape[0]): histt = hog.compute(gray_val[i].astype('uint8'),(32,32),(0,0)) hist_val[i] = histt.reshape((-10,))
emmmm这就求完了,接下来用SVM训练一下~~~~~
训练之前我也参考这答案对特征处理了一下,类似于归一化,让数据更接近。
先将数据乘1000,小数我感觉不太好看
hist_train = 1000 * hist_train hist_val = 1000 * hist_val
然后减去平均值,每一列
hist_train_mean = np.mean(hist_train,axis=0,keepdims=True) hist_val_mean = np.mean(hist_val,axis=0,keepdims=True) hist_train -= hist_train_mean hist_val -= hist_val_mean
再除以标准差
std_feat = np.std(hist_train,axis=0,keepdims=True) print(std_feat) hist_train /= std_feat hist_val /= std_feat
好,差不多了
我们开始训练
#step4 训练数据 SVM2 = SVM() SVM2.train(hist_train,Y_train,learning_rate=2.5e-7,reg=4e5,num_iters=1000,verbose = True) Y1 = SVM2.predict(hist_val) Y2 = SVM2.predict(hist_train) print('The Train Data result is %f'%np.mean(Y2 == Y_train)) print('The Val Data result is %f'%np.mean(Y1 == Y_val))
结果如下:
啊,应该还要补充一个神经网络训练~~~~~~~~~