遗传算法与深度学习实战(25)——使用Keras构建卷积神经网络

遗传算法与深度学习实战(25)——使用Keras构建卷积神经网络

    • 0. 前言
    • 1. 卷积神经网络基本概念
      • 1.1 卷积
      • 1.2 步幅
      • 1.3 填充
      • 1.4 激活函数
      • 1.5 池化
    • 2. 使用 Keras 构建卷积神经网络
    • 3. CNN 层的问题
    • 4. 模型泛化
    • 小结
    • 系列链接

0. 前言

卷积神经网络 (Convolutional Neural Network, CNN) 的提出是为了解决传统神经网络的缺陷。即使对象位于图片中的不同位置或其在图像中具有不同占比,CNN 依旧能够正确的处理这些图像,因此在对象分类/检测任务中更加有效。在本节中,我们将使用 Keras 构建卷积神经网络模型进行图像分类,介绍 CNN 的基础知识,并构建 CNN 模型。

1. 卷积神经网络基本概念

在本节中,首先介绍卷积神经网络 (Convolutional Neural Network, CNN) 的相关概念与组成,了解 CNN 的工作原理。

1.1 卷积

卷积是两个矩阵间的乘法——通常一个矩阵具有较大尺寸,另一个矩阵则较小。要了解卷积,首先讲解以下示例。给定矩阵 A 和矩阵 B 如下:

矩阵

在进行卷积时,我们将较小的矩阵在较大的矩阵上滑动,在上述两个矩阵中,当较小的矩阵 B 需要在较大矩阵 A 的整个区域上滑动时,会得到 9 次乘法运算,过程如下。
在矩阵 A 中从第 1 个元素开始选取与矩阵 B 相同尺寸的子矩阵 [ 1 2 0 1 1 1 3 3 2 ] \left[ \begin{array}{ccc} 1 & 2 & 0\\ 1 & 1 & 1\\ 3 & 3 & 2\\\end{array}\right] 113213012 和矩阵 B 相乘并求和:

卷积-1

1 × 3 + 2 × 1 + 0 × 1 + 1 × 2 + 1 × 3 + 1 × 1 + 3 × 2 + 3 × 2 + 2 × 3 = 29 1\times 3+2\times 1+0\times 1+1\times 2+1\times 3+1\times 1+3\times 2+3\times 2 + 2\times 3=29 1×3+2×1+0×1+1×2+1×3+1×1+3×2+3×2+2×3=29

然后,向右滑动一个窗口,选择第 2 个与矩阵 B 相同尺寸的子矩阵 [ 2 0 2 1 1 2 3 2 1 ] \left[ \begin{array}{ccc} 2 & 0 & 2\\ 1 & 1 & 2\\ 3 & 2 & 1\\\end{array}\right] 213012221 和矩阵 B 相乘并求和:

卷积-2

2 × 3 + 0 × 1 + 2 × 1 + 1 × 2 + 1 × 3 + 2 × 1 + 3 × 2 + 2 × 2 + 1 × 3 = 28 2\times 3+0\times 1+2\times 1+1\times 2+1\times 3+2\times 1+3\times 2+2\times 2 + 1\times 3=28 2×3+0×1+2×1+1×2+1×3+2×1+3×2+2×2+1×3=28

然后,再向右滑动一个窗口,选择第 3 个与矩阵 B 相同尺寸的子矩阵 [ 0 2 3 1 2 0 2 1 2 ] \left[ \begin{array}{ccc} 0 & 2 & 3\\ 1 & 2 & 0\\ 2 & 1 & 2\\\end{array}\right] 012221302 和矩阵 B 相乘并求和:

卷积-3

0 × 3 + 2 × 1 + 3 × 1 + 1 × 2 + 2 × 3 + 0 × 1 + 2 × 2 + 1 × 2 + 2 × 3 = 25 0\times 3+2\times 1+3\times 1+1\times 2+2\times 3+0\times 1+2\times 2+1\times 2 + 2\times 3=25 0×3+2×1+3×1+1×2+2×3+0×1+2×2+1×2+2×3=25

