数据集MNIST手写体识别 pyqt5+Pytorch/TensorFlow

GitHub - LINHYYY/Real-time-handwritten-digit-recognition: VGG16和PyQt5的实时手写数字识别/Real-time handwritten digit recognition for VGG16 and PyQt5
pyqt5+Pytorch内容已进行开源,链接如上,请遵守开源协议维护开源环境,如果觉得内容还可以的话请各位老板们点点star

数据集

给定数据集MNIST,Downloading data from

https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz

MNIST是一个计算机视觉数据集,它包含各种手写数字图片0,1,2,...,9

MNIST数据集包含:60000行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test)。训练数据集和测试数据集都包含有一张手写的数字,和对应的标签,训练数据集的图片是 mnist.train.images ,训练数据集的标签是 mnist.train.labels;测试数据集的图片是 mnist.test.images ,训练数据集的标签是 mnist.test.labels每一张图片都是28*28像素(784个像素点),可以用点矩阵来表示每张图片

 (一)应用TensorFlow机器学习库建模实现手写体(0,1,2,...,9)识别

1.1安装TensorFlow:

pip install tensorflowpip install --user --upgrade tensorflow  # install in $HOMEpip install tensorflow_cpu-2.6.0-cp36-cp36-win_amd64.whlpip install tensorflow==2.2.0pip install tensorflow_cpu-2.6.0-cp38-cp38-win_amd64.whl

查看安装库:pip list 

验证安装:

import tensorflow as tfprint(tf.reduce_sum(tf.random.normal([1000, 1000])))

1.2 安装Pytorch

pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.6 -c pytorch -c nvidiaprint(torch.__version__) #检查torch版本print(torch.cuda.device_count()) #Gpu数量print(torch.version.cuda) #检查cuda版本print(torch.cuda.is_available()) #检查cuda是否可用if torch.cuda.is_available():device = torch.device("cuda:0")else: device = torch.device("cpu")print(device)

2.下载数据集并归一化

import tensorflow as tf
tf.random.set_seed(100)   # 随机种子,以便在后续的代码中生成可重复的随机数。
# 注意,这个设置对GPU不起作用,因为GPU有自己独立的随机数生成器。mnist = tf.keras.datasets.mnist  # 下载数据集
(X_train, y_train), (X_test, y_test) = mnist.load_data()  # 划分为训练集和测试集
X_train, X_test = X_train/255.0, X_test/255.0 # 将图像数据归一化,使其范围在0到1之间

3.使用Sequential快速构建模型并自动完成训练

# 创建神经网络
model = tf.keras.models.Sequential([# 展成一维,(60000,28,28)----->(60000,784)tf.keras.layers.Flatten(input_shape=(28, 28)),    # 将图像数据展平为一维向量tf.keras.layers.Dense(128, activation='relu'),    # 隐藏层128个节点tf.keras.layers.Dropout(0.2),    # 丢弃20%的节点tf.keras.layers.Dense(10, activation='softmax')    # 10个输出值
])model.summary()    # 输出模型结构和参数信息
# 编译模型,指定相关参数
model.compile(optimizer='adam', # 指定优化器(Adamloss = 'sparse_categorical_crossentropy',   # 交叉熵# sparse_categorical_crossentropy是Softmax损失函数,# 因为输出已经通过Softmax转成了概率(而不是logits),因此无需设置from_logits为Truemetrics=['accuracy'])  # 评价标准
print("开始训练...")
model.fit(X_train ,y_train, epochs=10, batch_size=64)    # batch_size默认为32
print("训练完成")
print("开始预测...")
result = model.evaluate(X_test, y_test)
print("预测结束,loss:{}, accuracy:{}".format(result[0], result[1]))

执行结果:

4.查看X_train、X_test形状

(二) 使用keras.layers组合模型并手动控制训练过程

  • 准备数据
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Dropout
from tensorflow.keras import Modeltf.random.set_seed(100)
(X_train, y_train), (X_test, y_test) = mnist.load_data() # 加载数据集
X_train, X_test = X_train/255.0, X_test/255.0 # 归一化# 将特征数据集从(N,32,32)转变成(N,32,32,1),因为Conv2D需要(NHWC)四阶张量结构
X_train = X_train[..., tf.newaxis]    
X_test = X_test[..., tf.newaxis]
print(X_train.shape)batch_size = 64 # 设置训练集和测试集的批次大小
# 手动生成mini_batch数据集
# 使用shuffle()函数打乱数据,使用batch()函数将数据划分为批次
train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train))
.shuffle(10000).batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((X_test, y_test)).batch
(batch_size)

  • Python类建立组合模型保存训练集和测试集loss、accuracy
