要求很简单,给train和test集,训练模型实现图像分类。
这里使用的是残差连接模型,这个平台有预训练好的模型,可以直接拿来主义。
训练十几个迭代,每个批次60左右,准确率达到90%以上
一、导入库,解压文件
pythonimport os import zipfile import random import json import cv2 import numpy as np from PIL import Image import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split import paddle import paddle.nn as nn from paddle.io import Dataset,DataLoader from paddle.nn import \ Layer, \ Conv2D, Linear, \ Embedding, MaxPool2D, \ BatchNorm2D, ReLU import paddle.vision.transforms as transforms from paddle.vision.models import resnet50 from paddle.metric import Accuracy train_parameters = { "input_size": [3, 224, 224], # 输入图片的shape "class_dim": 12, # 分类数 "src_path":"data/data10954/cat_12_train.zip", # 原始数据集路径 "src_test_path":"data/data10954/cat_12_test.zip", # 原始数据集路径 "target_path":"/home/aistudio/data/dataset", # 要解压的路径 "train_list_path": "./train.txt", # train_data.txt路径 "eval_list_path": "./eval.txt", # eval_data.txt路径 "label_dict":{}, # 标签字典 "readme_path": "/home/aistudio/data/readme.json",# readme.json路径 "num_epochs":6, # 训练轮数 "train_batch_size": 16, # 批次的大小 "learning_strategy": { # 优化函数相关的配置 "lr": 0.0005 # 超参数学习率 } } scr_path=train_parameters['src_path'] target_path=train_parameters['target_path'] src_test_path=train_parameters["src_test_path"] z = zipfile.ZipFile(scr_path, 'r') z.extractall(path=target_path) z = zipfile.ZipFile(src_test_path, 'r') z.extractall(path=target_path) z.close() for imgpath in os.listdir(target_path + '/cat_12_train'): src = os.path.join(target_path + '/cat_12_train/', imgpath) img = Image.open(src) if img.mode != 'RGB': img = img.convert('RGB') img.save(src) for imgpath in os.listdir(target_path + '/cat_12_test'): src = os.path.join(target_path + '/cat_12_test/', imgpath) img = Image.open(src) if img.mode != 'RGB': img = img.convert('RGB') img.save(src)
解压后将所有图像变为RGB图像
二、加载训练集,进行预处理、数据增强、格式变换
pythontransform = transforms.Compose([ transforms.Resize(size=224), transforms.ColorJitter(0.2, 0.2, 0.2, 0.2), transforms.RandomHorizontalFlip(), transforms.RandomRotation(15), transforms.RandomResizedCrop(size=224, scale=(0.8, 1.0)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) x_train,x_eval,y_train=[],[],[]#获取训练图像和标签、测试图像和标签 contents=[] with open('data/data10954/train_list.txt')as f: contents=f.read().split('\n') for item in contents: if item=='': continue path='data/dataset/'+item.split('\t')[0] data=np.array(Image.open(path).convert('RGB')) data=np.array(transform(data)) x_train.append(data) y_train.append(int(item.split('\t')[-1])) contetns=os.listdir('data/dataset/cat_12_test') for item in contetns: path='data/dataset/cat_12_test/'+item data=np.array(Image.open(path).convert('RGB')) data=np.array(transform(data)) x_eval.append(data)
重点是transforms变换的预处理
三、划分训练集和测试集
pythonx_train=np.array(x_train) y_train=np.array(y_train) x_eval=np.array(x_eval) x_train,x_test,y_train,y_test=train_test_split(x_train,y_train,test_size=0.2,random_state=42,stratify=y_train) x_train=paddle.to_tensor(x_train,dtype='float32') y_train=paddle.to_tensor(y_train,dtype='int64') x_test=paddle.to_tensor(x_test,dtype='float32') y_test=paddle.to_tensor(y_test,dtype='int64') x_eval=paddle.to_tensor(x_eval,dtype='float32')
这是必要的,可以随时利用测试集查看准确率
四、加载预训练模型,选择损失函数和优化器
pythonlearning_rate=0.001 epochs =5 # 迭代轮数 batch_size = 50 # 批次大小 weight_decay=1e-5 num_class=12 cnn=resnet50(pretrained=True) checkpoint=paddle.load('checkpoint.pdparams') for param in cnn.parameters(): param.requires_grad=False cnn.fc = nn.Linear(2048, num_class) cnn.set_dict(checkpoint['cnn_state_dict']) criterion=nn.CrossEntropyLoss() optimizer = paddle.optimizer.Adam(learning_rate=learning_rate, parameters=cnn.fc.parameters(),weight_decay=weight_decay)
第一次训练把加载模型注释掉即可,优化器包含最后一层全连接的参数
五、模型训练
pythonif x_train.shape[3]==3: x_train=paddle.transpose(x_train,perm=(0,3,1,2)) dataset = paddle.io.TensorDataset([x_train, y_train]) data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True) for epoch in range(epochs): for batch_data, batch_labels in data_loader: outputs = cnn(batch_data) loss = criterion(outputs, batch_labels) print(epoch) loss.backward() optimizer.step() optimizer.clear_grad() print(f"Epoch [{epoch+1}/{epochs}], Loss: {loss.numpy()[0]}")#保存参数 paddle.save({ 'cnn_state_dict': cnn.state_dict(), }, 'checkpoint.pdparams')
使用批处理,这个很重要,不然平台分分钟炸了
六、测试集准确率
pythonnum_class=12 batch_size=64 cnn=resnet50(pretrained=True) checkpoint=paddle.load('checkpoint.pdparams') for param in cnn.parameters(): param.requires_grad=False cnn.fc = nn.Linear(2048, num_class) cnn.set_dict(checkpoint['cnn_state_dict']) cnn.eval() if x_test.shape[3]==3: x_test=paddle.transpose(x_test,perm=(0,3,1,2)) dataset = paddle.io.TensorDataset([x_test, y_test]) data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True) with paddle.no_grad(): score=0 for batch_data, batch_labels in data_loader: predictions = cnn(batch_data) predicted_probabilities = paddle.nn.functional.softmax(predictions, axis=1) predicted_labels = paddle.argmax(predicted_probabilities, axis=1) print(predicted_labels) for i in range(len(predicted_labels)): if predicted_labels[i].numpy()==batch_labels[i]: score+=1 print(score/len(y_test))
设置eval模式,使用批处理测试准确率