python实现卷积层

代码源自:

http://www.heibanke.com/2016/10/11/conv_layer_forward_backward/#comments


Convolution Layer Forward



import numpy as np

%load_ext autoreload
%autoreload 2

def conv_forward_naive(x, w, b, conv_param):
  """
  A naive implementation of the forward pass for a convolutional layer.

  The input consists of N data points, each with C channels, height H and width
  W. We convolve each input with F different filters, where each filter spans
  all C channels and has height HH and width HH.

  Input:
  - x: Input data of shape (N, C, H, W)
  - w: Filter weights of shape (F, C, HH, WW)
  - b: Biases, of shape (F,)
  - conv_param: A dictionary with the following keys:
    - 'stride': The number of pixels between adjacent receptive fields in the
      horizontal and vertical directions.
    - 'pad': The number of pixels that will be used to zero-pad the input.

  Returns a tuple of:
  - out: Output data, of shape (N, F, H', W') where H' and W' are given by
    H' = 1 + (H + 2 * pad - HH) / stride
    W' = 1 + (W + 2 * pad - WW) / stride
  - cache: (x, w, b, conv_param)
  """
  out = None
  N,C,H,W = x.shape
  F,_,HH,WW = w.shape
  S = conv_param['stride']
  P = conv_param['pad']
  Ho = 1 + (H + 2 * P - HH) / S
  Wo = 1 + (W + 2 * P - WW) / S
  x_pad = np.zeros((N,C,H+2*P,W+2*P))
  x_pad[:,:,P:P+H,P:P+W]=x
  #x_pad = np.pad(x, ((0,), (0,), (P,), (P,)), 'constant')
  out = np.zeros((N,F,Ho,Wo))

  for f in xrange(F):
    for i in xrange(Ho):
      for j in xrange(Wo):
        # N*C*HH*WW, C*HH*WW = N*C*HH*WW, sum -> N*1
        out[:,f,i,j] = np.sum(x_pad[:, :, i*S : i*S+HH, j*S : j*S+WW] * w[f, :, :, :], axis=(1, 2, 3)) 

    out[:,f,:,:]+=b[f]
  cache = (x, w, b, conv_param)
  return out, cache

我们可以用几个例子试试它的输出


x_shape = (2, 3, 4, 4) #n,c,h,w
w_shape = (2, 3, 3, 3) #f,c,hw,ww
x = np.ones(x_shape)
w = np.ones(w_shape)
b = np.array([1,2])

conv_param = {'stride': 1, 'pad': 0}
out, _ = conv_forward_naive(x, w, b, conv_param)

print out
print out.shape  #n,f,ho,wo结果如下:

[[[[ 28. 28.] [ 28. 28.]]

[[ 29. 29.] [ 29. 29.]]]

[[[ 28. 28.] [ 28. 28.]]

[[ 29. 29.] [ 29. 29.]]]]

(2, 2, 2, 2)

设置pad为1,自己再计算一下结果。尤其是结果的维数变化。 设置stride为3,pad为1呢? 还可以怎么设置呢?

Convolution Layer Backward



def conv_backward_naive(dout, cache):
  """
  A naive implementation of the backward pass for a convolutional layer.

  Inputs:
  - dout: Upstream derivatives.
  - cache: A tuple of (x, w, b, conv_param) as in conv_forward_naive

  Returns a tuple of:
  - dx: Gradient with respect to x
  - dw: Gradient with respect to w
  - db: Gradient with respect to b
  """
  dx, dw, db = None, None, None

  N, F, H1, W1 = dout.shape
  x, w, b, conv_param = cache
  N, C, H, W = x.shape
  HH = w.shape[2]
  WW = w.shape[3]
  S = conv_param['stride']
  P = conv_param['pad']


  dx, dw, db = np.zeros_like(x), np.zeros_like(w), np.zeros_like(b)
  x_pad = np.pad(x, [(0,0), (0,0), (P,P), (P,P)], 'constant')
  dx_pad = np.pad(dx, [(0,0), (0,0), (P,P), (P,P)], 'constant')
  db = np.sum(dout, axis=(0,2,3))

  for n in xrange(N):
    for i in xrange(H1):
      for j in xrange(W1):
        # Window we want to apply the respective f th filter over (C, HH, WW)
        x_window = x_pad[n, :, i * S : i * S + HH, j * S : j * S + WW]

        for f in xrange(F):
          dw[f] += x_window * dout[n, f, i, j] #F,C,HH,WW
          #C,HH,WW
          dx_pad[n, :, i * S : i * S + HH, j * S : j * S + WW] += w[f] * dout[n, f, i, j]

  dx = dx_pad[:, :, P:P+H, P:P+W]

  return dx, dw, db

