Pytorch 学习(二十五)---高级DataLoader技巧----每次返回的Tensor的size可以任意

默认的PyTorch DataLoader返回的Tensor尺寸固定,但有时我们需要处理尺寸变化的数据。文中讨论了如何避免对数据进行不必要的padding,提出了在DataLoader中使用自定义collate函数来实现每次返回Tensor的size可变,以适应不同大小的通道数需求。
摘要由CSDN通过智能技术生成

总说

大家都知道,默认的DataLoader每次返回的Tensor的尺寸都是固定的,因为batchsize>1时,默认需要stack一下,比如__getitem__()返回的图片return img,其中img是 CHW, 你在外面拿到就是 N*C*H*W了。因为,默认return torch.stack(batch, 0, out=out)了一下。如果每次img图片不一样,就会出错。

有些人会说,我直接设置一个数据集最大的HW呗,这样我们不管图片多大,全部pad成那么大,然后记录一下每张图片的hw,再返回return padded_img, h, w。再在外面进行相应的处理。

但是有些情况,就是有时候每次返回的tensor通道很大,上千上万的吧,有时候通道就很小。类似这样的情况,即每次返回的tensor的size相差很大!这时候,你肯定不愿意直接pad成最大的吧。我们希望,当拿到batch所有数据后,不是默认的直接stack,而是自己处理一些size不匹配的tensor

我们希望可以这样写:

class TrainDataset
首先,你需要导入 PyTorch 库: ```python import torch import torch.nn as nn import torch.optim as optim ``` 然后,定义一个继承自 nn.Module 的 CNN-LSTM 模型类,该类由两个子模块组成:一个卷积神经网络和一个长短时记忆网络。 ```python class CNN_LSTM(nn.Module): def __init__(self, num_classes): super(CNN_LSTM, self).__init__() self.cnn = nn.Sequential( nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2) ) self.lstm = nn.LSTM(input_size=64, hidden_size=128, num_layers=2, batch_first=True) self.fc = nn.Linear(128, num_classes) def forward(self, x): x = self.cnn(x) x = x.reshape(x.size(0), -1, 64) out, (h_n, c_n) = self.lstm(x) out = self.fc(out[:, -1, :]) return out ``` 在上面的代码中,我们定义了一个 CNN_LSTM 类,该类包含三个主要的组件: 1. CNN:由三个卷积层和三个最大池化层组成的卷积神经网络,用于从图像中提取特征。 2. LSTM:一个具有两个隐藏层和 128 个隐藏单元的 LSTM,用于学习序列数据之间的依赖关系。 3. 全连接层:将 LSTM 输出转换成模型预测的类别。 最后,我们可以定义模型的超参数并进行训练。 ```python # 定义超参数 num_classes = 10 learning_rate = 0.001 batch_size = 64 num_epochs = 10 # 加载数据集 train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, transform=transforms.ToTensor(), download=True) train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True) test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, transform=transforms.ToTensor()) test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False) # 实例化模型 model = CNN_LSTM(num_classes) # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate) # 训练模型 total_step = len(train_loader) for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): images = images.permute(0, 2, 3, 1) # 调整图像维度 outputs = model(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() if (i+1) % 100 == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, total_step, loss.item())) # 测试模型 model.eval() with torch.no_grad(): correct = 0 total = 0 for images, labels in test_loader: images = images.permute(0, 2, 3, 1) outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the model on the test images: {} %'.format(100 * correct / total)) ``` 在上面的代码中,我们首先加载 CIFAR-10 数据集并实例化 CNN-LSTM 模型。然后,我们定义了损失函数和优化器,并在训练过程中进行了模型的优化。最后,我们使用测试数据集对模型进行评估并输出准确率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值