当向右滑到尽头时,向下滑动一个窗口,并从矩阵 A 左边开始,选择第 4 个与矩阵 B 相同尺寸的子矩阵 [ 1 1 1 3 3 2 1 0 2 ] \left[ \begin{array}{ccc} 1 & 1 & 1\\ 3 & 3 & 2\\ 1 & 0 & 2\\\end{array}\right] 131130122 和矩阵 B 相乘并求和:

卷积-4

1 × 3 + 1 × 1 + 1 × 1 + 3 × 2 + 3 × 3 + 2 × 1 + 1 × 2 + 0 × 2 + 2 × 3 = 30 1\times 3+1\times 1+1\times 1+3\times 2+3\times 3+2\times 1+1\times 2+0\times 2 + 2\times 3=30 1×3+1×1+1×1+3×2+3×3+2×1+1×2+0×2+2×3=30

然后,继续向右滑动,并重复以上过程滑动矩阵窗口,直到滑动到最后一个子矩阵为止,得到最终的结果 [ 29 28 25 30 30 27 20 24 34 ] \left[ \begin{array}{ccc} 29 & 28 & 25\\ 30 & 30 & 27\\ 20 & 24 & 34\\\end{array}\right] 293020283024252734

特征图

完整的卷积计算过程如以下动图所示:

卷积

通常,我们把较小的矩阵 B 称为滤波器 (filter) 或卷积核 (kernel),使用 ⊗ \otimes 表示卷积运算,较小矩阵中的值通过梯度下降被优化学习,卷积核中的值则为网络权重。卷积后得到的矩阵,也称为特征图 (feature map)。
卷积核的通道数与其所乘矩阵的通道数相等。例如,当图像输入形状为 5 x 5 x 3 时(其中 3 为图像通道数),形状为 3 x 3 的卷积核也将具有 3 个通道,以便进行矩阵卷积运算:

三通道卷积

可以看到无论卷积核有多少通道,一个卷积核计算后都只能得到一个通道。多为了捕获图像中的更多特征,通常我们会使用多个卷积核,得到多个通道的特征图,当使用多个卷积核时,计算过程如下:

多卷积核

需要注意的是,卷积并不等同于滤波,最直观的区别在于滤波后的图像大小不变,而卷积会改变图像大小,关于它们之间更详细的计算差异,并非本节重点,因此不再展开介绍。

1.2 步幅

在前面的示例中,卷积核每次计算时在水平和垂直方向只移动一个单位,因此可以说卷积核的步幅 (Strides) 为 (1, 1),步幅越大,卷积操作跳过的值越多,例如以下为步幅为 (2, 2) 时的卷积过程:

步幅为2的卷积计算

1.3 填充

在前面的示例中,卷积操作对于输入矩阵的不同位置计算的次数并不相同,具体来说对于边缘的数值在卷积时,仅仅使用一次,而位于中心的值则会被多次使用,因此可能导致卷积错过图像边缘的一些重要信息。如果要增加对于图像边缘的考虑,我们将在输入矩阵的边缘周围的填充 (Padding) 零,下图展示了用 0 填充边缘后的矩阵进行的卷积运算,这种填充形式进行的卷积,称为 same 填充,卷积后得到的矩阵大小为 ⌊ d + 2 p − k s ⌋ + 1 \lfloor\frac {d+2p-k} s\rfloor+1 sd+2pk+1,其中 s s s 表示步幅, p p p 表示填充大小, k k k 表示滤波器尺寸。而未进行填充时执行卷积运算,也称为 valid 填充。

填充

1.4 激活函数

在传统神经网络中,隐藏层不仅将输入值乘以权重,而且还会对数据应用非线性激活函数,将值通过激活函数传递。CNN 中同样包含激活函数,包括 SigmoidReLUtanhLeakyReLU 等。

1.5 池化

研究了卷积的工作原理之后,我们将了解用于卷积操作之后的另一个常用操作:池化 (Pooling)。假设卷积操作的输出如下,为 2 x 2

[ 29 28 20 24 ] \left[ \begin{array}{cc} 29 & 28\\ 20 & 24\\\end{array}\right] [29202824]

