|
| 1 | +图像分类教程 |
| 2 | +========== |
| 3 | + |
| 4 | +在本教程中,我们将使用CIFAR-10数据集训练一个卷积神经网络,并使用这个神经网络来对图片进行分类。如下图所示,卷积神经网络可以辨识图片中的主体,并给出分类结果。 |
| 5 | +<center></center> |
| 6 | + |
| 7 | +## 数据准备 |
| 8 | +首先下载CIFAR-10数据集。下面是CIFAR-10数据集的官方网址: |
| 9 | + |
| 10 | +<https://www.cs.toronto.edu/~kriz/cifar.html> |
| 11 | + |
| 12 | +我们准备了一个脚本,可以用于从官方网站上下载CIFAR-10数据集,并将之转化为jpeg文件,存入我们为本文中的实验所设计的目录中。使用这个脚本前请确认已经安装了pillow及相关依赖模块。可以参照下面的命令进行安装和下载: |
| 13 | + |
| 14 | +1. 安装pillow |
| 15 | + |
| 16 | +```bash |
| 17 | +sudo apt-get install libjpeg-dev |
| 18 | +pip install pillow |
| 19 | +``` |
| 20 | + |
| 21 | +2. 下载数据集 |
| 22 | + |
| 23 | +```bash |
| 24 | +cd demo/image_classification/data/ |
| 25 | +sh download_cifar.sh |
| 26 | +``` |
| 27 | + |
| 28 | +CIFAR-10数据集包含60000张32x32的彩色图片。图片分为10类,每个类包含6000张。其中50000张图片用于组成训练集,10000张组成测试集。 |
| 29 | + |
| 30 | +下图展示了所有的照片分类,并从每个分类中随机抽取了10张图片: |
| 31 | +<center></center> |
| 32 | + |
| 33 | +脚本运行完成后,我们应当会得到一个名为cifar-out的文件夹,其下子文件夹的结构如下 |
| 34 | + |
| 35 | + |
| 36 | +``` |
| 37 | +train |
| 38 | +---airplane |
| 39 | +---automobile |
| 40 | +---bird |
| 41 | +---cat |
| 42 | +---deer |
| 43 | +---dog |
| 44 | +---frog |
| 45 | +---horse |
| 46 | +---ship |
| 47 | +---truck |
| 48 | +test |
| 49 | +---airplane |
| 50 | +---automobile |
| 51 | +---bird |
| 52 | +---cat |
| 53 | +---deer |
| 54 | +---dog |
| 55 | +---frog |
| 56 | +---horse |
| 57 | +---ship |
| 58 | +---truck |
| 59 | +``` |
| 60 | + |
| 61 | +cifar-out下包含`train`和`test`两个文件夹,其中分别包含了CIFAR-10中的训练数据和测试数据。这两个文件夹下各自有10个子文件夹,每个子文件夹下存储相应分类的图片。将图片按照上述结构存储好之后,我们就可以着手对分类模型进行训练了。 |
| 62 | + |
| 63 | +## 预处理 |
| 64 | +数据下载之后,还需要进行预处理,将数据转换为Paddle的格式。我们可以通过如下命令进行预处理工作: |
| 65 | + |
| 66 | +``` |
| 67 | +cd demo/image_classification/ |
| 68 | +sh preprocess.sh |
| 69 | +``` |
| 70 | + |
| 71 | +其中`preprocess.sh` 调用 `./demo/image_classification/preprocess.py` 对图片进行预处理 |
| 72 | +```sh |
| 73 | +export PYTHONPATH=$PYTHONPATH:../../ |
| 74 | +data_dir=./data/cifar-out |
| 75 | +python preprocess.py -i $data_dir -s 32 -c 1 |
| 76 | +``` |
| 77 | + |
| 78 | +`./demo/image_classification/preprocess.py` 使用如下参数: |
| 79 | + |
| 80 | +- `-i` 或 `--input` 给出输入数据所在路径; |
| 81 | +- `-s` 或 `--size` 给出图片尺寸; |
| 82 | +- `-c` 或 `--color` 标示图片是彩色图或灰度图 |
| 83 | + |
| 84 | +## 模型训练 |
| 85 | +在开始训练之前,我们需要先创建一个配置文件。下面我们给出了一个配置文件的示例(vgg_16_cifar.py)。**注意**,这里的列出的和`vgg_16_cifar.py`中有着细微的差别。 |
| 86 | + |
| 87 | +```python |
| 88 | +from paddle.trainer_config_helpers import * |
| 89 | +data_dir='data/cifar-out/batches/' |
| 90 | +meta_path=data_dir+'batches.meta' |
| 91 | +args = {'meta':meta_path, 'mean_img_size': 32, |
| 92 | + 'img_size': 32, 'num_classes': 10, |
| 93 | + 'use_jpeg': 1, 'color': "color"} |
| 94 | +define_py_data_sources2(train_list=data_dir+"train.list", |
| 95 | + test_list=data_dir+'test.list', |
| 96 | + module='image_provider', |
| 97 | + obj='processData', |
| 98 | + args=args) |
| 99 | +settings( |
| 100 | + batch_size = 128, |
| 101 | + learning_rate = 0.1 / 128.0, |
| 102 | + learning_method = MomentumOptimizer(0.9), |
| 103 | + regularization = L2Regularization(0.0005 * 128)) |
| 104 | + |
| 105 | +img = data_layer(name='image', size=3*32*32) |
| 106 | +lbl = data_layer(name="label", size=10) |
| 107 | +# small_vgg is predined in trainer_config_helpers.network |
| 108 | +predict = small_vgg(input_image=img, num_channels=3) |
| 109 | +outputs(classification_cost(input=predict, label=lbl)) |
| 110 | +``` |
| 111 | + |
| 112 | +在第一行中我们载入用于定义网络的函数。 |
| 113 | +```python |
| 114 | +from paddle.trainer_config_helpers import * |
| 115 | +``` |
| 116 | + |
| 117 | +之后定义的`define_py_data_sources2`使用python data provider接口,其中 `args`将在`image_provider.py`进行使用,后者负责将图片数据传递给Paddle |
| 118 | + - `meta`: 训练集平均值。 |
| 119 | + - `mean_img_size`: 特征图的平均高度及宽度。 |
| 120 | + - `img_size`:输入图片的高度及宽度。 |
| 121 | + - `num_classes`:分类的个数。 |
| 122 | + - `use_jpeg`:处理过程中数据存储格式 |
| 123 | + - `color`标示是否为彩色图片 |
| 124 | + |
| 125 | + `settings`用于设置训练算法。在下面的例子中,learning rate被设置为0.1除以每批图片数(batch size),而weight decay则为0.0005乘以每批图片数。 |
| 126 | + |
| 127 | + ```python |
| 128 | +settings( |
| 129 | + batch_size = 128, |
| 130 | + learning_rate = 0.1 / 128.0, |
| 131 | + learning_method = MomentumOptimizer(0.9), |
| 132 | + regularization = L2Regularization(0.0005 * 128) |
| 133 | +) |
| 134 | +``` |
| 135 | + |
| 136 | +`small_vgg`定义了网络结构。这里我们使用了VGG卷积神经网络的一个小型版本。关于VGG卷积神经网络的描述可以参考:[http://www.robots.ox.ac.uk/~vgg/research/very_deep/](http://www.robots.ox.ac.uk/~vgg/research/very_deep/)。 |
| 137 | +```python |
| 138 | +# small_vgg is predined in trainer_config_helpers.network |
| 139 | +predict = small_vgg(input_image=img, num_channels=3) |
| 140 | +``` |
| 141 | +生成配置之后,我们就可以运行脚本train.sh来训练模型。请注意下面的脚本中假设该脚本放置是在路径`./demo/image_classification`下的。如果要从其它路径运行,你需要修改下面的脚本中的路径,以及配置文件中的相应内容。 |
| 142 | + |
| 143 | +```bash |
| 144 | +config=vgg_16_cifar.py |
| 145 | +output=./cifar_vgg_model |
| 146 | +log=train.log |
| 147 | + |
| 148 | +paddle train \ |
| 149 | +--config=$config \ |
| 150 | +--dot_period=10 \ |
| 151 | +--log_period=100 \ |
| 152 | +--test_all_data_in_one_period=1 \ |
| 153 | +--use_gpu=1 \ |
| 154 | +--save_dir=$output \ |
| 155 | +2>&1 | tee $log |
| 156 | + |
| 157 | +python -m paddle.utils.plotcurve -i $log > plot.png |
| 158 | +``` |
| 159 | +- 这里我们使用的是GPU模式进行训练。如果你没有GPU环境,可以设置`use_gpu=0`。 |
| 160 | +- `./demo/image_classification/vgg_16_cifar.py`是网络和数据配置文件。各项参数的详细说明可以在命令行参数相关文档中找到 |
| 161 | +- 脚本`plotcurve.py`依赖于python的`matplotlib`模块。因此如果这个脚本运行失败,也许是因为需要安装`matplotlib` |
| 162 | + |
| 163 | +在训练完成后,训练及测试误差曲线图会被`plotcurve.py`脚本保存在 `plot.png`中。下面是一个误差曲线图的示例: |
| 164 | + |
| 165 | +<center></center> |
| 166 | + |
| 167 | +## 预测 |
| 168 | +在训练完成后,模型及参数会被保存在路径`./cifar_vgg_model/pass-%05d`下。例如第300次训练所得的模型会被保存在`./cifar_vgg_model/pass-00299`。 |
| 169 | + |
| 170 | +要对一个图片的进行分类预测,我们可以使用`predict.sh`,该脚本将输出预测分类的标签: |
| 171 | + |
| 172 | +``` |
| 173 | +sh predict.sh |
| 174 | +``` |
| 175 | + |
| 176 | +predict.sh: |
| 177 | +``` |
| 178 | +model=cifar_vgg_model/pass-00299/ |
| 179 | +image=data/cifar-out/test/airplane/seaplane_s_000978.png |
| 180 | +use_gpu=1 |
| 181 | +python prediction.py $model $image $use_gpu |
| 182 | +``` |
| 183 | + |
| 184 | +## 练习 |
| 185 | +在CUB-200数据集上使用VGG模型训练一个鸟类图片分类模型。相关的鸟类数据集可以从如下地址下载,其中包含了200种鸟类的照片(主要来自北美洲)。 |
| 186 | + |
| 187 | +<http://www.vision.caltech.edu/visipedia/CUB-200.html> |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | + |
| 192 | +## 细节探究 |
| 193 | +### 卷积神经网络 |
| 194 | +卷积神经网络是一种使用卷积层的前向神经网络,很适合构建用于理解图片内容的模型。一个典型的神经网络如下图所示: |
| 195 | + |
| 196 | + |
| 197 | + |
| 198 | +一个卷积神经网络包含如下层: |
| 199 | + |
| 200 | +- 卷基层:通过卷积操作从图片或特征图中提取特征 |
| 201 | +- 池化层:使用max-pooling方式进行特征压缩 |
| 202 | +- 全连接层:使用全连接,从特征中生成分类结果 |
| 203 | + |
| 204 | +卷积神经网络在图片分类上有着优异的表现,这是因为它发掘出了图片的两类重要信息:局部关联性质和空间不变性质。通过交替使用卷基和池化处理,卷积神经网络能够使得图片的这两类信息稳定地得到保持 |
| 205 | + |
| 206 | +关于如何定义网络中的层,以及如何在层之间进行连接,请参考文档中关于网络层的相关内容。 |
0 commit comments