要求很简单,给train和test集,训练模型实现图像分类。
这里使用的是残差连接模型,这个平台有预训练好的模型,可以直接拿来主义。
训练十几个迭代,每个批次60左右,准确率达到90%以上
- import 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图像
- transform = 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变换的预处理
- x_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')
这是必要的,可以随时利用测试集查看准确率
- learning_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)
第一次训练把加载模型注释掉即可,优化器包含最后一层全连接的参数
- if 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')
使用批处理,这个很重要,不然平台分分钟炸了
- num_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模式,使用批处理测试准确率