首页 > 其他分享 >深度学习-机器视觉part2

深度学习-机器视觉part2

时间:2024-04-02 20:32:48浏览次数:23  
标签:loss input label part2 num 深度 np 视觉 out

深度学习-机器视觉part2

文章目录

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

深度学习-机器视觉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)=−x∑​p(x)ln(q(x))
其中: p ( x ) p(x) p(x)为真实概率, q ( x ) q(x) q(x)为预测概率, H ( p , q ) H(p,q) H(p,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

标签:loss,input,label,part2,num,深度,np,视觉,out
From: https://blog.csdn.net/weixin_43186779/article/details/137256328

相关文章

  • 深度剖析:高岭土行业市场发展趋势与竞争格局
    一、行业简述   高岭土,作为一种重要的非金属矿产资源,以其独特的物理和化学性质在多个领域发挥着关键作用。其具有高白度、高分散性、高遮盖力等特点,被广泛应用于陶瓷、造纸、涂料、橡胶等工业领域。近年来,随着技术进步和市场需求的扩大,高岭土行业在中国得到了快速发展。......
  • AI小程序的创业方向:深度思考与逻辑引领
    随着人工智能技术的快速发展,AI小程序逐渐成为创业的新热点。在这个充满机遇与挑战的时代,我们有必要深入探讨AI小程序的创业方向,以把握未来的发展趋势。 一、目标市场定位首先,我们要明确目标市场。针对不同的用户需求,AI小程序可应用于各个领域,如电商、医疗、教育、金融等。在......
  • Android APP安全加固:深度解析代码混淆在保护应用安全方面的优势与局限性
    AndroidAPP加固是优化APK安全性的一种方法,常见的加固方式有混淆代码、加壳、数据加密、动态加载等。下面介绍一下AndroidAPP加固的具体实现方式。混淆代码使用ipaguard工具可以对代码进行混淆,使得反编译出来的代码很难阅读和理解,官网下载ipaguard即可。加固混淆......
  • 监听 watch props对象属性监听 或深度监听
    对象属性监听 props:{baseFormObj:Object,},watch:{'baseFormObj.measuresItems':{immediate:true,//如果需要组件创建时立即监听,设置为truehandler(newVal,oldVal){//当myProperty变化时,这里的代码会被执行}......
  • 基于深度学习的人脸表情识别系统
    基于深度学习的人脸表情识别系统摘要随着社会的进步和经济的发展,人工智能已经开始应用于各种各样的场景,最典型的应用就是机器人的应用。人机交互的设计已经越来越成熟,而机器人要想了解人的正确想法就不应仅体现在语言上,还应该在其他方面分析出人的正确情感,表情识别分析就......
  • 基于深度学习的疲劳检测算法
    摘要:为了实现对驾驶员驾驶状态的检测预警,避免发生交通事故。提出了一种基于改进多任务级联卷积神经网络(Multi-TaskConvolutionalNeuralNetworks,MTCNN)人脸检测及多特征融合的疲劳检测方法。算法利用改进的MTCNN进行人脸检测和面部9个特征点定位;基于特征点确定出嘴巴、眼睛......
  • 基于深度学习的咖啡豆叶片病害识别算法设计与实现任务书
    一、毕业设计(论文)课题的背景咖啡原产于非洲热带地区,距今发展己有1300多年的的历史。作为饮料,咖啡具有健胃、消食、利尿、醒脑、提神等功效。咖啡含有淀粉、糖分、脂肪和蛋白质等多种营养成分。其中小粒咖啡的主要成分含量为:粗纤维17.94、蛋白质13.86、粗脂肪11.97、淀粉6.......
  • 基于深度学习的健身动作识别纠正系统设计与实现开题报告
    一、本课题研究意义随着人们对身体健康和自身形体的愈发重视,健身逐渐成为人们日常生活中的一个重要部分,而科学的健身和标准的健身动作可以使人们健身时能够更好地拥有好的形体和保护自己的安全,防止不规范的动作造成的肌肉拉伤和无效化健身。本系统视频识别以深度学习中的S......
  • 对二叉树深度优先遍历php算法实现的改进(先序遍历,中序遍历,后序遍历)
        树是一种数据结构,二叉树是一种特殊的树。二叉树的特点是每个结点最多有两个儿子。以某种特定顺序访问树中所有的节点称为树的遍历,今天在查看了这遍文章:https://www.cnblogs.com/ivy-zheng/p/10995492.html 中对树的遍历的实现之后我对其PHP遍历算法代码进行了重构,这次......
  • 从原理到应用探索深度学习的技术
    随着大数据和计算能力的飞速发展,深度学习作为人工智能领域的一个重要分支,已经引起了广泛的关注和研究。深度学习通过模拟人脑神经网络的运作方式,使得机器能够学习并理解数据的内在规律和特征,从而实现更高级别的智能化。本文将深入探讨深度学习的基本原理、关键技术及其在各个领域......