文章目录

  • 作业介绍
  • 1. 加载数据
  • 2. 提取特征
  • 3. 使用SVM进行训练
  • 5. 使用神经网络训练特征
  • 6. 测试集上测试

作业介绍

  • 作业主页:Assignment #1
  • 作业目的:
    • 在之前的作业中,我们已经能够编写简单的分类器,接收原始RGB像素输入来进行分类,并且获得了不错的性能,本次作业中,我们将尝试使用从像素值中提取的稍微高级一点的特征(例如颜色直方图、HOG特征,SIFT特特征)来提升我们分类器的性能。
  • 官方给的示例代码:assigment #1 code

1. 加载数据

from cs231n.features import color_histogram_hsv, hog_featuredef get_CIFAR10_data(num_training=49000, num_validation=1000, num_test=1000):# Load the raw CIFAR-10 datacifar10_dir = 'cs231n/datasets/cifar-10-batches-py'X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)# Subsample the datamask = list(range(num_training, num_training + num_validation))X_val = X_train[mask]y_val = y_train[mask]mask = list(range(num_training))X_train = X_train[mask]y_train = y_train[mask]mask = list(range(num_test))X_test = X_test[mask]y_test = y_test[mask]return X_train, y_train, X_val, y_val, X_test, y_test# Cleaning up variables to prevent loading data multiple times (which may cause memory issue)
try:del X_train, y_traindel X_test, y_testprint('Clear previously loaded data.')
except:passX_train, y_train, X_val, y_val, X_test, y_test = get_CIFAR10_data()

2. 提取特征

  • 我们将提取HOG(方向梯度特征),其更注重图像的纹理特征,而忽略图像的颜色特征
  • 而且,我们也会提取HSV 色彩空间的 H 颜色通道的颜色直方图(color histogram)特征,其更加注重颜色特征
  • 最后,我们将两个特征联合起来(concatenation)。
  • fearture.pyhog_feature提取HOG特征,color_histogram_hsv提取颜色直方图,它们都作用于一张图像,并返回一个维特征向量
  • extract_features(imgs, feature_fns, verbose=False) 输入多个图像imgs和多个特征提取函数feature_fns,然后返回多个图像的特征,每个图像占一行,然后每行的特征就是多个特征提取函数的特征联合起来
from cs231n.features import *num_color_bins = 10 # Number of bins in the color histogram
feature_fns = [hog_feature, lambda img: color_histogram_hsv(img, nbin=num_color_bins)]
X_train_feats = extract_features(X_train, feature_fns, verbose=True)
X_val_feats = extract_features(X_val, feature_fns)
X_test_feats = extract_features(X_test, feature_fns)# Preprocessing: Subtract the mean feature
mean_feat = np.mean(X_train_feats, axis=0, keepdims=True)
X_train_feats -= mean_feat
X_val_feats -= mean_feat
X_test_feats -= mean_feat# Preprocessing: Divide by standard deviation. This ensures that each feature
# has roughly the same scale.
std_feat = np.std(X_train_feats, axis=0, keepdims=True)
X_train_feats /= std_feat
X_val_feats /= std_feat
X_test_feats /= std_feat# Preprocessing: Add a bias dimension
X_train_feats = np.hstack([X_train_feats, np.ones((X_train_feats.shape[0], 1))])
X_val_feats = np.hstack([X_val_feats, np.ones((X_val_feats.shape[0], 1))])
X_test_feats = np.hstack([X_test_feats, np.ones((X_test_feats.shape[0], 1))])
  • 注意,我们提取特征后都进行了规范化,减少了各个特征维度的尺度影响
  • 而且减的均值和方差,均是训练集的经验值。
  • 而且最后两个特征加在一起才155维
print(X_train_feats.shape)
print(X_val_feats.shape)
print(X_test_feats.shape)
"""
(49000L, 155L)
(1000L, 155L)
(1000L, 155L)
"""

3. 使用SVM进行训练