# 定义模型结构
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Dropout
from tensorflow.keras import Model
class Basic_CNN_Model(Model):def __init__(self):super(Basic_CNN_Model, self).__init__()# 定义卷积层self.conv1 = Conv2D(32, 3, activation='relu')    # 32个filter,3x3核(1x3x3)self.flatten = Flatten()self.d1 = Dense(128, activation='relu')    # 隐藏层128个节点self.d2 = Dense(10, activation='softmax')def call(self, X):X = self.conv1(X)X = self.flatten(X)X = self.d1(X)return self.d2(X)
model = Basic_CNN_Model()
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()    # 因为是softmax输出,因此无需指定from_logits=True
optimizer = tf.keras.optimizers.Adam()# tf.keras.metrics.Mean()对象,能够持续记录传入的数据并同步更新其mean值,直到调用reset_states()方法清空原有数据
train_loss = tf.keras.metrics.Mean(name='train_loss')    # 用于计算并保存平均loss
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')    # 用于计算并保存平均accuracy
test_loss = tf.keras.metrics.Mean(name='test_loss')
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')

  • 定义单批次的训练和预测操作
@tf.function    # @tf.function用于将python的函数编译成tensorflow的图结构
def train_step(images, labels):    # 针对batch_size个样本,进行一次训练with tf.GradientTape() as tape:predictions = model(images)loss = loss_object(labels, predictions)    # 计算损失函数值,(batch_size, loss)二维结构gradients = tape.gradient(loss, model.trainable_variables)    # 根据loss反向传播计算所有权重参数的梯度optimizer.apply_gradients(zip(gradients, model.trainable_variables))    # 使用优化器更新权重参数的梯度 train_loss(loss)    # 结合历史数据和新传入的loss,计算新的平均值train_accuracy(labels, predictions)@tf.function # 装饰器
def test_step(images, labels):    # 针对batch_size个样本,进行一次预测(无需更新梯度)predictions = model(images)t_loss = loss_object(labels, predictions) # 计算损失函数值test_loss(t_loss)
test_accuracy(labels, predictions)
  • 执行完整的训练过程
EPOCHS = 10 # 迭代次数
# TODO:完成完整的训练过程
for epoch in range(EPOCHS):for images, labels in train_ds: # 训练train_step(images, labels)for images, labels in test_ds: # 测试test_step(images, labels)# TODO:输出本周期所有批次训练(或测试)数据的平均loss和accuracy# 输出当前周期数据的平均loss和accuracyprint("Epoch  {:03d}, Loss: {:.3f}, Accuracy: {:.3%}".format(epoch, train_loss.result(), train_accuracy.result()))print("Test   {:03d}, Loss: {:.3f}, Accuracy: {:.3%}".format(epoch, test_loss.result(), test_accuracy.result()))

执行结果:

# 绘制训练测试曲线
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt# loss value
plt.plot(tr_loss_data, range(0, EPOCHS), label='train_loss')
plt.plot(ts_loss_data, range(0, EPOCHS), label='test_loss')
plt.title('loss curve')
plt.legend()  #显示上面的label
plt.xlabel('loss value') #x_label
plt.ylabel('epoch')#y_label
plt.show()# accuracy value
plt.plot(tr_acc_data, range(0, EPOCHS), label='train_accuracy')
plt.plot(ts_acc_data, range(0, EPOCHS), label='test_accuracy')
plt.title('accuracy curve')
plt.legend()  #显示上面的label
plt.xlabel('accuracy value') #x_label
plt.ylabel('epoch')#y_label
plt.show()

(三) 自定义卷积神经网络

