深度学习 精选笔记(4)线性神经网络-交叉熵回归与Softmax 回归

学习参考:

  • 动手学深度学习2.0
  • Deep-Learning-with-TensorFlow-book
  • pytorchlightning

①如有冒犯、请联系侵删。
②已写完的笔记文章会不定时一直修订修改(删、改、增),以达到集多方教程的精华于一文的目的。
③非常推荐上面(学习参考)的前两个教程,在网上是开源免费的,写的很棒,不管是开始学还是复习巩固都很不错的。

深度学习回顾,专栏内容来源多个书籍笔记、在线笔记、以及自己的感想、想法,佛系更新。争取内容全面而不失重点。完结时间到了也会一直更新下去,已写完的笔记文章会不定时一直修订修改(删、改、增),以达到集多方教程的精华于一文的目的。所有文章涉及的教程都会写在开头、一起学习一起进步。

一、交叉熵回归

交叉熵回归(Cross-Entropy Regression):交叉熵是一种用于衡量两个概率分布之间差异的指标,在机器学习中常用于分类问题的损失函数。交叉熵回归通常用于二分类问题,其中模型输出的是一个概率值,表示样本属于某一类的概率,损失函数是交叉熵损失函数。交叉熵损失函数可以表示为:
在这里插入图片描述

二、Softmax 回归

Softmax 回归:Softmax 回归是一种多分类模型,用于将模型的输出转化为多个类别的概率分布。在 Softmax 回归中,模型的最后一层是一个 Softmax 函数,将模型的输出转化为每个类别的概率,使得所有类别的概率之和为 1。
在这里插入图片描述

交叉熵回归通常用于二分类问题,而 Softmax 回归用于多分类问题。此外,Softmax 回归中的 Softmax 函数将模型输出转化为概率分布,而交叉熵回归中的损失函数用于衡量二分类模型输出与真实标签的差异。

1.分类问题

分类任务是机器学习和统计学中常见的一类任务,其目标是将数据集中的样本划分到预定义的类别或标签中。分类任务通常涉及预测离散的输出值,即将样本分为不同的类别。例如,将电子邮件分为“垃圾邮件”和“非垃圾邮件”、将图片识别为“猫”、“狗”或“鸟”等。

分类问题是指解决这类分类任务的问题。分类问题的关键在于构建一个分类模型,该模型可以根据输入的特征将样本正确地分配到各个类别中。常用的分类算法包括逻辑回归、支持向量机(SVM)、决策树、随机森林、K近邻(K-NN)等。

一种表示分类数据的简单方法:独热编码(one-hot encoding)。 独热编码是一个向量,它的分量和类别一样多。 类别对应的分量设置为1,其他所有分量设置为0。 从一个图像分类问题开始,假设每个图像属于类别“猫”“鸡”和“狗”中的一个、每次输入是一个 2×2 的灰度图像、每个图像对应四个特征𝑥1,𝑥2,𝑥3,𝑥4。标签 𝑦将是一个三维向量, 其中 (1,0,0) 对应于“猫”、 (0,1,0) 对应于“鸡”、 (0,0,1) 对应于“狗”。
在这里插入图片描述

2.网络结构

为了估计所有可能类别的条件概率,需要一个有多个输出的模型,每个类别对应一个输出。 为了解决线性模型的分类问题,需要和输出一样多的仿射函数(affine function)。 每个输出对应于它自己的仿射函数。

在识别猫、鸡、狗的任务中,为每个输入计算三个未规范化的预测(logit):𝑜1、𝑜2和𝑜3:
在这里插入图片描述
与线性回归一样,softmax回归也是一个单层神经网络。 由于计算每个输出 𝑜1 、 𝑜2 和 𝑜3取决于 所有输入 𝑥1 、 𝑥2 、 𝑥3 和 𝑥4 , 所以softmax回归的输出层也是全连接层。
在这里插入图片描述
通过向量形式表达为𝐨=𝐖𝐱+𝐛, 这是一种更适合数学和编写代码的形式。 由此,已经将所有权重放到一个3×4矩阵中。 对于给定数据样本的特征𝐱, 输出是由权重与输入特征进行矩阵-向量乘法再加上偏置𝐛得到的。

3.softmax运算

将优化参数以最大化观测数据的概率。 为了得到预测结果,将设置一个阈值,如选择具有最大概率的标签。

