PyTorch 数据集变换标准化 nb_samples += batch_samples IndexError: Dimension out of range (预计在 [-2, 1] 范围内,但得到 2)

发布于 2025-01-13 01:05:09 字数 3084 浏览 0 评论 0原文

目标:找到要在 data_transformstransforms.Normalize 部分中使用的均值和标准张量

疑问:我们是否需要为每个训练集、验证集和测试集提供三个不同的均值和标准张量?

错误:不确定如何将 PyTorch 论坛中的代码应用到我的数据加载器。下面是错误和代码。

我的图像不是自然图像,我计划使用 Inception V3 预训练的 ImageNet 进行微调。

我有来自 PyTorch 的此代码(进行了一些轻微的修改/添加)培训和Piotr 的代码在这里。但是,我收到一个错误:


# Create training and validation datasets
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val', 'test']}
# Create training and validation dataloaders
print('batch size: ', batch_size)
dataloaders_dict = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True, num_workers=4) for x in ['train', 'val', 'test']}
mean = 0.
std = 0.
nb_samples = 0.
for data in dataloaders_dict['train']:
    print(print(len(data)))
    print("data[0] shape: ", data[0].shape)
    batch_samples = data[0].size(0)
    
    data = data[0].view(batch_samples, data[0].size(1), -1)
    mean += data[0].mean(2).sum(0)
    std += data[0].std(2).sum(0)
    nb_samples += batch_samples

mean /= nb_samples
std /= nb_samples

我假设,我还需要对 dataloaders_dict['val'] 和 dataloaders_dict['test'] 使用与上面类似的代码。如果我错了,请纠正我。无论如何,错误是:

batch size:  512
2
None
data[0] shape:  torch.Size([512, 3, 299, 299])


 IndexError Traceback (most recent call last) Input In [19], in <module> **24** batch_samples = data[0].size(0) **26** data = data[0].view(batch_samples, data[0].size(1), -1) ---> 27 mean += data[0].mean(2).sum(0) **28** std += data[0].std(2).sum(0) **29** nb_samples += batch_samples IndexError: Dimension out of range (expected to be in range of [-2, 1], but got 2)

在此处输入图像描述

目前,我已经评论了数据转换的“标准化”部分,并仅将其用于调整内容大小。如果我们的初始目标是计算平均值和标准张量,我不确定数据转换到底应该是什么样子。如果有错请告诉我。

input_size = 299 # for Inception V3

data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(input_size),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        #transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(input_size),
        transforms.CenterCrop(input_size),
        transforms.ToTensor(),
        #transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    
    'test': transforms.Compose([
        transforms.Resize(input_size),
        transforms.CenterCrop(input_size),
        transforms.ToTensor(),
        #transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
}

Goal: find the mean and std tensors to use in transforms.Normalize part of data_transforms

Doubt: do we need to have three different mean and std tensors for each of the train, val, and test sets?

Error: not sure how to apply the code in PyTorch forum to my dataloader. Below is the error and code.

I have images that are not natural images and I am planning to use Inception V3 pretrained ImageNet for fine-tuning.

I have this code (with some slight modification/addition) from PyTorch training and Piotr's code here. However, I get an error:


# Create training and validation datasets
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val', 'test']}
# Create training and validation dataloaders
print('batch size: ', batch_size)
dataloaders_dict = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True, num_workers=4) for x in ['train', 'val', 'test']}
mean = 0.
std = 0.
nb_samples = 0.
for data in dataloaders_dict['train']:
    print(print(len(data)))
    print("data[0] shape: ", data[0].shape)
    batch_samples = data[0].size(0)
    
    data = data[0].view(batch_samples, data[0].size(1), -1)
    mean += data[0].mean(2).sum(0)
    std += data[0].std(2).sum(0)
    nb_samples += batch_samples

mean /= nb_samples
std /= nb_samples

I assume, I need to use similar code as above for also dataloaders_dict['val'] and dataloaders_dict['test']. Please correct me if I am wrong. Anyhow, the error is:

batch size:  512
2
None
data[0] shape:  torch.Size([512, 3, 299, 299])


 IndexError Traceback (most recent call last) Input In [19], in <module> **24** batch_samples = data[0].size(0) **26** data = data[0].view(batch_samples, data[0].size(1), -1) ---> 27 mean += data[0].mean(2).sum(0) **28** std += data[0].std(2).sum(0) **29** nb_samples += batch_samples IndexError: Dimension out of range (expected to be in range of [-2, 1], but got 2)

enter image description here

For now, I have commented the "Normalize" part of data transform and using it only for resizing matter. I am not sure how exactly Data Transform should look like if we have the initial goal of calculating mean and std tensors. Please let me know if it is wrong.

input_size = 299 # for Inception V3

data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(input_size),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        #transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(input_size),
        transforms.CenterCrop(input_size),
        transforms.ToTensor(),
        #transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    
    'test': transforms.Compose([
        transforms.Resize(input_size),
        transforms.CenterCrop(input_size),
        transforms.ToTensor(),
        #transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深海夜未眠 2025-01-20 01:05:09
def get_mean_std(loader):
    # VAR[X] = E[X**2] - E[X]**2
    channels_sum, channels_squared_sum, num_batches = 0, 0, 0
    for data, _ in loader:
        channels_sum += torch.mean(data, dim=[0,2,3])
        channels_squared_sum += torch.mean(data**2, dim=[0,2,3])
        num_batches += 1
    
    mean = channels_sum/num_batches
    std = (channels_squared_sum/num_batches - mean**2)**0.5
    return mean, std
train_mean, train_std = get_mean_std(dataloaders_dict['train'])
print(train_mean, train_std)

张量([0.7031, 0.5487, 0.6750]) 张量([0.2115, 0.2581, 0.1952])

test_mean, test_std = get_mean_std(dataloaders_dict['test'])
print(test_mean, test_std)

张量([0.7048, 0.5509, 0.6763]) 张量([0.2111, 0.2576, 0.1979])

val_mean, val_std = get_mean_std(dataloaders_dict['val'])
print(val_mean, val_std)

张量([0.7016, 0.5549, 0.6784]) 张量([0.2099, 0.2583, 0.1998])

取自此 YouTube 教程

def get_mean_std(loader):
    # VAR[X] = E[X**2] - E[X]**2
    channels_sum, channels_squared_sum, num_batches = 0, 0, 0
    for data, _ in loader:
        channels_sum += torch.mean(data, dim=[0,2,3])
        channels_squared_sum += torch.mean(data**2, dim=[0,2,3])
        num_batches += 1
    
    mean = channels_sum/num_batches
    std = (channels_squared_sum/num_batches - mean**2)**0.5
    return mean, std
train_mean, train_std = get_mean_std(dataloaders_dict['train'])
print(train_mean, train_std)

tensor([0.7031, 0.5487, 0.6750]) tensor([0.2115, 0.2581, 0.1952])

test_mean, test_std = get_mean_std(dataloaders_dict['test'])
print(test_mean, test_std)

tensor([0.7048, 0.5509, 0.6763]) tensor([0.2111, 0.2576, 0.1979])

val_mean, val_std = get_mean_std(dataloaders_dict['val'])
print(val_mean, val_std)

tensor([0.7016, 0.5549, 0.6784]) tensor([0.2099, 0.2583, 0.1998])

Took from this YouTube tutorial

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文