Python学习从0开始——Kaggle计算机视觉001

Python学习从0开始——Kaggle计算机视觉001

  • 一、卷积分类器
    • 1.分类器
    • 2.训练分类器
    • 3.使用
  • 二、卷积和RELU
    • 1.特征提取
    • 2.带卷积的过滤器定义
    • 3.激活:
    • 4.用ReLU检测
    • 5.使用
  • 三、最大池化
    • 1.最大池压缩
    • 2.使用
    • 3.平移不变性
  • 四、滑动窗口
    • 1.介绍
    • 2.步长
    • 3.边界
    • 4.使用
  • 五、自定义Convnet
    • 1.由浅到深
    • 2.卷积块
    • 3.设计
  • 六、数据增强
    • 1.假数据的有用性
    • 2.使用数据增强
    • 3.使用

一、卷积分类器

神经网络如何很好地“理解”自然图像以解决人类视觉系统可以解决的相同类型的问题,在这项任务中表现最好的神经网络被称为卷积神经网络(有时我们称之为convnet或CNN)。
卷积是一种数学运算,它赋予了convnet的各层独特的结构。
训练计算机可以从照片中识别植物种类的应用程序,就是一个图像分类器。

1.分类器

用于图像分类的卷积神经网络由两个部分组成:卷积基和密集头。
基库用于从图像中提取特征。它主要由执行卷积操作的层组成,但通常也包括其他类型的层。头部用于确定图像的类别。它主要由致密层组成,但可能包括其他层,如dropout。我们所说的视觉特征是什么意思?特征可以是一条线、一种颜色、一种纹理、一种形状、一种图案——或者是一些复杂的组合。

在这里插入图片描述

2.训练分类器

在训练过程中,网络的目标是学习两件事:从图像中提取哪些特征(基),哪个类与哪些特征(头)相匹配。如今,convnet很少接受从零开始的培训。更常见的是,我们重用预训练模型的基础。在预训练的基座上,我们接一个未经训练的头部。换句话说,我们重用了网络中已经学会做1的部分来提取特征,然后添加一些新的图层来学习2分类。

在这里插入图片描述

因为头部通常只由几个密集的层组成,所以可以从相对较少的数据中创建非常准确的分类器。
重用预训练模型是一种称为迁移学习的技术。它非常有效,现在几乎所有的图像分类器都会使用它。

3.使用

定义管道:

# Imports
import os, warnings
import matplotlib.pyplot as plt
from matplotlib import gridspecimport numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image_dataset_from_directory# Reproducability
def set_seed(seed=31415):np.random.seed(seed)tf.random.set_seed(seed)os.environ['PYTHONHASHSEED'] = str(seed)os.environ['TF_DETERMINISTIC_OPS'] = '1'
set_seed(31415)# 设置Matplotlib默认值
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)
plt.rc('image', cmap='magma')
warnings.filterwarnings("ignore") # 清理输出单元格# 加载训练和验证集
ds_train_ = image_dataset_from_directory('../input/car-or-truck/train',labels='inferred',label_mode='binary',image_size=[128, 128],interpolation='nearest',batch_size=64,shuffle=True,
)
ds_valid_ = image_dataset_from_directory('../input/car-or-truck/valid',labels='inferred',label_mode='binary',image_size=[128, 128],interpolation='nearest',batch_size=64,shuffle=False,
)# Data Pipeline
def convert_to_float(image, label):image = tf.image.convert_image_dtype(image, dtype=tf.float32)return image, labelAUTOTUNE = tf.data.experimental.AUTOTUNE
ds_train = (ds_train_.map(convert_to_float).cache().prefetch(buffer_size=AUTOTUNE)
)
ds_valid = (ds_valid_.map(convert_to_float).cache().prefetch(buffer_size=AUTOTUNE)
)

最常用的预训练数据集是ImageNet,这是一个包含多种自然图像的大型数据集。Keras在其应用程序模块中包括在ImageNet上预训练的各种模型。我们将使用的预训练模型称为VGG16。
定义预训练库:

pretrained_base = tf.keras.models.load_model('../input/cv-course-models/cv-course-models/vgg16-pretrained-base',
)
pretrained_base.trainable = False