softmax函数能够将未规范化的预测变换为非负数并且总和为1,同时让模型保持 可导的性质。 为了完成这一目标,我们首先对每个未规范化的预测求幂,这样可以确保输出非负。 为了确保最终输出的概率值总和为1,我们再让每个求幂后的结果除以它们的总和。如下式:
在这里插入图片描述
因此, 𝐲̂ 可以视为一个正确的概率分布。 softmax运算不会改变未规范化的预测 𝐨之间的大小次序,只会确定分配给每个类别的概率。 因此,在预测过程中,仍然可以用下式来选择最有可能的类别。

在这里插入图片描述
尽管softmax是一个非线性函数,但softmax回归的输出仍然由输入特征的仿射变换决定。 因此,softmax回归是一个线性模型(linear model)。

4.小批量样本的矢量化

为了提高计算效率并且充分利用GPU,通常会对小批量样本的数据执行矢量计算。 softmax回归的矢量计算表达式为:
在这里插入图片描述
相对于一次处理一个样本, 小批量样本的矢量化加快了 𝐗和𝐖的矩阵-向量乘法。 由于 𝐗中的每一行代表一个数据样本, 那么softmax运算可以按行(rowwise)执行: 对于 𝐎 的每一行,先对所有项进行幂运算,然后通过求和对它们进行标准化。

5.损失函数

需要一个损失函数来度量预测的效果。 将使用最大似然估计,这与在线性回归中相同。

(1)对数似然

softmax函数给出了一个向量 𝐲̂ , 可以将其视为“对给定任意输入 𝐱的每个类的条件概率”。 例如, 𝑦̂ 1 = 𝑃(𝑦=猫∣𝐱)。 假设整个数据集 {𝐗,𝐘}具有 𝑛个样本, 其中索引 𝑖的样本由特征向量 𝐱(𝑖)和独热标签向量 𝐲(𝑖)组成。 可以将估计值与实际值进行比较:
在这里插入图片描述
根据最大似然估计,最大化 𝑃(𝐘∣𝐗) ,相当于最小化负对数似然:
在这里插入图片描述
其中,对于任何标签 𝐲和模型预测 𝐲̂ ,损失函数为:
在这里插入图片描述
上述损失函数 通常被称为交叉熵损失公式(cross-entropy loss)

(2)softmax及其导数

由于softmax和相关的损失函数很常见, 因此需要更好地理解它的计算方式。将𝐲̂ =softmax(𝐨) 代入交叉熵损失公式中,得到:
在这里插入图片描述
考虑相对于任何未规范化的预测 𝑜𝑗 的导数,得到:
在这里插入图片描述
上述最终导数表示,导数是softmax模型分配的概率与实际发生的情况(由独热标签向量表示)之间的差异。

(3)交叉熵损失

定义损失 𝑙, 它是所有标签分布的预期损失值。 此损失称为交叉熵损失(cross-entropy loss),它是分类问题最常用的损失之一。
在这里插入图片描述

用一个概率向量表示来阐述整个结果的分布情况,如 (0.1,0.2,0.7), 而不是仅包含二元项的向量 (0,0,1) ,,即观察到的不仅仅是一个结果。

6.模型预测和评估

在训练softmax回归模型后,给出任何样本特征,便可以预测每个输出类别的概率。 通常使用预测概率最高的类别作为输出类别。 如果预测与实际类别(标签)一致,则预测是正确的。最后使用精度(accuracy)来评估模型的性能。 精度等于正确预测数与预测总数之间的比率。

三、Fashion-MNIST图片分类数据集

1.加载数据集

通过框架中的内置函数将Fashion-MNIST数据集下载并读取到内存中。Fashion-MNIST由10个类别的图像组成, 每个类别由训练数据集(train dataset)中的6000张图像 和测试数据集(test dataset)中的1000张图像组成。 因此,训练集和测试集分别包含60000和10000张图像。 测试数据集不会用于训练,只用于评估模型性能。

每个输入图像的高度和宽度均为28像素。 数据集由灰度图像组成,其通道数为1。 为了简洁起见、将高度 ℎ 像素、宽度 𝑤像素图像的形状记为 ℎ×𝑤或( ℎ , 𝑤 )。

