python - 为什么我的图像卷积函数这么慢?
问题描述
我不确定是否应该将这个发布在机器学习板上或这个上,但我选择了这个,因为我的问题更多地与优化有关。我正在尝试在 python 中从头开始构建一个 YOLO 模型,但是每个卷积操作需要 10 秒。显然我做错了什么,因为 YOLO 应该是超快的(能够实时产生结果)。我不需要网络实时运行,但如果在一张图像上运行需要几个小时,那么尝试训练它将是一场噩梦。我该如何优化下面的代码?显然还有很大的改进空间。
这是我的卷积函数:
def convolve(image, filter, stride, modifier):
new_image = np.zeros ([image.shape[0], _round((image.shape[1]-filter.shape[1])/stride)+1, _round((image.shape[2]-filter.shape[2])/stride)+1], float)
#convolve
for channel in range (0, image.shape[0]):
filterPositionX = 0
filterPositionY = 0
while filterPositionX < image.shape[1]-filter.shape[1]+1:
while filterPositionY < image.shape[2]-filter.shape[2]+1:
sum = 0
for i in range(0,filter.shape[1]):
for j in range(0,filter.shape[2]):
if filterPositionX+i<image.shape[1] and filterPositionY+j<image.shape[2]:
sum += image[channel][filterPositionX+i][filterPositionY+j]*filter[channel][i][j]
new_image[channel][int(filterPositionX/stride)][int(filterPositionY/stride)] = sum*modifier
filterPositionY += stride
filterPositionX += stride
filterPositionY = 0
#condense
condensed_new_image = np.zeros ([new_image.shape[1], new_image.shape[2]], float)
for i in range(0, new_image.shape[1]):
for j in range(0, new_image.shape[2]):
sum = 0
for channel in range (0, new_image.shape[0]):
sum += new_image[channel][i][j]
condensed_new_image[i][j] = sum
condensed_new_image = np.clip (condensed_new_image, 0, 255)
return condensed_new_image
在 448x448 灰度图像上使用 7x7 滤镜和 2 步幅运行该函数大约需要 10 秒。我的电脑有一个 i7 处理器。
解决方案
为什么慢:因为您编码的函数的时间复杂度为
O(n*n*n*k*k)
,其中图像大小为n*n
,过滤器大小为k*k
如何使其更快:避免循环并使用矩阵运算(向量化)。矩阵运算是并行的。
推荐阅读
- ios - 在后台执行 Apple 快捷方式
- docker - 如何让前端 Docker 容器找到后端容器 ip?
- dart - 在 Dart 中解析动态数据
- javascript - 如何使用 post 方法或在 javascript 中获取发送的数据
- .net - 如何避免在.NET中传递值类型参数时的装箱?
- javascript - PhoneGap/Cordova InAppBrowser 的定时弹出窗口?
- git - git difftool 挂起并且屏幕变得无响应
- android - 同步 FirebaseAuth.getInstance().signOut() 和异步 AuthUI.getInstance().signOut() 之间有什么区别吗
- wordpress - 通过子主题自定义主题
- python - 将输入从文本元组转换为浮点列表时的精度损失