上面的实现代码是最原始的。 matlab上为了加速,使用已有的conv函数实现上述过程,才有了很多博文上提到的翻转180度两次的过程,翻来翻去的反而不容易理解整个过程。其实卷积层的前向和后向传播,跟信号处理的卷积操作没有直接关系。就是相关和点乘操作。其它实现都是优化加速方法。

我们对反向传播也举个例子


x_shape = (2, 3, 4, 4)
w_shape = (2, 3, 3, 3)
x = np.ones(x_shape)
w = np.ones(w_shape)
b = np.array([1,2])

conv_param = {'stride': 1, 'pad': 0}

Ho = (x_shape[3]+2*conv_param['pad']-w_shape[3])/conv_param['stride']+1
Wo = Ho

dout = np.ones((x_shape[0], w_shape[0], Ho, Wo))

out, cache = conv_forward_naive(x, w, b, conv_param)
dx, dw, db = conv_backward_naive(dout, cache)

print "out shape",out.shape
print "dw=========================="
print dw
print "dx=========================="
print dx
print "db=========================="
print db

out shape (2, 2, 2, 2)

dw==========================

[[[[ 8. 8. 8.] [ 8. 8. 8.] [ 8. 8. 8.]]

[[ 8. 8. 8.] [ 8. 8. 8.] [ 8. 8. 8.]]

[[ 8. 8. 8.] [ 8. 8. 8.] [ 8. 8. 8.]]]

[[[ 8. 8. 8.] [ 8. 8. 8.] [ 8. 8. 8.]]

[[ 8. 8. 8.] [ 8. 8. 8.] [ 8. 8. 8.]]

[[ 8. 8. 8.] [ 8. 8. 8.] [ 8. 8. 8.]]]]

dx==========================

[[[[ 2. 4. 4. 2.] [ 4. 8. 8. 4.] [ 4. 8. 8. 4.] [ 2. 4. 4. 2.]]

[[ 2. 4. 4. 2.] [ 4. 8. 8. 4.] [ 4. 8. 8. 4.] [ 2. 4. 4. 2.]]

[[ 2. 4. 4. 2.] [ 4. 8. 8. 4.] [ 4. 8. 8. 4.] [ 2. 4. 4. 2.]]]

[[[ 2. 4. 4. 2.] [ 4. 8. 8. 4.] [ 4. 8. 8. 4.] [ 2. 4. 4. 2.]]

[[ 2. 4. 4. 2.] [ 4. 8. 8. 4.] [ 4. 8. 8. 4.] [ 2. 4. 4. 2.]]

[[ 2. 4. 4. 2.] [ 4. 8. 8. 4.] [ 4. 8. 8. 4.] [ 2. 4. 4. 2.]]]]

db==========================

[ 8. 8.]