%matplotlib inline
import tensorflow as tf
from d2l import tensorflow as d2ld2l.use_svg_display()#执行之后会启动下载数据集到本地,不建议开飞机再运行此代码下载、亲测会丢包导致数据不完整而报错。
mnist_train, mnist_test = tf.keras.datasets.fashion_mnist.load_data()

如果下载失败(通常是这个文件t10k-images-idx3-ubyte.gz失败),也可以直接访问 Fashion-MNIST 数据集的官方网站或者仓库:Fashion-MNIST.

  • 下载数据集文件夹。

  • 将这四个文件放置在您项目的数据集目录中,例如 ~/.keras/datasets/fashion-mnist/。

下载失败的话删除~/.keras/datasets/fashion-mnist/文件夹重新运行直到成功为止。

Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
29515/29515 [==============================] - 0s 1us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz
26421880/26421880 [==============================] - 6s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz
5148/5148 [==============================] - 0s 0s/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz
4422102/4422102 [==============================] - 1s 0us/step

Fashion-MNIST中包含的10个类别,分别为t-shirt(T恤)、trouser(裤子)、pullover(套衫)、dress(连衣裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、bag(包)和ankle boot(短靴)。 以下函数用于在数字标签索引及其文本名称之间进行转换。

def get_fashion_mnist_labels(labels):  #@save"""返回Fashion-MNIST数据集的文本标签"""text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]
#创建一个函数来可视化这些样本
def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save"""绘制图像列表"""figsize = (num_cols * scale, num_rows * scale)_, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)axes = axes.flatten()for i, (ax, img) in enumerate(zip(axes, imgs)):ax.imshow(img.numpy())ax.axes.get_xaxis().set_visible(False)ax.axes.get_yaxis().set_visible(False)if titles:ax.set_title(titles[i])return axes

查看数据:

X = tf.constant(mnist_train[0][:10])
y = tf.constant(mnist_train[1][:10])
show_images(X, 2, 5, titles=get_fashion_mnist_labels(y));

在这里插入图片描述

2.读取小批量数据

为了在读取训练集和测试集时更容易,使用内置的数据迭代器,而不是从零开始创建。在每次迭代中,数据迭代器每次都会读取一小批量数据,大小为batch_size。 通过内置数据迭代器,可以随机打乱了所有样本,从而无偏见地读取小批量。

batch_size = 256
train_iter = tf.data.Dataset.from_tensor_slices(mnist_train).batch(batch_size).shuffle(len(mnist_train[0]))

数据迭代器是获得更高性能的关键组件。依靠实现良好的数据迭代器,利用高性能计算来避免减慢训练过程。

3.整合组件

def load_data_fashion_mnist(batch_size, resize=None):   #@save"""下载Fashion-MNIST数据集,然后将其加载到内存中"""mnist_train, mnist_test = tf.keras.datasets.fashion_mnist.load_data()# 将所有数字除以255,使所有像素值介于0和1之间,在最后添加一个批处理维度,# 并将标签转换为int32。process = lambda X, y: (tf.expand_dims(X, axis=3) / 255,tf.cast(y, dtype='int32'))resize_fn = lambda X, y: (tf.image.resize_with_pad(X, resize, resize) if resize else X, y)return (tf.data.Dataset.from_tensor_slices(process(*mnist_train)).batch(batch_size).shuffle(len(mnist_train[0])).map(resize_fn),tf.data.Dataset.from_tensor_slices(process(*mnist_test)).batch(batch_size).map(resize_fn))

通过指定resize参数来测试load_data_fashion_mnist函数的图像大小调整功能。

train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:print(X.shape, X.dtype, y.shape, y.dtype)break

四、从0实现softmax回归

1.加载数据集

引入Fashion-MNIST数据集, 并设置数据迭代器的批量大小为256。

import tensorflow as tf
from IPython import display
from d2l import tensorflow as d2lbatch_size = 256
# load_data_fashion_mnist函数已封装在d2l模块里面可以直接调用。也可以调用上面的。
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

2.初始化模型参数

输出与类别一样多。 (因为数据集有10个类别,所以网络输出维度为10)。 因此,权重将构成一个 784×10 的矩阵, 偏置将构成一个 1×10 的行向量。 与线性回归一样,将使用正态分布初始化权重W,偏置初始化为0。

num_inputs = 784
num_outputs = 10W = tf.Variable(tf.random.normal(shape=(num_inputs, num_outputs),mean=0, stddev=0.01))
b = tf.Variable(tf.zeros(num_outputs))