from cs231n.classifiers.linear_classifier import LinearSVMlearning_rates = [1e-9, 1e-8, 1e-7]
regularization_strengths = [5e4, 5e5, 5e6]num_iters = 3000
results = {}
best_val = -1
best_lr = None
best_reg = None
best_svm = None## train the svm
for lr in learning_rates:for rs in regularization_strengths:svm = LinearSVM()train_loss = svm.train(X_train_feats,y_train,lr,rs,num_iters)y_train_pred = svm.predict(X_train_feats)y_train_acc = np.mean(y_train_pred == y_train)y_val_pred = svm.predict(X_val_feats)y_val_acc = np.mean(y_val_pred == y_val)results[(lr,rs)] = (y_train_acc,y_val_acc)if y_val_acc > best_val:best_val = y_val_accbest_svm = svmbest_lr = lrbest_reg = rs# Print out results.
for lr, reg in sorted(results):train_accuracy, val_accuracy = results[(lr, reg)]print('lr %e reg %e train accuracy: %f val accuracy: %f' % (lr, reg, train_accuracy, val_accuracy))print('Best validation accuracy during cross-validation:\nlr = %e, reg = %e, best_val = %f' %(best_lr, best_reg, best_val))
lr 1.400000e-07 reg 8.000000e+03 train accuracy: 0.355735 val accuracy: 0.365000
lr 1.400000e-07 reg 9.000000e+03 train accuracy: 0.365163 val accuracy: 0.375000
lr 1.400000e-07 reg 1.000000e+04 train accuracy: 0.366959 val accuracy: 0.366000
lr 1.400000e-07 reg 1.100000e+04 train accuracy: 0.368102 val accuracy: 0.364000
lr 1.400000e-07 reg 1.800000e+04 train accuracy: 0.378694 val accuracy: 0.375000
lr 1.400000e-07 reg 1.900000e+04 train accuracy: 0.373551 val accuracy: 0.371000
lr 1.400000e-07 reg 2.000000e+04 train accuracy: 0.372694 val accuracy: 0.371000
lr 1.400000e-07 reg 2.100000e+04 train accuracy: 0.375959 val accuracy: 0.386000
lr 1.500000e-07 reg 8.000000e+03 train accuracy: 0.359776 val accuracy: 0.372000
lr 1.500000e-07 reg 9.000000e+03 train accuracy: 0.368939 val accuracy: 0.377000
lr 1.500000e-07 reg 1.000000e+04 train accuracy: 0.362878 val accuracy: 0.364000
lr 1.500000e-07 reg 1.100000e+04 train accuracy: 0.378367 val accuracy: 0.370000
lr 1.500000e-07 reg 1.800000e+04 train accuracy: 0.379041 val accuracy: 0.376000
lr 1.500000e-07 reg 1.900000e+04 train accuracy: 0.378796 val accuracy: 0.393000
lr 1.500000e-07 reg 2.000000e+04 train accuracy: 0.374878 val accuracy: 0.382000
lr 1.500000e-07 reg 2.100000e+04 train accuracy: 0.378837 val accuracy: 0.384000
lr 1.600000e-07 reg 8.000000e+03 train accuracy: 0.362878 val accuracy: 0.362000
lr 1.600000e-07 reg 9.000000e+03 train accuracy: 0.370755 val accuracy: 0.375000
lr 1.600000e-07 reg 1.000000e+04 train accuracy: 0.378837 val accuracy: 0.387000
lr 1.600000e-07 reg 1.100000e+04 train accuracy: 0.377265 val accuracy: 0.389000
lr 1.600000e-07 reg 1.800000e+04 train accuracy: 0.381735 val accuracy: 0.382000
lr 1.600000e-07 reg 1.900000e+04 train accuracy: 0.378857 val accuracy: 0.381000
lr 1.600000e-07 reg 2.000000e+04 train accuracy: 0.378959 val accuracy: 0.398000
lr 1.600000e-07 reg 2.100000e+04 train accuracy: 0.381980 val accuracy: 0.384000
Best validation accuracy during cross-validation:
lr = 1.600000e-07, reg = 2.000000e+04, best_val = 0.398000
  • 可以发现,特区的特征维度比原始像素维度要低很多,而且训练也更快,精度也可能更高。

测试集精度

# Evaluate your trained SVM on the test set
y_test_pred = best_svm.predict(X_test_feats)
test_accuracy = np.mean(y_test == y_test_pred)
print(test_accuracy) # 0.418
# 之前只有0.367,但是超参数也有一定影响,只不过这里特征影响比较大

可视化错误情况

  • 观察我们分类器实际性能的一个重要方式就是,可视化我们分类器错分的样本,看其有什么特征
  • 我们每个选择我们分类器将其分为A类,但是实际上不是A类的图像来展示
examples_per_class = 8
classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
for cls, cls_name in enumerate(classes):idxs = np.where((y_test != cls) & (y_test_pred == cls))[0]idxs = np.random.choice(idxs, examples_per_class, replace=False)for i, idx in enumerate(idxs):plt.subplot(examples_per_class, len(classes), i * len(classes) + cls + 1)plt.imshow(X_test[idx].astype('uint8'))plt.axis('off')if i == 0:plt.title(cls_name)
plt.show()

Q: Describe the misclassification results that you see. Do they make sense?
A: 错误分类的图像和真正图像在颜色和形状上都有些许相似