假设使用池化块(或者类比卷积核,我们也可以称之为池化核)为 2 x 2 的最大池化,那么将会输出 29 作为池化结果。假设卷积步骤的输出是一个更大的矩阵,如下所示:
[ 29 28 25 29 20 24 30 26 27 23 26 27 24 25 23 31 ] \left[ \begin{array}{cccc} 29 & 28 & 25 & 29\\ 20 & 24 & 30 & 26\\ 27 & 23 & 26 & 27\\ 24 & 25 & 23 & 31\\\end{array}\right] 29202724282423252530262329262731
当池化核为 2 x 2,且步幅为 2 时,最大池化会将此矩阵划分为 2 x 2 的非重叠块,并且仅保留每个块中最大的元素值,如下所示:

[ 29 28 ∣ 25 29 20 24 ∣ 30 26 — — — — — 27 23 ∣ 26 27 24 25 ∣ 23 31 ] = [ 29 30 27 31 ] \left[ \begin{array}{ccccc} 29 & 28 & | & 25 & 29\\ 20 & 24 & | & 30 & 26\\ —&—&—&—&—\\ 27 & 23 & | & 26 & 27\\ 24 & 25 & | & 23 & 31\\\end{array}\right]=\left[ \begin{array}{cc} 29 & 30\\ 27 & 31\\\end{array}\right] 29202724282423252530262329262731 =[29273031]

从每个池化块中,最大池化仅选择具有最高值的元素。除了最大池化外,也可以使用平均池化,其将输出每个池化块中的平均值作为结果,在实践中,与其他类型的池化相比,最常使用的池化为最大池化。

2. 使用 Keras 构建卷积神经网络

在本节中,我们在 Fashion-MNIST 数据集上执行图像分类,Fashion-MNIST 是一个基本测试数据集,可以对其进行裁剪,减少用于训练或推理的数据量,以减少进化所需的运行时间。

(1) 加载 Fashion 数据集,对数据进行归一化并将其整形为形状为 (28,28,1) 的张量,其中 1 表示通道,这是因为数据集中的 2D 数组未定义通道,我们从原始数据集中提取前 1,000 个样本进行训练和 100 个用于测试:

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import numpy as np
import math
import timeimport matplotlib.pyplot as plt
from livelossplot import PlotLossesKerasdataset = datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = dataset.load_data()# normalize and reshape data
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype("float32") / 255.0
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype("float32") / 255.0x_train = x_train[:1000]
y_train= y_train[:1000]
x_test = x_test[:100]
y_test= y_test[:100]class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat','Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']def plot_data(num_images, images, labels):grid = math.ceil(math.sqrt(num_images))plt.figure(figsize=(grid*2,grid*2))for i in range(num_images):plt.subplot(grid,grid,i+1)plt.xticks([])plt.yticks([])plt.grid(False)     plt.imshow(images[i].reshape(28,28))plt.xlabel(class_names[labels[i]])      plt.show()plot_data(25, x_train, y_train)

减小数据集规模并非理想方案,但当我们尝试优化数千甚至数万个个体时,这样做可以节省大量时间。

数据集

(2) 构建模型, 每个 Conv2D 层定义了应用于输入的卷积操作。在连续应用卷积层的过程中,滤波器或通道的数量从上一层扩展。例如,第一个 Conv2D 层将输入通道从 1 扩展到 64。然后,后续层将其缩小到 32,然后到 16,其中每个卷积层都添加一个 MaxPooling 层,用于总结特征:

model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same", input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2), padding="same"))
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding="same"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(16, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))model.summary()

通过在图像上滑动滤波器块来生成相应的输出,其中每次卷积核滑动操作得到一个输出值,滤波器中的卷积核值或权重/参数是可以学习的。通常卷积操作的输出非常大,每个滤波器都会产生类似图像的输出块。减少数据量可以通过使用池化层,除了最大池化,还可以使用其他变体来获取收集特征的最小值或平均值。设置模型的卷积和最大池化层之后,使用 model.summary() 打印模型摘要。

模型摘要

(3) 展平 CNN 层的输出,并输入到全连接层中,该层包含 10 个神经元(输出为 10 个类别):

model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10))model.summary()

网络模型

(4) 训练模型,训练后输出结果如下所示。通常,在此数据集的优化后的性能达到 98% 左右,由于使用完整数据集进行训练非常耗时,我们仅抽取了少量数据样本:

