Starter Bundle (初级篇)
学习基础知识:
Practitioner Bundle (中级篇)
更深入地学习深度学习,理解高级的技巧以探索最佳实践技巧和经验法则。
ImageNet Bundle(高级篇)
完全深入深度学习在计算机视觉的实践,包括如何在大型数据集-ImageNet上训练大规模地神经网络以及年龄和性别预测、汽车制造和模型分类、表情识别等实际案例。
主要三个模块:
通常,像素被认为是出现在图像中给定位置的光的“颜色”或“强度”。
像素的两种形式:
我们可以将RGB图像概念化,该图像由宽度W和高度H的三个独立矩阵组成,每个RGB分量一个,如图3.5所示。我们可以将这三个矩阵结合起来,得到形状为W×H×D的多维数组,其中D是通道的深度或数量(对于RGB颜色空间,D = 3)
关于NumPy中为什么把高放在前面:
When defining the dimensions of matrix, we always write it as rows x columns. The number of rows in an image is its height whereas the number of columns is the image’s width. The depth will still remain the depth.
要注意:OpenCV实际上以蓝色,绿色,红色顺序(GBR)存储像素值(而不是RGB)。
——历史原因
注意:忽略宽高比(aspect ratio)可能会导致图像看起来压缩和变形
From a strictly aesthetic point of view, you almost always want to ensure the aspect ratio of the image is maintained when resizing an image – but this guideline isn’t always the case for deep learning. Most neural networks and Convolutional Neural Networks applied to the task of image classification assume a fixed size input, meaning that the dimensions of all images you pass through the network must be the same. Common choices for width and height image sizes inputted to Convolutional Neural Networks include 32 × 32, 64 × 64, 224 × 224, 227 × 227, 256 × 256, and 299 × 299.
输入大小固定
必要性
机器学习算法模型,比如KNN、SVM甚至是CNN都需要一个固定大小的特征向量。因此,图片都需要进过预处理并缩放到具有相同的宽和高。
-方法
① 有很多高级方法在考虑**纵横比( aspect ratio)**的情况下进行转换;
② 有些方法直接粗暴转换(忽视纵横比);
如何选择要看方差因素的复杂性:在有些情况,忽略纵横比效果可以,但是有些情况下却需要保留纵横比。
代码
① preprocess an image:
(simple_preprocessor)
import cv2
class SimplePreprocessor:
def __init__(self, width, height, inter=cv2.INTER_AREA):
# store the target image width, height, and interpolation
# method used when resizing
self.width = width
self.height = height
self.inter = inter
def preprocess(self, image):
# resize the image to a fixed size, ignoring the aspect
# ratio
return cv2.resize(image, (self.width, self.height),
interpolation=self.inter)
(这里只是处理单张图片-没有考虑导入整个数据)
② load a collection of images from disk
(simple_dataset_loader)
import os
import cv2
import numpy as np
class SimpleDatasetLoader:
# Method: Constructor
def __init__(self, preprocessors=None):
"""
:param preprocessors: List of image preprocessors
"""
self.preprocessors = preprocessors
if self.preprocessors is None:
self.preprocessors = []
# Method: Used to load a list of images for pre-processing
def load(self, image_paths, verbose=-1):
"""
:param image_paths: List of image paths
:param verbose: Parameter for printing information to console
:return: Tuple of data and labels
"""
data, labels = [], []
for i, image_path in enumerate(image_paths):
image = cv2.imread(image_path)
label = image_path.split(os.path.sep)[-2]
if self.preprocessors is not None:
for p in self.preprocessors:
image = p.preprocess(image)
data.append(image)
labels.append(label)
if verbose > 0 and i > 0 and (i+1) % verbose == 0:
print('[INFO]: Processed {}/{}'.format(i+1, len(image_paths)))
return (np.array(data), np.array(labels))
③ more advanced dataset loaders
参数学习
K-NN 算法实质上并没有“学习”任何东西,它完全依赖于输入的数据对新数据做出决策。
因此如果算法出错,它无法做出相应的“改进“,而且算法的体量完全随着输入数据维度的增加而线性增加。
取而代之,更理想的方法是定义一个机器学习模型,该模型可以在训练期间从我们的输入数据中学习模式(要求我们在训练过程中花费更多的时间),但是其却有以下好处:由少量参数定义,而且可以简单的用这些参数(而不是训练量)来表示模型。这种方式的机器学习就叫做参数学习。
“A learning model that summarizes data with a set of parameters of fixed size (independent of the number of training examples) is called a parametric model. No matter how much data you throw at the parametric model, it won’t change its mind about how many parameters it needs.” – Russell and Norvig (2009) [73]
使用了参数化学习(parameterized learning),我们就可以从输入数据中学习并发现潜在的模式。
传统的梯度下降算法在训练完整个训练集之后才更新一次权重(performs only one weight update per epoch):太慢,而且浪费计算资源.
参数:learning rate
梯度下降由学习率来进行控制。
学习率是迄今训练自己的模型最为重要的一个参数:
太大的学习率会导致学不到任何东西,太小的学习率会导致要话花费很长时间才能到达一个合理的loss。
(并不需要经过一次 epoch,而是)每隔一个 batch 就更新一次权重
参数: batch size
Instead of computing our gradient