背景
最近一个学长让我用机器学习做一个分类任务,就是根据拍摄的图片然后得到转弯的方向,然后有大小两个选择,然后我计划用ai stdio上一个开源的项目直接套用,我是4000张训练集,1000张测试集,这也是我第一次用paddl去实现一个自己想要去实现的功能,然后开始吧!
开始
项目参考:https://aistudio.baidu.com/bjcpu02/user/264545/1673990/notebooks/1673990.ipynb
然后计划是使用resnet的模型进行,有一个项目是进行花的分类的可以先学习一下这个,然后熟悉一下做分类的流程!
先是对各种数据集进行压缩之后挂载在数据集上:
之后就是解压:先看看解压命令:记住不要忘了!
# 解压花朵数据集
!cd data/data2815 && unzip -q flower_photos.zip
然后这里它是解压了一个预训练参数,这个是什么呢,还有一个名和它很像是预训练模型,就是这个是人家已经的到的模型和一些参数,然后我们可以直接套用在我们的数据集中,然后得到我们的参数,这样可以节约时间。
数据处理
对本地数据做一些预处理,主要用于随机分组,一部分用于训练,一部分用于验证。同时生产两者的标签文件
然后这个几乎是必须的,然后这个操作我们必须学会,我们一行行看看它的代码。
导入库
import codecs
import os
import random
import shutil
from PIL import Image
然后我就是直接手动建立了2个txt文件,要不还得用代码操作啥的,现在首要的目的就是在这两个文件夹下写入我们的图片的名称和及其类别。
先在label_list.txt上写下;
0 直
1 右转大
2 右转小
3 左转大
4 左转小
然后用代码写剩下两个txt文件,先打开:
train_file = codecs.open("train.txt", 'w')
eval_file = codecs.open("eval.txt", 'w')
然后我们先获得一个文件夹的文件名:(os模块:https://blog.csdn.net/xxlovesht/article/details/80913193)
zhi_data = os.listdir("直")
print(zhi_data)
然后我们在将其路径加上后写入到train.txt文件夹里,我在这里是写了一个函数,然后可以看一下,我感觉我写的还是比较简单的:
label = {"直":0,
"右转大":1,
"右转小":2,
"左转大":3,
"左转小":4}
def data_write(dir):
name = os.listdir(dir)
#print(name)
for i in name:
with open("train.txt","a") as f:
lujing = os.path.join(dir,i)
print(lujing)
end = lujing + " " + str(label[dir])+"\n"
print(end)
f.write(end)
data_write("直")
然后的话在对其他的文件夹进行操作,然后train.txt的就写完了,下一步就是对eval.txt进行书写,方法还是一样的。
训练配置
- 训练轮数
- 每批次训练图片数量
- 是否使用GPU训练
- 学习率调整
- 训练图片尺寸
先还是导入库:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import numpy as np
import time
import math
import paddle
import paddle.fluid as fluid
import codecs
import logging
from paddle.fluid.initializer import MSRA
from paddle.fluid.initializer import Uniform
from paddle.fluid.param_attr import ParamAttr
from PIL import Image
from PIL import ImageEnhance
然后我们直接复制这些参数,但是要改一些路径:
train_parameters = {
"input_size": [3, 224, 224],
"class_dim": -1, # 分类数,会在初始化自定义 reader 的时候获得
"image_count": -1, # 训练图片数量,会在初始化自定义 reader 的时候获得
"label_dict": {},
"data_dir": "/home/aistudio", # 训练数据存储地址
"train_file_list": "train.txt",
"label_file": "label_list.txt",
"save_freeze_dir": "./freeze-model",
"save_persistable_dir": "./persistable-params",
"continue_train": True, # 是否接着上一次保存的参数接着训练,优先级高于预训练模型
"pretrained": True, # 是否使用预训练的模型
"pretrained_dir": "ResNet50_pretrained",
"mode": "train",
"num_epochs": 1,
"train_batch_size": 24,
"mean_rgb": [127.5, 127.5, 127.5], # 常用图片的三通道均值,通常来说需要先对训练数据做统计,此处仅取中间值
"use_gpu": True,
"image_enhance_strategy": { # 图像增强相关策略
"need_distort": True, # 是否启用图像颜色增强
"need_rotate": True, # 是否需要增加随机角度
"need_crop": True, # 是否要增加裁剪
"need_flip": True, # 是否要增加水平随机翻转
"hue_prob": 0.5,
"hue_delta": 18,
"contrast_prob": 0.5,
"contrast_delta": 0.5,
"saturation_prob": 0.5,
"saturation_delta": 0.5,
"brightness_prob": 0.5,
"brightness_delta": 0.125
},
"early_stop": {
"sample_frequency": 50,
"successive_limit": 3,
"good_acc1": 0.92
},
"rsm_strategy": {
"learning_rate": 0.002,
"lr_epochs": [20, 40, 60, 80, 100],
"lr_decay": [1, 0.5, 0.25, 0.1, 0.01, 0.002]
},
"momentum_strategy": {
"learning_rate": 0.002,
"lr_epochs": [20, 40, 60, 80, 100],
"lr_decay": [1, 0.5, 0.25, 0.1, 0.01, 0.002]
},
"sgd_strategy": {
"learning_rate": 0.002,
"lr_epochs": [20, 40, 60, 80, 100],
"lr_decay": [1, 0.5, 0.25, 0.1, 0.01, 0.002]
},
"adam_strategy": {
"learning_rate": 0.002
}
}
然后我们初始化函数,其实直接设置也行。
def init_train_parameters():
"""
初始化训练参数,主要是初始化图片数量,类别数
:return:
"""
train_file_list = os.path.join(train_parameters['data_dir'], train_parameters['train_file_list'])
label_list = os.path.join(train_parameters['data_dir'], train_parameters['label_file'])
index = 0
with codecs.open(label_list, encoding='utf-8') as flist:
lines = [line.strip() for line in flist]
for line in lines:
parts = line.strip().split()
train_parameters['label_dict'][parts[1]] = int(parts[0])
index += 1
train_parameters['class_dim'] = index
with codecs.open(train_file_list, encoding=