#python #deep-learning #torchvision
#python #глубокое обучение #torchvision
Вопрос:
Я пытаюсь запустить следующий код, который сообщал о хорошей работе с другими пользователями, но я обнаружил эту ошибку.
— кодирование: utf-8 ——
Импортируйте материал
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils import data
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import cv2
import numpy as np
import csv
Шаг 1: считывание из файла журнала
samples = []
with open('data/driving_log.csv') as csvfile:
reader = csv.reader(csvfile)
next(reader, None)
for line in reader:
samples.append(line)
Шаг 2: разделите данные на обучающий набор и набор проверки
train_len = int(0.8*len(samples))
valid_len = len(samples) - train_len
train_samples, validation_samples = data.random_split(samples, lengths=[train_len, valid_len])
Шаг 3a: определите процессы увеличения, преобразования, параметры и набор данных для dataloader
def augment(imgName, angle):
name = 'data/IMG/' imgName.split('/')[-1]
current_image = cv2.imread(name)
current_image = current_image[65:-25, :, :]
if np.random.rand() < 0.5:
current_image = cv2.flip(current_image, 1)
angle = angle * -1.0
return current_image, angle
class Dataset(data.Dataset):
def __init__(self, samples, transform=None):
self.samples = samples
self.transform = transform
def __getitem__(self, index):
batch_samples = self.samples[index]
steering_angle = float(batch_samples[3])
center_img, steering_angle_center = augment(batch_samples[0], steering_angle)
left_img, steering_angle_left = augment(batch_samples[1], steering_angle 0.4)
right_img, steering_angle_right = augment(batch_samples[2], steering_angle - 0.4)
center_img = self.transform(center_img)
left_img = self.transform(left_img)
right_img = self.transform(right_img)
return (center_img, steering_angle_center), (left_img, steering_angle_left), (right_img, steering_angle_right)
def __len__(self):
return len(self.samples)
Шаг 3b: создание генератора с использованием загрузчика данных для распараллеливания процесса
transformations = transforms.Compose([transforms.Lambda(lambda x: (x / 255.0) - 0.5)])
params = {'batch_size': 32,
'shuffle': True,
'num_workers': 4}
training_set = Dataset(train_samples, transformations)
training_generator = data.DataLoader(training_set, **params)
validation_set = Dataset(validation_samples, transformations)
validation_generator = data.DataLoader(validation_set, **params)
Step4: Define the network
class NetworkDense(nn.Module):
def __init__(self):
super(NetworkDense, self).__init__()
self.conv_layers = nn.Sequential(
nn.Conv2d(3, 24, 5, stride=2),
nn.ELU(),
nn.Conv2d(24, 36, 5, stride=2),
nn.ELU(),
nn.Conv2d(36, 48, 5, stride=2),
nn.ELU(),
nn.Conv2d(48, 64, 3),
nn.ELU(),
nn.Conv2d(64, 64, 3),
nn.Dropout(0.25)
)
self.linear_layers = nn.Sequential(
nn.Linear(in_features=64 * 2 * 33, out_features=100),
nn.ELU(),
nn.Linear(in_features=100, out_features=50),
nn.ELU(),
nn.Linear(in_features=50, out_features=10),
nn.Linear(in_features=10, out_features=1)
)
def forward(self, input):
input = input.view(input.size(0), 3, 70, 320)
output = self.conv_layers(input)
output = output.view(output.size(0), -1)
output = self.linear_layers(output)
return output
class NetworkLight(nn.Module):
def __init__(self):
super(NetworkLight, self).__init__()
self.conv_layers = nn.Sequential(
nn.Conv2d(3, 24, 3, stride=2),
nn.ELU(),
nn.Conv2d(24, 48, 3, stride=2),
nn.MaxPool2d(4, stride=4),
nn.Dropout(p=0.25)
)
self.linear_layers = nn.Sequential(
nn.Linear(in_features=48*4*19, out_features=50),
nn.ELU(),
nn.Linear(in_features=50, out_features=10),
nn.Linear(in_features=10, out_features=1)
)
def forward(self, input):
input = input.view(input.size(0), 3, 70, 320)
output = self.conv_layers(input)
output = output.view(output.size(0), -1)
output = self.linear_layers(output)
return output
Step5: Define optimizer
model = NetworkLight()
optimizer = optim.Adam(model.parameters(), lr=0.0001)
criterion = nn.MSELoss()
Step6: Check the device and define function to move tensors to that device
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print('device is: ', device)
def toDevice(datas, device):
imgs, angles = datas
return imgs.float().to(device), angles.float().to(device)
Step7: Train and validate network based on maximum epochs defined
max_epochs = 22
for epoch in range(max_epochs):
model.to(device)
# Training
train_loss = 0
model.train()
for local_batch, (centers, lefts, rights) in enumerate(training_generator):
# Transfer to GPU
centers, lefts, rights = toDevice(centers, device), toDevice(lefts, device), toDevice(rights, device)
# Model computations
optimizer.zero_grad()
datas = [centers, lefts, rights]
for data in datas:
imgs, angles = data
# print("training image: ", imgs.shape)
outputs = model(imgs)
loss = criterion(outputs, angles.unsqueeze(1))
loss.backward()
optimizer.step()
train_loss = loss.data[0].item()
if local_batch % 100 == 0:
print('Loss: %.3f '
% (train_loss/(local_batch 1)))
# Validation
model.eval()
valid_loss = 0
with torch.set_grad_enabled(False):
for local_batch, (centers, lefts, rights) in enumerate(validation_generator):
# Transfer to GPU
centers, lefts, rights = toDevice(centers, device), toDevice(lefts, device), toDevice(rights, device)
# Model computations
optimizer.zero_grad()
datas = [centers, lefts, rights]
for data in datas:
imgs, angles = data
# print("Validation image: ", imgs.shape)
outputs = model(imgs)
loss = criterion(outputs, angles.unsqueeze(1))
valid_loss = loss.data[0].item()
if local_batch % 100 == 0:
print('Valid Loss: %.3f '
% (valid_loss/(local_batch 1)))
Шаг 8: определите состояние и сохраните запись модели в состояние
state = {
'model': model.module if device == 'cuda' else model,
}
torch.save(state, 'model.h5')
это сообщение об ошибке:
"D:VICOBack upvenvScriptspython.exe" "D:/VICO/Back up/venv/Scripts/self_driving_car.py"
device is: cpu
Traceback (most recent call last):
File "D:/VICO/Back up/venv/Scripts/self_driving_car.py", line 163, in <module>
for local_batch, (centers, lefts, rights) in enumerate(training_generator):
File "D:VICOBack upvenvlibsite-packagestorchutilsdatadataloader.py", line 291, in __iter__
return _MultiProcessingDataLoaderIter(self)
File "D:VICOBack upvenvlibsite-packagestorchutilsdatadataloader.py", line 737, in __init__
w.start()
File "C:UsersisonataAppDataLocalProgramsPythonPython37libmultiprocessingprocess.py", line 112, in start
self._popen = self._Popen(self)
File "C:UsersisonataAppDataLocalProgramsPythonPython37libmultiprocessingcontext.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:UsersisonataAppDataLocalProgramsPythonPython37libmultiprocessingcontext.py", line 322, in _Popen
return Popen(process_obj)
File "C:UsersisonataAppDataLocalProgramsPythonPython37libmultiprocessingpopen_spawn_win32.py", line 89, in __init__
reduction.dump(process_obj, to_child)
File "C:UsersisonataAppDataLocalProgramsPythonPython37libmultiprocessingreduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <function <lambda> at 0x0000002F2175B048>: attribute lookup <lambda> on __main__ failed
Process finished with exit code 1
Я не уверен, что следующий шаг для решения проблемы.
Комментарии:
1. Использование
state = {'model' : model.state_dict()}
, за которым следуетmodel.load_state_dict(...)
при загрузке
Ответ №1:
pickle
не удаляет объекты функций. Он ожидает найти объект функции, импортировав его модуль и просмотрев его имя. лямбды — это анонимные функции (без имени), поэтому это не работает. Решение состоит в том, чтобы назвать функцию на уровне модуля. Единственная лямбда, которую я нашел в вашем коде, это
transformations = transforms.Compose([transforms.Lambda(lambda x: (x / 255.0) - 0.5)])
Предполагая, что это проблемная функция, вы можете
def _my_normalization(x):
return x/255.0 - 0.5
transformations = transforms.Compose([transforms.Lambda(_my_normalization])
У вас могут быть другие проблемы, потому что похоже, что вы выполняете работу на уровне модуля. Если это многопроцессорная обработка, и вы работаете в Windows, новый процесс импортирует файл и снова запустит весь этот код на уровне модуля. Это не проблема в linux / mac, где разветвленный процесс уже имеет модули, загруженные из родительского.
Комментарии:
1. Да, на самом деле у меня другая проблема с многопроцессорной обработкой.»Ошибка времени выполнения: была предпринята попытка запустить новый процесс до того, как текущий процесс завершил фазу начальной загрузки. Вероятно, это означает, что вы не используете fork для запуска дочерних процессов, и вы забыли использовать правильную идиому в главном модуле: if name == ‘ main ‘: freeze_support() … Строка «freeze_support()» может быть опущена, если программа не будет заморожена для создания исполняемого файла.
2. Привет, tdelaney, есть идеи по решению этой проблемы? Спасибо
3. Похоже, вы работаете в Windows. В Windows модули повторно импортируются в дочерние процессы. Все, что выполняется на уровне модуля, выполняется в дочернем элементе, в вашем случае это включает код, который создает подпроцессы, что приводит к бесконечному порождению процессов. Используйте
if __name__ == "__main__":
в своем основном скрипте. Просто найдите «Ошибка времени выполнения: была предпринята попытка запустить новый процесс», и вы получите сотню обращений.4. Спасибо tdelaney, я ввел if name == » main «: и main() на шаге 7, и все работает хорошо.