接下来,连接分类器头部,本例使用隐藏单元层(第一个Dense层),然后使用另一个层将输出转换为类别1 Truck的概率分数。Flatten层将基座的二维输出转换为头部所需的一维输入。

from tensorflow import keras
from tensorflow.keras import layersmodel = keras.Sequential([pretrained_base,layers.Flatten(),layers.Dense(6, activation='relu'),layers.Dense(1, activation='sigmoid'),
])

最后,训练模型。由于这是一个二分类问题,我们将使用crossentropy 和 accuracy的二进制版本。adam优化器通常表现良好,所以选择它。

model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['binary_accuracy'],
)history = model.fit(ds_train,validation_data=ds_valid,epochs=30,verbose=0,
)

在训练神经网络时,检查损失图和度量图。历史对象在字典history.history中包含这些信息。我们可以使用Pandas将该字典转换为数据框,并使用内置方法绘制。

import pandas as pdhistory_frame = pd.DataFrame(history.history)
history_frame.loc[:, ['loss', 'val_loss']].plot()
history_frame.loc[:, ['binary_accuracy', 'val_binary_accuracy']].plot();

二、卷积和RELU

1.特征提取

三个操作:

  • 过滤图像的特定特征(卷积)
  • 在过滤图像(ReLU)中检测该特征
  • 压缩图像以增强特征(最大池化)

在这里插入图片描述

2.带卷积的过滤器定义

from tensorflow import keras
from tensorflow.keras import layersmodel = keras.Sequential([layers.Conv2D(filters=64, kernel_size=3), # activation is None# More layers follow
])

在训练过程中,卷积神经网络学习到的权重主要包含在卷积层中。这些权重我们称之为“核”(kernels),可以将它们表示为小数组。内核通过扫描图像并产生像素值的加权和来操作。通过这种方式,内核就像一个偏光透镜,强调或弱化某些信息模式。

在这里插入图片描述

核定义了卷积层如何连接到后面的层。上面的核将输出中的每个神经元连接到输入中的九个神经元。通过使用kernel_size设置内核的维度,可以设置convnet如何形成这些连接。大多数情况下,内核的维数为奇数——比如kernel_size=(3,3)或(5,5)——这样单个像素就会位于中心,但这不是必需的。卷积层中的核决定了它创建的特征类型。在训练过程中,convnet试图学习解决分类问题所需要的特征。这意味着找到它的核的最佳值。

3.激活:

网络中的激活我们称之为特征映射。它们是当我们对图像应用过滤器时产生的结果;它们包含内核提取的视觉特征。下面是一些内核和他们制作的特征图。
在这里插入图片描述

从内核中的数字模式中,你可以知道它创建的特征映射的类型。一般来说,卷积在其输入中强调的内容将与核中的正数的形状相匹配。上面左边和中间的核都将过滤水平形状。使用filters参数设置卷积层创建多少个特征映射作为输出。

4.用ReLU检测

特征映射经过过滤后,通过激活函数。带有整流器的神经元称为整流线性单元。因此也将整流函数称为ReLU激活,ReLU函数。ReLU激活可以在它自己的激活层中定义,但多数情况下,只将它作为Conv2D的激活函数包含进去。

model = keras.Sequential([layers.Conv2D(filters=64, kernel_size=3, activation='relu')# More layers follow
])

ReLU激活表示负值不重要,因此将它们设置为0。与其他激活函数一样,ReLU函数也是非线性的。从本质上讲,这意味着网络中所有层的总效果与你仅仅将效果加在一起所得到的效果是不同的——这与你只使用一个层所获得的效果是一样的。非线性确保了特征会以有趣的方式结合在一起,随着它们深入到网络中。

5.使用

import tensorflow as tf
import matplotlib.pyplot as plt
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)
plt.rc('image', cmap='magma')image_path = '../input/computer-vision-resources/car_feature.jpg'
image = tf.io.read_file(image_path)
image = tf.io.decode_jpeg(image)#原图
plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image), cmap='gray')
plt.axis('off')
plt.show();#定义kernel
kernel = tf.constant([[-1, -1, -1],[-1,  8, -1],[-1, -1, -1],
])plt.figure(figsize=(3, 3))
#kernel数组
show_kernel(kernel)#过滤器
image_filter = tf.nn.conv2d(input=image,filters=kernel,strides=1,padding='SAME',
)plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image_filter))
plt.axis('off')
plt.show();#ReLU检测
image_detect = tf.nn.relu(image_filter)plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image_detect))
plt.axis('off')
plt.show();