例如上图中,第一列把鸟分成飞机,可能是:1.飞机经常处于蓝色天空下;2:鸟儿和飞机的形状类似。

5. 使用神经网络训练特征

  • 我们在用我们提取的特征实验一下精度提升了多少
  • 之前在原始像素特征上,我的实验结果如下:
Best hidden_size: 160
Best lr: 9.000000e-04
Best reg: 5.000000e-04
train accuracy: 0.660156
val accuracy: 0.541000
  • 但是这次我发现使用之前的超参数,学习率太低了,因为迭代了相同的次数后,准确率在0.3左右,而学习率设置在1e-1左右的时候准确率才在0.5~0.6之间。
from cs231n.classifiers.neural_net import TwoLayerNetprint(X_train_feats.shape)
# 网络结构
input_size = X_train_feats.shape[1]
num_classes = 10# 超参数
hidden_num = [40,80,160,320,640]
learning_rate_choice = [1e-2,3e-2,5e-2,7e-2,9e-2,1e-1,3e-1,5e-1]
reg_choice = [5e-6,5e-5,5e-4]
num_iters = 3000
batch_size = 256
learning_rate_decay = 0.98# 中间结果
best_net = None
best_hidden = None
best_lr = None
best_reg = None
best_val = -1 # 最好的验证集精度
results = {} # 存储训练集和验证集的精度for hidden in hidden_num:for lr in learning_rate_choice:for reg in reg_choice:net = TwoLayerNet(input_size,hidden,num_classes)stats = net.train(X= X_train_feats,y=y_train,X_val = X_val_feats,y_val=y_val,learning_rate=lr,reg=reg,num_iters=num_iters,batch_size = batch_size)train_acc = stats["train_acc_history"][-1] # 有多个epochval_acc = stats["val_acc_history"][-1] # 有多个epochresults[(hidden,lr,reg)] = (train_acc,val_acc)if val_acc > best_val:best_val = val_accbest_lr = lrbest_reg = regbest_hidden = hiddenbest_net = netprint("hidden_size:%d lr:%e reg:%e train_acc:%f val_acc:%f" %(hidden,lr,reg,train_acc,val_acc))print('Best hidden_size: %d\n Best lr: %e\nBest reg: %e\ntrain accuracy: %f\nval accuracy: %f' %(best_hidden, best_lr, best_reg, results[(best_hidden,best_lr, best_reg)][0], results[(best_hidden,best_lr, best_reg)][1]))
Best hidden_size: 640
Best lr: 3.000000e-01
Best reg: 5.000000e-04
train accuracy: 0.785156
val accuracy: 0.609000
  • 可以看见,这次准确率最高时0.61,而且不只是中间隐藏层个数是640时取得
# Visualize the cross-validation results
import mathmarker_size = 100
for i,hidden in enumerate(hidden_num):x_scatter = [math.log10(x[1]) for x in results if x[0] == hidden] # 学习率y_scatter = [math.log10(x[2]) for x in results if x[0] == hidden] # 惩罚强度# 画训练集colors = [results[x][0] for x in results if x[0] == hidden]plt.subplot(3,2,2*(i%3)+1)plt.scatter(x_scatter,y_scatter,marker_size,c=colors)plt.colorbar()plt.xlabel('log learning rate')plt.ylabel('log regularization strength')plt.title('hidden_num = %d training accuracy' % hidden)# 画测试集colors = [results[x][1] for x in results if x[0] == hidden]plt.subplot(3,2,2*(i%3)+2)plt.scatter(x_scatter,y_scatter,marker_size,c=colors)plt.colorbar()plt.xlabel('log learning rate')plt.ylabel('log regularization strength')plt.title('hidden_num = %d validation accuracy' % hidden)if(i % 3 == 0):plt.subplots_adjust(hspace = 0.6)plt.show()


  • 而在调试的时候,我发现学习率非常重要,所以我们可以先初步划分一个范围[1e-5,1e-4,1e-3,1e-2,1e-1],然后看先少迭代几次看,准确率怎么样,据此再缩短范围,比如这次我就缩小到了[1e-2,5e-1]之间,准确率是比较高的。
  • 考虑到是不是准确率太低,更新的太慢,所以,我设置了小的准确率加大了迭代次数,看准确率怎么样? 发现学习率小确实需要多迭代几次,而不能直接否认其它超参数没效。 当然,在实际操作中我们也是希望我们的学习率不大不小,不然一次完整训练太费时了。

6. 测试集上测试

# Run your best neural net classifier on the test set. You should be able
# to get more than 55% accuracy.
test_acc = (best_net.predict(X_test_feats) == y_test).mean()
print(test_acc) # 0.593

