оригинал:воооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооо
Оригинальное название: a_few_helpful_pytorch_tips_examples_included
Автор перевода: kbsc13
Контакты:
Гитхаб:GitHub.com/CCC013/AI_Ah…
Публичный аккаунт WeChat:Примечания к алгоритму ИИ
предисловие
Это раздел машинного обучения зарубежного форума reddit. Кто-то обобщил около 7 полезных навыков PyTorch, а также привел примеры кода и видео colab. Код и ссылки на видео выглядят следующим образом:
Код:col AB.research.Google.com/drive/15VG только…
видео:youtu.be/BoC8SGaT3GE
Видео так же заливается на мою б станцию синхронно, ссылка такая:
Кроме того, код и видео можно получить, ответив на «12» на фоне официального аккаунта.
1. Создавайте тензоры прямо на целевом устройстве
Первый трюк заключается в использованииdevice
Параметры создают тензоры непосредственно на целевом устройстве.Вот время работы двух подходов.
Первый заключается в том, чтобы сначала создать тензоры на процессоре, а затем использовать.cuda()
Переходя к графическому процессору, код выглядит так:
start_time = time.time()
for _ in range(100):
# Creating on the CPU, then transfering to the GPU
cpu_tensor = torch.ones((1000, 64, 64))
gpu_tensor = cpu_tensor.cuda()
print('Total time: {:.3f}s'.format(time.time() - start_time))
Второй — создать тензор непосредственно на целевом устройстве, код выглядит следующим образом:
start_time = time.time()
for _ in range(100):
# Creating on GPU directly
cpu_tensor = torch.ones((1000, 64, 64), device='cuda')
print('Total time: {:.3f}s'.format(time.time() - start_time))
Время выполнения для обоих методов следующее:
Видно, что скорость создания тензоров непосредственно на целевом устройстве очень высока;
2. Используйте как можно большеSequential
Этаж
Вторая техника заключается в использованииSequential
слой, чтобы код выглядел более лаконичным.
Первый код для построения сетевой модели выглядит следующим образом:
class ExampleModel(nn.Module):
def __init__(self):
super().__init__()
input_size = 2
output_size = 3
hidden_size = 16
self.input_layer = nn.Linear(input_size, hidden_size)
self.input_activation = nn.ReLU()
self.mid_layer = nn.Linear(hidden_size, hidden_size)
self.mid_activation = nn.ReLU()
self.output_layer = nn.Linear(hidden_size, output_size)
def forward(self, x):
z = self.input_layer(x)
z = self.input_activation(z)
z = self.mid_layer(z)
z = self.mid_activation(z)
out = self.output_layer(z)
return out
Эффект от его работы следующий:
с использованиемSequential
Способ построения сетевой модели следующий:
class ExampleSequentialModel(nn.Module):
def __init__(self):
super().__init__()
input_size = 2
output_size = 3
hidden_size = 16
self.layers = nn.Sequential(
nn.Linear(input_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, output_size))
def forward(self, x):
out = self.layers(x)
return out
Эффект от его работы следующий:
можно увидеть сnn.Sequential
Код для построения сетевой модели более лаконичен.
3. Не используйте списки для хранения сетевых слоев
Третий прием заключается в том, что не рекомендуется использовать список для хранения созданных сетевых слоев, т.к.nn.Module
Классы не могут успешно зарегистрировать их. Вместо этого список должен быть передан вnn.Sequential
середина.
Первый — показать плохой пример:
class BadListModel(nn.Module):
def __init__(self):
super().__init__()
input_size = 2
output_size = 3
hidden_size = 16
self.input_layer = nn.Linear(input_size, hidden_size)
self.input_activation = nn.ReLU()
# Fairly common when using residual layers
self.mid_layers = []
for _ in range(5):
self.mid_layers.append(nn.Linear(hidden_size, hidden_size))
self.mid_layers.append(nn.ReLU())
self.output_layer = nn.Linear(hidden_size, output_size)
def forward(self, x):
z = self.input_layer(x)
z = self.input_activation(z)
for layer in self.mid_layers:
z = layer(z)
out = self.output_layer(z)
return out
bad_list_model = BadListModel()
print('Output shape:', bad_list_model(torch.ones([100, 2])).shape)
gpu_input = torch.ones([100, 2], device='cuda')
gpu_bad_list_model = bad_list_model.cuda()
print('Output shape:', bad_list_model(gpu_input).shape)
Приведенная выше запись сообщит об ошибке при печати второго предложения:
Правильное написание:
class CorrectListModel(nn.Module):
def __init__(self):
super().__init__()
input_size = 2
output_size = 3
hidden_size = 16
self.input_layer = nn.Linear(input_size, hidden_size)
self.input_activation = nn.ReLU()
# Fairly common when using residual layers
self.mid_layers = []
for _ in range(5):
self.mid_layers.append(nn.Linear(hidden_size, hidden_size))
self.mid_layers.append(nn.ReLU())
self.mid_layers = nn.Sequential(*self.mid_layers)
self.output_layer = nn.Linear(hidden_size, output_size)
def forward(self, x):
z = self.input_layer(x)
z = self.input_activation(z)
z = self.mid_layers(z)
out = self.output_layer(z)
return out
correct_list_model = CorrectListModel()
gpu_input = torch.ones([100, 2], device='cuda')
gpu_correct_list_model = correct_list_model.cuda()
print('Output shape:', correct_list_model(gpu_input).shape)
Его результат печати:
4. Используйте это правильноdistributions
Четвертый трюк — это PyTorch.torch.distributions
В библиотеке есть отличные объекты и методы для реализации дистрибутива, но они не очень хорошо используются, ссылка на официальную документацию:
Вот пример использования:
5. Использование на долгосрочных индикаторахdetach
Пятая хитрость заключается в том, что если вам нужно хранить тензорные метрики между эпохами, используйте.detach()
для предотвращения утечек памяти.
Ниже приведен пример кода для иллюстрации, первая — начальная конфигурация:
# Setup
example_model = ExampleModel()
data_batches = [torch.rand((10, 2)) for _ in range(5)]
criterion = nn.MSELoss(reduce='mean')
Пример плохого кода:
losses = []
# Training loop
for batch in data_batches:
output = example_model(batch)
target = torch.rand((10, 3))
loss = criterion(output, target)
losses.append(loss)
# Optimization happens here
print(losses)
Результат печати следующий:
Правильное написание
losses = []
# Training loop
for batch in data_batches:
output = example_model(batch)
target = torch.rand((10, 3))
loss = criterion(output, target)
losses.append(loss.item()) # Or `loss.item()`
# Optimization happens here
print(losses)
Результат печати следующий:
следует позвонить сюдаloss.item()
метод сохранения значения потерь в каждую эпоху.
6. Советы по удалению моделей на GPU
Шестой прием заключается в использованииtorch.cuda.empty_cache()
Чтобы очистить кэш графического процессора, этот метод полезен при работе с ноутбуками, особенно если вы хотите удалить и воссоздать большую модель.
Пример использования следующий:
import gc
example_model = ExampleModel().cuda()
del example_model
gc.collect()
# The model will normally stay on the cache until something takes it's place
torch.cuda.empty_cache()
7. Звоните перед тестированиемeval()
Последнее не забудьте позвонить перед началом тестаmodel.eval()
, это просто, но легко забыть. Эта операция внесет необходимые изменения в некоторые сетевые уровни, которые по-разному устанавливаются на этапах обучения и проверки. Затронутые модули включают:
- Dropout
- Batch Normalization
- RNNs
- Lazy Variants
Это может относиться к:stackoverflow.com/questions/6…
Пример использования следующий:
example_model = ExampleModel()
# Do training
example_model.eval()
# Do testing
example_model.train()
# Do training again