【飞桨】【图像分类】模板

图像分类基本都用以下代码:

除了数据集不同,其他都类似。新项目直接改就行。

# 导入所需要的库
from sklearn.utils import shuffle
import os
import pandas as pd
import numpy as np
from PIL import Image

import paddle
import paddle.nn as nn
from paddle.io import Dataset
import paddle.vision.transforms as T
import paddle.nn.functional as F
from paddle.metric import Accuracy

import warnings
warnings.filterwarnings("ignore")

# 读取数据
train_images = pd.read_csv('lemon_lesson/train_images.csv', usecols=['id','class_num'])
test_images = pd.read_csv('lemon_lesson/sample_submit.csv', usecols=['id','class_num'])

# labelshuffling

def labelShuffling(dataFrame, groupByName = 'class_num'):

    groupDataFrame = dataFrame.groupby(by=[groupByName])
    labels = groupDataFrame.size()
    print("length of label is ", len(labels))
    maxNum = max(labels)
    lst = pd.DataFrame()
    for i in range(len(labels)):
        print("Processing label  :", i)
        tmpGroupBy = groupDataFrame.get_group(i)
        createdShuffleLabels = np.random.permutation(np.array(range(maxNum))) % labels[i]
        print("Num of the label is : ", labels[i])
        lst=lst.append(tmpGroupBy.iloc[createdShuffleLabels], ignore_index=True)
        print("Done")
    # lst.to_csv('test1.csv', index=False)
    return lst

# 划分训练集和校验集
all_size = len(train_images)
print(all_size)
print(train_images['id'].values)
print(train_images['class_num'].values)

print(len(test_images))
print(test_images['id'].values)
print(test_images['class_num'].values)


import paddle
from paddle.vision.transforms import Compose, ColorJitter, Resize,Transpose, Normalize
import cv2
import numpy as np
from PIL import Image
from paddle.io import Dataset

import paddle.vision.transforms as T
from paddle.vision.transforms import Compose, Resize, ColorJitter,RandomHorizontalFlip,ToTensor

#自定义的数据预处理函数,输入原始图像,输出处理后的图像,可以借用paddle.vision.transforms的数据处理功能
def preprocessEnhance(img):
    transform = Compose([T.ColorJitter(0.125,0.4,0.4,0.08),####亮度、对比度、饱和度、色调等增强策略尽量与测试集样本分布保持一致,避免极端
                        T.Pad(2),
                        T.RandomRotation(5),#旋转角度按常规考虑偏转量设置即可
                        T.RandomResizedCrop(224,scale=(0.7901, 0.8920),ratio=(1, 1)),#适度放大拉伸后,上采样至224像素,兼容预训练模型的训练样本尺寸224
                        T.RandomHorizontalFlip(0.5),#大部分实物拍摄样本考虑水平翻转即可
        Normalize(mean=[127.5, 127.5, 127.5], std=[127.5, 127.5, 127.5], data_format='HWC'), #标准化
        Transpose(), #原始数据形状维度是HWC格式,经过Transpose,转换为CHW格式
        ])
    img = transform(img).astype("float32")
    return img

def preprocess(img):
    transform = Compose([
        Resize(size=(224, 224)), #把数据长宽像素调成224*224
        Normalize(mean=[127.5, 127.5, 127.5], std=[127.5, 127.5, 127.5], data_format='HWC'), #标准化
        Transpose(), #原始数据形状维度是HWC格式,经过Transpose,转换为CHW格式
        ])
    img = transform(img).astype("float32")
    return img

#自定义数据读取器
class Reader(Dataset):
    def __init__(self, data, is_val, imageFolder):
        super().__init__()
        self.is_val=is_val
        self.imageFolder=imageFolder
        #在初始化阶段,把数据集划分训练集和测试集。由于在读取前样本已经被打乱顺序,取20%的样本作为测试集,80%的样本作为训练集。
        self.samples = data[-int(len(data)*0.2):] if is_val else data[:-int(len(data)*0.2)]

    def __getitem__(self, idx):
        #处理图像
        img_path = self.imageFolder + self.samples['id'].values[idx] #得到某样本的路径
        img = Image.open(img_path)
        if img.mode != 'RGB':
            img = img.convert('RGB')
        
        if self.is_val:
            img = preprocess(img) 
        else:
            img = preprocessEnhance(img) #数据预处理--这里仅包括简单数据预处理,没有用到数据增强

        #处理标签
        label = self.samples["class_num"].values[idx] #得到某样本的标签
        label = np.array([label], dtype="int64") #把标签数据类型转成int64
        return img, label

    def __len__(self):
        #返回每个Epoch中图片数量
        return len(self.samples)

data_list = train_images

#生成训练数据集实例
train_dataset = Reader(data_list, is_val=False, imageFolder="lemon_lesson/train_images/")

#生成测试数据集实例
eval_dataset = Reader(data_list, is_val=True, imageFolder="lemon_lesson/train_images/")


test_dataset = Reader(test_images, is_val=True, imageFolder="lemon_lesson/test_images/")

#打印一个训练样本
#print(train_dataset[1136][0])
print(train_dataset[2][0].shape)
print(train_dataset[2][1])


print(eval_dataset[2][0].shape)
print(eval_dataset[2][1])

print(test_dataset[2][0].shape)
print(test_dataset[2][1])

net=paddle.vision.models.resnet101(num_classes=4,pretrained=True)
model = paddle.Model(net)

train_parameters = {
    "train_dataset_size": len(train_dataset),                                #输入图片的数量
    "batch_size": 64,
    "epoch_num":20,
    "learning_rate":0.0005,
    "eta_min":0.00001,
    "decay_rate":0.02,  #L2正则化参数,过拟合时调大,欠拟合时调小,建议在学习率设置合理的情况下,尝试由小到大2~10倍递增
}
optimizer = paddle.optimizer.Adam(learning_rate=0.0001, parameters=model.parameters())

model.prepare(paddle.optimizer.Adam(learning_rate=paddle.optimizer.lr.PiecewiseDecay(boundaries=[5,10,15], values=[0.0005,0.0001,0.00002,0.00001]), 
                                    parameters=model.parameters(),
                                    weight_decay=paddle.regularizer.L2Decay(train_parameters['decay_rate'])),
              paddle.nn.CrossEntropyLoss(),
              paddle.metric.Accuracy(topk=(1, 5)))

#上述优化器中的学习率(learning_rate)参数很重要。要是训练过程中得到的准确率呈震荡状态,忽大忽小,可以试试进一步把学习率调低。

visualdl=paddle.callbacks.VisualDL(log_dir='visual_log')

model.fit(train_data=train_dataset,     #训练数据集
          eval_data=eval_dataset,         #测试数据集
          epochs=train_parameters['epoch_num'],
          batch_size=train_parameters['batch_size'],
          shuffle=True,#每个EPOCH打乱一次样本,少许提升训练效果
          verbose=1,
          save_dir='./model1/',
          save_freq=2,
          callbacks=[visualdl])

result = model.evaluate(test_dataset, verbose=1)

print(result)

 

 

课程链接:https://aistudio.baidu.com/aistudio/course/introduce/11939?directly=1&shared=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值