三、最大池化

1.最大池压缩

from tensorflow import keras
from tensorflow.keras import layersmodel = keras.Sequential([layers.Conv2D(filters=64, kernel_size=3), # activation is Nonelayers.MaxPool2D(pool_size=2),# More layers follow
])

MaxPool2D层与Conv2D层非常相似,除了它使用简单的maximum函数而不是kernel,其pool_size参数类似于kernel_size。然而,MaxPool2D层在其kernel中不像卷积层那样具有任何可训练的权重。
在应用ReLU函数(Detect)之后,特征映射最终会产生大量的“死区”,即只包含0的大块区域(图像中的黑色区域)。在整个网络中携带这些0个激活会增加模型的大小,而不会增加很多有用的信息。相反,我们想要压缩特征映射,只保留最有用的部分——特征本身。

在这里插入图片描述

这实际上就是最大池化所做的。最大池取原始特征映射中的一个激活补丁,并用该补丁中的最大激活替换它们。在ReLU激活后使用,具有“强化”功能的效果。池化步骤将活动像素的比例增加到零像素。

2.使用

#接二、卷积和ReLU的使用代码
import tensorflow as tfimage_condense = tf.nn.pool(input=image_detect, # 图像在上面的检测步骤window_shape=(2, 2),pooling_type='MAX',strides=(2, 2),padding='SAME',
)plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image_condense))
plt.axis('off')
plt.show();

3.平移不变性

我们称零像素为“不重要”。这是否意味着它们根本不携带任何信息?事实上,零像素携带位置信息。空白仍然将特征定位在图像中。当MaxPool2D删除其中一些像素时,它会删除特征映射中的一些位置信息。这给了一个convnet一个叫做平移不变性的属性。这意味着具有最大池化的convnet将倾向于不通过图像中的位置来区分特征。(“平移”是在不旋转或改变物体形状或大小的情况下改变物体的位置。)
对下面的特性映射重复应用最大池化:

在这里插入图片描述

经过多次池化,原始图像中的两个点变得无法区分。换句话说,池化破坏了它们的一些位置信息。由于网络不再能够在特征映射中区分它们,它也不能在原始图像中区分它们:它对位置的差异变得不变性。实际上,池化只在网络中创建小距离的平移不变性,就像图像中的两个点一样。开始时相距很远的特征在池化之后仍然明显;只有部分位置信息丢失了,但不是全部。

在这里插入图片描述

对于图像分类器来说,这种对特征位置微小差异的不变性是一个很好的属性。仅仅因为视角或框架的不同,相同的特征可能会被定位在原始图像的不同部分,但我们仍然希望分类器能够识别出它们是相同的。因为这种不变性是内置在网络中的,我们可以使用更少的数据进行训练:我们不再需要教它忽略这种差异。这使得卷积网络比只有密集层的网络具有很大的效率优势。

四、滑动窗口

1.介绍

卷积和池化操作有一个共同的特点:它们都是在滑动窗口上执行的。对于卷积,这个“窗口”是由内核的维度,参数kernel_size给出的。对于池化,它是池化窗口,由pool_size给出。
还有两个额外的参数会影响卷积层和池化层——它们是窗口的步长和是否在图像边缘使用填充。strides参数表示在每一步中窗口应该移动多远,padding参数描述我们如何处理输入边缘的像素。
有了这两个参数,定义这两个层就变成了:

from tensorflow import keras
from tensorflow.keras import layersmodel = keras.Sequential([layers.Conv2D(filters=64,kernel_size=3,strides=1,padding='same',activation='relu'),layers.MaxPool2D(pool_size=2,strides=1,padding='same')# More layers follow
])

2.步长

窗口在每一步移动的距离被称为步长(stride)。我们需要在图像的两个维度上指定步长:一个用于从左到右的移动,另一个用于从上到下的移动。
当步长在任一方向上大于1时,滑动窗口将在每一步跳过输入中的某些像素。因为我们想要使用高质量的特征来进行分类,卷积层通常会有步长(strides)为(1, 1)。增加步长意味着我们在总结时会错过一些可能有价值的信息。然而,最大池化层(Max Pooling layers)几乎总是会有大于1的步长值,如(2, 2)或(3, 3),但不会大于窗口本身。
最后,请注意,当步长在两个方向上的值相同时,你只需要设置那个数字;例如,代替strides=(2, 2),你可以在参数设置中使用strides=2。

