神经网络基础

神经网络基础

在这里插入图片描述

传统神经网络

神经网络可以视为一个满足拓扑排序的无环有向图,这张图可以按层铺开,最低的一层表示输入,入度为0,而最高的一层为输出,出度为0。两个神经元之间的边具有特定的权。

除去输入神经元和输出神经元,图中每一个神经元都连接着上一层所有神经元,同时也连接到下一层所有的神经元。每一个神经元直接获取输入或者从上一层获取输入,这些输入首先加权,然后求和,最后通过激活函数,产生本神经元的输出,如果还存在下一层神经元,那么输出会继续传递下去。

通过不断地进行以上步骤,神经网络便能够将原始输入逐层传递,最终在输出层得到输出,完成预测。

优化函数:
我们可以看出神经网络层次越多,网络越复杂,直接求解几乎不可能,因此我们直接采用随机梯度下降的方法。

也正是因此,神经网络的优化函数很简单,f=y’-y。y’代表预测值,y代表真实值。我们训练的目标便是,不断调整神经元之间的权值使得f=y’-y最小。

训练方式:
科学家们发明出一套反向自动微分的方法用于学习,它通过两次遍历神经网络进行梯度下降,第一次正向遍历,是从输入层到输入层,计算预测值,进而得到误差值,第二次反向遍历,从输入层到输出层,将误差的影响从输出层传递回输入层,并且在过程中,对神经元间的权值进行调整,以实现梯度下降。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CNN

卷积
离散卷积的数学公式可以表示为如下形式:

f(x) = - 其中C(k)代表卷积操作数,g(i)代表样本数据, f(x)代表输出结果。

举例如下:

假设g(i)是一个一维的函数,而且代表的样本数为G = [1,2,3,4,5,6,7,8,9]

假设C(k)是一个一维的卷积操作数, 操作数为C=[-1,0,1]

则输出结果f(x)可以表示为 F=[1,2,2,2,2,2,2,2,1] //边界数据未处理

以上只是一维的情况下,当对一幅二维数字图像加以卷积时,其数学意义可以解释如下:

源图像是作为输入源数据,处理以后要的图像是卷积输出结果,卷积操作数作为Filter

在XY两个方向上对源图像的每个像素点实施卷积操作。如图所示:

粉红色的方格每次在X/Y前进一个像素方格,就会产生一个新的输出像素,图中深蓝色的代

表要输出的像素方格,走完全部的像素方格,就得到了所有输出像素。
卷积运算
CNN

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
具有三个特性:
稀疏连接
参数共享
等变表示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

目标分类:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

目标探测:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

循环神经网络RNN

在这里插入图片描述
在这里插入图片描述

CNN+RNN

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对抗网络GAN

在这里插入图片描述

迁移学习:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

