【发布时间】:2020-06-01 06:47:24
【问题描述】:
我正在尝试使用 EasyCython 模块将纯 Python 模块转换为与 Cython 兼容的模块。
然而问题是,在尝试执行 EasyCython 时,它会失败并出现错误:
G:\Proc\python\FV>easycython F_V.pyx
Compiling F_V.pyx because it changed.
[1/1] Cythonizing F_V.pyx
C:\Users\Rika\Anaconda3\Lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: G:\Proc\python\FV\F_V.pyx
tree = Parsing.p_module(s, pxd, full_module_name)
Error compiling Cython file:
------------------------------------------------------------
...
# or the network would mistake some one else for someother people! (for example someone has a profile image
# while the other doesnt, when confronted with the profile image, the network most likely find more features
# from the person that has already a profile image of him in the fbank (unless the change is noticeable
# this really can be a major issue)))
# @benchmark
cpdef _identify_id(self, input_img_embedding, list embedding_list, bint short_circut=True, bint accumulate_score=False):
^
------------------------------------------------------------
F_V.pyx:929:10: cdef statement not allowed here
Traceback (most recent call last):
File "C:\Users\Rika\Anaconda3\Lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Users\Rika\Anaconda3\Lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\Rika\Anaconda3\Scripts\easycython.exe\__main__.py", line 7, in <module>
File "C:\Users\Rika\Anaconda3\Lib\site-packages\begin\main.py", line 54, in start
collector=self._collector)
File "C:\Users\Rika\Anaconda3\Lib\site-packages\begin\cmdline.py", line 253, in apply_options
return_value = call_function(func, signature(ext), opts)
File "C:\Users\Rika\Anaconda3\Lib\site-packages\begin\cmdline.py", line 236, in call_function
return func(*pargs, **kwargs)
File "C:\Users\Rika\Anaconda3\Lib\site-packages\easycython\easycython.py", line 77, in main
ext_modules = cythonize(ext_modules),
File "C:\Users\Rika\Anaconda3\Lib\site-packages\Cython\Build\Dependencies.py", line 1102, in cythonize
cythonize_one(*args)
File "C:\Users\Rika\Anaconda3\Lib\site-packages\Cython\Build\Dependencies.py", line 1225, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: F_V.pyx
以下是使用 cython 类型注释的两种方法。
#@benchmark
cpdef _identify_id(self, input_img_embedding, list embedding_list, bint short_circut=True, bint accumulate_score=False):
# These are the underlying types for the arguments and local variables used here
# input_img_embedding_type: <class 'torch.Tensor'> shape:torch.Size([1, 512])
# feature1 type: <class 'torch.Tensor'> shape: torch.Size([1, 512])
# x1 type: <class 'torch.Tensor'> shape: torch.Size([1, 512])
# cosine type: <class 'numpy.float32'> shape: ()
# np.clip(cosine) type: <class 'numpy.float64'> shape: ()
#
cdef float min_theta = 1000.0
cdef float total_theta = 0.0
cdef char* id_name = 'None' #None
for (name, feature1) in embedding_list:
id_name = name
x1 = feature1 / np.linalg.norm(feature1)
cosine = np.dot(input_img_embedding.squeeze(0), x1.squeeze(0))
cdef float cosine = np.clip(cosine, -1.0, 1.0)
cdef float theta = math.acos(cosine)
cdef float theta = theta * 180 / math.pi
if short_circut:
if theta < self._threshold:
return id_name, theta
if theta < min_theta:
min_theta = theta
total_theta += theta
# the elses from now on are for debugging purposes
if not short_circut and not accumulate_score:
if min_theta < self._threshold:
return id_name, min_theta
else:
return 'unknown', min_theta
if accumulate_score:
final_score = total_theta/len(embedding_list)
if final_score < self._threshold:
return id_name, final_score
else:
return 'unknown', final_score
return 'unknown', theta # min_theta
#@benchmark
cpdef _check_in_fbank(self, img):
"""Checks whether a given image is represented in the face bank.
Arguments:
img {torch.tensor} -- input image to be verified
Returns:
tuple(name, theta)
"""
# These are the underlying python types
# img type: <class 'torch.Tensor'> shape: torch.Size([3, 112, 112])
# feature0 type: <class 'torch.Tensor'> shape: torch.Size([1, 512])
# x0 type: <class 'torch.Tensor'> shape: torch.Size([1, 512])
with Benchmark_Block("model frwd took: "):
feature0 = self.model(img.unsqueeze(0)).cpu().detach()
x0 = feature0 / np.linalg.norm(feature0)
cdef list lst = []
for img_list in self._fbank_embeddings:
cdef tuple f = self._identify_id(x0, img_list, short_circut=self.short_circut, accumulate_score=self.accumulate_score)
lst.append(f)
cdef tuple min_val = min(lst, key=lambda t: t[1])
print(f'lst of returned results : {lst}. The minimum is: {min_val} in {len(self._fbank_embeddings)} enteries')
return min_val
我在这里缺少什么?
【问题讨论】:
-
装饰器(我标记的副本的主题)是一个问题 -
cdef函数不允许使用它。int*是另一个问题 -def函数不允许使用它(因为它没有等效的 Python 类型)。cpdef具有cdef和def函数的所有限制(有关说明,请参阅 stackoverflow.com/questions/28362009/…) -
话虽如此 - 您显示的代码与您显示的错误不匹配,所以谁知道。如果这个+副本不能帮助您解决它,那么我很乐意重新打开它
-
谢谢,但如果我删除所有 int* 以及装饰器,我仍然会遇到同样的错误。我更新了错误日志,之前忘记更新了。
-
恐怕我现在不知道,但我已经删除了重复的标志
-
谢谢,我很欣赏它。同时我添加了一些关于参数类型和其他局部变量的更多信息,所以它可以显示我做错了什么。