model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])history = model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test),callbacks=[PlotLossesKeras()],verbose=0)test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)

模型性能监控

可以看到,在验证数据上的准确率稳定在 81% 左右。由于同一类别中的样本变化很小,在 Fashion-MNIST 数据集上使用简单 CNN 就可以得到较高准确率,但对于像 CIFAR-10CIFAR-100 同一类别中样本变化较大的数据集,情况将有所不同。
观察训练和测试的损失和准确率之间的差异。可以看到,模型在第 3epoch 时在测试数据上的推理能力开始下降。这可能与数据规模缩小或模型构建有关。在之后的学习中,我们将介绍一些经典的 CNN 架构。

3. CNN 层的问题

接下来,我们将进一步探索 CNN 架构,并了解了 CNN 的局限性。当正确使用时,CNN 是一个很好的工具,但如果使用不当,也会引发一系列问题,了解问题有助于更好的理解进化优化。

(1) 构建模型,只使用一个 CNN 层。定义一个具有 64 个滤波器和 3×3 卷积核的层,模型摘要输入如下所示,模型总参数量超过 600 万:

model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same", input_shape=(28, 28, 1)))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10))model.summary()

模型摘要

(2) 训练模型,训练结果输出如下。可以看到,模型在训练数据上的表现非常好,但在验证/测试数据上的表现很差。这是因为具有超过 600 万参数的模型会记住训练数据集,无法很好的泛化到模型未见到的数据集上,即过拟合现象。可以看到训练集的准确率接近 100%,然而在测试/验证集的准确率大幅下降:

model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])history = model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test),callbacks=[PlotLossesKeras()],verbose=0)

CNN 问题

4. 模型泛化

我们通常希望构建能够泛化的模型,因此,将数据分成训练集和测试集来验证模型的泛化能力。为了提高模型的泛化能力,可以应用例如批归一化和 dropout 等技术。然而,在某些情况下,泛化可能并非最终目标,我们可能希望识别特定的数据集,在这种情况下,就需要模型能够记住数据。

(1) 接下来,我们研究池化对卷积输出的影响,构建包含池化层的卷积神经网络,为了提高模型的泛化能力,还在池化层之间添加了批归一化层:

model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same", input_shape=(28, 28, 1)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2), padding="same"))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10))model.summary()

模型摘要如下所示。可以看到,由于添加了池化,此模型的参数量约为上一模型的四分之一。

模型摘要

(2) 对模型进行 10epoch 的训练,输出结果如下所示。虽然该模型仍存在过拟合的现象,但模型已经具有很好的泛化能力,可以看到模型验证准确率得到提升且损失得到降低:

model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])history = model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test),callbacks=[PlotLossesKeras()],verbose=0)

模型训练过程

我们可以通过调整多个超参数改进模型,例如添加更多的 CNN 层、批归一化层、dropout、池化层,或修改卷积层的核大小或滤波器数量等。

小结

卷积神经网络 (Convolutional Neural Network, CNN) 是一种深度学习模型,特别适用于图像和视频等数据。它的设计灵感来源于生物学中对动物视觉皮层的理解,通过多层次的卷积和池化操作来实现对图像特征的学习和提取。在本节中,我们介绍了 CNN 的基本组件,并使用 Keras 实现了 CNN 模型。

系列链接

遗传算法与深度学习实战(1)——进化深度学习
遗传算法与深度学习实战(2)——生命模拟及其应用
遗传算法与深度学习实战(3)——生命模拟与进化论
遗传算法与深度学习实战(4)——遗传算法(Genetic Algorithm)详解与实现
遗传算法与深度学习实战(5)——遗传算法中常用遗传算子
遗传算法与深度学习实战(6)——遗传算法框架DEAP
遗传算法与深度学习实战(7)——DEAP框架初体验
遗传算法与深度学习实战(8)——使用遗传算法解决N皇后问题
遗传算法与深度学习实战(9)——使用遗传算法解决旅行商问题
遗传算法与深度学习实战(10)——使用遗传算法重建图像
遗传算法与深度学习实战(11)——遗传编程详解与实现
遗传算法与深度学习实战(12)——粒子群优化详解与实现
遗传算法与深度学习实战(13)——协同进化详解与实现
遗传算法与深度学习实战(14)——进化策略详解与实现
遗传算法与深度学习实战(15)——差分进化详解与实现
遗传算法与深度学习实战(16)——神经网络超参数优化
遗传算法与深度学习实战(17)——使用随机搜索自动超参数优化
遗传算法与深度学习实战(18)——使用网格搜索自动超参数优化
遗传算法与深度学习实战(19)——使用粒子群优化自动超参数优化
遗传算法与深度学习实战(20)——使用进化策略自动超参数优化
遗传算法与深度学习实战(21)——使用差分搜索自动超参数优化
遗传算法与深度学习实战(22)——使用Numpy构建神经网络
遗传算法与深度学习实战(23)——利用遗传算法优化深度学习模型
遗传算法与深度学习实战(24)——在Keras中应用神经进化优化

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Docker Compose 来编排部署LMTNR项目

