卷积神经网络-week1编程题1(一步步搭建卷积神经网络)

导包

1 import numpy as np
2 import h5py
3 import matplotlib.pyplot as plt
4 
5 plt.rcParams['figure.figsize'] = (5.0, 4.0) # set default size of plots
6 plt.rcParams['image.interpolation'] = 'nearest'
7 plt.rcParams['image.cmap'] = 'gray'
8 
9 np.random.seed(1)

Padding

函数解释:np.pad(array, pad_width, mode, **kwargs)

  • array——表示需要填充的数组;
  • pad_width——表示每个轴(axis)边缘需要填充的数值数目;
  • 参数输入方式为:((before_1, after_1), … (before_N, after_N)),其中(before_1, after_1)表示第1轴两边缘分别填充before_1个和after_1个数值。取值为:{sequence, array_like, int}
  • mode——表示填充的方式(取值:str字符串或用户提供的函数),总共有11种填充模式;
 1 def zero_pad(X, pad):
 2     """
 3     Pad with zeros all images of the dataset X. The padding is applied to the height and width of an image, 
 4     as illustrated in Figure 1.
 5     
 6     Argument:
 7     X -- python numpy array of shape (m, n_H, n_W, n_C) representing a batch of m images
 8     pad -- integer, amount of padding around each image on vertical and horizontal dimensions
 9     
10     Returns:
11     X_pad -- padded image of shape (m, n_H + 2*pad, n_W + 2*pad, n_C)
12     """
13     
14     ### START CODE HERE ### (≈ 1 line)
15     X_pad=np.pad(X,(
16                     (0,0),       #样本数,不填充
17                     (pad,pad),   #图像高度,你可以视为上面填充x个,下面填充y个(x,y)
18                     (pad,pad),   #图像宽度,你可以视为左边填充x个,右边填充y个(x,y)
19                     (0,0)),      #通道数,不填充
20                     'constant', constant_values=0)      #连续一样的值填充
21     ### END CODE HERE ###
22     
23     return X_pad

单步卷积

图中蓝色方框与滤波器进行作用,计算获得值-5的过程就是一次单步卷积。

 1 def conv_single_step(a_slice_prev, W, b):
 2     """
 3     Apply one filter defined by parameters W on a single slice (a_slice_prev) of the output activation 
 4     of the previous layer.
 5     
 6     Arguments:
 7     a_slice_prev -- slice of input data of shape (f, f, n_C_prev)
 8     W -- Weight parameters contained in a window - matrix of shape (f, f, n_C_prev)
 9     b -- Bias parameters contained in a window - matrix of shape (1, 1, 1)
10     
11     Returns:
12     Z -- a scalar value, result of convolving the sliding window (W, b) on a slice x of the input data
13     """
14 
15     ### START CODE HERE ### (≈ 2 lines of code)
16     # Element-wise product between a_slice and W. Do not add the bias yet.
17     s = np.multiply(a_slice_prev,W)
18     # Sum over all entries of the volume s.
19     Z=np.sum(s)
20     # Add bias b to Z. Cast b to a float() so that Z results in a scalar value.
21     Z=Z+float(b)
22     ### END CODE HERE ###
23 
24     return Z

卷积神经网络-前向传播

A_prev(shape = (5,5,3))的左上角选择一个2x2的矩阵进行切片操作:a_slice_prev = a_prev[0:2,0:2,:]

 1 def conv_forward(A_prev, W, b, hparameters):
 2     """
 3     Implements the forward propagation for a convolution function
 4 
 5     Arguments:
 6     A_prev -- output activations of the previous layer, numpy array of shape (m, n_H_prev, n_W_prev, n_C_prev)
 7     W -- Weights, numpy array of shape (f, f, n_C_prev, n_C)
 8     b -- Biases, numpy array of shape (1, 1, 1, n_C)
 9     hparameters -- python dictionary containing "stride" and "pad"
10 
11     Returns:
12     Z -- conv output, numpy array of shape (m, n_H, n_W, n_C)
13     cache -- cache of values needed for the conv_backward() function
14     """
15     ### START CODE HERE ###
16     # Retrieve dimensions from A_prev's shape (≈1 line)
17     (m, n_H_prev, n_W_prev, n_C_prev)=A_prev.shape
18     # Retrieve dimensions from W's shape (≈1 line)
19     (f, f, n_C_prev, n_C)=W.shape
20     # Retrieve information from "hparameters" (≈2 lines)
21     stride=hparameters['stride']
22     pad=hparameters['pad']
23 
24     # Compute the dimensions of the CONV output volume using the formula given above. Hint: use int() to floor. (≈2 lines)
25     n_H=int((n_H_prev+2*pad-f)/stride+1)
26     n_W=int((n_W_prev+2*pad-f)/stride+1)
27 
28     # Initialize the output volume Z with zeros. (≈1 line)
29     Z=np.zeros((m,n_H,n_W,n_C))
30 
31     # Create A_prev_pad by padding A_prev
32     A_prev_pad=zero_pad(A_prev, pad)
33 
34     for i in range(m):                               # loop over the batch of training examples
35         a_prev_pad = A_prev_pad[i]                     # Select ith training example's padded activation
36         for h in range(n_H):                           # loop over vertical axis of the output volume
37             for w in range(n_W):                       # loop over horizontal axis of the output volume
38                 for c in range(n_C):                   # loop over channels (= #filters) of the output volume
39 
40                     # Find the corners of the current "slice" (≈4 lines)
41                     vert_start=h*stride         #竖向,开始的位置
42                     vert_end=vert_start+f       #竖向,结束的位置
43                     horiz_start=w*stride        #横向,开始的位置
44                     horiz_end=horiz_start+f     #横向,结束的位置
45                     # Use the corners to define the (3D) slice of a_prev_pad (See Hint above the cell). (≈1 line)
46                     a_slice_prev = a_prev_pad[vert_start:vert_end,horiz_start:horiz_end,:]
47                     # Convolve the (3D) slice with the correct filter W and bias b, to get back one output neuron. (≈1 line)
48                     Z[i,h,w,c]=conv_single_step(a_slice_prev, W[:,:,:,c], b[0,0,0,c])
49     ### END CODE HERE ###
50 
51     # Making sure your output shape is correct
52     assert(Z.shape == (m, n_H, n_W, n_C))
53     # Save information in "cache" for the backprop
54     cache = (A_prev, W, b, hparameters)
55     return Z, cache

池化层

 1 def pool_forward(A_prev, hparameters, mode = "max"):
 2     """
 3     Implements the forward pass of the pooling layer
 4     
 5     Arguments:
 6     A_prev -- Input data, numpy array of shape (m, n_H_prev, n_W_prev, n_C_prev)
 7     hparameters -- python dictionary containing "f" and "stride"
 8     mode -- the pooling mode you would like to use, defined as a string ("max" or "average")
 9     
10     Returns:
11     A -- output of the pool layer, a numpy array of shape (m, n_H, n_W, n_C)
12     cache -- cache used in the backward pass of the pooling layer, contains the input and hparameters 
13     """
14     
15     # Retrieve dimensions from the input shape
16     (m, n_H_prev, n_W_prev, n_C_prev) = A_prev.shape
17     
18     # Retrieve hyperparameters from "hparameters"
19     f = hparameters["f"]
20     stride = hparameters["stride"]
21     
22     # Define the dimensions of the output
23     n_H = int(1 + (n_H_prev - f) / stride)
24     n_W = int(1 + (n_W_prev - f) / stride)
25     n_C = n_C_prev
26     
27     # Initialize output matrix A
28     A = np.zeros((m, n_H, n_W, n_C))              
29     
30     ### START CODE HERE ###
31     for i in range(m):                         # loop over the training examples
32         for h in range(n_H):                     # loop on the vertical axis of the output volume
33             for w in range(n_W):                 # loop on the horizontal axis of the output volume
34                 for c in range (n_C):            # loop over the channels of the output volume
35                     
36                     # Find the corners of the current "slice" (≈4 lines)
37                     vert_start = h * stride
38                     vert_end = vert_start + f
39                     horiz_start = w * stride
40                     horiz_end = horiz_start + f
41                     
42                     # Use the corners to define the current slice on the ith training example of A_prev, channel c. (≈1 line)
43                     a_prev_slice = A_prev[i, vert_start:vert_end, horiz_start:horiz_end, c]
44                     
45                     # Compute the pooling operation on the slice. Use an if statment to differentiate the modes. Use np.max/np.mean.
46                     if mode == "max":
47                         A[i, h, w, c] = np.max(a_prev_slice)
48                     elif mode == "average":
49                         A[i, h, w, c] = np.mean(a_prev_slice)   
50     ### END CODE HERE ###
51     
52     # Store the input and hparameters in "cache" for pool_backward()
53     cache = (A_prev, hparameters)   
54     # Making sure your output shape is correct
55     assert(A.shape == (m, n_H, n_W, n_C))
56     return A, cache

卷积层的反向传播(选学)

​ Wc是过滤器,dZhw是卷积层第h行第w列的使用点乘计算后的输出Z的梯度。

da_perv_pad[vert_start:vert_end,horiz_start:horiz_end,:] += W[:,:,:,c] * dZ[i,h,w,c]

dWc是一个过滤器的梯度,aslice是Zij的激活值

dW[:,:,:, c] += a_slice * dZ[i , h , w , c]

db[:,:,:,c] += dZ[ i, h, w, c] 
 1 def conv_backward(dZ, cache):
 2     """
 3     Implement the backward propagation for a convolution function
 4     
 5     Arguments:
 6     dZ -- gradient of the cost with respect to the output of the conv layer (Z), numpy array of shape (m, n_H, n_W, n_C)
 7     cache -- cache of values needed for the conv_backward(), output of conv_forward()
 8     
 9     Returns:
10     dA_prev -- gradient of the cost with respect to the input of the conv layer (A_prev),
11                numpy array of shape (m, n_H_prev, n_W_prev, n_C_prev)
12     dW -- gradient of the cost with respect to the weights of the conv layer (W)
13           numpy array of shape (f, f, n_C_prev, n_C)
14     db -- gradient of the cost with respect to the biases of the conv layer (b)
15           numpy array of shape (1, 1, 1, n_C)
16     """   
17     ### START CODE HERE ###
18     # Retrieve information from "cache"
19     (A_prev, W, b, hparameters)=cache
20     # Retrieve dimensions from A_prev's shape
21     (m, n_H_prev, n_W_prev, n_C_prev)=A_prev.shape
22     # Retrieve dimensions from W's shape
23     (f, f, n_C_prev, n_C)=W.shape
24     # Retrieve information from "hparameters"
25     stride=hparameters['stride']
26     pad=hparameters['pad']
27     # Retrieve dimensions from dZ's shape
28     (m, n_H, n_W, n_C)=dZ.shape
29     
30     # Initialize dA_prev, dW, db with the correct shapes
31     dA_prev=np.zeros((m, n_H_prev, n_W_prev, n_C_prev))
32     dW=np.zeros((f, f, n_C_prev, n_C))
33     db=np.zeros((1, 1, 1, n_C))
34     
35     # Pad A_prev and dA_prev
36     A_prev_pad=zero_pad(A_prev,pad)
37     dA_prev_pad=zero_pad(dA_prev, pad)
38     
39     for i in range(m):                       # loop over the training examples
40         
41         # select ith training example from A_prev_pad and dA_prev_pad
42         a_prev_pad = A_prev_pad[i]
43         da_prev_pad = dA_prev_pad[i]
44         
45         for h in range(n_H):                   # loop over vertical axis of the output volume
46             for w in range(n_W):               # loop over horizontal axis of the output volume
47                 for c in range(n_C):           # loop over the channels of the output volume
48                     
49                     # Find the corners of the current "slice"
50                     vert_start = h
51                     vert_end = vert_start + f
52                     horiz_start = w
53                     horiz_end = horiz_start + f
54                     
55                     # Use the corners to define the slice from a_prev_pad
56                     a_slice = a_prev_pad[vert_start:vert_end, horiz_start:horiz_end, :]
57                     # Update gradients for the window and the filter's parameters using the code formulas given above
58                     da_prev_pad[vert_start:vert_end, horiz_start:horiz_end,:] += W[:,:,:,c] * dZ[i, h, w, c]
59                     dW[:,:,:,c] += a_slice * dZ[i,h,w,c]
60                     db[:,:,:,c] += dZ[i,h,w,c]
61                     
62         # Set the ith training example's dA_prev to the unpaded da_prev_pad (Hint: use X[pad:-pad, pad:-pad, :])
63         dA_prev[i,:,:,:] = da_prev_pad[pad:-pad, pad:-pad, :]
64     ### END CODE HERE ###
65     
66     # Making sure your output shape is correct
67     assert(dA_prev.shape == (m, n_H_prev, n_W_prev, n_C_prev))   
68     return dA_prev, dW, db

池化层的反向传播(选学)

创建掩码矩阵(保存最大值位置)

def create_mask_from_window(x):
    """
    Creates a mask from an input matrix x, to identify the max entry of x.
    
    Arguments:
    x -- Array of shape (f, f)
    
    Returns:
    mask -- Array of the same shape as window, contains a True at the position corresponding to the max entry of x.
    """
    ### START CODE HERE ### (≈1 line)
    mask = x == np.max(x)
    ### END CODE HERE ###
    
    return mask

均值池化层的反向传播

 1 def distribute_value(dz, shape):
 2     """
 3     Distributes the input value in the matrix of dimension shape
 4     
 5     Arguments:
 6     dz -- input scalar
 7     shape -- the shape (n_H, n_W) of the output matrix for which we want to distribute the value of dz
 8     
 9     Returns:
10     a -- Array of size (n_H, n_W) for which we distributed the value of dz
11     """
12     
13     ### START CODE HERE ###
14     # Retrieve dimensions from shape (≈1 line)
15     (n_H, n_W) = shape
16     
17     # Compute the value to distribute on the matrix (≈1 line)
18     average = dz / (n_H * n_W)
19     
20     # Create a matrix where every entry is the "average" value (≈1 line)
21     a = np.ones(shape) * average
22     ### END CODE HERE ###
23     
24     return a

池化层的反向传播

 1 def pool_backward(dA, cache, mode = "max"):
 2     """
 3     Implements the backward pass of the pooling layer
 4     
 5     Arguments:
 6     dA -- gradient of cost with respect to the output of the pooling layer, same shape as A
 7     cache -- cache output from the forward pass of the pooling layer, contains the layer's input and hparameters 
 8     mode -- the pooling mode you would like to use, defined as a string ("max" or "average")
 9     
10     Returns:
11     dA_prev -- gradient of cost with respect to the input of the pooling layer, same shape as A_prev
12     """    
13     ### START CODE HERE ###    
14     # Retrieve information from cache (≈1 line)
15     (A_prev, hparameters) = cache    
16     # Retrieve hyperparameters from "hparameters" (≈2 lines)
17     stride = hparameters["stride"]
18     f = hparameters["f"]    
19     # Retrieve dimensions from A_prev's shape and dA's shape (≈2 lines)
20     m, n_H_prev, n_W_prev, n_C_prev = A_prev.shape
21     m, n_H, n_W, n_C = dA.shape
22     
23     # Initialize dA_prev with zeros (≈1 line)
24     dA_prev = np.zeros(A_prev.shape)
25     
26     for i in range(m):                       # loop over the training examples
27         # select training example from A_prev (≈1 line)
28         a_prev = A_prev[i]
29         for h in range(n_H):                   # loop on the vertical axis
30             for w in range(n_W):               # loop on the horizontal axis
31                 for c in range(n_C):           # loop over the channels (depth)
32                     # Find the corners of the current "slice" (≈4 lines)
33                     vert_start = h
34                     vert_end = vert_start + f
35                     horiz_start = w
36                     horiz_end = horiz_start + f
37                     
38                     # Compute the backward propagation in both modes.
39                     if mode == "max":
40                         # Use the corners and "c" to define the current slice from a_prev (≈1 line)
41                         a_prev_slice = a_prev[vert_start:vert_end, horiz_start:horiz_end, c]
42                         # Create the mask from a_prev_slice (≈1 line)
43                         mask = create_mask_from_window(a_prev_slice)
44                         # Set dA_prev to be dA_prev + (the mask multiplied by the correct entry of dA) (≈1 line)
45                         dA_prev[i, vert_start:vert_end, horiz_start:horiz_end, c] += np.multiply(mask, dA[i, h, w, c])
46                         
47                     elif mode == "average":
48                         # Get the value a from dA (≈1 line)
49                         da = dA[i, h, w, c]
50                         # Define the shape of the filter as fxf (≈1 line)
51                         shape = (f, f)
52                         # Distribute it to get the correct slice of dA_prev. i.e. Add the distributed value of da. (≈1 line)
53                         dA_prev[i, vert_start:vert_end, horiz_start:horiz_end, c] += distribute_value(da, shape)
54                         
55     ### END CODE ###
56     
57     # Making sure your output shape is correct
58     assert(dA_prev.shape == A_prev.shape) 
59     return dA_prev
原文地址:https://www.cnblogs.com/cxq1126/p/13149873.html