深度学习-机器视觉part2

news2024/10/6 9:26:13

深度学习-机器视觉part2

文章目录

  • 深度学习-机器视觉part2
    • 一、从卷积到卷积神经网络
    • 二、手撕卷积代码
      • 2.1 动机
      • 2.2 数据集
      • 2.3 卷积操作
        • 2.3.1 填充(padding)
        • 2.3.2 卷积块
        • 2.3.3 池化
        • 2.3.4 Softmax
      • 2.4 完整CNN
      • 2.5 训练改进
    • 三、经典CNN模型介绍
    • 四、CNN模型的实际应用
    • 参考

一、从卷积到卷积神经网络

深度学习-机器视觉part1

二、手撕卷积代码

2.1 动机

通过普通的神经网络可以实现,但是现在图片越来越大,如果通过 NN 来实现,训练的参数太多。例如 224 x 224 x 3 = 150,528,隐藏层设置为 1024 就需要训练参数 150,528 x 1024 = 1.5 亿 个,这还是第一层,因此会导致我们的网络很庞大。

另一个问题就是特征位置在不同的图片中会发生变化。例如小猫的脸在不同图片中可能位于左上角或者右下角,因此小猫的脸不会激活同一个神经元。

2.2 数据集

我们使用手写数字数据集 MNIST 。

在这里插入图片描述

每个数据集都以一个 28x28 像素的数字。

普通的神经网络也可以处理这个数据集,因为图片较小,另外数字都集中在中间位置,但是现实世界中的图片分类问题可就没有这么简单了,这里只是抛砖引玉哈。

2.3 卷积操作

CNN 相较于 NN 来说主要是增加了基于 convolution 的卷积层。卷基层包含一组 filter,每一个 filter 都是一个 2 维的矩阵。以下为 3x3 filter:

我们可以通过输入的图片和上面的 filter 来做卷积运算,然后输出一个新的图片。包含以下步骤:

    • 将 filter 叠加在图片的顶部,一般是左上角
    • 然后执行对应元素的相乘
    • 将相乘的结果进行求和,得到输出图片的目标像素值
    • 重复以上操作在所有位置上
2.3.1 填充(padding)

可以通过在周围补 0 实现输出前后图像大小一致,如下所示:

在这里插入图片描述

这叫做 “same padding”,不过一般不用 padding,叫做 “valid” padding。

2.3.2 卷积块

CNN 包含卷基层,卷基层通过一组 filter 将输入的图片转为输出的图片。卷基层的主要参数是 filter 的个数。

对于 MNIST CNN,我使用一个含有 8 个 filter 的卷基层,意味着它将 28x28 的输入图片转为 26x26x8 的输出集:

在这里插入图片描述

import numpy as np
 
class Conv3x3:
    # A Convolution layer using 3x3 filters.
 
    def __init__(self, num_filters):
        self.num_filters = num_filters
 
        # filters is a 3d array with dimensions (num_filters, 3, 3)
        # We divide by 9 to reduce the variance of our initial values
        self.filters = np.random.randn(num_filters, 3, 3) / 9

接下来,具体实现卷基层:

class Conv3x3:
    def iterate_regions(self, image):
        h,w = image.shape
        for i in range(h-2):
            for j in range(w-2):
                im_region = image[i:(i+3),j:(j+3)]
                yield  im_region, i, j
    
    def forward(self, input):
        h,w = input.shape
        output = np.zeros((h-2,w-2,self.num_filters))
        for im_region,i,j in self.iterate_regions(input):
            output[i,j] = np.sum(im_region * self.filters, axis = (1,2))
        return output 
2.3.3 池化
import numpy as np
 