使用 Docker Compose 来部署一个包含 Linux、MySQL、Tomcat、Nginx 和 Redis 的完整项目的例子。假设我们要部署一个简单的 Java Web 应用,并且使用 Nginx 作为反向代理服务器。 项目目录结构 首先需要确保 Docker 和docker-compose已经安装并正在运行。docker --v…

快速理解倒排索引在ElasticSearch中的作用

一.基础概念 定义: 倒排索引是一种数据结构,用来加速文本数据的搜索和检索,和传统的索引方式不同,倒排索引会被每个词汇项与包含该词汇项的文档关联起来,从而去实现快速的全文检索。 举例: 在传统的全文…

跨平台应用开发框架(3)-----Qt(样式篇)

目录 1.QSS 1.基本语法 2.QSS设置方式 1.指定控件样式设置 2.全局样式设置 1.样式的层叠特性 2.样式的优先级 3.从文件加载样式表 4.使用Qt Designer编辑样式 3.选择器 1.类型选择器 2.id选择器 3.并集选择器 4.子控件选择器 5.伪类选择器 4.样式属性 1.盒模型 …

Pump Science平台深度剖析:兴起、优势、影响与未来

在过去的几个月里,人们越来越关注去中心化科学(DeSci)。DeSci 是一种利用区块链技术进行科学研究的新方法。传统的科学研究经常面临所谓的“死亡之谷”,这指的是基础科学研究与成功开发和造福患者的实施之间的重要时期。DeSci 旨在…

网安瞭望台第4期:nuclei最新poc分享

国内外要闻 多款 D-Link 停产路由器漏洞:攻击者可远程执行代码 近日,知名网络硬件制造商 D-Link 发布重要安全公告。由于存在严重的远程代码执行(RCE)漏洞,其敦促用户淘汰并更换多款已停产的 VPN 路由器型号。 此次…

TDengine在debian安装

参考官网文档&#xff1a; 官网安装文档链接 从列表中下载获得 Deb 安装包&#xff1b; TDengine-server-3.3.4.3-Linux-x64.deb (61 M) 进入到安装包所在目录&#xff0c;执行如下的安装命令&#xff1a; sudo dpkg -i TDengine-server-<version>-Linux-x64.debNOTE 当…

Mybatis集成篇(一)

Spring 框架集成Mybatis 目前主流Spring框架体系中&#xff0c;可以集成很多第三方框架&#xff0c;方便开发者利用Spring框架机制使用第三方框架的功能。就例如本篇Spring集成Mybatis 简单集成案例&#xff1a; Config配置&#xff1a; Configuration MapperScan(basePack…

k8s Init:ImagePullBackOff 的解决方法

kubectl describe po (pod名字) -n kube-system 可查看pod所在的节点信息 例如&#xff1a; kubectl describe po calico-node-2lcxx -n kube-system 执行拉取前先把用到的节点的源换了 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"re…

nginx+php压测及报错优化

测试环境&#xff1a;虚拟机centos7&#xff0c;nginxphp 压测工具&#xff1a;Apipost 访问的php程序中添加sleep()增加程序执行时长&#xff0c;使用Apipost进行压测&#xff0c;根据服务器配置设置一个大概可能触发报错的并发和轮训次数&#xff0c;若无报错逐渐增加并发和…

【数据结构】ArrayList与顺序表