3.定义softmax操作

实现softmax由三个步骤组成:

  • 对每个项求幂(使用exp);
  • 对每一行求和(小批量中每个样本是一行),得到每个样本的规范化常数;
  • 将每一行除以其规范化常数,确保结果的和为1。
def softmax(X):X_exp = tf.exp(X)partition = tf.reduce_sum(X_exp, 1, keepdims=True)return X_exp / partition  # 这里应用了广播机制

对于任何随机输入,将每个元素变成一个非负数。 此外,依据概率原理,每行总和为1]。

4.定义模型

定义softmax操作后,可以实现softmax回归模型。 下面的代码定义了输入如何通过网络映射到输出。 注意,将数据传递到模型之前,使用reshape函数将每张原始图像展平为向量。

def net(X):return softmax(tf.matmul(tf.reshape(X, (-1, W.shape[0])), W) + b)

5.交叉熵损失函数

实现交叉熵损失函数

def cross_entropy(y_hat, y):return -tf.math.log(tf.boolean_mask(y_hat, tf.one_hot(y, depth=y_hat.shape[-1])))

6.分类精度

当预测与标签分类y一致时,即是正确的。 分类精度即正确预测数量与总预测数量之比。 虽然直接优化精度可能很困难(因为精度的计算不可导), 但精度通常是最关心的性能衡量标准,在训练分类器时几乎总会关注它。

def accuracy(y_hat, y):  #@save"""计算预测正确的数量"""if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:y_hat = tf.argmax(y_hat, axis=1)cmp = tf.cast(y_hat, y.dtype) == yreturn float(tf.reduce_sum(tf.cast(cmp, y.dtype)))

同样,对于任意数据迭代器data_iter可访问的数据集, 可以评估在任意模型net的精度。

def evaluate_accuracy(net, data_iter):  #@save"""计算在指定数据集上模型的精度"""metric = Accumulator(2)  # 正确预测数、预测总数for X, y in data_iter:metric.add(accuracy(net(X), y), d2l.size(y))return metric[0] / metric[1]

定义一个实用程序类Accumulator,用于对多个变量进行累加。 在上面的evaluate_accuracy函数中, 在Accumulator实例中创建了2个变量, 分别用于存储正确预测的数量和预测的总数量。 当遍历数据集时,两者都将随着时间的推移而累加。

class Accumulator:  #@save"""在n个变量上累加"""def __init__(self, n):self.data = [0.0] * ndef add(self, *args):self.data = [a + float(b) for a, b in zip(self.data, args)]def reset(self):self.data = [0.0] * len(self.data)def __getitem__(self, idx):return self.data[idx]

7.训练模型

定义一个函数来训练一个迭代周期。 请注意,updater是更新模型参数的常用函数,它接受批量大小作为参数。 它可以是d2l.sgd函数,也可以是框架的内置优化函数。

def train_epoch_ch3(net, train_iter, loss, updater):  #@save"""训练模型一个迭代周期(定义见第3章)"""# 训练损失总和、训练准确度总和、样本数metric = Accumulator(3)for X, y in train_iter:# 计算梯度并更新参数with tf.GradientTape() as tape:y_hat = net(X)# Keras内置的损失接受的是(标签,预测),这不同于用户在本书中的实现。# 本书的实现接受(预测,标签),例如我们上面实现的“交叉熵”if isinstance(loss, tf.keras.losses.Loss):l = loss(y, y_hat)else:l = loss(y_hat, y)if isinstance(updater, tf.keras.optimizers.Optimizer):params = net.trainable_variablesgrads = tape.gradient(l, params)updater.apply_gradients(zip(grads, params))else:updater(X.shape[0], tape.gradient(l, updater.params))# Keras的loss默认返回一个批量的平均损失l_sum = l * float(tf.size(y)) if isinstance(loss, tf.keras.losses.Loss) else tf.reduce_sum(l)metric.add(l_sum, accuracy(y_hat, y), tf.size(y))# 返回训练损失和训练精度return metric[0] / metric[2], metric[1] / metric[2]

训练函数实现之前,定义一个在动画中绘制数据的实用程序类Animator, 它能够简化本书其余部分的代码。

