Вопрос: Как можно улучшить следующий код с точки зрения (1) эффективности, (2) памяти и (3) стиля / простоты?
train_means = np.mean(train_data.reshape(784, 10, 1000), axis=2)
train_classes, test_classes = (np.argmin(np.sum(np.square(data[:,:,np.newaxis] - train_means[:,np.newaxis,:]), axis=0), axis=1) for data in (train_data, test_data))
train_acc, test_acc = (np.mean(np.equal(classes, np.repeat(np.arange(10), classes.size // 10))) for classes in (train_classes, test_classes))
Здесьспецификация переменных и задачи:
# train_data: shape of (784, 10000)
# test_data: shape of (784, 1000)
#
# In both cases, each column is a vectorization of a 28 x 28 image of a handwritten digit
# (0-9) where the correct classification is 0 for the first tenth of the columns, 1 for
# the second tenth, and so on. The goal is to write a nearest centroid classifier and
# output its accuracy on each data set.
Например, у меня есть одна проблема: в вычитании data[:,:,np.newaxis] - train_means[:,np.newaxis,:]
создается массив (784, 10000, 10)
, который занимает больше памяти, чем мне нужно использовать,Могу ли я избежать выделения такого большого количества памяти, не жертвуя при этом какой-либо эффективностью (и в идеале какой-либо простотой кода)?
Еще одна проблема - это понимание, которое я использую для применения процедур как к данным обучения, так и к данным тестирования. Будет ли это поощряться или считаться запутанным (или, может быть, это просто неуместные личные предпочтения)?
Контекст: Это моя попытка написать оптимизированную версию ближайшего классификатора центроидов для классификации. некоторые изображения из набора данных MNIST рукописных цифр. Я немного новичок в numpy и был удивлен, насколько лаконично этот код мог быть написан с помощью широковещательных и векторизованных операций, но мне было интересно, если я все еще пропускаю некоторые, возможно, важные улучшения.