精华内容
下载资源
问答
  • keras环境下,搭建卷积神经网络,通过资料理解,可以掌握卷积神经网络运行机制以及每层训练参数的个数的计算方法。
  • 一、前言本文通过Python构建CNN(卷积神经网络)体系,对mnist(手写数字图片)进行识别,手写数字是从0到9,数据分为60000条训练集,10000条测试集。二、卷积神经网络搭建卷积神经网路与...卷积神经网络分为七部分...

    一、前言

    本文通过Python构建CNN(卷积神经网络)体系,对mnist(手写数字图片)进行识别,手写数字是从0到9,数据分为60000条训练集,10000条测试集。

    二、卷积神经网络搭建

    卷积神经网路与普通神经网络,最大的区别是其主要以卷积层和池化层为主,而普通神经网络主要以全连接层为主。卷积层和池化层不仅学习到数据的空间结构关系,还减少了模型的参数的数量,提升了学习的效率。卷积神经网络分为七个部分:数据预处理(Data Preprocessing)、卷积层构建(Convolution)、池化层构建(Pooling)、全连接层构建(Affine)、激活函数(Activation)、优化器(Optimizer)、损失函数(Loss Function)。

    1、数据预处理(Data Preprocessing)

    由于mnist数据是以压缩文件的形式储存的,所以需要对数据进行解压,以及图片大小进行变换定义操作。首先导入所需模块,以及数据文件、shape定义:

    import numpy as np

    import gzip

    key_file = {

    'train_img':'mnist/train-images-idx3-ubyte.gz',

    'train_label':'mnist/train-labels-idx1-ubyte.gz',

    'test_img':'mnist/t10k-images-idx3-ubyte.gz',

    'test_label':'mnist/t10k-labels-idx1-ubyte.gz'

    }

    train_num = 60000

    test_num = 10000

    img_dim = (1, 28, 28)

    img_size = 784

    编写数据的解压函数:

    def load_mnist(normalize=True, flatten=True, one_hot_label=False):

    dataset = {}

    for key, file in key_file.items():

    if 'label' not in key:

    with gzip.open(file, 'rb') as f:

    data = np.frombuffer(f.read(), np.uint8, offset=16)

    data = data.reshape(-1, img_size)

    dataset[key] = data

    else:

    with gzip.open(file, 'rb') as f:

    labels = np.frombuffer(f.read(), np.uint8, offset=8)

    dataset[key] = labels

    if not flatten:

    for key in ('train_img', 'test_img'):

    dataset[key] = dataset[key].reshape(-1, 1, 28, 28)

    return (dataset['train_img'], dataset['train_label']), (dataset['test_img'], dataset['test_label'])

    flatten参数的意思是否要对数据进项展开。

    将数据分为训练数据集和测试数据集:

    (x_train, y_train), (x_test, y_test) = load_mnist(flatten=False)

    2、卷积层构建(Convolution)

    由于数据的结构,在运行卷积运算的时候,会嵌套好几层的for循环语句,导致计算速度过慢。通过编写im2col函数,将输入数据展开以适合滤波器,实现将3维数据转换为2维矩阵,从而可以进行向量运算,提升运算效率。

    im2col函数实现:

    def im2col(input_data, filter_h, filter_w, stride=1, pad=0):

    N, C, H, W = input_data.shape

    out_h = (H + 2*pad - filter_h) // stride + 1

    out_w = (W + 2*pad - filter_w) // stride + 1

    img = np.pad(input_data, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant')

    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))

    for y in range(filter_h):

    y_max = y + stride*out_h

    for x in range(filter_w):

    x_max = x + stride*out_w

    col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]

    col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)

    return col

    卷积层在进行反向传播的优化运算时候,im2col展开的数据不利于进行,需要进行im2col的逆处理。

    col2im(im2col的逆处理)函数定义:

    def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):

    N, C, H, W = input_shape

    out_h = (H + 2*pad - filter_h) // stride + 1

    out_w = (W + 2*pad - filter_w) // stride + 1

    col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)

    img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))

    for y in range(filter_h):

    y_max = y + stride*out_h

    for x in range(filter_w):

    x_max = x + stride*out_w

    img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]

    return img[:, :, pad:H + pad, pad:W + pad]

    卷积层运算定义,需要定义卷积层的正向传播运算(forward)和反向传播运算(backward):

    class Convolution:

    def __init__(self, W, b, stride=1, pad=0):

    self.W = W

    self.b = b

    self.stride = stride

    self.pad = pad

    self.x = None

    self.col = None

    self.col_W = None

    self.dW = None

    self.db = None

    def forward(self, x):

    FN, C, FH, FW = self.W.shape

    N, C, H, W = x.shape

    out_h = 1 + int((H + 2*self.pad - FH) / self.stride)

    out_w = 1 + int((W + 2*self.pad - FW) / self.stride)

    col = im2col(x, FH, FW, self.stride, self.pad)

    col_W = self.W.reshape(FN, -1).T

    out = np.dot(col, col_W) + self.b

    out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

    self.x = x

    self.col = col

    self.col_W = col_W

    return out

    def backward(self, dout):

    FN, C, FH, FW = self.W.shape

    dout = dout.transpose(0, 2, 3, 1).reshape(-1, FN)

    self.db = np.sum(dout, axis=0)

    self.dW = np.dot(self.col.T, dout)

    self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)

    dcol = np.dot(dout, self.col_W.T)

    dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)

    return dx

    3、池化层构建(Pooling)

    池化层是对卷积层进行下采样操作,缩小高、长方向上的空间运算,池化运算分为Max池化和Average池化,一般池化运算的步幅和池化窗口大小保持一致,本次采用Max池化运算,即取池化窗口的最大值。

    池化层定义:

    class Pooling:

    def __init__(self, pool_h, pool_w, stride=1, pad=0):

    self.pool_h = pool_h

    self.pool_w = pool_w

    self.stride = stride

    self.pad = pad

    self.x = None

    self.arg_max = None

    def forward(self, x):

    N, C, H, W = x.shape

    out_h = int(1 + (H - self.pool_h) / self.stride)

    out_w = int(1 + (W - self.pool_w) / self.stride)

    col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)

    col = col.reshape(-1, self.pool_h*self.pool_w)

    arg_max = np.argmax(col, axis=1)

    out = np.max(col, axis=1)

    out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

    self.x = x

    self.arg_max = arg_max

    return out

    def backward(self, dout):

    dout = dout.transpose(0, 2, 3, 1)

    pool_size = self.pool_h * self.pool_w

    dmax = np.zeros((dout.size, pool_size))

    dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten()

    dmax = dmax.reshape(dout.shape + (pool_size,))

    dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)

    dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad)

    return dx

    4、全连接层构建(Affine)

    卷积神经网络最后的输出层是由全连接层进行构建,便于输出数据结果的完整性。

    全连接层定义:

    class Affine:

    def __init__(self, W, b):

    self.W = W

    self.b = b

    self.x = None

    self.original_x_shape = None

    self.dW = None

    self.db = None

    def forward(self, x):

    self.original_x_shape = x.shape

    x = x.reshape(x.shape[0], -1)

    self.x = x

    out = np.dot(self.x, self.W) + self.b

    return out

    def backward(self, dout):

    dx = np.dot(dout, self.W.T)

    self.dW = np.dot(self.x.T, dout)

    self.db = np.sum(dout, axis=0)

    dx = dx.reshape(*self.original_x_shape)

    return dx

    5、激活函数(Activation)

    深度学习中常用的激活函数有:sigmoid函数、relu函数、tanh函数、softmax函数等。由于mnist是多分类输出的图片识别,因此主要用到relu函数和softmax函数。

    relu函数分布是小于0的结果都为0,大于0的结果为输入,以至于relu函数降低一般的计算量,提升计算的效率。定义如下:

    class Relu:

    def __init__(self):

    self.mask = None

    def forward(self, x):

    self.mask = (x <= 0)

    out = x.copy()

    out[self.mask] = 0

    return out

    def backward(self, dout):

    dout[self.mask] = 0

    dx = dout

    return dx

    softmax函数常用与多输出的运行,各分类输出的总和为1。定义如下:

    def softmax(x):

    if x.ndim == 2:

    x = x.T

    x = x - np.max(x, axis=0)

    y = np.exp(x) / np.sum(np.exp(x), axis=0)

    return y.T

    x = x - np.max(x)

    return np.exp(x) / np.sum(np.exp(x))

    6、优化器(Optimizer)

    深度学习目前常用的优化器有:SGD(随机梯度下降)、Momentum、AdaGrad、Adam等。由于Adam优化器相对有较快的运算速度,并能够很好的收敛的特点,所以本次优化器采用Adam优化器。

    Adam优化器定义:

    class Adam:

    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):

    self.lr = lr

    self.beta1 = beta1

    self.beta2 = beta2

    self.iter = 0

    self.m = None

    self.v = None

    def update(self, params, grads):

    if self.m is None:

    self.m, self.v = {}, {}

    for key, val in params.items():

    self.m[key] = np.zeros_like(val)

    self.v[key] = np.zeros_like(val)

    self.iter += 1

    lr_t = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter)

    for key in params.keys():

    self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])

    self.v[key] += (1 - self.beta2) * (grads[key] ** 2 - self.v[key])

    params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)

    7、损失函数(Loss Function)

    本次的mnist是属于多分类的任务,所以采用交叉熵来计算模型的损失,由于交叉熵能够用梯度来优化模型。

    交叉熵损失函数定义:

    def cross_entropy_error(y, t):

    if y.ndim == 1:

    t = t.reshape(1, t.size)

    y = y.reshape(1, y.size)

    if t.size == y.size:

    t = t.argmax(axis=1)

    batch_size = y.shape[0]

    return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size

    损失函数的反向传播函数定义:

    class SoftmaxWithLoss:

    def __init__(self):

    self.loss = None

    self.y = None

    self.t = None

    def forward(self, x, t):

    self.t = t

    self.y = softmax(x)

    self.loss = cross_entropy_error(self.y, self.t)

    return self.loss

    def backward(self, dout=1):

    batch_size = self.t.shape[0]

    if self.t.size == self.y.size:

    dx = (self.y - self.t) / batch_size

    else:

    dx = self.y.copy()

    dx[np.arange(batch_size), self.t] -= 1

    dx = dx / batch_size

    return dx

    最后将搭建卷积神经网络(SimpleConvNet)的总体模型:

    SimpleConvNet卷积神经网络实现predict(预测)、loss(损失计算)、accuracy(准确计算)、gradient(梯度计算)、save_params(保存权重)、load_params(读取权重)等功能。

    class SimpleConvNet:

    def __init__(self, input_dim=(1, 28, 28),

    conv_param={'filter_num': 30, 'filter_size': 5, 'pad': 0, 'stride': 1},

    hidden_size=100, output_size=10, weight_init_std=0.01):

    filter_num = conv_param['filter_num']

    filter_size = conv_param['filter_size']

    filter_pad = conv_param['pad']

    filter_stride = conv_param['stride']

    input_size = input_dim[1]

    conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride + 1

    pool_output_size = int(filter_num * (conv_output_size/2) * (conv_output_size/2))

    self.params = {}

    self.params['W1'] = weight_init_std * np.random.randn(filter_num,

    input_dim[0], filter_size, filter_size)

    self.params['b1'] = np.zeros(filter_num)

    self.params['W2'] = weight_init_std * np.random.randn(pool_output_size, hidden_size)

    self.params['b2'] = np.zeros(hidden_size)

    self.params['W3'] = weight_init_std * np.random.randn(hidden_size, output_size)

    self.params['b3'] = np.zeros(output_size)

    self.layers = OrderedDict()

    self.layers['Conv1'] = Convolution(self.params['W1'], self.params['b1'],

    conv_param['stride'], conv_param['pad'])

    self.layers['Relu1'] = Relu()

    self.layers['Pool1'] = Pooling(pool_h=2, pool_w=2, stride=2)

    self.layers['Affine1'] = Affine(self.params['W2'], self.params['b2'])

    self.layers['Relu2'] = Relu()

    self.layers['Affine2'] = Affine(self.params['W3'], self.params['b3'])

    self.last_layer = SoftmaxWithLoss()

    def predict(self, x):

    for layer in self.layers.values():

    x = layer.forward(x)

    return x

    def loss(self, x, t):

    y = self.predict(x)

    return self.last_layer.forward(y, t)

    def accuracy(self, x, t, batch_size=100):

    if t.ndim != 1: t = np.argmax(t, axis=1)

    acc = 0.0

    for i in range(int(x.shape[0] / batch_size)):

    tx = x[i*batch_size:(i+1)*batch_size]

    tt = t[i*batch_size:(i+1)*batch_size]

    y = self.predict(tx)

    y = np.argmax(y, axis=1)

    acc += np.sum(y == tt)

    return acc / x.shape[0]

    def gradient(self, x, t):

    self.loss(x, t)

    dout = 1

    dout = self.last_layer.backward(dout)

    layers = list(self.layers.values())

    layers.reverse()

    for layer in layers:

    dout = layer.backward(dout)

    grads = {}

    grads['W1'], grads['b1'] = self.layers['Conv1'].dW, self.layers['Conv1'].db

    grads['W2'], grads['b2'] = self.layers['Affine1'].dW, self.layers['Affine1'].db

    grads['W3'], grads['b3'] = self.layers['Affine2'].dW, self.layers['Affine2'].db

    return grads

    def save_params(self, file_name='params.pkl'):

    params = {}

    for key, val in self.params.items():

    params[key] = val

    with open(file_name, 'wb') as f:

    pickle.dump(params, f)

    def load_params(self, file_name='params.pkl'):

    with open(file_name, 'rb') as f:

    params = pickle.load(f)

    for key, val in params.items():

    self.params[key] = val

    for i, key in enumerate(['Conv1', 'Affine1', 'Affine2']):

    self.layers[key].W = self.params['W' + str(i + 1)]

    self.layers[key].b = self.params['b' + str(i + 1)]

    通过搭建的卷积神经网络模型,得到最好的测试成绩为99%的正确率。

    当然后续还可以采用Dropout方法以便于使用更复杂的网络架构、数据增强、预训练的卷积神经网络等方法进一步提升预测的准确率。

    总体来说,在图片识别的方法上,卷积神经网络有着较强的优势,但是同样面临着一些挑战,如何合理的调节超参数?由于重头运算对于计算的开销,将会花费不少的时间,当然也可以凭借以往的一些经验,合理的尝试一些比较好的取值,深度学习还存在较大的发展空间,保持不断学习,运用新的方法,就像Geoffrey Hinton开发Dropout方法一样,灵感之一来自于银行防欺诈机制。

    展开全文
  • 今天,我们来分享一篇博文,关于如何计算图像张量的大小以及确定卷积神经网络各层参数个数的公式。假设我们已经熟悉了卷积神经网络相关概念。在这里,我们把张量定义为有任意通道数的图像。 我们将用AlexNet作为例子...

    今天,我们来分享一篇博文,关于如何计算图像张量的大小以及确定卷积神经网络各层参数个数的公式。假设我们已经熟悉了卷积神经网络相关概念。在这里,我们把张量定义为有任意通道数的图像。

    张量是在深度学习中表示数据的标准方式。
    简单来说,张量是二维表(矩阵)到更高维的扩展。

    有效AttributeError: module ‘tensorflow’ has no attribute "…"解决办法
    一般,这是由于版本不兼容的问题,中间加上compat.v1

    tf.compat.v1.placeholder
    

    我们将用AlexNet作为例子,在这里我们把AlexNet的结构拿来参考。
    在这里插入图片描述
    在这里,我们先来了解AlexNet的结构

    1. 输入层:彩色图片的大小2272273
    2. 卷积层1:96 kernels 11*11 步长4 零边距填充
    3. 最大池化层1:3*3 步长2 避免平均池化的模糊化效果
    4. 卷积层2:256 kernels 5*5 步长1 填充2
    5. 最大池化层2:3*3 步长2 避免平均池化的模糊化效果
    6. 卷积层3:384 kernels 3*3 步长1 填充1
    7. 卷积层4:384 kernels 3*3 步长1 填充1
    8. 卷积层2:256 kernels 3*3 步长1 填充1
    9. 最大池化层3:3*3 步长2 避免平均池化的模糊化效果
    10. 全连接层1:4096神经元
    11. 全连接层2:4096神经元
    12. 全连接层3:1000神经元
      其中,最大池化是可重叠的,步长小于窗口宽度。分批(Batches) 和 周期(Epochs)在使用训练集训练神经网络的时候,相比于一次将所有的样本全部输入到网络中,一个更好的选择是:先将数据随机地分为几个大小一致的数据块,再分批次输入。跟一次性训练出来的模型相比,分批训练能够使模型的适用性更好。一个Epoch表示,对所有的Batch都进行了一次训练。

    AlexNet 的特点如下:

    更深的网络结构
    使用层叠的卷积层,即卷积层+卷积层+池化层来提取图像的特征
    使用Dropout抑制过拟合
    使用数据增强Data Augmentation抑制过拟合
    使用Relu替换之前的sigmoid的作为激活函数
    多GPU训练
    

    其中,数据增强部分,神经网络由于训练的参数多,表能能力强,所以需要比较多的数据量,不然很容易过拟合。当训练数据有限时,可以通过一些变换从已有的训练数据集中生成一些新的数据,以快速地扩充训练数据。对于图像数据集来说,可以对图像进行一些形变操作:翻转/随机裁剪/平移,颜色光照的变换

    下面,重点来了:
    卷积神经网络的参数个数和张量大小(翻译),每一层具体的练习结果参考上方链接。

    确定张量大小

    How to calculate the tensor size at each stage
    How to calculate the total number of parameters in the network

    我们先来明确各变量名称

    变量 含义
    O 输出图像的大小
    I 输入图像的大小
    K 卷积层所用卷积核大小
    N 卷积核数量
    S 步长
    P 边界填补

    卷积层输出张量大小

    O=IK+2PS+1O= \frac{I-K+2P}{S}+1
    输出图像的通道个数等于我们使用的卷积核的个数。
    例如:在 AlexNet,输入图像大小为2272273227*227*3,第一个卷积层有96个1111311*11*3卷积核,步长为4,没有边界填充。第一个卷积层输出大小便是
    O=22711+204+1=55O = \frac{227-11+2*0}{4}+1 = 55
    输出张量大小为555596
    在 LeNet,输入图像大小为32321,第一个卷积层有6个551卷积核,步长为1,边界填充和输入相同。
    第一个卷积层输出大小便是?
    O=325+201+1=28O = \frac{32-5+2*0}{1}+1 = 28
    输出张量大小为2828628*28*6

    # Conv2D layer
      X = keras.layers.Conv2D(filters=6, kernel_size=(5, 5), strides=(1, 1), 
                              activation='tanh', 
                              padding='same', name="leNet5_conv1")(X_in)
    

    池化层输出张量大小

    变量 含义
    O 输出图像的大小
    I 输入图像的大小
    S 步长
    PsP_s 池化大小

    O=IPsS+1O=\frac{I-P_s}{S}+1
    这个公式可以从卷积层公式推导出来,只需要把边界填充看作0,让池化大小等价于卷积核大小。需要注意的是,池化层并不改变输出通道的大小。假设本层输入张量大小为28286
    O=2821+1O=\frac{28-2}{1}+1
    输出张量大小为27276

     # Pooling layer
      X = keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(1, 1), padding='valid')(X)
    

    全连接层的输出张量大小

    等价于该层的神经元的个数

    def leNet5(input_shape):
      """
      Define the LeNet-5
      Input:
        input_shape [tuple]: shape of input image (height, width, channel)
      Output:
        model (a tensorflow model instance)
      """
      
      # Input layer
      X_in = keras.layers.Input(shape=input_shape)
      
      
      # Conv2D layer
      X = keras.layers.Conv2D(filters=6, kernel_size=(5, 5), strides=(1, 1), 
                              activation='tanh', 
                              padding='same', name="leNet5_conv1")(X_in)
      
      # Pooling layer
      X = keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(1, 1), padding='valid')(X)
    
      # Conv2D
      X = keras.layers.Conv2D(filters=16, kernel_size=(5, 5), strides=(1, 1), 
                              activation='tanh', 
                              padding='valid', name='leNet5_conv2')(X)
    
      # Pooling layer
      X = keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid')(X)
    
      # Conv2D
      X = keras.layers.Conv2D(filters=120, kernel_size=(5, 5), strides=(1, 1), 
                              activation='tanh', 
                              padding='valid', name='leNet5_conv3')(X)
      
      # Flatten CNN output so that it can be connected to dense layer
      X = keras.layers.Flatten()(X)
    
      # Dense
      X = keras.layers.Dense(84, activation='tanh')(X)
    
      # Output layer
      y = keras.layers.Dense(10, activation='softmax')(X)
    
      model = keras.Model(inputs=X_in, outputs=y, name='leNet5')
      return model
    

    确定参数大小

    变量 含义
    WcW_c 卷积权重
    BcB_c 卷积偏置
    P 卷积层所用参数数量
    N 卷积核数量
    K 卷积核大小(宽度)
    C 输入图像的通道

    Wc=K2CNW_c = K^2*C*N
    Bc=NB_c = N
    Pc=Wc+BcP_c = W_c + B_c

    卷积层的参数

    CNN里面,有两种参数,权重和偏置

    全连接层的参数

    全连接层与全连接层相互连接的参数,感性认识,F 代表全连接层含有的神经元个数,F1F_{-1}代表上一个全连接层含有的神经元个数$$
    参考人工智能实验课——神经网络手写数字识别学习笔记(二)

    Wff=F1FW_{ff} = F_{-1}*F
    Bff=FB_{ff} = F
    Pff=Wff+BffP_{ff} = W_{ff} + B_{ff}
    全连接层与卷积层相互连接的参数

    变量 含义
    WcfW_{cf} FC卷积权重
    BcfB_{cf} FC卷积偏置
    O 上一卷积层输出张量大小
    N 上一卷积层的卷积核个数
    F FC 神经元个数

    Wcf=O2NFW_{cf} = O^2 * N*F
    Bcf=FB_{cf} = F
    Pcf=Wcf+BcfP_{cf} = W_{cf}+B_{cf}

    今日写CSDN的背景音乐是:)
    The Music of the Night (From “The Phantom of the Opera”)

    Night-time sharpens, heightens each sensation
    夜色渐暗,激发灵感
    Darkness stirs and wakes imagination
    黑暗作祟,唤醒想像空间
    Silently the senses abandon their defenses
    潜移默化,感官放弃抵抗

    Slowly, gently, night unfurls its splendor
    缓缓的,轻柔的,夜色展现光彩
    Grasp it,sense it, tremulous and tender
    抓住它,感受它,颤栗而轻柔
    Turn your face away form the garish light of day
    别再回顾炫彩夺目的白天
    Turn your thoughts away from cold unfeeling light
    别再想那些冷酷无情的光线
    And listen to the music of the night
    聆听这暗夜的乐音吧

    展开全文
  • keras搭建卷积神经网络构建模型参数个数计算方式 计算过程 (1)用一十二个333的卷积核对三通道图像1501503进行卷积。每一个卷积核有一个偏置。则此层参数个数为(333+1)12=336。 (2)经过上面的操作,生成了一...

    keras搭建卷积神经网络构建模型参数个数计算方式

    在这里插入图片描述

    计算过程
    (1)用一十二个3x3x3的卷积核对三通道图像150x150x3进行卷积。每一个卷积核有一个偏置。则此层参数个数为(3x3x3+1)x12=336。
    (2)经过上面的操作,生成了一十二幅尺寸为150x150x1的图像。则用五个3x3x12的卷积核对单通道图像150x150x1进行卷积。每个卷积核有一个偏置。此层参数的个数为(3x3x12+1)x5=545。(3)卷积后,进行padding补零。后得到五个75x75的单通道的灰度图像。
    (4)将图像的每一个像素看成一个神经元,然后平铺开来有神经元个数75x75x5=28125个。(5)上面的28125个神经元与第一个dense层的128个神经元全链接,有未知参数个数(75x75x5+1)x128=3600128个。
    (6)上面的128个神经元与最后一个dense层的十个输出神经元全连接,有未知参数个数(128+1)x10=1290个。
    (7)因此,总共的未知参数个数为336+545+3600128+1290=3602299个。

    计算结果

    在这里插入图片描述

    展开全文
  • 如果您参考具有16层的VGG...观察由3 x conv3-256 层组成的第3个卷积阶段:第一有N = 128输入平面,F = 256输出平面,另外两有N = 256输入平面和F = 256输出平面 .对于这些层中的每一层,卷积核为3x3 ....

    如果您参考具有16层的VGG网络(表1,列D),则 138M 指的是该网络的 total number of parameters ,即包括所有卷积层,但也包括完全连接的层 .

    观察由3 x conv3-256 层组成的第3个卷积阶段:

    第一个有N = 128个输入平面,F = 256个输出平面,

    另外两个有N = 256个输入平面和F = 256个输出平面 .

    对于这些层中的每一层,卷积核为3x3 . 在参数方面,这给出了:

    128x3x3x256(权重)256(偏差)=第一个参数295,168,

    256x3x3x256(权重)256(偏差)=另外两个参数的590,080个参数 .

    如上所述,您必须对所有层执行此操作,但也必须对完全连接的层执行此操作,并将这些值相加以获得最终的138M数 .

    UPDATE :各层之间的细分给出:

    conv3-64 x 2 : 38,720

    conv3-128 x 2 : 221,440

    conv3-256 x 3 : 1,475,328

    conv3-512 x 3 : 5,899,776

    conv3-512 x 3 : 7,079,424

    fc1 : 102,764,544

    fc2 : 16,781,312

    fc3 : 4,097,000

    TOTAL : 138,357,544

    特别是对于完全连接的层(fc):

    fc1 (x): (512x7x7)x4,096 (weights) + 4,096 (biases)

    fc2 : 4,096x4,096 (weights) + 4,096 (biases)

    fc3 : 4,096x1,000 (weights) + 1,000 (biases)

    (x)参见本文第3.2节:首先将完全连接的层转换为卷积层(第一个FC层转换为7×7转换层,最后两个FC层转换为1×1转换层) .

    Details about fc1

    如上所述,在馈送完全连接的层之前的空间分辨率是7x7像素 . 这是因为这个VGG Net在卷积之前使用了空间填充,详见本文第2.1节:

    [...] conv的空间填充 . 层输入使得在卷积之后保留空间分辨率,即,对于3×3转换,填充是1个像素 . 层 .

    使用这样的填充,并使用224x224像素输入图像,分辨率随着以下层逐渐减少:112x112,56x56,28x28,14x14和7x7在具有512个特征映射的最后卷积/池化阶段之后 .

    这给出了一个传递给 fc1 的特征向量,其维数为:512x7x7 .

    展开全文
  • 卷积神经网络的卷积核大小、卷积层数、每层map个数都是如何确定下来的呢?看到有些答案是刚开始随机初始化卷积核大小,卷积层数和map个数是根据经验来设定的,但这个里面应该是有深层次原因吧,比如下面的手写字卷积...
  • 而每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。参数共享参数共享最大的作用莫过于很大限度地减少运算量了。多核一般我们都不会只用一...
  • 一、卷积神经网络参数计算 CNN一牛逼的地方就在于通过感受野和权值共享减少了神经网络需要训练的参数的个数,所谓权值共享就是同一Feature Map中神经元权值共享,该Feature Map中的所有神经元使用同一权值。...
  • 卷积神经网络参数优化策略(一)

    千次阅读 2020-05-14 11:20:53
    最近卷积神经网络(CNN)很火热,它在图像分类领域的卓越表现引起了大家的广泛关注。本文总结和摘录了Michael Nielsen的那本Neural Network and Deep Learning一书中关于深度学习一章中关于提高泛化能力的一些概述和...
  • 全连接,隐层神经元的数目为 10610^6 时,则每一输入像素与每一隐层神经元之间都是待学习的参数, 数目为 106×106=101210^6\times 10^6=10^{12} 卷积卷积核的大小为 10×1010\times 10 时, 步长为 10,103...
  • 卷积神经网络的卷积核大小、卷积层数、每层map个数都是如何确定下来的呢?看到有些答案是刚开始随机初始化卷积核大小,卷积层数和map个数是根据经验来设定的,但这个里面应该是有深层次原因吧,比如下面的手写字卷积...
  • 卷积神经网络是一多层的神经网络,每层由多二维平面组成,而每平面由多独立神经元组成。  图:卷积神经网络的概念示范:输入图像通过和三可训练的滤波器和可加偏置进行卷积,滤波过程如图一,卷积后在C1...
  • 卷积神经网络CNN是多层神经网络的一个变种,传统的多层神经网络,当隐层数变多时,节点数目过多时就会造成参数个数过多,训练难度极大。这时会想,如果在该网络中藏有一种深层的神经网络模型,在该模型中,参数个数...
  • CNN 卷积神经网络卷积神经网络(Convolutional Neural Network,CNN)是图像处理领域最为常见的一种深度学习方法。在图像处理领域,网络的输入是像素点组成的高维特征,如果仍然使用传统的前馈神经网络主要存在...
  • 卷积后卷积层大小 W2= (W1-F+2P)/S +1 ... 即(卷积核宽x卷积核高)x卷积核的个数 + 偏差个数(即卷积核的个数,每一层有一个bias) Padding的大小 P = (F-S)/2 即(卷积核的宽度-步长)的一半 ...
  • 卷积神经网络个数,维数是根据经验,请问初始化怎样,听说是初始化为很小值,请问 又根据什么调整卷积核的参数呢?
  • 卷积神经网络参数量和计算量的计算

    万次阅读 多人点赞 2019-08-15 15:49:08
    0 前言 我们在设计一个CNN网络时,通常要考虑两个事情,一个是这个网络需要的计算量有多大,一个是这个模型的...参数量以参数个数为单位,要计算内存或显存的,用参数量乘以每个参数所占的字节数即可。 1 计算量 ...
  • 参考:https://www.cnblogs.com/hejunlin1992/p/7624807.html举例1: 比如输入是一32x32x3的图像,3表示RGB三通道,每filter/kernel是5x5x3,一个卷积核产生一feature map,下图中,有65x5x3的卷积核,故...
  • 神经网络学习(十三)卷积神经网络的MATLAB实现

    万次阅读 多人点赞 2018-03-27 16:08:28
    上一节,我们简单探讨了卷积神经网络的反向传播算法,本节我们着手实现了一简单的卷积神经网,在此之前先以最基本的批量随机梯度下降法+L2正则化对对卷积神经网络的反向传播算法做一很简单回顾。 需要确定...
  • 本篇文章来自于learnopencv....在这篇文章中,我们分享了一些公式来计算张量(图像)的大小和卷积神经网络(CNN)中每一层的参数个数。 此帖子不定义CNN中使用的基本术语...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 707
精华内容 282
关键字:

卷积神经网络参数个数