AlexNet经典卷积网络

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
AlexNet经典卷积网络
"""
import tensorflow as tf
import time
from datetime import datetime
import math


def inference_op(images):
    """
    实现前向传播

    """

    # 实现第一个卷积层
    with tf.name_scope('conv1'):
        parameter = []

        kernel = tf.Variable(tf.truncated_normal([11, 11, 3, 96], stddev=0.1), name='weights')
        conv = tf.nn.conv2d(images, kernel, strides=[1, 4, 4, 1], padding='SAME')
        bias = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[96]), trainable=True, name='bias')
        conv1 = tf.nn.relu(tf.nn.bias_add(conv, bias))

        # 打印第一个卷积层
        print(conv1.op.name, '', conv1.get_shape().as_list())
        parameter += [kernel, bias]

    # 添加一个LRN层和最大池化层
    lrn1 = tf.nn.lrn(conv1, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='lrn1')
    pool1 = tf.nn.max_pool(lrn1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID', name='pool1')
    # 打印该网络结构
    print(pool1.op.name, '', pool1.get_shape().as_list())

    # 实现第二个卷积层
    with tf.name_scope('conv2'):
        kernel = tf.Variable(tf.truncated_normal([5, 5, 96, 256], stddev=0.1), name='weights')
        conv = tf.nn.conv2d(pool1, kernel, strides=[1, 1, 1, 1], padding='SAME')
        bias = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name='bias')
        conv2 = tf.nn.relu(tf.nn.bias_add(conv, bias))

        # 打印第二个卷积层
        print(conv2.op.name, '', conv2.get_shape().as_list())
        parameter += [kernel, bias]

    # 添加一个LRN层和最大池化层
    lrn2 = tf.nn.lrn(conv2, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='lrn2')
    pool2 = tf.nn.max_pool(lrn2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID', name='pool2')
    # 打印该网络结构
    print(pool2.op.name, '', pool2.get_shape().as_list())

    # 实现第三个卷积层
    with tf.name_scope('conv3'):
        kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 384], stddev=0.1), name='weights')
        conv = tf.nn.conv2d(pool2, kernel, strides=[1, 1, 1, 1], padding='SAME')
        bias = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[384]), trainable=True, name='bias')
        conv3 = tf.nn.relu(tf.nn.bias_add(conv, bias))

        # 打印第三个卷积层
        print(conv3.op.name, '', conv3.get_shape().as_list())
        parameter += [kernel, bias]

    # 实现第四个卷积层
    with tf.name_scope('conv4'):
        kernel = tf.Variable(tf.truncated_normal([3, 3, 384, 384], stddev=0.1), name='weights')
        conv = tf.nn.conv2d(conv3, kernel, strides=[1, 1, 1, 1], padding='SAME')
        bias = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[384]), trainable=True, name='bias')
        conv4 = tf.nn.relu(tf.nn.bias_add(conv, bias))

        # 打印第四个卷积层
        print(conv4.op.name, '', conv4.get_shape().as_list())
        parameter += [kernel, bias]

    # 实现第五个卷积层
    with tf.name_scope('conv5'):
        kernel = tf.Variable(tf.truncated_normal([3, 3, 384, 256], stddev=0.1), name='weights')
        conv = tf.nn.conv2d(conv4, kernel, strides=[1, 1, 1, 1], padding='SAME')
        bias = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name='bias')
        conv5 = tf.nn.relu(tf.nn.bias_add(conv, bias))

        # 打印第五个卷积层
        print(conv5.op.name, '', conv5.get_shape().as_list())
        parameter += [kernel, bias]

    # 添加最大池化层
    pool5 = tf.nn.max_pool(conv5, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID', name='pool5')
    # 打印该网络结构
    print(pool5.op.name, '', pool5.get_shape().as_list())

    # 至此卷积结束,将pool5输出向量,方便全连层的输入
    pool_shape = pool5.get_shape().as_list()
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
    reshaped = tf.reshape(pool5, [pool_shape[0], nodes])

    # 创建第一个全连层
    with tf.name_scope('fc_1'):
        fc1_weights = tf.Variable(tf.truncated_normal([nodes, 4096], stddev=0.1, name='weights'))
        fc1_bias = tf.Variable(tf.constant(0.0, shape=[4096]), trainable=True, name='bias')
        fc_1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_bias)

        # 打印第一个全连层的信息
        print(fc_1.op.name, '', fc_1.get_shape().as_list())
        parameter += [fc1_weights, fc1_bias]

    # 创建第二个全连层
    with tf.name_scope('fc_2'):
        fc2_weights = tf.Variable(tf.truncated_normal([4096, 4096], stddev=0.1, name='weights'))
        fc2_bias = tf.Variable(tf.constant(0.0, shape=[4096]), trainable=True, name='bias')
        fc_2 = tf.nn.relu(tf.matmul(fc_1, fc2_weights) + fc2_bias)

        # 加入drop增大泛化能力
        fc_2 = tf.nn.dropout(fc_2, keep_prob=0.5)

        # 打印第二个全连层的信息
        print(fc_2.op.name, '', fc_2.get_shape().as_list())
        parameter += [fc2_weights, fc2_bias]

    return fc_2, parameter


batch_size = 32
num_batch = 100
image_size = 224

"创建计算图用于运行该问题,一般不做处理为默认计算图"
g1 = tf.Graph()
with g1.as_default():
    # 创建模拟的图片数据
    images = tf.Variable(tf.random_normal([batch_size, image_size, image_size, 3], stddev=0.1))

    # 运行前向传播过程
    fc_2, parameter = inference_op(images)
    # init_op = tf.global_variables_initializer()

    # 配置会话,用于设置GPU的分配策略
    # 采用最佳适配合算法
    config = tf.ConfigProto()
    config.gpu_options.allocator_type = 'BFC'

"前向传播与评测前向传播的耗时"
with tf.Session(config=config, graph=g1) as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)

    num_steps_burn_in = 10
    total_dural = 0.0
    total_dural_squared = 0.0
    back_total_dural = 0.0
    back_total_dural_squared = 0.0

    for i in range(num_batch + num_steps_burn_in):
        start_time = time.time()
        _ = sess.run(fc_2)
        duration = time.time() - start_time
        if i >= num_steps_burn_in:
            if i % 10 == 0:
                print('%s:step %d,duration = %.3f' % (datetime.now(), i - num_steps_burn_in, duration))
                total_dural += duration
                total_dural_squared += duration ** 2
    averege_time = total_dural / num_batch
    # 打印时间
    print('%s:Forward across %d step, %.3f +/- %.3f sec/batch' %
          (datetime.now(), num_batch, averege_time, math.sqrt(total_dural_squared / num_batch - averege_time ** 2)))

    "反向传播与评测反向传播的耗时"
    # 梯度优化 因为没有放入实测数据,目标损失为fc2下的L2正则损失
    grad = tf.gradients(tf.nn.l2_loss(fc_2), parameter)

    # 运行BP传播过程
    for i in range(num_batch + num_steps_burn_in):
        start_time = time.time()
        _ = sess.run(grad)
        duration = time.time() - start_time
        if i >= num_steps_burn_in:
            if i % 10 == 0:
                print('%s:step %d,duration = %.3f' % (datetime.now(), i - num_steps_burn_in, duration))
                back_total_dural += duration
                back_total_dural_squared += duration ** 2

    back_averege_t = back_total_dural / num_batch
    print('%s:Forward-Backward across %d step, %.3f +/- %.3f sec/batch' %
          (datetime.now(), num_batch, back_averege_t,
           math.sqrt(back_total_dural_squared / num_batch - back_averege_t ** 2)))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值