[CS231n Assignment #1] 简单图像分类器——高级图像特征分类相关推荐

  1. TensorFlow练习11: 图像分类器 – retrain谷歌Inception模型(转)

    原文地址:https://www.tuicool.com/articles/ieQZVfa 前一帖< TensorFlow练习10: 实现谷歌Deep Dream >使用到了谷歌训练的In ...

  2. PyTorch入门(三)--实现简单图像分类器

    实现简单图像分类器 1. 数据加载 1.1 常用公共数据集加载 1.2 私人数据集加载方法 2. 定义神经网络 3. 定义权值更新与损失函数 4. 训练与测试神经网络 5. 神经网络的保存与载入 本篇 ...

  3. 【PyTorch】实现一个简单的CNN图像分类器

    本文记录了一个简单的基于pytorch的图像多分类器模型构造过程,参考自Pytorch官方文档.磐创团队的<PyTorch官方教程中文版>以及余霆嵩的<PyTorch 模型训练实用教 ...

  4. 30分钟 Keras 创建一个图像分类器

    深度学习是使用人工神经网络进行机器学习的一个子集,目前已经被证明在图像分类方面非常强大.尽管这些算法的内部工作在数学上是严格的,但 Python 库(比如 keras)使这些问题对我们所有人都可以接近 ...

  5. 白话——胡说图像分类器

    以下信息全部是作者的个人理解,记录下来方便用简单的视角去理解复杂的问题,其中不乏胡说八道和想当然,如有与事实不符的地方,请大家多多批评指正! 图像分类器最早诞生的应该是贝叶斯分类器: 为什么?因为贝叶 ...

  6. tensorflow 迁移学习_基于 TensorFlow.js 1.5 的迁移学习图像分类器

    在黑胡桃社区的体验案例中,有一个"人工智能教练",它其实是一个自定义的图像分类器.使用 TensorFlow.js 这个强大而灵活的 Javascript 机器学习库可以很轻松地构 ...

  7. 用PyTorch创建一个图像分类器?So easy!(Part 1)

    经过了几个月的学习和实践,我完成了优达学城网站上<Python Programming with Python Nanodegree>课程的学习,该课程的终极项目就是使用Pytorch为1 ...

  8. 如何用PyTorch训练图像分类器

    本文为 AI 研习社编译的技术博客,原标题 : How to Train an Image Classifier in PyTorch and use it to Perform Basic Infe ...

  9. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了. 在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简 ...

最新文章

  1. ValueError: Classification metrics can‘t handle a mix of multiclass and unknown targets
  2. 【Deep Learning笔记】感知机模型和学习策略
  3. UWP 文件读写API
  4. [YTU]_1046 ( 输入10个数字,然后逆序输出)
  5. 关于jQuery获取Action返回的JSON数据 项目真实案例 记录(Struts2)
  6. 【Verilog】有限状态机
  7. ML之KMeans:利用KMeans算法对Boston房价数据集(两特征+归一化)进行二聚类分析
  8. [摘录]优势谈判目录
  9. 关于 SAP Spartacus Loader Meta Reducer 的用途 - loading 在 true 和 false之前切换的逻辑
  10. C++ 多态在异常中的使用
  11. mysql待办事项表名_Activiti中彻底解决待办事项列表查询复杂、API不友好的设计方案...
  12. SAP 产品部署方式及定价模型
  13. ppt怎么一次性改全部字体_PPT的字体怎么选择?
  14. 控制台应用程序《石头剪刀布》——新手,
  15. uniapp 安装uView-ui教程
  16. Zoom支持自动生成字幕;SharePlay上线;Safari 更新导致大量bug |WebRTC风向
  17. 整理wind商誉数据2016-2019
  18. linux tty core code,linux tty core 源码分析(8)
  19. 数据库复杂查询,左联右联 聚合 计数 时间查询等,持续更新
  20. 周报格式(sohu)

热门文章

  1. 编写一个C程序,实现以下功能: 编写一个函数jugde(int b[],int n),该函数能将一个一维整型数组调整为左右两边,凡是奇数均放左边,凡是偶数均放在右边。
  2. 计算机二级office难吗
  3. html二级菜单的创建
  4. Android 中 Base64 转换成 图片
  5. 【Python】 面向对象:输出年龄最大的对象所对应的名字
  6. VFP中使用语言的注意事项
  7. 基于阿里云的手机短信验证码和注册校验逻辑
  8. PS人物脸部去高光简单之法
  9. 【SARIMAX】Champagne Sales
  10. linux字符串转为整型,C语言将字符串转换为整数