# 导入所需库及库函数
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPool2D, Dropout
from tensorflow.keras import Modeltf.random.set_seed(100) # 设定随机种子
mnist = tf.keras.datasets.mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data() # 划分为训练集和测试集
X_train, X_test = X_train/255.0, X_test/255.0 # 归一化# 将特征数据集从(N,32,32)转变成(N,32,32,1),因为Conv2D需要(NHWC)四阶张量结构
X_train = X_train[..., tf.newaxis]    
X_test = X_test[..., tf.newaxis]batch_size = 64  #每次迭代都使用64个样本# 手动生成mini_batch数据集
train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train)).shuffle(10000).batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((X_test, y_test)).batch(batch_size)class Deep_CNN_Model(Model):
# 包括两个卷积层、两个池化层、一个全连接层和一个softmax层def __init__(self):super(Deep_CNN_Model, self).__init__()self.conv1 = Conv2D(32, 5, activation='relu')self.pool1 = MaxPool2D()self.conv2 = Conv2D(64, 5, activation='relu')self.pool2 = MaxPool2D()self.flatten = Flatten()self.d1 = Dense(128, activation='relu')self.dropout = Dropout(0.2)self.d2 = Dense(10, activation='softmax')def call(self, X):X = self.conv1(X)X = self.pool1(X)X = self.conv2(X)X = self.pool2(X)X = self.flatten(X)X = self.d1(X)X = self.dropout(X)   # 无需在此处设置training状态。只需要在调用Model.call时,传递training参数即可return self.d2(X)
# 定义卷积神经网络、损失函数以及优化器
model = Deep_CNN_Model()
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
optimizer = tf.keras.optimizers.Adam()train_loss = tf.keras.metrics.Mean(name='train_loss')
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
test_loss = tf.keras.metrics.Mean(name='test_loss')
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')# TODO:定义单批次的训练和预测操作
@tf.function # 装饰器将训练和测试操作转换为TensorFlow图模式
def train_step(images, labels):with tf.GradientTape() as tape: # 记录模型在训练模式下的前向传播过程predictions = model(images, training=True)loss = loss_object(labels, predictions)gradients = tape.gradient(loss, model.trainable_variables) # 计算损失函数对模型参数的梯度optimizer.apply_gradients(zip(gradients, model.trainable_variables))train_loss(loss)train_accuracy(labels, predictions)@tf.function
def test_step(images, labels): # 计算模型在测试模式下的前向传播过程,以及计算损失函数和测试准确率predictions = model(images, training=False)loss = loss_object(labels, predictions)test_loss(loss)test_accuracy(labels, predictions)# TODO:执行完整的训练过程
EPOCHS = 10 # 训练的周期数
for epoch in range(EPOCHS):# 训练本周期所有批次数据for images, labels in train_ds:train_step(images, labels)# 在测试数据集上评估模型性能for test_images, test_labels in test_ds:test_step(test_images, test_labels)# TODO:输出本周期所有批次训练(或测试)数据的平均loss和accuracytrain_loss_value, train_accuracy_value = train_loss.result(), train_accuracy.result()test_loss_value, test_accuracy_value = test_loss.result(), test_accuracy.result()print(f"Epoch {epoch+1}, Train Loss: {train_loss_value}, Train Accuracy: {train_accuracy_value}, Test Loss: {test_loss_value}, Test Accuracy: {test_accuracy_value}")# 重置损失和准确率train_loss.reset_states()train_accuracy.reset_states()test_loss.reset_states()test_accuracy.reset_states()

代码训练执行结果:


# 绘制折线图,描述变化趋势
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# loss value
plt.plot(A_loss_data, range(0, EPOCHS), label='train_loss')
plt.plot(B_loss_data, range(0, EPOCHS), label='test_loss')
plt.title('loss curve')
plt.legend()  #显示上面的label
plt.xlabel('loss value') #x_label
plt.ylabel('epoch')#y_label
plt.show()
# accuracy value
plt.plot(A_acc_data, range(0, EPOCHS), label='train_accuracy')
plt.plot(B_acc_data, range(0, EPOCHS), label='test_accuracy')
plt.title('accuracy curve')
plt.legend()  #显示上面的label
plt.xlabel('accuracy value') #x_label
plt.ylabel('epoch')#y_label
plt.show()

(四) Pytorch自定义实现VGG16的手写数字识别

VGG16是一种广泛使用的卷积神经网络模型,它在ImageNet图像分类任务中表现优异。VGG16模型由英国计算机科学家 Karen Simonyan 和 Andrew Zisserman 提出。VGG16模型采用了大量的3x3卷积层和最大池化层,使得模型能够提取到更加丰富的图像特征。

VGG16模型包含13个卷积层和3个全连接层。其中,卷积层用于提取图像特征,全连接层用于分类。

