改进了训练cifar10的第一个pytorch程序(很简单的那种):

我的第一个pytorch人工智能程序(最简单而高效的方式)-CSDN博客

下面看代码:#50轮,47分,改进后50轮54分

import torch
#import tqdm
from torchvision import datasets
from torchvision import transforms
from torch.utils.data import DataLoader
import torch.optim
import time

batch_size = 64
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 注意不要放到 前面

# 1 数据
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),  #先四周填充0,再把图像随机裁剪成32*32
    transforms.RandomHorizontalFlip(),  #图像一半的概率翻转,一半的概率不翻转
    transforms.ToTensor(),
    transforms.Normalize((0, 0, 0), (1, 1, 1)), #R,G,B每层的归一化用到的均值和方差
])
transform = transforms.Compose([
    transforms.ToTensor(),
   # transforms.Normalize( (0.1307,), (0.3081,) )
    transforms.Normalize((0, 0, 0), (1,1, 1))
])


train_set = datasets.CIFAR100(root = './data',
                              train=True,
                              transform = transform_train,
                              download=True)

test_set =datasets.CIFAR100(root = './data',
                            train=False,
                            transform= transform,
                            download=True)
train_loader = DataLoader( train_set, shuffle=True, batch_size=batch_size)
test_loader = DataLoader( test_set, shuffle=False, batch_size=batch_size)
# 2 模型
class ResidualBlock( torch.nn.Module ):
    def __init__(self, channels):
        super( ResidualBlock, self).__init__()
        self.Conv1 = torch.nn.Conv2d( channels, channels, kernel_size=(3, 3), padding=1)
        self.Conv2 = torch.nn.Conv2d( channels, channels, kernel_size=(3, 3), padding=1)
      
        self.relu=torch.nn.LeakyReLU()
      
    def forward(self, x):
        y = self.relu((self.Conv1(x) ))
        y = (self.Conv2(y))
       
        return self.relu( y+x )

class Model( torch.nn.Module ):
    def __init__(self):
        super( Model, self).__init__()
        self.conv1 = torch.nn.Conv2d( 3, 32, kernel_size=(3,3) , padding=1)
      
        self.conv2 = torch.nn.Conv2d( 32, 64,kernel_size=(3,3) , padding=1 )
       
       
     
        
       
        self.relu=torch.nn.LeakyReLU()
        self.resblk1 = ResidualBlock(32)
        self.resblk2 = ResidualBlock(64)
        self.pool = torch.nn.MaxPool2d(2)
       
        self.out = torch.nn.Linear(4096*4,100)
      
        
    def forward(self, x):      
   
        x =  self.relu( (self.conv1(x) ) )
        x = self.resblk1(x)
       
        x = self.pool( self.relu( (self.conv2(x) ) ))
        x = self.resblk2(x)
       
       # x = self.pool(x) 
        x=x.view(x.size(0),-1)
        x=self.out(x)
        return x
  

# 3 训练
train_loss = []
train_accuracy = []
model = Model()
model.to(device)
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD( model.parameters(), lr=0.01, momentum=0.5, weight_decay=5e-4)

def train( epoch):
    L = 0.0
    total = 0
    correct = 0
   # for index, data in enumerate( tqdm.tqdm( train_loader), start=0 ):
    for index, data in enumerate(train_loader, start=0):
        x, y = data
        x = x.to(device) # 记得前面的”x = “否则没转换
        y = y.to(device)
        y_ = model(x)
        _, predicted = torch.max(y_.data, dim=1)
        loss = criterion( y_, y )
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()        
      
        L += loss.data.item() # loss是tensor,想让L保持float所以要写成loss.data.item()
        total += y.size(0)
        correct += (predicted == y).sum().item()
    acc = (100 * correct / total)
    print('Accuracy on train set: %d %%' % acc)
    train_accuracy.append(acc)
    L /= batch_size
    train_loss.append(L) # L已经是float了,不需要再加.data.item()
    print('[%d-th] loss: %.3f' % (epoch, L) )
    if epoch == 20:
      for param_group in optimizer.param_groups:
          param_group['lr'] *= 0.1
    if epoch == 40:
       for param_group in optimizer.param_groups:
           param_group['lr'] *= 0.1

def test():
    total = 0
    correct = 0
    with torch.no_grad():
        for data in test_loader:
            x, y = data
            x = x.to(device)
            y = y.to(device)
            y_head = model(x)
            _, predicted = torch.max(y_head.data, dim=1)
            total += y.size(0)
            correct += (predicted == y).sum().item()
    print( 'Accuracy on test set: %d %%' % (100*correct/total))

if __name__ == '__main__':
   
    for epoch in range(50):
        time_start = time.perf_counter()
        train(epoch)
        print('%f s' % (time.perf_counter() - time_start))
    test()
  
    PATH = './cifar_ResNet_simple100.pth'
    torch.save(model.state_dict(), PATH)#50轮,47分,改进后50轮54分

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