3.边界

在进行滑动窗口计算时,有一个问题是关于在输入边界处如何处理。完全保持在输入图像内部意味着窗口永远不会像输入中的其他像素那样正好覆盖这些边界像素。既然我们没有将所有像素完全平等地处理,那么会不会有问题?
卷积如何处理这些边界值是由其填充参数(padding parameter)决定的。在TensorFlow中,你有两个选择:要么设置padding=‘same’,要么设置padding=‘valid’。每种方式都有其利弊。
当我们设置padding='valid’时,卷积窗口将完全保持在输入内部。缺点是输出会缩小(失去像素),而且内核越大,输出缩小得越多。这将限制网络可以包含的层数,尤其是当输入尺寸较小时。
另一种选择是使用padding=‘same’。这里的技巧是在输入的边界周围填充0,只填充足够的0以使输出的尺寸与输入的尺寸相同。然而,这可能会削弱边界像素的影响。

4.使用

import tensorflow as tf
import matplotlib.pyplot as pltplt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)
plt.rc('image', cmap='magma')image = circle([64, 64], val=1.0, r_shrink=3)
image = tf.reshape(image, [*image.shape, 1])
# kernel 
kernel = tf.constant([[-1, -2, -1],[0, 0, 0],[1, 2, 1]],
)show_kernel(kernel)show_extraction(image, kernel,# 窗口参数,步长1conv_stride=1,pool_size=2,pool_stride=2,subplot_shape=(1, 4),figsize=(14, 6),
)

在这里插入图片描述

show_extraction(image, kernel,# 步长3conv_stride=3,pool_size=2,pool_stride=2,subplot_shape=(1, 4),figsize=(14, 6),    
)

在这里插入图片描述

这似乎降低了特征提取的质量。我们的输入圈非常“精细”,只有1像素宽。步长为3的卷积过于粗糙,无法从中生成良好的特征图。有时,模型将在其初始层中使用具有较大步幅的卷积。这通常还需要一个更大的内核。

五、自定义Convnet

1.由浅到深

卷积网络通过三种操作来执行特征提取:过滤、检测和压缩。单轮特征提取只能从图像中提取相对简单的特征,比如简单的线条或对比。这些方法太简单,无法解决大多数分类问题。相反,convnets会一遍又一遍地重复这种提取,因此,随着特征在网络中的深入,它们变得更加复杂和精细。

2.卷积块

卷积神经网络通过将它们传递给一长串的卷积块来实现这种特征提取。这些卷积块是Conv2D和MaxPool2D层的堆叠,每个块代表一轮特征提取,通过组合这些块,卷积神经网络可以组合和重新组合产生的特征,使它们增长并适应当前的问题。现代卷积神经网络的深层结构使得这种复杂的特征工程得以实现,并在很大程度上决定了它们优越的性能。

3.设计

# Imports
import os, warnings
import matplotlib.pyplot as plt
from matplotlib import gridspecimport numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image_dataset_from_directory# 复用函数
def set_seed(seed=31415):np.random.seed(seed)tf.random.set_seed(seed)os.environ['PYTHONHASHSEED'] = str(seed)os.environ['TF_DETERMINISTIC_OPS'] = '1'
set_seed()# 设置Matplotlib默认值
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)
plt.rc('image', cmap='magma')
warnings.filterwarnings("ignore") # to clean up output cells# 加载训练和验证集
ds_train_ = image_dataset_from_directory('../input/car-or-truck/train',labels='inferred',label_mode='binary',image_size=[128, 128],interpolation='nearest',batch_size=64,shuffle=True,
)
ds_valid_ = image_dataset_from_directory('../input/car-or-truck/valid',labels='inferred',label_mode='binary',image_size=[128, 128],interpolation='nearest',batch_size=64,shuffle=False,
)# 数据管道
def convert_to_float(image, label):image = tf.image.convert_image_dtype(image, dtype=tf.float32)return image, labelAUTOTUNE = tf.data.experimental.AUTOTUNE
ds_train = (ds_train_.map(convert_to_float).cache().prefetch(buffer_size=AUTOTUNE)
)
ds_valid = (ds_valid_.map(convert_to_float).cache().prefetch(buffer_size=AUTOTUNE)
)