class VGGBlock(nn.Module):def __init__(self, in_channels, out_channels, batch_norm=False): # 输入输出通道数,是否使用批量归一化super().__init__()conv2_params = {'kernel_size': (3, 3),'stride'     : (1, 1),'padding'   : 1}noop = lambda x : xself._batch_norm = batch_norm# 卷积层self.conv1 = nn.Conv2d(in_channels=in_channels, out_channels=out_channels , **conv2_params)self.bn1 = nn.BatchNorm2d(out_channels) if batch_norm else noopself.conv2 = nn.Conv2d(in_channels=out_channels, out_channels=out_channels, **conv2_params)self.bn2 = nn.BatchNorm2d(out_channels) if batch_norm else noop# 最大池化层self.max_pooling = nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2))@propertydef batch_norm(self):return self._batch_normdef forward(self,x): # 依次经过conv1、conv2,使用ReLU激活函数,最后通过max_pooling层减小特征图的大小神经网络模型构建x = self.conv1(x)x = self.bn1(x)x = F.relu(x)x = self.conv2(x)x = self.bn2(x)x = F.relu(x)x = self.max_pooling(x)return x# VGG16类定义一个VGG16网络,该网络由四个卷积块和全连接层组成,该类继承自nn.Module。
class VGG16(nn.Module):def __init__(self, input_size, num_classes=10, batch_norm=False): # 类别数(num_classes)super(VGG16, self).__init__()self.in_channels, self.in_width, self.in_height = input_size# VGG网络的四个卷积块self.block_1 = VGGBlock(self.in_channels, 64, batch_norm=batch_norm)self.block_2 = VGGBlock(64, 128, batch_norm=batch_norm)self.block_3 = VGGBlock(128, 256, batch_norm=batch_norm)self.block_4 = VGGBlock(256,512, batch_norm=batch_norm)# 全连接层self.classifier = nn.Sequential(nn.Linear(2048, 4096),nn.ReLU(True),nn.Dropout(p=0.65),nn.Linear(4096, 4096),nn.ReLU(True),nn.Dropout(p=0.65),nn.Linear(4096, num_classes) )@propertydef input_size(self):return self.in_channels, self.in_width, self.in_heightdef forward(self, x): # 将输入图像x传递给VGGBlock对象,然后将输出特征展平,最后通过全连接层计算类别概率x = self.block_1(x)x = self.block_2(x)x = self.block_3(x)x = self.block_4(x)x = x.view(x.size(0), -1)x = self.classifier(x)return x

1、导入所需库

import torchimport torchvisionimport torchvision.transforms as transformsimport torch.optim as optimimport torch.nn.functional as Fimport torch.nn as nnfrom torchvision import modelsimport matplotlib.pyplot as pltimport numpy as np # linear algebraimport pandas as pdimport timefrom VGG import VGG16,VGGBlock

2、进行模型训练

整个训练过程分为以下几个步骤:

1.初始化模型、损失函数、优化器等。

def train(loaders, optimizer, criterion, epochs=10, save_param=True, dataset="mnist"):global deviceglobal model

2.定义训练和测试的加载器

model = model.to(device)history_loss = {"train": [], "test": []}history_accuracy = {"train": [], "test": []}best_test_accuracy = 0start_time = time.time()

3.使用try-except结构捕获可能的键盘中断异常。

    except KeyboardInterrupt: # 用户键盘中断异常print("Interrupted")

4.使用for循环进行训练和测试。

for epoch in range(epochs):sum_loss = {"train": 0, "test": 0}sum_accuracy = {"train": 0, "test": 0}for split in ["train", "test"]:if split == "train":model.train()else:model.eval()

5.计算每个批次的损失和准确率。

# 计算批次的loss/accuracyepoch_loss = {split: sum_loss[split] / len(loaders[split]) for split in ["train", "test"]}epoch_accuracy = {split: sum_accuracy[split] / len(loaders[split]) for split in ["train", "test"]}

6.计算每个epoch的损失和准确率。

for (inputs, labels) in loaders[split]:inputs = inputs.to(device)labels = labels.to(device)optimizer.zero_grad()prediction = model(inputs)labels = labels.long()loss = criterion(prediction, labels)sum_loss[split] += loss.item()  # 更新lossif split == "train":loss.backward()  # 计算梯度optimizer.step()_,pred_label = torch.max(prediction, dim = 1)pred_labels = (pred_label == labels).float()batch_accuracy = pred_labels.sum().item() / inputs.size(0)sum_accuracy[split] += batch_accuracy  # 更新accuracy

训练过程截图:

3、Main主程序

