代码:
# https://github.com/PacktPublishing/Modern-Computer-Vision-with-PyTorch # https://github.com/PacktPublishing/Modern-Computer-Vision-with-PyTorch################### Chapter Three ######################################## 第三章 读取数据集并显示 from torch.utils.data import Dataset, DataLoader import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt #########################################################################%matplotlib inline device = "cuda" if torch.cuda.is_available() else "cpu" from torchvision import datasets data_folder = '~/data/FMNIST' # This can be any directory you want to # download FMNIST to fmnist = datasets.FashionMNIST(data_folder, download=True, train=True) tr_images = fmnist.data tr_targets = fmnist.targets######################################################################## class FMNISTDataset(Dataset):def __init__(self, x, y):x = x.float()x = x.view(-1,28*28)self.x, self.y = x, ydef __getitem__(self, ix):x, y = self.x[ix], self.y[ix]return x.to(device), y.to(device)def __len__(self):return len(self.x) ######################################################################## def get_data():train = FMNISTDataset(tr_images, tr_targets)trn_dl = DataLoader(train, batch_size=32, shuffle=True)return trn_dl ########################################################################from torch.optim import SGD def get_model():model = nn.Sequential(nn.Linear(28 * 28, 1000),nn.ReLU(),nn.Linear(1000, 10)).to(device)loss_fn = nn.CrossEntropyLoss()optimizer = SGD(model.parameters(), lr=1e-2)return model, loss_fn, optimizer ######################################################################## def train_batch(x, y, model, opt, loss_fn):model.train() # <- let's hold on to this until we reach dropout section# call your model like any python function on your batch of inputsprediction = model(x)# compute lossbatch_loss = loss_fn(prediction, y)# based on the forward pass in `model(x)` compute all the gradients of# 'model.parameters()' batch_loss.backward()# apply new-weights = f(old-weights, old-weight-gradients) where# "f" is the optimizer opt.step()# Flush gradients memory for next batch of calculations opt.zero_grad()return batch_loss.item()######################################################################## def accuracy(x, y, model):model.eval() # <- let's wait till we get to dropout section# get the prediction matrix for a tensor of `x` imagesprediction = model(x)# compute if the location of maximum in each row coincides# with ground truthmax_values, argmaxes = prediction.max(-1)is_correct = argmaxes == yreturn is_correct.cpu().numpy().tolist() ######################################################################## trn_dl = get_data() print(trn_dl) model, loss_fn, optimizer = get_model() # ######################################################################## losses, accuracies = [], [] for epoch in range(5):print(epoch)epoch_losses, epoch_accuracies = [], []for ix, (x, y) in enumerate(iter(trn_dl)):#x, y = batchprint("++++++++++++++++++++++++++++++++++++++++++++++")print(ix,x,y)batch_loss = train_batch(x, y, model, optimizer, loss_fn)epoch_losses.append(batch_loss)epoch_loss = np.array(epoch_losses).mean()for ix, batch in enumerate(iter(trn_dl)):x, y = batchis_correct = accuracy(x, y, model)epoch_accuracies.extend(is_correct)epoch_accuracy = np.mean(epoch_accuracies)losses.append(epoch_loss)accuracies.append(epoch_accuracy) # ######################################################################## # epochs = np.arange(5)+1 plt.figure(figsize=(20,5)) plt.subplot(121) plt.title('Loss value over increasing epochs') plt.plot(epochs, losses, label='Training Loss') plt.legend() plt.subplot(122) plt.title('Accuracy value over increasing epochs') plt.plot(epochs, accuracies, label='Training Accuracy') #plt.gca().set_yticklabels(['{:.0f}%'.format(x*100) for x in plt.gca().get_yticks()]) plt.legend() plt.show()
文心一言修改后的代码
# 导入必要的库 from torch.utils.data import Dataset, DataLoader import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt# 设置设备为CUDA(如果可用)或CPU device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 下载FashionMNIST数据集 import torchvision from torchvision import datasetsdata_folder = '~/data/FMNIST' # 数据集下载目录 fmnist = datasets.FashionMNIST(data_folder, download=True, train=True, transform= torchvision.transforms.ToTensor()) tr_images, tr_targets = fmnist.data, fmnist.targets# 自定义FashionMNIST数据集类 class FMNISTDataset(Dataset):def __init__(self, images, targets):# 将图像数据转换为浮点型,并展平self.images = images.float().view(-1, 28 * 28)self.targets = targetsdef __getitem__(self, index):# 根据索引获取图像和标签,并移动到指定设备image, target = self.images[index], self.targets[index]return image.to(device), target.to(device)def __len__(self):# 返回数据集的大小return len(self.images)# 获取数据加载器 def get_data():dataset = FMNISTDataset(tr_images, tr_targets)data_loader = DataLoader(dataset, batch_size=32, shuffle=True)return data_loader# 获取模型、损失函数和优化器 def get_model():model = nn.Sequential(nn.Linear(28 * 28, 1000),nn.ReLU(),nn.Linear(1000, 10)).to(device)loss_fn = nn.CrossEntropyLoss()optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 使用更常见的写法return model, loss_fn, optimizer# 训练一个批次的数据 def train_batch(images, targets, model, optimizer, loss_fn):model.train() # 设置模型为训练模式outputs = model(images) # 前向传播loss = loss_fn(outputs, targets) # 计算损失optimizer.zero_grad() # 清零梯度loss.backward() # 反向传播optimizer.step() # 更新权重return loss.item()# 计算准确率 def calculate_accuracy(images, targets, model):model.eval() # 设置模型为评估模式with torch.no_grad(): # 禁用梯度计算outputs = model(images)_, predicted = torch.max(outputs, 1)is_correct = (predicted == targets).cpu().numpy()return is_correct.tolist()# 主训练循环 trn_dl = get_data() model, loss_fn, optimizer = get_model()losses, accuracies = [], [] for epoch in range(5):epoch_losses, epoch_accuracies = [], []for images, targets in trn_dl: # 直接迭代DataLoaderbatch_loss = train_batch(images, targets, model, optimizer, loss_fn)epoch_losses.append(batch_loss)epoch_loss = np.mean(epoch_losses)# 注意:这里不应该再次迭代DataLoader来计算准确率,因为这样会打乱数据顺序# 为了简化,我们只在每个epoch结束时使用一小部分数据来计算准确率(不推荐这样做,仅用于演示)# 正确的做法是使用一个验证集或者在每个epoch结束时不打乱数据地计算整个训练集的准确率# 但为了保持示例的简洁性,我们仍然这样做 with torch.no_grad():model.eval() # 设置模型为评估模式(虽然在这个简化的例子中不是必需的,因为我们已经禁用了梯度)# 假设我们只使用前100个批次的数据来计算准确率(这只是一个示例,不推荐这样做)for i in range(100): # 注意:这里应该有一个更好的方法来处理,比如使用验证集images, targets = next(iter(trn_dl)) # 小心:这会改变DataLoader的状态!if i >= len(trn_dl): # 如果已经迭代完,则重新迭代(但这在真实场景中是不推荐的)trn_dl = get_data() # 重新获取数据加载器(不推荐)# 更好的做法是使用一个固定的验证集is_correct = calculate_accuracy(images, targets, model)epoch_accuracies.extend(is_correct)epoch_accuracy = np.mean(epoch_accuracies)losses.append(epoch_loss)accuracies.append(epoch_accuracy)# 绘制损失和准确率曲线 epochs = np.arange(1, 6) # 正确的epoch范围 plt.figure(figsize=(20, 5)) plt.subplot(1, 2, 1) plt.title('Loss over Epochs') plt.plot(epochs, losses, label='Training Loss') plt.legend() plt.subplot(1, 2, 2) plt.title('Accuracy over Epochs') plt.plot(epochs, accuracies, label='Training Accuracy') plt.legend() plt.show()