class Animator:  #@save"""在动画中绘制数据"""def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None,ylim=None, xscale='linear', yscale='linear',fmts=('-', 'm--', 'g-.', 'r:'), nrows=1, ncols=1,figsize=(3.5, 2.5)):# 增量地绘制多条线if legend is None:legend = []d2l.use_svg_display()self.fig, self.axes = d2l.plt.subplots(nrows, ncols, figsize=figsize)if nrows * ncols == 1:self.axes = [self.axes, ]# 使用lambda函数捕获参数self.config_axes = lambda: d2l.set_axes(self.axes[0], xlabel, ylabel, xlim, ylim, xscale, yscale, legend)self.X, self.Y, self.fmts = None, None, fmtsdef add(self, x, y):# 向图表中添加多个数据点if not hasattr(y, "__len__"):y = [y]n = len(y)if not hasattr(x, "__len__"):x = [x] * nif not self.X:self.X = [[] for _ in range(n)]if not self.Y:self.Y = [[] for _ in range(n)]for i, (a, b) in enumerate(zip(x, y)):if a is not None and b is not None:self.X[i].append(a)self.Y[i].append(b)self.axes[0].cla()for x, y, fmt in zip(self.X, self.Y, self.fmts):self.axes[0].plot(x, y, fmt)self.config_axes()display.display(self.fig)display.clear_output(wait=True)

实现一个训练函数, 它会在train_iter访问到的训练数据集上训练一个模型net。 该训练函数将会运行多个迭代周期(由num_epochs指定)。 在每个迭代周期结束时,利用test_iter访问到的测试数据集对模型进行评估。

def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):  #@save"""训练模型(定义见第3章)"""animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],legend=['train loss', 'train acc', 'test acc'])for epoch in range(num_epochs):train_metrics = train_epoch_ch3(net, train_iter, loss, updater)test_acc = evaluate_accuracy(net, test_iter)animator.add(epoch + 1, train_metrics + (test_acc,))train_loss, train_acc = train_metricsassert train_loss < 0.5, train_lossassert train_acc <= 1 and train_acc > 0.7, train_accassert test_acc <= 1 and test_acc > 0.7, test_acc

作为一个从零开始的实现,使用定义的 小批量随机梯度下降来优化模型的损失函数,设置学习率为0.1。

class Updater():  #@save"""用小批量随机梯度下降法更新参数"""def __init__(self, params, lr):self.params = paramsself.lr = lrdef __call__(self, batch_size, grads):d2l.sgd(self.params, grads, self.lr, batch_size)updater = Updater([W, b], lr=0.1)

之前定义的小批量随机梯度下降如下,已经封装在d2l模块中了:

def sgd(params, grads, lr, batch_size):  #@save"""小批量随机梯度下降"""for param, grad in zip(params, grads):param.assign_sub(lr*grad/batch_size)

训练模型50个迭代周期。 请注意,迭代周期(num_epochs)和学习率(lr)都是可调节的超参数。 通过更改它们的值,可以提高模型的分类精度。

num_epochs = 50
train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)

在这里插入图片描述

8.预测

模型已经准备好对图像进行分类预测。 给定一系列图像,将比较它们的实际标签(文本输出的第一行)和模型预测(文本输出的第二行)。

def predict_ch3(net, test_iter, n=6):  #@save"""预测标签(定义见第3章)"""for X, y in test_iter:breaktrues = d2l.get_fashion_mnist_labels(y)preds = d2l.get_fashion_mnist_labels(tf.argmax(net(X), axis=1))titles = [true +'\n' + pred for true, pred in zip(trues, preds)]d2l.show_images(tf.reshape(X[0:n], (n, 28, 28)), 1, n, titles=titles[0:n])predict_ch3(net, test_iter)

在这里插入图片描述

五、简洁实现softmax回归

softmax回归的输出层是一个全连接层,只需在Sequential中添加一个带有10个输出的全连接层。

import tensorflow as tf
from d2l import tensorflow as d2l#加载数据集
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)# 初始化模型参数,仍然以均值0和标准差0.01随机初始化权重。
net = tf.keras.models.Sequential()
net.add(tf.keras.layers.Flatten(input_shape=(28, 28)))
weight_initializer = tf.keras.initializers.RandomNormal(mean=0.0, stddev=0.01)
net.add(tf.keras.layers.Dense(10, kernel_initializer=weight_initializer))# 交叉熵损失函数,在交叉熵损失函数中传递未规范化的预测,并同时计算softmax及其对数。
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)# 使用学习率为0.1的小批量随机梯度下降作为优化算法
trainer = tf.keras.optimizers.SGD(learning_rate=0.1)# 调用之前定义的训练函数训练模型
num_epochs = 10
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