class MaxPool2:
    # A Max Pooling layer using a pool size of 2.
 
    def iterate_regions(self, image):
        '''
        Generates non-overlapping 2x2 image regions to pool over.
        - image is a 2d numpy array
        '''
        # image: 26x26x8
        h, w, _ = image.shape
        new_h = h // 2
        new_w = w // 2
 
        for i in range(new_h):
            for j in range(new_w):
                im_region = image[(i * 2):(i * 2 + 2), (j * 2):(j * 2 + 2)]
                yield im_region, i, j
 
    def forward(self, input):
        '''
        Performs a forward pass of the maxpool layer using the given input.
        Returns a 3d numpy array with dimensions (h / 2, w / 2, num_filters).
        - input is a 3d numpy array with dimensions (h, w, num_filters)
        '''
        # input: 卷基层的输出,池化层的输入
        h, w, num_filters = input.shape
        output = np.zeros((h // 2, w // 2, num_filters))
 
        for im_region, i, j in self.iterate_regions(input):
            output[i, j] = np.amax(im_region, axis=(0, 1))
        return output
2.3.4 Softmax
  • 用法

我们将要使用一个含有 10 个节点(分别代表相应数字)的 softmax 层,作为我们 CNN 的最后一层。最后一层为一个全连接层,只是激活函数为 softmax。经过 softmax 的变换,数字就是具有最高概率的节点。

在这里插入图片描述

  • 交叉熵损失函数

交叉熵损失函数用来计算概率间的距离:
H ( p , q ) = − ∑ x p ( x ) l n ( q ( x ) ) H(p,q) = - \sum_xp(x)ln(q(x)) H(p,q)=xp(x)ln(q(x))
其中: p ( x ) p(x) p(x)为真实概率, q ( x ) q(x) q(x)为预测概率, H ( p , q ) H(p,q) Hp,q为预测结果与真实结果的差距

  • 代码
import numpy as np
 
class Softmax:
    # A standard fully-connected layer with softmax activation.
 
    def __init__(self, input_len, nodes):
        # We divide by input_len to reduce the variance of our initial values
        # input_len: 输入层的节点个数,池化层输出拉平之后的
        # nodes: 输出层的节点个数,本例中为 10
        # 构建权重矩阵,初始化随机数,不能太大
        self.weights = np.random.randn(input_len, nodes) / input_len
        self.biases = np.zeros(nodes)
 
    def forward(self, input):
        '''
        Performs a forward pass of the softmax layer using the given input.
        Returns a 1d numpy array containing the respective probability values.
        - input can be any array with any dimensions.
        '''
        # 3d to 1d,用来构建全连接网络
        input = input.flatten()
 
        input_len, nodes = self.weights.shape
 
        # input: 13x13x8 = 1352
        # self.weights: (1352, 10)
        # 以上叉乘之后为 向量,1352个节点与对应的权重相乘再加上bias得到输出的节点
        # totals: 向量, 10
        totals = np.dot(input, self.weights) + self.biases
        # exp: 向量, 10
        exp = np.exp(totals)
        return exp / np.sum(exp, axis=0)

2.4 完整CNN

import mnist
import numpy as np
 
# We only use the first 1k testing examples (out of 10k total)
# in the interest of time. Feel free to change this if you want.
test_images = mnist.test_images()[:1000]
test_labels = mnist.test_labels()[:1000]
 
conv = Conv3x3(8)                                    # 28x28x1 -> 26x26x8
pool = MaxPool2()                                    # 26x26x8 -> 13x13x8
softmax = Softmax(13 * 13 * 8, 10) # 13x13x8 -> 10
 
def forward(image, label):
    '''
    Completes a forward pass of the CNN and calculates the accuracy and
    cross-entropy loss.
    - image is a 2d numpy array
    - label is a digit
    '''
    # We transform the image from [0, 255] to [-0.5, 0.5] to make it easier
    # to work with. This is standard practice.
  
   # out 为卷基层的输出, 26x26x8
    out = conv.forward((image / 255) - 0.5)
    # out 为池化层的输出, 13x13x8
    out = pool.forward(out)
    # out 为 softmax 的输出, 10
    out = softmax.forward(out)
 
    # Calculate cross-entropy loss and accuracy. np.log() is the natural log.
    # 损失函数的计算只与 label 的数有关,相当于索引
    loss = -np.log(out[label])
    # 如果 softmax 输出的最大值就是 label 的值,表示正确,否则错误
    acc = 1 if np.argmax(out) == label else 0
 
    return out, loss, acc
 
print('MNIST CNN initialized!')
 
loss = 0
num_correct = 0
# enumerate 函数用来增加索引值
for i, (im, label) in enumerate(zip(test_images, test_labels)):
    # Do a forward pass.
    _, l, acc = forward(im, label)
    loss += l
    num_correct += acc
 
    # Print stats every 100 steps.
    if i % 100 == 99:
        print(
            '[Step %d] Past 100 steps: Average Loss %.3f | Accuracy: %d%%' %
            (i + 1, loss / 100, num_correct)
        )
        loss = 0
        num_correct = 0

此代码为原理代码,使用随机数进行学习和训练,效果不佳,准确率大概为10%左右,还需要改进。

2.5 训练改进

import mnist
import numpy as np
 
# We only use the first 1k examples of each set in the interest of time.
# Feel free to change this if you want.
train_images = mnist.train_images()[:1000]
train_labels = mnist.train_labels()[:1000]
test_images = mnist.test_images()[:1000]
test_labels = mnist.test_labels()[:1000]
 
conv = Conv3x3(8)                                    # 28x28x1 -> 26x26x8
pool = MaxPool2()                                    # 26x26x8 -> 13x13x8
softmax = Softmax(13 * 13 * 8, 10) # 13x13x8 -> 10
 
def forward(image, label):
    '''
    Completes a forward pass of the CNN and calculates the accuracy and
    cross-entropy loss.
    - image is a 2d numpy array
    - label is a digit
    '''
    # We transform the image from [0, 255] to [-0.5, 0.5] to make it easier
    # to work with. This is standard practice.
    out = conv.forward((image / 255) - 0.5)
    out = pool.forward(out)
    out = softmax.forward(out)
 
    # Calculate cross-entropy loss and accuracy. np.log() is the natural log.
    loss = -np.log(out[label])
    acc = 1 if np.argmax(out) == label else 0
 
    return out, loss, acc
    # out: vertor of probability
    # loss: num
    # acc: 1 or 0
 
def train(im, label, lr=.005):
    '''
    Completes a full training step on the given image and label.
    Returns the cross-entropy loss and accuracy.
    - image is a 2d numpy array
    - label is a digit
    - lr is the learning rate
    '''
    # Forward
    out, loss, acc = forward(im, label)
 
    # Calculate initial gradient
    gradient = np.zeros(10)
    gradient[label] = -1 / out[label]
 
    # Backprop
    gradient = softmax.backprop(gradient, lr)
    gradient = pool.backprop(gradient)
    gradient = conv.backprop(gradient, lr)
 
    return loss, acc
 
print('MNIST CNN initialized!')
 
# Train the CNN for 3 epochs
for epoch in range(3):
    print('--- Epoch %d ---' % (epoch + 1))
 
    # Shuffle the training data
    permutation = np.random.permutation(len(train_images))
    train_images = train_images[permutation]
    train_labels = train_labels[permutation]
 
    # Train!
    loss = 0
    num_correct = 0
 
    # i: index
    # im: image
    # label: label
    for i, (im, label) in enumerate(zip(train_images, train_labels)):
        if i > 0 and i % 100 == 99:
            print(
                '[Step %d] Past 100 steps: Average Loss %.3f | Accuracy: %d%%' %
                (i + 1, loss / 100, num_correct)
            )
            loss = 0
            num_correct = 0
 
        l, acc = train(im, label)
        loss += l
        num_correct += acc
 
# Test the CNN
print('\n--- Testing the CNN ---')
loss = 0
num_correct = 0
for im, label in zip(test_images, test_labels):
    _, l, acc = forward(im, label)
    loss += l
    num_correct += acc
 
num_tests = len(test_images)
print('Test Loss:', loss / num_tests)
print('Test Accuracy:', num_correct / num_tests)

三、经典CNN模型介绍

未完待续

四、CNN模型的实际应用

未完待续

参考

Python 徒手实现 卷积神经网络 CNN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1573653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL Server详细安装使用教程

1.安装环境 现阶段基本不用SQL Server数据库了,看到有这样的分析话题,就把多年前的存货发一下,大家也可以讨论看看,思路上希望还有价值。 SQL Server 2008 R2有32位版本和64位版本,32位版本可以安装在Windows XP及以上…

网络安全之代码签名证书申请

代码签名,作为一种数字安全机制,对于软件开发、分发及用户使用环节具有至关重要的意义。以下从六大方面阐述代码签名必不可少的重要性: 确保代码来源可信: 代码签名如同软件的“身份证”,通过数字证书对开发者身份进…

2024年船舶、海洋工程与应用技术国际学术会议(ICSOEAT 2024)

2024 International Conference on Shipbuilding, Ocean Engineering and Applied Technology ●会议简介 2024年船舶、海洋工程与应用技术国际学术会议(ICSOEAT 2024)旨在汇聚全球船舶、海洋工程与应用技术领域的专家学者,共同探讨行业前沿…

【话题】程序员35岁会失业吗?

大家好,我是全栈小5,欢迎阅读小5的系列文章,这是《话题》系列文章 目录 背景招聘分析一、技术更新换代的挑战二、经验与技术的双重优势三、职业发展的多元化选择四、个人成长与职业规划的平衡五、结语文章推荐 背景 35岁被认为是程序员职业生…

【浅尝C++】多态机制=>重载重写隐藏的区别/抽象类/单继承与多继承的虚函数表/多态原理及虚函数表内存存储详谈

🏠专栏介绍:浅尝C专栏是用于记录C语法基础、STL及内存剖析等。 🎯每日格言:每日努力一点点,技术变化看得见。 文章目录 多态的概念多态的定义及实现多态的构成条件虚函数虚函数的重写override与final(C11&a…

ffmpeg 将多个视频片段合成一个视频

ffmpeg 将多个视频片段合成一个视频 References 网络视频 6 分钟的诅咒。 新建文本文件 filelist.txt filelist.txtfile output_train_video_0.mp4 file output_train_video_1.mp4 file output_train_video_2.mp4 file output_train_video_3.mp4 file output_train_video_4.m…

C语言完结篇(17)

编译和链接 1. 翻译环境和运⾏环境 2. 翻译环境:预编译编译汇编链接 我们知道计算机能够执行的是二进制的指令 而我们的C语言代码都是文本信息 所以我们需要让C语言代码转变为二进制的指令(这是需要编译器来进行处理的) 翻译环境和运⾏…

2024年MathorCup妈妈杯数学建模思路D题思路解析+参考成品

1 赛题思路 (赛题出来以后第一时间在群内分享,点击下方群名片即可加群) 2 比赛日期和时间 报名截止时间:2024年4月11日(周四)12:00 比赛开始时间:2024年4月12日(周五)8:00 比赛结束时间&…

RGB三通道和灰度值的理解

本文都是来自于chatGPT的回答!!! 目录 Q1:像素具有什么属性?Q2:图像的色彩是怎么实现的?Q3:灰度值和颜色值是一个概念吗?Q4:是不是像素具有灰度值,也有三个颜色分量RGB?Q5:灰度图像是没有色彩的吗?Q6: 彩色图像是既具有灰度值也具有RGB三…

Java Spring IoCDI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性

💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 前提小知识:高内…

16-代码随想录206反转链表

16-代码随想录206反转链表 206.反转链表 力扣题目链接(opens new window) 题意:反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 206. 反转链表 给你单链表的头节点 head ,请你反转链表&…

RTX RTOS 操作实例分析之---线程(thread)

0 Preface/Foreword 1 线程(thread) 1.1 线程定义 1.1.1 USE_BASIC_THREADS(宏定义) 经过以上步骤(makefile包含),USE_BASIC_THREADS在编译阶段被定义到相应的模块中。 1.1.2 定义线程ID变量…

博客部署004-centos安装mysql及redis

1、如何查看当前centos版本? cat /etc/os-release 2、安装mysql 我的是centos8版本,使用dnf命令 2.1 CentOS 7/8: sudo yum install -y mysql-community-server 或者在CentOS 8上,使用DNF:🌟 sudo dnf install -y mysql-ser…

无尽加班何时休--状态模式

1.1 加班,又是加班! 公司的项目很急,所以要求加班。经理把每个人每天的工作都排得满满的,说做完就可以回家,但是没有任何一个人可以在下班前完成的,基本都得加班,这就等于是自愿加班。我走时还有…

[技术闲聊]我对电路设计的理解(七)-Cadence原理图绘制

一、原理图软件推荐 之前的章节有讲过AD、PADS、Cadence,以及三者的应用标准,今天再讲讲这一点。 如果是学生,可以学习AD软件,因为学校在学习,上手容易,而且即使工作后,如果是电机控制等4层板或…

数据劫持的冲突问题

在近段时间我又再一次使用了数据劫持,发现了一些冲突问题,并在此介绍我所应用的场景。 一、冲突问题 在之前的文章中有介绍过数据劫持,但后来使用的很少,最近在一次使用的过程中,发现了一些问题。 1.value属性的冲突…

第十四届蓝桥杯省赛大学C组(C/C++)填充

原题链接:填充 有一个长度为 n 的 01 串,其中有一些位置标记为 ?,这些位置上可以任意填充 0 或者 1,请问如何填充这些位置使得这个 01 串中出现互不重叠的 0 和 1 子串最多,输出子串个数。 输入格式 输入一行包含一…

【51单片机学习记录】超声波测距

一、超声波测距概述 (1)超声波时间差测距原理 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声…

环形链表 - LeetCode 热题 25

大家好!我是曾续缘🥰 今天是《LeetCode 热题 100》系列 发车第 25 天 链表第 4 题 ❤️点赞 👍 收藏 ⭐再看,养成习惯 环形链表 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可…