# mainmodel = VGG16((1,32,32), batch_norm=True)# 随机梯度下降(SGD)optimizer = optim.SGD(model.parameters(), lr=0.001)criterion = nn.CrossEntropyLoss() # 交叉熵损失函数transform = transforms.Compose([transforms.Resize(32),transforms.ToTensor(),])# 加载数据集train_set = torchvision.datasets.MNIST(root='', train=True, download=True, transform=transform)test_set = torchvision.datasets.MNIST(root='', train=False, download=True, transform=transform)# 查看数据集信息print(f"Number of training samples: {len(train_set)}")print(f"Number of test samples: {len(test_set)}")# 提取数据标签x_train, y_train = train_set.data, train_set.targetsprint(x_train, y_train)# 如果训练集的图像数据的维度是3,则添加一个维度,使其变为B*C*H*W的格式if len(x_train.shape) == 3:x_train = x_train.unsqueeze(1)print(x_train.shape)# 制作 40 张图像的网格,每行 8 张图像x_grid = torchvision.utils.make_grid(x_train[:40], nrow=8, padding=2)print(x_grid.shape)# 将 tensor 转换为 numpy 数组npimg = x_grid.numpy()# 转换为 H*W*C 形状npimg_tr = np.transpose(npimg, (1, 2, 0))plt.imshow(npimg_tr, interpolation='nearest')image, label = train_set[200]plt.imshow(image.squeeze(), cmap='gray')print('Label:', label)train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)test_loader = torch.utils.data.DataLoader(test_set, batch_size=64, shuffle=False)loaders = {"train": train_loader,"test": test_loader}train(loaders, optimizer, criterion, epochs=15) 

在上述代码中,定义了优化器optimizer,使用SGD进行优化;使用交叉熵损失函数,并且定义一个图像处理管道transform,将图像大小调整为32x32,并将图像转化为张量。

加载MNIST数据集,并查看数据集信息,从数据集中提取图像数据和标签,如果训练集的图像数据的维度是3,则添加一个维度,使其变为BCH*W的格式。将张量转换为NumPy数组,并将其转换为HWC的形状。

4、使用pyqt5制作一个简单交互界面

利用pyqt5进行简单交互界面的制作,并且调用预测图片结果的函数,实时处理并且反馈回简单界面中。

声明了一个画板类,简单实现了清空画板、调用预测结果函数、退出的功能。

通过将用户手写的数字图片保存,传入函数中进行结果的预测,反馈最终的可能性最大的结果标签。

5、运行示例

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

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

相关文章

redis集群简单介绍及其搭建过程

Redis集群 1、哨兵模式 哨兵可以有多个,从服务器也可以有多个,从服务器也可以有多个,在Redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会实现主从切换&#x…

百度大模型安全荣获2024世界智能产业博览会“Find智能科技创新应用典型案例”

6月20日,2024世界智能产业博览会在天津开幕。会议聚焦人工智能、智能网联汽车、智能制造等年度热点议题,由世界智能产业博览会组委会指导,世界智能产业博览会组委会秘书处、中国新一代人工智能战略发展研究院、中国软件行业协会、中国网络空间…

极客之夜 | XCTF国际网络攻防联赛十周年庆典圆满落幕

在数字化浪潮的推动下,网络安全已成为全球关注的焦点。十年磨一剑,XCTF国际网络攻防联赛以其卓越的赛事品质和深远的影响力,成为网络安全领域的一面旗帜。极客之夜,我们齐聚一堂,共同庆祝XCTF的十年辉煌,展…

sheng的学习笔记-AI-高斯混合模型(GMM)

AI目录:sheng的学习笔记-AI目录-CSDN博客 sheng的学习笔记-AI-聚类(Clustering)-CSDN博客需要学习前置知识: 聚类,可参考 sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 EM算法,可参考 sheng的学习笔记-AI-EM算法-CSDN博客 贝…

OVS:网桥的状态:fail_mode模式

目录 1.创建一个普通的ovs网桥不做任何配置 2.检测fail_mode值,默认为空 3.创建netns并配置sto网桥的两个普通端口并配置IP信息 4.默认情况下的两个端口下挂两个虚拟机v3,v4天然通信-ping-ok 5.修改网桥的fail_mode为standalone,原来的通信没有影响 6.修改了…

伸缩盒模型,flex布局