现在定义模型,看看模型是如何由Conv2D和MaxPool2D层(基础)的三个块组成的,然后是密集层的头部。我们可以通过填充适当的参数或多或少直接将这个图转换为Keras Sequential模型。

from tensorflow import keras
from tensorflow.keras import layersmodel = keras.Sequential([# 第一个卷积块layers.Conv2D(filters=32, kernel_size=5, activation="relu", padding='same',# give the input dimensions in the first layer# [height, width, color channels(RGB)]input_shape=[128, 128, 3]),layers.MaxPool2D(),# 第二个卷积块layers.Conv2D(filters=64, kernel_size=3, activation="relu", padding='same'),layers.MaxPool2D(),# 第三个卷积块layers.Conv2D(filters=128, kernel_size=3, activation="relu", padding='same'),layers.MaxPool2D(),# 分类器头layers.Flatten(),layers.Dense(units=6, activation="relu"),layers.Dense(units=1, activation="sigmoid"),
])
model.summary()

注意,在这个定义中,过滤器的数量是如何逐块加倍的:32,64,128。这是一种常见的模式。由于MaxPool2D层减少了特征映射的大小,我们得以增加创建的数量。

#训练
model.compile(optimizer=tf.keras.optimizers.Adam(epsilon=0.01),loss='binary_crossentropy',metrics=['binary_accuracy']
)history = model.fit(ds_train,validation_data=ds_valid,epochs=40,verbose=0,
)#生成图像
import pandas as pdhistory_frame = pd.DataFrame(history.history)
history_frame.loc[:, ['loss', 'val_loss']].plot()
history_frame.loc[:, ['binary_accuracy', 'val_binary_accuracy']].plot();

六、数据增强

1.假数据的有用性

提高机器学习模型性能的最好方法是在更多的数据上训练它。模型需要学习的例子越多,它就越能识别出图像中哪些差异是重要的,哪些是不重要的。更多的数据有助于模型更好地泛化。获取更多数据的一个简单方法是使用你已经拥有的数据。如果我们可以以保留类的方式转换数据集中的图像,我们可以教分类器忽略这些类型的转换。例如,无论一辆车在照片中是朝左还是朝右,都不会改变它是一辆车而不是一辆卡车的事实。因此,如果我们用翻转的图像来增强训练数据,我们的分类器将学习到“左或右”是一个应该忽略的差异。这就是数据增强背后的整个思想:添加一些看起来很像真实数据的额外假数据,分类器就会得到改进。

2.使用数据增强

通常,在扩充数据集时会使用多种转换。这些可能包括旋转图像,调整颜色或对比度,扭曲图像或许多其他事情,通常组合应用。下面是一张图片可能被变换的不同方式的例子:

在这里插入图片描述

数据增强通常是在线完成的,也就是说,当图像被输入网络进行训练时。回想一下,训练通常是在小批量数据上完成的。这是使用数据增强时一批16张图像的样子:

在这里插入图片描述

每次在训练中使用图像时,应用一个新的随机变换。通过这种方式,模型总是看到一些与之前不同的东西。训练数据中的这种额外方差有助于模型处理新数据。重要的是要记住,并不是每个转换都对给定的问题有用。最重要的是,无论使用什么转换,都不应该混淆这些类。

3.使用

Keras允许两种方式扩展数据。第一种方法是使用ImageDataGenerator之类的函数将其包含在数据管道中。第二种方法是通过使用Keras的预处理层将其包含在模型定义中。这就是我们要采取的方法。对我们来说,主要的优势是图像转换将在GPU而不是CPU上计算,这可能会加快训练速度。
下面通过数据增强来改进一中的分类器。

