На что-либо определенное внутри класса должно ссылаться квалифицированное имя, либо непосредственно на класс, либо на его экземпляр. Таким образом, самое простое решение здесь - это явный вызов NN.generate_random_nodes
для рекурсивного вызова и self.generate_random_nodes
в начальных вызовах к нему (показаны только методы с изменениями):
@staticmethod
def generate_random_nodes(dropout_prob, size):
temp = np.random.binomial(1, dropout_prob, size)
# Must explicitly qualify recursive call
return temp if not sum(temp) else NN.generate_random_nodes(dropout_prob, size)
def compute_dropout(self, activations, dropout_prob = 0.5):
[...]
mult = np.copy(activations)
# Can call static on self just fine, and avoids hard-coding class name
temp = self.generate_random_nodes(dropout_prob, size=activations.shape[0])
mult[:,i] = temp
activations*=mult
return activations
Обратите внимание, что в качестве реализации CPython подробно о Python 3.x, ссылка __class__
внутри метода, определенного в классе, создает область замыкания, которая дает вам доступ к классу, в котором он был определен, что позволяет вам избежать повторения, явно указав класс, поэтому generate_random_nodes
может быть:
@staticmethod
def generate_random_nodes(dropout_prob, size):
temp = np.random.binomial(1, dropout_prob, size)
# Must qualify recursive call
return temp if not sum(temp) else __class__.generate_random_nodes(dropout_prob, size)
, что имеет пару преимуществ:
__class__
немного быстрее, чем поиск глобальных областей действия NN
, и NN
класса изменяется во время разработки, вам вообще не нужно менять generate_random_nodes
(потому что он неявно получает ссылку на класс, в котором он был определен). Вы также можете (не полагаясь на детали реализации CPython) изменить его на classmethod
, чтобы получить то же основное преимущество:
@classmethod
def generate_random_nodes(cls, dropout_prob, size):
temp = np.random.binomial(1, dropout_prob, size)
# Must qualify recursive call
return temp if not sum(temp) else cls.generate_random_nodes(dropout_prob, size)
, поскольку classmethod
s получают ссылку на класс, к которому они были вызваны (класс экземпляра, к которому они были вызваны, если вызван на экземпляре) Это небольшое злоупотребление classmethod
(единственное предназначение classmethod
предназначено для альтернативных конструкторов в иерархиях классов, где подклассы должны быть в состоянии быть созданы с использованием альтернативного конструктора без перегрузки его в подклассе); это совершенно законно, просто немного неортодоксально.
Как описано ниже в комментариях:
temp
только если sum
его 0
, что означает temp
- массив всех нулей), что значительно увеличивает вероятность рекурсии и делает ошибку рекурсии почти наверняка для достаточно высоких аргументов dropout_prob
/ size
. Итак, вы хотите изменить temp if not sum(temp) else <recursive call>
на temp if sum(temp) else <recursive call>
, или для лучшей производительности / очевидности, учитывая, что это массив numpy
, temp if temp.any() else <recursive call>
. И хотя вероятность того, что ошибки рекурсии могут начаться с малой вероятности, может начаться, если вы хотите быть очень осторожным, просто перейдите на подход while
, основанный на циклах, который не может рисковать неопределенной рекурсией:
@staticmethod
def generate_random_nodes(dropout_prob, size):
while True:
temp = np.random.binomial(1, dropout_prob, size)
if temp.any():
return temp
Кажется, что это не выполнимо межплатформенным способом, не используя собственные интерфейсы.
В Windows, можно использовать свободное библиотека JIntellitype.
Если бы кто-либо хочет сделать OSX или версии Linux части JNI Jintellitype, я был бы более, чем рад добавить тех к библиотеке JIntellitype.
Melloware
Для Linux (X11) там JXGrabKey: http://sourceforge.net/projects/jxgrabkey/
существует также учебное руководство для захвата глобальной горячей клавиши на Linux: http://ubuntuforums.org/showthread.php?t=864566
я не сделал, хотя находят решение для OS X все же.
Для создания чего-то для всех 3 платформ я предложил бы разделить вниз JIntellitype (это - лицензия Apache) к, он - глобальная функциональность горячей клавиши и расширение его с OS X и функциональностью X11...