簡體   English   中英

如何在numpy中為CNN實現反卷積層?

[英]How can I implement deconvolution layer for a CNN in numpy?

我嘗試為卷積網絡實現解卷積層。 我的意思是去卷積是假設我有3x227x227輸入圖像到一個過濾器尺寸為3x11x11和步幅4的55x55 。因此得到的特征圖的大小為55x55 我嘗試做的是應用反向操作,我將55x55特征映射再次3x227x2273x227x227圖像。 基本上, 55x55特征圖上的每個值都由3x11x11濾鏡加權並投影到圖像空間,並且由於步幅而對重疊區域進行平均。

我嘗試在numpy中實現它而沒有任何成功。 我找到了一個蠻力嵌套for循環的解決方案,但它很慢。 如何有效地實現numpy? 歡迎任何幫助。

正如在這個問題中所討論的,解卷積只是一個卷積層,但具有特定的填充,步幅和濾波器尺寸選擇。

例如,如果當前圖像大小為55x55 ,則可以應用padding=20stride=1filter=[21x21]的卷積來獲得75x75圖像,然后使用95x95等等。 (我不是說這個數字的選擇給出了輸出圖像所需的質量 ,只是尺寸。實際上,我認為從227x22755x55下采樣然后再采樣到227x227太過激進,但你可以自由嘗試任何架構)。

這是任何步幅和填充的正向傳遞的實現。 它進行了im2col轉換 ,但是使用numpy中的stride_tricks 它不像現代GPU實現那樣優化,但肯定比4個內部循環更快:

import numpy as np

def conv_forward(x, w, b, stride, pad):
  N, C, H, W = x.shape
  F, _, HH, WW = w.shape

  # Check dimensions
  assert (W + 2 * pad - WW) % stride == 0, 'width does not work'
  assert (H + 2 * pad - HH) % stride == 0, 'height does not work'

  # Pad the input
  p = pad
  x_padded = np.pad(x, ((0, 0), (0, 0), (p, p), (p, p)), mode='constant')

  # Figure out output dimensions
  H += 2 * pad
  W += 2 * pad
  out_h = (H - HH) / stride + 1
  out_w = (W - WW) / stride + 1

  # Perform an im2col operation by picking clever strides
  shape = (C, HH, WW, N, out_h, out_w)
  strides = (H * W, W, 1, C * H * W, stride * W, stride)
  strides = x.itemsize * np.array(strides)
  x_stride = np.lib.stride_tricks.as_strided(x_padded,
                                             shape=shape, strides=strides)
  x_cols = np.ascontiguousarray(x_stride)
  x_cols.shape = (C * HH * WW, N * out_h * out_w)

  # Now all our convolutions are a big matrix multiply
  res = w.reshape(F, -1).dot(x_cols) + b.reshape(-1, 1)

  # Reshape the output
  res.shape = (F, N, out_h, out_w)
  out = res.transpose(1, 0, 2, 3)
  out = np.ascontiguousarray(out)
  return out

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM