基于numpy实现离散卷积和CNN

复习了一下离散卷积,主要的步骤就是翻转、平移、相乘
复习了一下CNN的简单过程,并且看了一些卷机神经网络(CNN)反向传播算法,这个反向传播确实要比DNN的复杂一些,等过段时间写个博客总结一下吧。

基于numpy实现离散卷积


def conv(lst1, lst2):
    res = []
    lst1.reverse()
    len1 = len(lst1)
    len2 = len(lst2)

    for i in range(1, len1+1):   # 移入翻转后的第一个信号
        tmp = lst1[len1-i:]
        sum_area = sum((i*j for i, j in zip(tmp, lst2)))
        res.append(sum_area)
    for i in range(1, len2):    #移出翻转后的第一个信号
        tmp = lst2[i:]
        sum_area = sum(((i*j for i, j in zip(tmp, lst1))))
        res.append(sum_area)
    return res

if __name__ == '__main__':
    lst1 = [1, 2, 3]
    lst2 = [4, 5]
    print(conv(lst1, lst2))

基于numpy实现CNN

这部分代码是参考吴恩达 深度学习 编程作业 CNN4-1,没有写反向传播的部份了。

import numpy as np
import h5py
import matplotlib.pyplot as plt

# matplotlib inline
plt.rcParams['figure.figsize'] = (5.0, 4.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

# load_ext autoreload
# autoreload 2

np.random.seed(1)
def zeros_pad(X, pad):
    X_pad = np.pad(X, ((0,0), (pad,pad), (pad,pad), (0,0)), 'constant')
    return X_pad

def conv_singl_step(a_slice_prev, W, b):
    # a_slice_prev:(f, f, n_C_prev)   W:(f, f, n_C_prev)
    # b: (1, 1, 1)
    s = a_slice_prev*W
    z = np.sum(s)
    z = z+b
    return z

def conv_forward(A_prev, W, b, hparameters):
    # A_prev: (m, n_H_prev, n_W_prev, n_C_prev)
    # W: (f, f, n_C_prev, n_C)
    # b: (1, 1, 1, n_C)
    # hparameters: python dictionary containing "stride" and "pad"
    (m, n_H_prev, n_W_prev, n_C_prev) = A_prev.shape
    (f, f, n_C_prev, n_C) = W.shape
    stride = hparameters["stride"]
    pad = hparameters["pad"]

    n_H = int((n_H_prev-f+2*pad)/stride+1)
    n_W = int((n_W_prev-f+2*pad)/stride+1)

    Z = np.zeors((m, n_H, n_W, n_C))
    A_prev_pad = zeros_pad(A_prev, pad)

    for i in range(m):
        a_prev_pad = A_prev_pad[i, :, :, :]
        for h in range(n_H):
            for w in range(n_W):
                for c in range(n_C):
                    h_start = stride*h
                    h_end = h_start+f
                    w_start = stride*w
                    w_end = w_start+f

                    a_slice_prev = a_prev_pad[h_start:h_end, w_start:w_end, :]
                    Z[i, h, w, c] = conv_singl_step(a_slice_prev, W[:,:,:,c], b[:,:,:,c])

    assert Z.shape == (m, n_H, n_W, n_C)
    cache = (A_prev, W, b, hparameters)
    return Z, cache

def pool_forward(A_prev, hparameters, mode='max'):
    # A_prev : (m, n_H_prev, n_W_prev, n_C_prev)
    # hparameters : dictionary containing "f" and "stride"
    # mode : the pooling mode including "max" or "average"

    (m, n_H_prev, n_W_prev, n_C_prev) = A_prev.shape
    f = hparameters['f']
    stride = hparameters['stride']

    n_H = int((n_H_prev-f)/stride+1)
    n_W = int((n_W_prev-f)/stride+1)
    n_C = n_C_prev

    A = np.zeros((m, n_H, n_W, n_C))
    for i in range(m):
        for h in range(n_H):
            for w in range(n_W):
                for c in range(n_C):
                    h_start = h*stride
                    h_end = h_start+f
                    w_start = w*stride
                    w_end = w_start+f

                    a_prev_slice = A_prev[i, h_start:h_end, w_start:w_end, :]
                    if mode == 'max':
                        A[i, h, w, c] = np.max(a_prev_slice)
                    elif mode == 'average':
                        A[i, h, w, c] = np.mean(a_prev_slice)
    cache = (A_prev, hparameters)
    assert A.shape == (m, n_H, n_W, n_C)
    return A, cache

上一篇:thinkphp 数据缓存


下一篇:thinkphp empty标签