# Imports
import os, warnings
import matplotlib.pyplot as plt
from matplotlib import gridspecimport numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image_dataset_from_directorydef set_seed(seed=31415):np.random.seed(seed)tf.random.set_seed(seed)os.environ['PYTHONHASHSEED'] = str(seed)#os.environ['TF_DETERMINISTIC_OPS'] = '1'
set_seed()# 参数
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)
plt.rc('image', cmap='magma')
warnings.filterwarnings("ignore") # to clean up output cells# 加载数据集和验证集
ds_train_ = image_dataset_from_directory('../input/car-or-truck/train',labels='inferred',label_mode='binary',image_size=[128, 128],interpolation='nearest',batch_size=64,shuffle=True,
)
ds_valid_ = image_dataset_from_directory('../input/car-or-truck/valid',labels='inferred',label_mode='binary',image_size=[128, 128],interpolation='nearest',batch_size=64,shuffle=False,
)# 管道
def convert_to_float(image, label):image = tf.image.convert_image_dtype(image, dtype=tf.float32)return image, labelAUTOTUNE = tf.data.experimental.AUTOTUNE
ds_train = (ds_train_.map(convert_to_float).cache().prefetch(buffer_size=AUTOTUNE)
)
ds_valid = (ds_valid_.map(convert_to_float).cache().prefetch(buffer_size=AUTOTUNE)
)

定义模型:

from tensorflow import keras
from tensorflow.keras import layers
# 这是TF 2.2中的一个新特性
from tensorflow.keras.layers.experimental import preprocessingpretrained_base = tf.keras.models.load_model('../input/cv-course-models/cv-course-models/vgg16-pretrained-base',
)
pretrained_base.trainable = Falsemodel = keras.Sequential([# 预处理preprocessing.RandomFlip('horizontal'), # 左右翻转preprocessing.RandomContrast(0.5), # 对比度变化50%pretrained_base,# 头部layers.Flatten(),layers.Dense(6, activation='relu'),layers.Dense(1, activation='sigmoid'),
])

测试评估:

model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['binary_accuracy'],
)history = model.fit(ds_train,validation_data=ds_valid,epochs=30,verbose=0,
)import pandas as pdhistory_frame = pd.DataFrame(history.history)history_frame.loc[:, ['loss', 'val_loss']].plot()
history_frame.loc[:, ['binary_accuracy', 'val_binary_accuracy']].plot();

该模型的学习曲线能够保持在一起,并且我们在验证损失和准确性方面取得了一些适度的改进。这表明数据集确实从增强中受益。

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

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

相关文章

Vue 简单自定义标签

Vue 简单自定义标签 思路&#xff1a; 1、计算每个项离父级左侧宽 left 2、计算当前滑块的宽&#xff0c;绝对定位 3、下一个项的宽/2-滑块的宽/2下一项离父级左侧的宽 left 4、使用定位left&#xff08;性能较差一点&#xff09; 或 translate 移动距离 <template><…

