【发布时间】:2021-09-07 07:38:31
【问题描述】:
我想构建一个类似于本文中的 CNN:https://arxiv.org/abs/1603.08511 (https://richzhang.github.io/colorization/)。 作为数据,我从 LAB - 颜色空间获得了图像。我为这些 l 和 a、b 值编写了一个数据加载器,并将 l 值作为我的神经网络的输入,并将 a、b 值作为标签。 我在标准损失函数中收到错误“仅支持一批空间目标(3D 张量),但目标大小为:: [1, 2, 64, 64]”。 我将作为“标签”插入到标准()方法中的内容存在问题。但是标签的尺寸对我来说似乎是正确的:[1, 2, 64, 64] --> [batch_size, in_channels (a,b), width, heigth]。 我将 batch_size 设置为 1 以查看它是否正常工作。我尝试使用 pytorch.squeeze() 仅削减 batch_size 维度,但它没有用。我不明白为什么我不能将这种形状和大小的向量放入标准()函数。任何帮助表示赞赏!我的代码如下:
#importing the libraries
import numpy as np
import pandas as pd
from numpy import random
# for creating validation set
from sklearn.model_selection import train_test_split
# PyTorch libraries and modules
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import transforms
from torch.autograd import Variable
from torch.nn import Linear, ReLU, CrossEntropyLoss, Sequential, Conv2d, MaxPool2d, Module, Softmax, BatchNorm2d, Dropout
from torch.optim import Adam, SGD
from torch.utils.data import Dataset, DataLoader
from torchvision import datasets
from torch.utils.data.sampler import SubsetRandomSampler
from typing import Any, Tuple
# set device
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# define local paths
L_path = 'l/gray_scale.npy'
ab1_path = 'ab/ab/ab1.npy'
ab2_path = 'ab/ab/ab2.npy'
ab3_path = 'ab/ab/ab3.npy'
image_size = 64
class ColorDataset(Dataset):
def __init__(self, transformations=None, seed=42) -> None:
if transformations is None:
self.transformations = transforms.Compose([
transforms.ToPILImage(),
transforms.Resize(image_size),
transforms.ToTensor()
])
else:
self.transformations = transformations
self.seed = seed
self.L = np.load(L_path)
self.L = np.expand_dims(self.L, -1)
# self.L = self.L.transpose((0, 3, 1, 2))
self.ab = np.concatenate([
np.load(ab1_path),
np.load(ab2_path),
np.load(ab3_path)
], axis=0)
# self.ab = self.ab.transpose((0, 3, 1, 2))
print("All inputs loaded")
def __len__(self) -> int:
return len(self.L)
def __getitem__(self, index: int) -> Tuple[Any, Any]:
random.seed(self.seed)
L = self.transformations(self.L[index])
random.seed(self.seed)
ab = self.transformations(self.ab[index])
return L, ab
# initialize dataset
dataset = ColorDataset()
dataset_size = len(dataset)
# set relative test size (for split)
test_size = 0.3
indices = list(range(dataset_size))
np.random.shuffle(indices)
split = int(np.floor(test_size * dataset_size))
train_index, test_index = indices[split:], indices[:split]
train_sampler = SubsetRandomSampler(train_index)
test_sampler = SubsetRandomSampler(test_index)
# set batch size
batch_size = 1
train_loader = DataLoader(dataset, batch_size=batch_size, sampler=train_sampler, num_workers=0)
test_loader = DataLoader(dataset, batch_size=batch_size, sampler=test_sampler, num_workers=0)
# Network
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1_1 = nn.Conv2d(1, 64, 1)
self.conv1_2 = nn.Conv2d(64, 64, 1)
self.batch_norm_1 = nn.BatchNorm2d(64)
self.conv2_1 = nn.Conv2d(64, 128, 1, 2)
self.conv2_2 = nn.Conv2d(128, 128, 1)
self.batch_norm_2 = nn.BatchNorm2d(128)
self.conv3_1 = nn.Conv2d(128, 256, 1, 2)
self.conv3_2 = nn.Conv2d(256, 256, 1)
self.conv3_3 = nn.Conv2d(256, 256, 1)
self.batch_norm_3 = nn.BatchNorm2d(256)
self.conv4_1 = nn.Conv2d(256, 512, 1, 2)
self.conv4_2 = nn.Conv2d(512, 512, 1)
self.conv4_3 = nn.Conv2d(512, 512, 1)
self.batch_norm_4 = nn.BatchNorm2d(512)
self.conv5_1 = nn.Conv2d(512, 512, 1)
self.conv5_2 = nn.Conv2d(512, 512, 1)
self.conv5_3 = nn.Conv2d(512, 512, 1)
self.batch_norm_5 = nn.BatchNorm2d(512)
self.conv6_1 = nn.Conv2d(512, 512, 1)
self.conv6_2 = nn.Conv2d(512, 512, 1)
self.conv6_3 = nn.Conv2d(512, 512, 1)
self.batch_norm_6 = nn.BatchNorm2d(512)
self.conv7_1 = nn.Conv2d(512, 256, 1)
self.conv7_2 = nn.Conv2d(256, 256, 1)
self.conv7_3 = nn.Conv2d(256, 256, 1)
self.batch_norm_7 = nn.BatchNorm2d(256)
self.conv8_1 = nn.Conv2d(256, 128, 1)
self.conv8_2 = nn.Conv2d(128, 128, 1, 1)
self.conv8_3 = nn.Conv2d(128, 128, 1)
#define forward pass
def forward(self, x):
# Pass data through conv1_1
x = self.conv1_1(x)
# Use the rectified-linear activation function over x
x = F.relu(x)
x = self.conv1_2(x)
x = F.relu(x)
#batch normalization
x = self.batch_norm_1(x)
x = self.conv2_1(x)
x = F.relu(x)
x = self.conv2_2(x)
x = F.relu(x)
#batch normalization
x = self.batch_norm_2(x)
x = self.conv3_1(x)
x = F.relu(x)
x = self.conv3_2(x)
x = F.relu(x)
x = self.conv3_3(x)
#batch normalization
x = self.batch_norm_3(x)
x = self.conv4_1(x)
x = F.relu(x)
x = self.conv4_2(x)
x = F.relu(x)
x = self.conv4_3(x)
#batch normalization
x = self.batch_norm_4(x)
x = self.conv5_1(x)
x = F.relu(x)
x = self.conv5_2(x)
x = F.relu(x)
x = self.conv5_3(x)
#batch normalization
x = self.batch_norm_5(x)
x = self.conv6_1(x)
x = F.relu(x)
x = self.conv6_2(x)
x = F.relu(x)
x = self.conv6_3(x)
#batch normalization
x = self.batch_norm_6(x)
x = self.conv7_1(x)
x = F.relu(x)
x = self.conv7_2(x)
x = F.relu(x)
x = self.conv7_3(x)
#batch normalization
x = self.batch_norm_7(x)
x = self.conv8_1(x)
x = F.relu(x)
x = self.conv8_2(x)
x = F.relu(x)
x = self.conv8_3(x)
return x
model = Net()
optimizer = Adam(model.parameters(), lr=0.07)
# defining the loss function
criterion = CrossEntropyLoss()
# checking if GPU is available
if torch.cuda.is_available():
model = model.cuda()
criterion = criterion.cuda()
#labels und output des netzwerks in criterion
def train(epoch):
model.train()
train_loss = 0
# train the model
model.train() # prep model for training
for data, label in train_loader:
data = data.to('cuda')
label = label.to('cuda')
print(label.size())
# clear the gradients of all optimized variables
optimizer.zero_grad()
#forward pass: compute predicted outputs by passing inputs to the model
output = model(data)
# calculate the loss
label = label.long() #convert label to long since in criterion long is expected
loss = criterion(output, label) #l value is data, ab values are labels
# backward pass: compute gradient of the loss with respect to model parameters
loss.backward()
# perform a single optimization step (parameter update)
optimizer.step()
# update running training loss
train_loss += loss.item() * data.size(0)
# calculate average loss over an epoch
train_loss = train_loss / len(train_loader.sampler)
# printing the loss
print('Epoch : ', epoch+1, '\t', 'loss :', train_loss)
# defining number of epochs
n_epochs = 1
# empty list to store training losses (actually not used)
train_losses = []
# training the model
for epoch in range(n_epochs):
train(epoch)
这里是错误:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-25-c26ffccd8f7e> in <module>
250 # training the model
251 for epoch in range(n_epochs):
--> 252 train(epoch)
<ipython-input-25-c26ffccd8f7e> in train(epoch)
224 label = label.long() #convert label to long since in criterion long is expected
225 print(label.size())
--> 226 loss = criterion(output, label) #l value is data, ab values are labels
227 # backward pass: compute gradient of the loss with respect to model parameters
228 loss.backward()
~\anaconda3\lib\site-packages\torch\nn\modules\module.py in _call_impl(self, *input, **kwargs)
725 result = self._slow_forward(*input, **kwargs)
726 else:
--> 727 result = self.forward(*input, **kwargs)
728 for hook in itertools.chain(
729 _global_forward_hooks.values(),
~\anaconda3\lib\site-packages\torch\nn\modules\loss.py in forward(self, input, target)
960 def forward(self, input: Tensor, target: Tensor) -> Tensor:
961 return F.cross_entropy(input, target, weight=self.weight,
--> 962 ignore_index=self.ignore_index, reduction=self.reduction)
963
964
~\anaconda3\lib\site-packages\torch\nn\functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction)
2466 if size_average is not None or reduce is not None:
2467 reduction = _Reduction.legacy_get_string(size_average, reduce)
-> 2468 return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
2469
2470
~\anaconda3\lib\site-packages\torch\nn\functional.py in nll_loss(input, target, weight, size_average, ignore_index, reduce, reduction)
2264 ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
2265 elif dim == 4:
-> 2266 ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
2267 else:
2268 # dim == 3 or dim > 4
RuntimeError: 1only batches of spatial targets supported (3D tensors) but got targets of size: : [1, 2, 64, 64]
【问题讨论】:
标签: python deep-learning neural-network pytorch conv-neural-network