ArrayList与顺序表 1.线性表2.顺序表2.1 接口的实现 3. ArrayList简介4. ArrayList使用4.2 ArrayList常见操作4.3 ArrayList的遍历4.4 ArrayList的扩容机制 5. ArrayList的具体使用5.1 杨辉三角5.2 简单的洗牌算法 6. ArrayList的问题及思考 【本节目标】 线性表顺序表ArrayLis…

GaussDB高智能--智能优化器介绍

书接上文库内AI引擎&#xff1a;模型管理&数据集管理&#xff0c;从模型管理与数据集管理两方面介绍了GaussDB库内AI引擎&#xff0c;本篇将从智能优化器方面解读GaussDB高智能技术。 4 智能优化器 随着数据库与AI技术结合的越来越紧密&#xff0c;相关技术在学术界的数…

GDPU Android移动应用 数据存储

又是学到了数据持久化。 登录界面 题外话&#xff1a;有无动画大佬带带呀&#xff0c;前端移动端可免( •̀ .̫ •́ )&#xff0c;合作可私信哦。 1.用户登陆和“记住我”功能 该内容拥有两个Activity活动视图&#xff1a; &#xff08;1&#xff09;LoginActivity&#x…

麒麟性能评估优化

cpu性能 Vmstat输出结果详解如下: r 列表示运行和等待cpu时间片的进程数,这个值如果长期大于系统CPU的个数,说 明CPU不足,需要增加CPU; b 列表示在等待资源的进程数,比如正在等待I/O、或者内存交换等; us 列显示了用户进程消耗的CPU 时间百分比。us的值比较高时,说明用…

Python基础学习-12匿名函数lambda和map、filter

目录 1、匿名函数&#xff1a; lambda 2、Lambda的参数类型 3、map、 filter 4、本节总结 1、匿名函数&#xff1a; lambda 1&#xff09;语法&#xff1a; lambda arg1, arg2, …, argN : expression using arg 2&#xff09; lambda是一个表达式&#xff0c;而不是一个语…

uniapp定义new plus.nativeObj.View实现APP端全局弹窗

为什么要用new plus.nativeObj.View在APP端实现弹窗&#xff1f;因为uni.showModal在APP端太难看了。 AppPopupView弹窗函数参数定义 参数一:弹窗信息(所有属性可不填&#xff0c;会有默认值) 1.title:"", //标题 2.content:"", //内容 3.confirmBoxCo…

Qt读写Usb设备的数据

Qt读写Usb设备的数据 问题:要读取usb设备进行通讯&#xff0c;qt好像没有对应的库支持。解决&#xff1a;libusbwindow下载 :Linux下载: QtUsb 开源的第三方库库里面的函数说明&#xff1a;window版本&#xff1a;Linux中也提供的直接下载测试代码&#xff1a;库下载&#xff1…

opengl 三角形

最后效果&#xff1a; OpenGL version: 4.1 Metal 不知道为啥必须使用VAO 才行。 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include <vector>void framebuffer_size_callback(GLFWwindow *window, int width, int heigh…

【C语言篇】探索 C 语言结构体:从基础语法到数据组织的初体验

我的个人主页 我的专栏&#xff1a;C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 目录 什么是结构体结构体的定义与使用结构体内存布局嵌套结构体与指针结构体数组的操作结构体与函数结构体内存对齐机制位域与结构体的结合动态内存分…

mfc110u.dll是什么意思,mfc110u.dll丢失解决方法大全详解

mfc110u.dll是Microsoft Foundation Classes (MFC)库的一个特定版本&#xff08;版本11.0&#xff09;的Unicode动态链接库文件。MFC是Microsoft为C开发者设计的一个应用程序框架&#xff0c;主要用于简化Windows应用程序的开发工作。这个框架封装了很多Windows API函数&#x…

python代码示例(读取excel文件,自动播放音频)

目录 python 操作excel 表结构 安装第三方库 代码 自动播放音频 介绍 安装第三方库 代码 python 操作excel 表结构 求出100班同学的平均分 安装第三方库 因为这里的表结构是.xlsx文件,需要使用openpyxl库 如果是.xls格式文件,需要使用xlrd库 pip install openpyxl /…