这里为什么是d2l.train_ch3函数来训练而不是类似tf内置的model.fit()呢?因为train_ch3函数里面已经封装好了训练过程和可视化功能。利用Animator类来可视化训练进度。
在这里插入图片描述
预测:

d2l.predict_ch3(net, test_iter)

在这里插入图片描述

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

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

相关文章

现代化数据架构升级:毫末智行自动驾驶如何应对年增20PB的数据规模挑战?

毫末智行是一家致力于自动驾驶的人工智能技术公司&#xff0c;其前身是长城汽车智能驾驶前瞻分部&#xff0c;以零事故、零拥堵、自由出行和高效物流为目标&#xff0c;助力合作伙伴重塑和全面升级整个社会的出行及物流方式。 在自动驾驶领域中&#xff0c;是什么原因让毫末智行…

【设计模式】5种创建型模式详解

创建型模式提供创建对象的机制,能够提升已有代码的灵活性和复用性。 常用的有:单例模式、工厂模式(工厂方法和抽象工厂)、建造者模式。不常用的有:原型模式。一、单例模式 1.1 单例模式介绍 1 ) 定义 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,此模…

Jupyterlab 和 JupyternoteBook 修改默认路径

Jupyterlab 和 JupyternoteBook 修改默认路径 在使用 JupyterLab 或 Jupyter Notebook 进行数据分析、机器学习项目时&#xff0c;经常会遇到需要修改默认工作目录的需求。默认情况下&#xff0c;JupyterLab 和 Jupyter Notebook 会在启动时打开你的用户目录&#xff08;例如&…

Linux 不同架构、不同系统的问题

文章目录 一、麒麟V10&#xff08;kylin&#xff09;操作系统中&#xff0c;sudo执行程序后&#xff0c;其环境变量依然为用户家目录。&#xff08;1&#xff09;背景&#xff08;2&#xff09;原因&#xff08;3&#xff09;解决办法 二、统信&#xff08;UOS&#xff09;操作…

GDB之(1)入门指令参数介绍

GDB之(1)基础入门指令参数介绍 Author&#xff1a;Once Day Date: 2022年7月29日/2024年2月26日 漫漫长路&#xff0c;才刚刚开始… 全系列文章请查看专栏: Linux实践记录_Once-Day的博客-CSDN博客 推荐参考文档&#xff1a; GDB: The GNU Project Debugger (sourceware.o…

机器学习 | 基本概念梳理——数据集评估,任务,训练和测试,期望结果

文章目录 1 整体概念梳理1.1 数据集与数据术语——原材料1.2 任务术语——目标1.3 训练和测试术语——怎么做1.4 结果——预期期望 整体框架 机器学习的基本概念全梳理 我们通过一个生动形象的例子来介绍这些概念 我们假设有一个任务是根据地理天气等特征位置预测经纬度 1 整…

2023 re:Invent 用 Amazon Q 打造你的知识库

前言 随着 ChatGPT 的问世&#xff0c;我们迎来了许多创新和变革的机会。一年一度的亚马逊云科技大会 re:Invent 也带来了许多前言的技术&#xff0c;其中 Amazon CEO Adam Selipsky 在 2023 re:Invent 大会中介绍 Amazon Q 让我印象深刻&#xff0c;这预示着生成式 AI 的又一…

VUE从0到1创建项目及基本路由、页面配置

一、创建项目:(前提已经安装好vue和npm) 目录:E:\personal\project_pro\ windows下,win+R 输入cmd进入命令行: cd E:\personal\project_pro E:# 创建名为test的项目 vue create test# 用上下键选择vue2或vue3,回车确认创建本次选择VUE3 创建好项目后,使用…

Nginx之rewrite重写功能

一、rewrite概述 1、rewrite功能 访问重写 rewrite 是 Nginx HTTP 请求处理过程中的一个重要功能&#xff0c;它是以模块的形式存在于代码中的&#xff0c;其功能是对用户请求的 URI 进行 PCRE 正则重写&#xff0c;然后返回 30 重定向跳转或按条件执行相关配置。 Nginx服务…