### 回答1: 在 Python实现卷积神经网络需要使用一些工具,例如 NumPy 库来进行矩阵运算和 TensorFlow 或 PyTorch 库来构建和训练模型。 要使用 TensorFlow 实现卷积神经网络,首先需要安装 TensorFlow 库,然后可以使用其中的函数和类来构建模型。 例如,下面是一个简单的卷积神经网络的示例代码: ```python import tensorflow as tf # 输入数据 input_data = tf.placeholder(tf.float32, [None, 28, 28, 1]) # 第一层卷积 conv1 = tf.layers.conv2d(input_data, 32, (5, 5), activation=tf.nn.relu) # 第一层池化 pool1 = tf.layers.max_pooling2d(conv1, (2, 2), (2, 2)) # 第二层卷积 conv2 = tf.layers.conv2d(pool1, 64, (5, 5), activation=tf.nn.relu) # 第二层池化 pool2 = tf.layers.max_pooling2d(conv2, (2, 2), (2, 2)) # 全连接层 fc1 = tf.layers.dense(tf.contrib.layers.flatten(pool2), 1024, activation=tf.nn.relu) # 输出层 output = tf.layers.dense(fc1, 10) ``` 在这段代码中,我们使用了 TensorFlow 中的卷积层、池化层和全连接层来构建卷积神经网络。 要训练模型,还需要定义损失函数、优化器和训练步骤。例如: ```python # 定义损失函数和优化器 loss = tf.loss ### 回答2: 卷积神经网络(Convolutional Neural Network,CNN)是一种常用于图像识别和计算机视觉任务的深度学习模型。Python提供了多个库和框架来实现卷积神经网络。 在Python中,最常用且流行的框架之一是TensorFlow。TensorFlow提供了丰富的功能以实现卷积神经网络。下面是一个简单的CNN实现步骤: 1. 导入所需的库和模块: ```python import tensorflow as tf from tensorflow.keras import datasets, layers, models ``` 2. 加载和预处理数据集: ```python (train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data() train_images, test_images = train_images / 255.0, test_images / 255.0 ``` 3. 构建卷积神经网络模型: ```python model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) ``` 4. 添加全连接层和输出层: ```python model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(10)) ``` 5. 编译和训练模型: ```python model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy']) model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels)) ``` 6. 预测和评估模型: ```python test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2) print('Test accuracy:', test_acc) ``` 这只是一个简单的例子,实际的卷积神经网络可能更加复杂,包括更多的卷积层、池化层和全连接层。通过调整模型的结构和参数,可以进一步优化CNN的性能。 除了TensorFlow,还有其他一些Python库和框架,如Keras、PyTorch和Caffe,也可以轻松实现卷积神经网络。每个库和框架都有自己的特点和优势,可以根据具体需求选择合适的工具。 ### 回答3: 卷积神经网络(Convolutional Neural Networks, CNN)是一种广泛应用于计算机视觉和图像识别任务的深度学习模型。Python提供了多种库和框架来实现卷积神经网络,其中最受欢迎的是TensorFlow和PyTorch。 使用Python实现卷积神经网络的一般步骤如下: 1. 数据准备:首先,需要准备用于训练和测试模型的数据集。可以使用Python的库(如NumPy和Pandas)来加载、处理和转换数据。 2. 模型搭建:在Python中,可以使用TensorFlow或PyTorch等库来定义卷积神经网络模型。首先,需要导入相关库,并创建一个模型对象。然后,可以通过添加各种层(如卷积层、池化层和全连接层)来构建模型结构。 3. 模型训练:训练卷积神经网络需要提供输入数据和相应的标签。可以使用Python的库来分割数据集为训练集和测试集,并在训练集上迭代多次以优化模型参数。通过调用模型对象的训练函数,可以实现模型的训练过程。 4. 模型评估:训练完成后,可以使用测试集数据来评估模型的性能。可以使用Python的库计算准确率和损失函数等指标。 5. 模型预测:训练好的卷积神经网络模型可以用于预测新的未知数据。通过使用训练好的模型对新数据进行前向传播,得到预测结果。 总之,Python是一种强大的编程语言,提供了多种库和框架来实现卷积神经网络。可以根据具体需求选择合适的库和框架,并按照上述步骤进行实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值