Как использовать AlexNet с одним каналом
Я новичок в pytorch и имел проблемы с каналами в AlexNet. Я использую его для проекта "gta san andreas self car car", я собрал набор данных из черно-белого изображения с одним каналом и пытаюсь обучить AlexNet с помощью сценария:
from AlexNetPytorch import*
import torchvision
import torchvision.transforms as transforms
import torch.optim as optim
import torch.utils.data
import numpy as np
import torch
from IPython.core.debugger import set_trace
AlexNet = AlexNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(AlexNet.parameters(), lr=0.001, momentum=0.9)
all_data = np.load('training_data.npy')
inputs= all_data[:,0]
labels= all_data[:,1]
inputs_tensors = torch.stack([torch.Tensor(i) for i in inputs])
labels_tensors = torch.stack([torch.Tensor(i) for i in labels])
data_set = torch.utils.data.TensorDataset(inputs_tensors,labels_tensors)
data_loader = torch.utils.data.DataLoader(data_set, batch_size=3,shuffle=True, num_workers=2)
if __name__ == '__main__':
for epoch in range(8):
runing_loss = 0.0
for i,data in enumerate(data_loader , 0):
inputs= data[0]
inputs = torch.FloatTensor(inputs)
labels= data[1]
labels = torch.FloatTensor(labels)
optimizer.zero_grad()
# set_trace()
inputs = torch.unsqueeze(inputs, 1)
outputs = AlexNet(inputs)
loss = criterion(outputs , labels)
loss.backward()
optimizer.step()
runing_loss +=loss.item()
if i % 2000 == 1999: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('finished')
Я использую AlexNet по ссылке: https://github.com/pytorch/vision/blob/master/torchvision/models/alexnet.py
Но изменилась строка 18 из:
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2)
Кому:
nn.Conv2d(1, 64, kernel_size=11, stride=4, padding=2)
Потому что я использую только один канал в обучающих изображениях, но я получаю эту ошибку:
File "training_script.py", line 44, in <module>
outputs = AlexNet(inputs)
File "C:\Users\Mukhtar\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 477, in __call__
result = self.forward(*input, **kwargs)
File "C:\Users\Mukhtar\Documents\AI_projects\gta\AlexNetPytorch.py", line 34, in forward
x = self.features(x)
File "C:\Users\Mukhtar\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 477, in __call__
result = self.forward(*input, **kwargs)
File "C:\Users\Mukhtar\Anaconda3\lib\site-packages\torch\nn\modules\container.py", line 91, in forward
input = module(input)
File "C:\Users\Mukhtar\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 477, in __call__
result = self.forward(*input, **kwargs)
File "C:\Users\Mukhtar\Anaconda3\lib\site-packages\torch\nn\modules\pooling.py", line 142, in forward
self.return_indices)
File "C:\Users\Mukhtar\Anaconda3\lib\site-packages\torch\nn\functional.py", line 396, in max_pool2d
ret = torch._C._nn.max_pool2d_with_indices(input, kernel_size, stride, padding, dilation, ceil_mode)
RuntimeError: Given input size: (256x1x1). Calculated output size: (256x0x0). Output size is too small at c:\programdata\miniconda3\conda-bld\pytorch-cpu_1532499824793\work\aten\src\thnn\generic/SpatialDilatedMaxPooling.c:67
Я не знаю, что не так, это неправильно, чтобы изменить размер канала, как это, и если это не так, не могли бы вы привести меня к нейронной сети, которая работает с одним каналом, как я сказал, что я новичок в Pytorch и Я не хочу писать nn сам.
2 ответа
Ваша ошибка не связана с использованием полутоновых изображений вместо RGB. Ваша ошибка связана с пространственными размерами входных данных: при "пересылке" входного изображения через сетку его размер (в пространстве объектов) становится равным нулю - это ошибка, которую вы видите. Вы можете использовать это хорошее руководство, чтобы увидеть, что происходит с выходным размером каждого слоя (conv/pooling) в зависимости от размера ядра, шага и заполнения.
Alexnet ожидает, что его входные изображения будут 224 на 224 пикселя - убедитесь, что ваши входные данные имеют одинаковый размер.
Другие вещи, которые вы упустили из виду:
Вы используете архитектуру Alexnet, но вы инициализируете ее случайными весами вместо использования предварительно обученных весов (обученных на imagenet). Чтобы получить обученную копию alexnet, вам нужно создать такую сеть
AlexNet = alexnet(pretrained=True)
Как только вы решите использовать предварительно обученную сеть, вы не сможете изменить ее первый слой с 3-х входных каналов на три (обученный вес просто не подойдет). Самый простой способ - сделать ваши входные изображения "красочными", просто повторяя один канал три раза. Увидеть
repeat()
для получения дополнительной информации.
Проблема была с размером моего ввода, я дал ему (32x32), когда я должен был дать ему (224x224) - я новичок в AlexNet, поэтому я не знал, что он принимает этот размер -. Я изменил свои изображения в (224x224), и теперь я тренирую CNN.