idea 创建打包 android App

1、使用 idea 创建 android 工程 2、 配置构建 sdk 3、配置 gradle a、进入 gradle 官网&#xff0c;选择 install &#xff08;默认是最新版本&#xff09; b、选择包管理安装&#xff0c;手动安装选择下面一个即可 c、安装 sdk 并通过 sdk 安装 gradle 安装 sdk&#xff1a…

软件无线电SDR加人工智能算法实现无人机频谱探测

通用软件无线电接收机作为传感器实时接收探测无线电信号&#xff0c;加上深度学习算法实现频谱识别&#xff0c;(https://img-blog.csdnimg.cn/5a6c4d89a047453a94f763f4e67aeb17.png)

合并果子(哈夫曼树)NOIP2004提高组

在一个果园里&#xff0c;达达已经将所有的果子打了下来&#xff0c;而且按果子的不同种类分成了不同的堆。 达达决定把所有的果子合成一堆。 每一次合并&#xff0c;达达可以把两堆果子合并到一起&#xff0c;消耗的体力等于两堆果子的重量之和。 可以看出&#xff0c;所有…

大话设计模式——3.建造者模式(Builder Pattern)

1.定义&#xff1a; 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。UML图 2.示例&#xff1a; 汽车或者电脑的组装可以采用构造者模式进行设计&#xff0c;如汽车的引擎或者轮胎&#xff0c;电脑的处理器、内存、主板等都可以进行…

flutter简单的MethodChannel通道Demo(引入调用小红书sdk)

flutter端创建MethodChannel类 import package:flutter/services.dart;//MethodChannel const methodChannel const MethodChannel(com.flutter.demo.MethodChannel);class FlutterMethodChannel {/** MethodChannel flutter给原生发信息* 在方法通道上调用方法invokeMethod*…

[开源协议] 什么是MIT协议及其使用场景

什么是MIT协议? MIT协议是一种开放源代码软件授权协议&#xff0c;全称为Massachusetts Institute of Technology License。该协议允许自由地使用、复制、修改、合并、发布、分发、再授权和销售软件及其副本的任何部分。MIT协议要求在软件的所有副本中包含版权声明和许可声明…

高性能API云原生网关 APISIX安装与配置指南

Apache APISIX是Apache软件基金会下的顶级项目&#xff0c;由API7.ai开发并捐赠。它是一个高性能的云原生API网关&#xff0c;具有动态、实时等特点。 APISIX网关可作为所有业务的流量入口&#xff0c;为用户提供了丰富的功能&#xff0c;包括动态路由、动态上游、动态证书、A…

瀑布型还是敏捷型?一次搞懂主数据项目实施方法

在主数据项目实施的过程中&#xff0c;经常会碰到一个让人头痛的问题&#xff0c;我该选择什么样的实施方法才能够更为高效地完成项目的交付&#xff1f; 得帆经过多年在软件行业的摸爬滚打&#xff0c;总结出了适合主数据项目的实施方法。接下来我们将为大家介绍两种常用的实…

gitlab添加ssh公钥

一&#xff1a;生成公钥 桌面鼠标右击打开 Open Git Bash here (前提是安装了Git)&#xff1b; 2.输入命令 ssh-keygen -t rsa -C "123*****90qq.com"来生成新的密钥对,将其中的"123*****90qq.com"替换为你自己的电子邮件地址。 命令&#xff1a;ssh-keyg…

提升Vue3应用效率的秘诀:深入比较ref与reactive!

ref 和 reactive 是 Vue3 中实现响应式数据的核心 API。ref 用于包装基本数据类型&#xff0c;而 reactive 用于处理对象和数组。尽管 reactive 似乎更适合处理对象&#xff0c;但 Vue3 官方文档更推荐使用 ref。 我的想法&#xff0c;ref就是比reactive好用&#xff0c;官方也…

Vue:vue的安装与环境的搭建

文章目录 环境搭建安装node.js&#xff08;比较简单&#xff09;安装Vue脚手架初始化启动 环境搭建 安装node.js&#xff08;比较简单&#xff09; 首先要安装node.js&#xff0c;进入官网下载即可。 更改安装路径&#xff0c;保持默认配置&#xff0c;一直点击下一步安装即可…