目录 1、伸缩容器、伸缩项目 2、主轴方向(flex-direction) 3、主轴换行方式(flex-wrap) 4、flex-flow 5、主轴对齐方式(justify-content) 6、侧轴对齐方式_一行(align-items) 7、侧轴对齐方式_多行(align-content) 8、元素水平垂直居中 9、项目在主轴的基准长度(flex-b…

运维.Linux下执行定时任务(中:Cron的常用替代方案)

运维系列 Linux下执行定时任务(中:Cron的常用替代方案) - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAd…

CMA软件测试报告对企业和用户有什么好处?

CMA是中国计量认证的简称,由省级以上人民政府计量行政部门对检测机构的检测能力及可靠性进行的一种全面的认证及评价,认证对象是所有对社会出具公正数据的产品质量监督检验机构及其它各类实验室,是需要强制性认证的资质。取得该资质认证的&am…

【golang学习之旅】复杂数据类型——指针 函数

系列文章 【golang学习之旅】使用VScode安装配置Go开发环境 【golang学习之旅】报错:a declared but not used 【golang学习之旅】Go 的基本数据类型 【golang学习之旅】深入理解字符串string数据类型 【golang学习之旅】go mod tidy 【golang学习之旅】记录一次 p…

这就是人性的丑恶,很残酷但很现实

这些年我喜欢跟垃圾撕破脸,包括垃圾亲戚,我是不会跟你讲什么感情的,该滚蛋就滚蛋。我最不喜欢听什么今日留一线,日后好相见。 之前我还不懂事的时候,就有那种亲戚叫我帮他介绍工作,我照做了。 结果&#xf…

Android 11 ,默认授予预置应用/APK 需要的权限,解决permission denied for window type 2003 问题。

写这篇文章的原因是解决了一个APP闪退的问题,闪退的原因是插拔U盘时,注册的广播接收者接收到广播需要弹出一个Dialog询问是否需要打开U盘,这个Dialog设置的是系统级别悬浮窗,没有这个权限,报错导致闪退,下面…

腰背肌筋膜炎的症状及治疗

腰背肌筋膜炎的症状 一、疼痛特点: 主要表现为腰背部弥漫性钝痛,尤以两侧腰肌及髂嵴上方更为明显。疼痛特点为晨起痛,日间轻,傍晚复重。长时间不活动或活动过度均可诱发疼痛,病程长,且因劳累及气候变化而发…

小红书营销:解锁企业增长新引擎,与小红书集成实现精准获客

在数字化营销的新时代,小红书以其独特的社区文化和精准的用户定位,成为了品牌和企业争相入驻的热门平台。今天将探讨如何通过小红书平台进行营销获客,并强调与企业集成的重要性,以实现更高效的品牌增长。 一、小红书营销的独特优…

基于 MHA 的 MySQL 高可用主从架构

Author:Arsen Date:2024/06/25 目录 一、前言1.1 概述1.2 组件1.3 流程 二、环境三、部署3.1 基本环境3.1.1 hosts 配置3.1.2 配置 SSH 免密访问 3.2 MySQL 主从3.2.1 基础环境配置3.2.2 启动 MySQL 实例3.2.3 配置 MySQL 主从3.2.4 MySQL 主从同步验证 …

Calibre - 合并电子书(EpubMerge)

这里使用 Calibre 软件和 EpubMerge 插件 EpubMerge github : https://github.com/JimmXinu/EpubMerge 1、安装 Merge 插件 安装后需要重启 calibre 2、查看设置 4 3、选中文件、开始合并 合并完成后,会弹窗窗口,来编辑 合辑的元信息 完成…

基于python的随机森林多分类模型

1.随机森林多分类模型 1.1 基本原理 随机森林(Random Forest)是一种基于决策树的集成学习方法,它通过将多个决策树进行组合,以投票或平均的方式得到最终的预测结果。在多分类问题中,随机森林通过构建多个决策树&#…

开发RpcProvider的网络服务

首先更改src的CMakeLists.txt的内容为: #当前目录的所有源文件放入SRC_LIST aux_source_directory(. SRC_LIST)#生成SHARED动态库 #add_library(mprpc SHARED ${SRC_LIST})#由于muduo是静态库,为了使用muduo,将mprpc也生成为静态库 add_libr…

A股周一走势历史罕见,你知道是为什么吗?

今天的A股,让人历史罕见,你知道是为什么吗?盘面出现2个重要信号,一起来看看: 1、今天大盘低开低走,跌懵了,两市板块全部在等待翻红,这让人历史罕见。 2、盘面出现2个重要信号&#x…

【计算机毕业设计】167校园失物招领微信小程序

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

办公人导航-上网导航,找网站,下软件,找资源!

办公人导航是一个专门为办公人员设计的实用导航网站,旨在帮助用户高效地找到各种优质的办公资源和工具。无论是需要查找办公软件、学习资源还是娱乐工具,在办公人导航上都能找到你需要的内容。 办公人导航-实用的办公生活导航网站!https://ww…