(几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。

(几何:六边形面积)编写程序&#xff0c;提示用户输入六边形的边长&#xff0c;然后显示它的面积。计 算六边形面积的公式是: 这里的s就是边长。下面是一个运行示例 package myjava; import java.math.*; import java.util.Scanner; public class cy {public static void main(S…

gridview的模板按钮如何判断用户点击的是哪一行

在asp.net的 GridView 控件中&#xff0c;判断用户点击的是哪一行通常可以通过处理 GridView 的 RowCommand 事件来实现。RowCommand 事件会在 GridView 的每个按钮&#xff08;除非另有指定的CommandName&#xff09;被点击时触发&#xff0c;并且事件参数中包含了足够的信息来…

阿里云域名解析

阿里云域名控制台&#xff1a;https://dc.console.aliyun.com/next/index#/domain-list/all

.net 调用海康SDK以及常见的坑解释

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !序言 在工控领域,很多时候需要…

MPT(merkle Patricia trie )及理解solidity里的storage

what&#xff1f; MPT树是一种数据结构&#xff0c;用于在以太坊区块链中高效地存储和检索账户状态、交易历史和其他重要数据。MPT树的设计旨在结合Merkle树和Patricia树的优点&#xff0c;以提供高效的数据存储和验证 MPT树由四种类型的节点组成&#xff1a; **扩展节点&…

max code size exceeded

Warning! Error encountered during contract execution [max code size exceeded] 智能合约编译时提示 contracts/core/CORE.sol:15:1: Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on m…

小而美的算法技巧:前缀和数组

小而美的算法技巧&#xff1a;前缀和数组 类似动态规划。 class NumArray {private int[] preSum;public NumArray(int[] nums) {preSumnew int[nums.length1];//preSum[0]的前缀和为0for(int i1;i<preSum.length;i){preSum[i]nums[i-1]preSum[i-1];//先计算累加和}}publi…

解锁ChatGPT:从原理探索到GPT-2的中文实践及性能优化

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

视频生成模型 Dream Machine 开放试用;微软将停止 Copilot GPTs丨 RTE 开发者日报 Vol.224

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

2.6数据报与虚电路

数据报 当作为通信子网用户的端系统要发送一个报文时&#xff0c;在端系统中实现的高层协议先把报文拆成若干个带有序号的数据单元&#xff0c;并在网络层加上地址等控制信息后形成数据报分组(即网络层PDU)中间结点存储分组一段很短的时间&#xff0c;找到最佳的路由后&#x…

6.nginx负载均衡

说明 增加服务器的数量,将请求分发到各个服务器上。 将原来请求集中到单个服务器上的情况改为将请求分发到多个服务器上。 案例 浏览器请求地址http://ip/edu/a.html, 负载均衡的效果,平分到8080和8081两台服务上中。 准备工作 tomcat8080配置 tomcat8081配置 直接通过…

Deepstream 应用——去掉矩形框和文字

问题 如何去掉矩形框&#xff1f;以及矩形框上文字&#xff1f; 思路 参照Deepstream用户手册——DeepStream应用及配置文件-CSDN博客 可以看到修改OSD组可以操控矩形框以及文字&#xff1b; 具体方法 若为配置文件将下列项内容修改如下所示&#xff1a; display-text0dis…

【ARMv8/ARMv9 硬件加速系列 1 -- SVE | NEON | SIMD | VFP | MVE | MPE 基础介绍】

文章目录 ARM 扩展功能介绍VFP (Vector Floating Point)SIMD (Single Instruction, Multiple Data)NEONSVE (Scalable Vector Extension)SME (Scalable Matrix Extension)CME (Compute Matrix Engine)MVE (M-profile Vector Extension)MPE (Media Processing Engine)总结 ARM 扩…

嵌入式学习记录6.13(qt day1)

一.思维导图 二.练习&#xff08;简单模拟tim界面&#xff09; 2.1代码 mywidget.cpp #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {this->setWindowTitle("Tim");this->setWindowIcon(QIcon("C:\\Users\\zy\…

微信小程序-uniapp-切换tab时数据列表如何切换?

如图&#xff1a; 这里有两个tab&#xff0c;要保证每次切换后列表保持不变&#xff0c;就必须在运行时要有两个持久化的数据源&#xff0c;每个tab是一个列表&#xff0c;让我们来设计一下这样的数据结构。 首先我们的数据结构是这样的&#xff1a; 体现在vue的data是这样的&a…

Qt多线程之moveToThread()函数

文章目录 一、moveToThread()执行后&#xff0c;当前代码线程没有改变。二、对象执行moveToThread()后&#xff0c;哪些成员加入了子线程1、创建对象时不指定父对象2、对属性对象使用moveToThread加入子线程作用域3、将属性对象的创建放到子线程中执行 三、C内存模型 在使用“继…

ollama系统更改模型存放位置

1.windows 设置完后可以在cmd中检查一下&#xff1a;echo %ollama_models% 2.linux 首先第一步&#xff1a;cd /etc/systemd/system/ 打开配置文件vim ollama.service 第二步&#xff1a;目录下的environment里面分号隔开添加OLLAMA_MODELS环境变量 第三步&#xff1a;source …

【Kadane】Leetcode 918. 环形子数组的最大和【中等】

环形子数组的最大和 给定一个长度为 n 的环形整数数组 nums &#xff0c;返回 nums 的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c; nums[i] 的下一个元素是 nums[(i 1) % n] &#xff0c;nums[i] 的前一个元素是 nums…

工作组局域网-ARP欺骗-攻击防御单双向

免责声明:本文仅做技术交流与学习... 目录 断网限制-单向 环境: 演示: win10: 欺骗前 欺骗后 kali: kali执行命令: win10结果: 劫持数据-双向 欺骗&#xff1a; 网络分析&#xff1a; 防御--动态解析改静态 中间人攻击 断网限制-单向 环境: 靶机:win10 攻击机:kali…