神经网络初识-以MINST数据集和CIFAR10数据集为例

news2025/1/10 13:29:29

文章目录

  • 1 什么是神经网络
    • 1.1 神经元模型
    • 1.2 感知机
    • 1.3 多层神经网络
    • 1.4 为什么要使用神经网络
  • 2 全连接神经网络
    • 2.1 简介
    • 2.2 梯度下降
    • 2.2 反向传播
    • 2.3 代码实现
  • 3 卷积神经网络
    • 3.1 简介
    • 3.2 代码实现
  • 总结

1 什么是神经网络

人工神经网络(artificial neural network,缩写ANN),简称神经网络(neural network,缩写NN)或类神经网络,是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。

神经网络主要由:输入层,隐藏层,输出层构成。当隐藏层只有一层时,该网络为两层神经网络,由于输入层未做任何变换,可以不看做单独的一层。实际中,网络输入层的每个神经元代表了一个特征,输出层个数代表了分类标签的个数(在做二分类时,如果采用sigmoid分类器,输出层的神经元个数为1个;如果采用softmax分类器,输出层神经元个数为2个;如果是多分类问题,即输出类别>=3时,输出层神经元为类别个数),而隐藏层层数以及隐藏层神经元是由人工设定。一个基本的两层神经网络可见下图(注意:说神经网络多少层数的时候一般不包括输入层。 在神经网络中的激活主要讲的是梯度的更新的激活):

在这里插入图片描述

1.1 神经元模型

神经网络的最基本的构成元素是神经元(Neuron),也就是Kohonen的定义中的简单单元。学过生物的都知道,人的大脑中有上亿个神经元构成神经网络,生物神经网络中各个网络之间相互连接,通过神经递质相互传递信息。如果某个神经元接收了足够多的神经递质(乙酰胆碱),那么其点位变会积累地足够高,从而超过某个阈值(Threshold)。超过这个阈值之后,这个神经元变会被激活,达到兴奋的状态,而后发送神经递质给其他的神经元。

1943年,McCulloch和Pitts将生物神经网络工作的原理抽象成了一个简单的机器学习模型——MP神经元模型。

1.2 感知机

感知机(Perceptron)是由两层神经元所构成。

在这里插入图片描述
如图所示,输入层接收输入信号之后传输给输出层,输出层即阈值逻辑单元(MP神经元)。通过感知机可以轻易地实现逻辑与、或、非运算。

1.3 多层神经网络

在这里插入图片描述

1.4 为什么要使用神经网络

首先,神经网络应用在分类问题中效果很好。 工业界中分类问题居多。LR 或者 linear SVM 更适用线性分类。如果数据非线性可分(现实生活中多是非线性的),LR 通常需要靠特征工程做特征映射,增加高斯项或者组合项;SVM需要选择核。 而增加高斯项、组合项会产生很多没有用的维度,增加计算量。GBDT 可以使用弱的线性分类器组合成强分类器,但维度很高时效果可能并不好。而神经网络在三层及以上时,能够很好地进行非线性可分。

2 全连接神经网络

这里将以MINST数据集为例,实现手写数字的识别。

2.1 简介

网络的结构如下,输入层一共28*28=784个神经元,隐藏层共15个神经元(这里可以自由设置),输出层一个十个神经元,分别代表十个数字(0~9)。

在这里插入图片描述
对于上图中的神经网络结构,假设我们随机初始化各个神经元的权值,并且将手写数字图片”9“传入到网络中,可以预见网络大概率并不会得到正确答案,但是我们可以通过不断调整权值来让它输出正确的结果。对于简单的模型也许这样做是可行的,因为毕竟可以调整的权重数据很少,但是对于我们定义的网络,它其中包含了784x15+15x10+15+10 = 11935个参数,手动修改就很不现实。

因此我们希望能够设计出一种学习算法,帮助我们自动调整感知器中的权重和偏置,以至于网络的输出能够拟合所有的训练输入。因此我们定义一个损失函数:

在这里插入图片描述
a代表的是神经网络的输出,y(x)代表的是输入x的标签。(前面的1/2是为了损失函数求导方便)

我们的目的,就是要最小化代价函数,代价函数越接近0,识别的效果就越好。

2.2 梯度下降

梯度下降的目的就是最小化代价函数。梯度表示的是各点处的函数值减小最多的方向,每次朝着梯度的方向,能够最大限度的减少函数的值。

因此,在寻找函数的最小值(或者尽可能小的值)的位置的任务中,要以梯度的信息为线索,决定前进的方向。在梯度法中,函数的取值从当前位置沿着梯度方向前进一定距离,然后在新的地方重新求梯度,再沿着新梯度方向前进,如此反复,不断地沿梯度方向前进。像这样,通过不断地沿梯度方向前进, 逐渐减小函数值的过程就是梯度法(gradient method)。

因此我们就有了下面这个更新w,b的式子。

在这里插入图片描述

η为学习率。它的主要功能是用来控制每次变化的多少。如果太大,可能就会错过最低点;如果太小,每次变化的又太少,则需要花费很多的时间。因此选择一个合适的值非常重要。

2.2 反向传播

反向传播(Backpropagation)是神经网络中一种用于训练模型的常用算法。它通过计算模型输出与真实值之间的误差,并将误差从输出层向输入层进行传播,以更新模型的权重和偏置。

下面是反向传播算法的简要步骤:

初始化:随机初始化神经网络的权重和偏置。

前向传播:将输入样本通过神经网络,按照顺序进行计算,直到获得输出。每个神经元接收来自上一层的输入,并通过激活函数计算输出。

计算误差:将神经网络的输出与真实值进行比较,计算误差(通常使用损失函数来度量误差)。

反向传播:从输出层开始,将误差从后一层传递到前一层。通过链式法则,计算每个神经元对误差的贡献,并将误差传递到上一层。

权重更新:使用梯度下降法则,根据每个权重对误差的贡献来更新神经网络的权重。梯度下降使用误差对权重的偏导数来确定每个权重的调整方向和大小。

重复步骤2-5:重复执行前向传播、误差计算、反向传播和权重更新的步骤,直到达到停止条件(例如,达到最大迭代次数或误差低于某个阈值)。

通过多次迭代上述步骤,神经网络可以逐渐优化权重和偏置,使其能够更好地拟合训练数据,并在新的输入上进行准确的预测。

反向传播是一种高效的训练神经网络的方法,它使得神经网络能够学习复杂的非线性关系。然而,反向传播算法也存在一些挑战,如梯度消失和过拟合等问题,针对这些问题,研究者们提出了一些改进的方法和技术。

2.3 代码实现

导入相关包

import torch
import torchvision
import torch.nn as nn
import torchvision.transforms as transforms

配置训练参数

#超参数
num_classes = 10  #类别个数
num_epochs = 10   #迭代次数/训练次数
learning_rate = 0.01  #学习率,方法更新的速率
batch_size = 64    #批次,批量大小,每次传输图片的个数

下载数据集

#训练集
train_dataset = torchvision.datasets.MNIST(root = './data',
                                           train = True,
                                          download = True,
                                          transform = transforms.Compose([
                                           transforms.Resize((28,28)),transforms.ToTensor()])
                                          )


#测试集
test_dataset = torchvision.datasets.MNIST(root = './data',
                                           train = False,
                                          download = True,
                                          transform = transforms.Compose([
                                           transforms.Resize((28,28)),transforms.ToTensor()])
                                          )

加载训练与测试数据,对图片进行分组、打乱顺序

#加载训练数据,对图片进行分组、打乱顺序
train_loader = torch.utils.data.DataLoader(dataset = train_dataset,batch_size = batch_size,shuffle = True)
#加载测试数据,对图片进行分组、打乱顺序
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,batch_size = batch_size,shuffle = True)

查看数据集和测试集的内容数量

在这里插入图片描述

定义网络结构

# 定义网络结构
class network(nn.Module):
    def __init__(self,num_classes):
        super(network, self).__init__()
        #继承父类,即此处的nn.Module
        
        self.fc1 = nn.Linear(784,64)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(64,num_classes)
        #前向传播
    def forward(self, x):
        
        x = x.view(x.size()[0], -1)
        #x.view(x.size()[0], -1)将前面多维度的tensor展平成一维
        x = self.fc1(x)
        x = self.fc2(x)
        return x

配置优化器

model = network(num_classes).cpu() #让网络模型在cpu上运行

loss = nn.CrossEntropyLoss()  #交叉熵损失函数,返回值是误差,用以表示模型算法模型对图片识别的结果与图片本身的标签之间的偏差

optimizer = torch.optim.Adam(model.parameters(),learning_rate)
#优化器:优化参数,包括w和b,更新w和吧,使得算法的输出结果更贴近正确结果

进行模型训练

#训练
group = len(train_loader)  #获取图片组数
for epoch in range(num_epochs):  #num_epochs = 10,epoch是0-9,range(10)是0到9的数字序列
    
#     i = 0
    for i,(images,labels) in enumerate(train_loader):
        images = images.cpu()
        labels = labels.cpu()
        
        #forward前向传播
        output = model(images)  #获取输出
        cost = loss(output,labels)  #获取误差
        
        #反向传播
        optimizer.zero_grad()  #清空梯度存储空间
        cost.backward()  #对loss进行求导(求梯度)
        optimizer.step()  # w = w - learning_rate * 偏w , b = b - learning_rate * 偏b
        
        if (i + 1) == 400:
            print("epoch:[{}/{}],step:[{}/{}],loss:{:.4f}".format(epoch+1, num_epochs, i+1, group, cost.item()))
        
#         i += 1

训练时过程如下

在这里插入图片描述

数据测试

#测试
with torch.no_grad():  #测试阶段不需要梯度更新(参数更新),即:w和b不需要求导求梯度,因此不需要grad
    correct = 0  # 存储识别正确的图片张数
    for images,labels in test_loader:
        images = images.cpu()
        labels = labels.cpu()
        
        #前向传播
        output = model(images)  #output仅仅是模型的输出,形式是10个张量类型的数据tensor([])
        _,predict = torch.max(output,1) # predict是确切的某一个类,预测结果
        #torch.max(x,1) 返回的是两个结果,第一个是x里的最大值,第二个是最大值所在的位置(索引)
        #最大值所在的位置(索引)才是预测的类
        #比如图片0,torch.max(output,1)结果是tensor([22,13,10,11,5,19,14,0,4,1]),最大值是22,22所在位置是0,则predict = 0
        
        correct += (predict == labels).sum().item() # (predict == labels).sum().item()的结果是每一组图片中预测正确的图片数(识别正确的数量)
    
    accruacy = correct / len(test_dataset)
    print("Accuracy:{}%".format(accruacy * 100))

在这里插入图片描述
对于手写体识别数据集,经过三层全连接神经网络,经过10次的迭代周期之后,最终达到了98.76%的识别正确率

之后我们借用此网络但将数据集换为cifar10,对于此数据集,训练效果不佳,简单更改网络结构和训练参数后,仅使用全连接神经网络的训练效果仅可达到52%
在这里插入图片描述

在这里插入图片描述

3 卷积神经网络

针对上一节末尾提出的问题,下面将加入卷积神经网络,对cifar10数据集的训练进行优化

3.1 简介

卷积神经网络(Convolutional Neural Network,简称CNN)是一种主要用于图像处理和模式识别任务的深度学习模型。它通过模拟人类视觉系统的工作原理,能够自动学习图像中的特征和模式。

CNN主要由以下几个组件构成:

卷积层(Convolutional Layer):卷积层是CNN的核心组件。它通过使用一系列可学习的滤波器(也称为卷积核或特征检测器),在输入图像上进行滑动窗口式的卷积操作。每个滤波器会提取出图像中的不同特征,例如边缘、纹理等。卷积操作可以有效地捕捉局部特征,并保持平移不变性。

激活函数(Activation Function):卷积层的输出经过激活函数进行非线性映射,以引入非线性关系。常用的激活函数包括ReLU(Rectified Linear Unit)、Sigmoid和Tanh等。ReLU是最常用的激活函数,它能够保留正数输入并将负数输入归零。

池化层(Pooling Layer):池化层用于减少特征图的空间尺寸,并降低计算量。常用的池化操作是最大池化(Max Pooling),它在每个池化窗口中选择最大值作为输出。最大池化能够保留主要特征并提高空间不变性。

全连接层(Fully Connected Layer):在经过一系列卷积层和池化层之后,通常会添加全连接层。全连接层将前一层的所有神经元与当前层的每个神经元相连接,用于对特征进行分类和预测。

CNN的训练过程通常采用反向传播算法。通过将输入样本传递给网络,并与标签进行比较,计算预测值与真实值之间的误差。然后,通过反向传播算法逐层更新网络中的权重和偏置,以减小误差,并提高模型的准确性。

卷积神经网络在计算机视觉领域取得了巨大的成功。它能够自动学习图像的特征表示,从而实现图像分类、目标检测、图像分割等任务。此外,CNN还具有参数共享和稀疏连接等特性,使得它能够处理大规模图像数据并具有较好的泛化能力。

3.2 代码实现

我们仍以手写体识别的代码进行改进
修改数据下载部分的代码,改完使用cifar10数据集

#训练集
train_dataset = torchvision.datasets.CIFAR10(root = './data',#存储位置
                                           train = True,#是否是训练操作
                                          download = True,#是否下载训练集
                                          transform =transforms.ToTensor()
                                          )
test_dataset = torchvision.datasets.CIFAR10(root = './data',
                                           train = False,
                                          download = True,
                                          transform = transforms.ToTensor())

通过查看此数据集的简介,发现这个数据集的数据大小均一致,所以不必对图像大小进行处理
训练集与测试集数据数量如下

在这里插入图片描述
定义网络结构如下

# 定义网络结构
class network(nn.Module):
    def __init__(self,num_classes):
        super(network, self).__init__()
        #继承父类,即此处的nn.Module
        self.conv1 = nn.Sequential(
            nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        # 第一个卷积层后的大小:int((32-3+2*1)/1+1) = 32,第一个最大池化结果:int((32-2)/2+1) = 16

        self.conv2 = nn.Sequential(
            nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        # 第二个卷积层后的大小:int((16-3+2*1)/1+1) = 16,第二个最大池化结果:int((16-2)/2+1) = 8

        self.conv3 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        # 第三个卷积层后的大小:int((8-3+2*1)/1+1) = 8,第三个最大池化结果:int((8-2)/2+1) = 4

        self.fc1 = nn.Linear(64 * 4 * 4, 256)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(256, 128)
        self.fc3 = nn.Linear(128, num_classes)
        
        #前向传播
    def forward(self, x):
        
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.fc3(x)
        
        return x

添加三个卷积层作为网络结构

配置优化器

model = network(num_classes).cpu() #让网络模型在cpu上运行

loss = nn.CrossEntropyLoss()  #交叉熵损失函数,返回值是误差,用以表示模型算法模型对图片识别的结果与图片本身的标签之间的偏差

optimizer = torch.optim.Adam(model.parameters(),learning_rate)
#优化器:优化参数,包括w和b,更新w和吧,使得算法的输出结果更贴近正确结果

进行模型训练

#训练
group = len(train_loader)  #获取图片组数

epoch_arr = []
loss_arr = []

for epoch in range(num_epochs):  #num_epochs = 10,epoch是0-9,range(10)是0到9的数字序列
    
#     i = 0
    epoch_arr.append(epoch)
    for i,(images,labels) in enumerate(train_loader):
        images = images.cpu()
        labels = labels.cpu()
        
        #forward前向传播
        output = model(images)  #获取输出
        cost = loss(output,labels)  #获取误差
        
        #反向传播
        optimizer.zero_grad()  #清空梯度存储空间b
        cost.backward()  #对loss进行求偏导(求梯度) ,偏w,偏b
        optimizer.step()  # w = w - learning_rate * 偏w , b = b - learning_rate * 偏b
        
        if (i + 1) == 400:
            loss_arr.append(cost.item())
            print("epoch:[{}/{}],step:[{}/{}],loss:{:.4f}".format(epoch+1, num_epochs,i + 1, group,cost.item()))
        
#         i += 1
        # cost返回结果:tensor()

训练过程如下:
在这里插入图片描述

模型测试结果如下,

在这里插入图片描述

与之前使用全连接神经网络的对比,发现卷积神经网络对于cifar10数据集的训练,准确度有明显的提升。

总结

在本博客中,我们初步了解了神经网络,并对全连接神经网络(FCN)和卷积神经网络(CNN)进行了介绍和简单实现。

我们了解了全连接神经网络的基本结构。全连接神经网络由多个神经元组成,每个神经元都与前一层的所有神经元相连接。我们了解了前向传播、反向传播以及权重更新的基本步骤,这是训练全连接神经网络的关键。

接下来,我们学习了卷积神经网络的特点和应用。卷积神经网络通过使用卷积层、激活函数和池化层,能够更好地捕捉图像中的局部特征并保持空间不变性。我们了解了卷积操作的原理以及最大池化的作用,这些都对于图像处理任务非常重要。

初步认识了神经网络,探讨了全连接神经网络和卷积神经网络的原理和应用。神经网络作为一种强大的机器学习模型,具有广泛的应用领域,特别是在计算机视觉任务中取得了巨大的成功。通过进一步学习和实践,我们可以深入了解神经网络的更高级概念和技术,进一步提升我们在这个领域的能力和应用水平。

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

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

相关文章

【论文精读】Vis-MVSNet: Visibility-aware Multi-view Stereo Network

今天属于是重读经典了,这是一篇发表在BMVC2020上的文章,试图解决MVS中可见性的问题。该文章最近在拓展之后被发表在了IJCV上。本文的解读是基于扩展之后的IJCV版本,期刊的版本内容更加详细一点。 文章链接:BMVC2020版本和IJCV版本…

【电子学会】2023年05月图形化四级 -- 绘制同心圆

绘制同心圆 1. 准备工作 (1)保留小猫角色; (2)背景为默认白色。 2. 功能实现 (1)点击绿旗,小猫询问“请问绘制几个同心圆?”; (2)…

044、TiDB特性_PlacementPolicy

Placement Rules in SQL之前 跨地域部署的集群,无法本地访问无法根据业务隔离资源难以按照业务登记配置资源和副本数 Placement Rules in SQL之后 跨地域部署的集群,支持本地访问根据业务隔离资源按照业务等级配置资源和副本数 配置 labels 设置 Ti…

这个怎么弄?电脑没有d3dx9_43.dll?

在使用某些电脑软件或游戏时,遇到这样的提示:找不到d3dx9_43.dll,无法继续执行代码。这个问题比较常见,很多人不知道该怎么解决。如果你也遇到这个问题,不要着急。本文将详细介绍如何解决找不到d3dx9_43.dll无法继续执…

计算机网络基础第四章

一、网络层概述 1.1 网络层功能概述 主要任务是把分组从源端传到目的端,为分组交换网上的不同主机提供通信服务。网络层传输单位是数据报。 功能一:路由选择与分组转发(最佳路径)功能二:异构网络互联功能三&#xf…

23年测试岗面试,高频自动化测试面试题(付答案)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 面试题1&#xff…

高等数学专题(1)三角函数公式大全

本帖的公式内容可以并列全网最全(doge),博主多方面搜集并总结了最重要和常用的三角函数公式,具体为以下几个内容: 1.诱导公式 2.平方关系 3.二倍角公式 4.半角公式 5.和差角公式 6.积化和差 7.和差化积 8.辅助角公式 9…

半小时漫画计算机

ISBN: 978-7-121-41557-9 作者:刘欣(码农翻身) 绘画:刘奕君 页数:210页 阅读时间:2023-06-03 推荐指数:★★★★★ 以漫画的形式来讲解计算机的基础知识, 主要涉及到CPU、内存、网络…

CentOs进行AKShare HTTP 部署并供外网IP调用

需求背景 周末闲聊之时,看了akshare的官方文档,之前都是通过python程序去调用数据,作为一个java开发者,我觉得甚是不太方便。认真看了一下文档,是我失敬了。大佬已经推出了aktools工具,这样就可以通过http…

时钟案例.js

案例已经在一个html中写完 要求通过node.js将其分成html css js 三个文件 正则表达式 就是把字符串表示出来 读取文件 读取css 同理还有js 和html 素材代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><me…

MySQL---索引

目录 一、索引的分类 二、索引的底层原理是什么&#xff1f; 2.1、Innodb和MyIsAM两种引擎搜索数据时候的区别&#xff1a; 2.2、为什么MySQL&#xff08;MyIsAM、Innodb&#xff09;索引选择B树而不是B树呢&#xff1f; 2.3、Innodb的主键索引和二级索引&#xff08;辅助…

【图游走+二分图】牛客小白月赛 43 F

F-全体集合_牛客小白月赛43 (nowcoder.com) 题意&#xff1a; 思路&#xff1a; 首先是经典的猜结论环节 这个结论可以想象特殊情况&#xff0c;把图看成一条链&#xff0c;多模拟几个例子 然后会发现一个很显然的结论&#xff1a;在链上的两个人点之间的距离一定是偶数 然…

【【51单片机的蜂鸣器实现小星星】】

用单片机的蜂鸣&#xff0c;实现简单小星星 我们在设置板子的时候要翻转 翻转IO口是因为使用了步进电机的多余的芯片管脚 我们翻转之后还想让它保持一段时间 就是先翻转500次 Delay(1&#xff09;之后 就是最小的单位每隔1ms 周期就是2ms 频率就是500HZ 蜂鸣器播放音乐 我们首…

【040】巧妙地穿梭双端:掌握C++ STL中deque容器的强大功能

巧妙地穿梭双端&#xff1a;掌握C STL中deque容器的强大功能 引言一、deque容器概述二、deque容器实现原理三、deque容器常用API3.1、deque的构造函数3.2、deque的赋值操作3.3、deque的大小操作3.4、deque的双端插入和删除操作3.5、deque的数据存取3.6、deque的插入操作3.7、de…

Spring IOC AOP

IOC容器 概念 IOC&#xff0c;全程Inversion of Control&#xff08;控制反转&#xff09; 通过控制反转&#xff08;创建对象的权限交给框架&#xff0c;所以叫反转&#xff09;创建的对象被称为Spring Bean&#xff0c;这个Bean和用new创建出来的对象是没有任何区别的。 官…

排序算法第三辑——交换排序

目录 ​编辑 一&#xff0c;交换排序算法的简介 二&#xff0c;冒泡排序 冒泡排序代码&#xff1a;排升序 三&#xff0c;快速排序 1.霍尔大佬写的快速排序 2.挖坑法 3.前后指针法 四&#xff0c;以上代码的缺陷与改正方法 三数取中 三路划分&#xff1a; 五&#…

真的绝了,通过注释来埋点好简单!!

目录 回顾 开始 插件编写 功能一 功能二 功能三 合并功能 运行代码 总结 这篇文章主要讲如何根据注释&#xff0c;通过babel插件自动地&#xff0c;给相应函数插入埋点代码&#xff0c;在实现埋点逻辑和业务逻辑分离的基础上&#xff0c;配置更加灵活 回顾 上篇文章…

微服务系列文章之 Springboot应用在k8s集群中配置的使用

Docker部署其实也可以再docker run或者dockerfile里面&#xff0c;将配置文件目录映射到宿主机&#xff0c;然后通过宿主机配置文件修改参数。 FROM docker.io/python:3.6MAINTAINER tianye # 设置容器时间 RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&am…

Windows安装Oh-My-Posh美化Powershell

Windows Terminal&#xff1a;https://www.microsoft.com/store/productId/9N0DX20HK701 最新Powershell下载&#xff1a;https://github.com/PowerShell/PowerShell/releases Oh-My-Posh官网&#xff1a;https://ohmyposh.dev/ Nerd字体下载&#xff1a;https://www.nerdfonts…

Git源代码管理方案

背景 现阶段的Git源代码管理上有一些漏洞&#xff0c;导致在每次上线发布的时间长、出问题&#xff0c;对整体产品的进度有一定的影响。 作用 新的Git源代码管理方案有以下作用&#xff1a; 多功能并行开发时&#xff0c;测试人员可以根据需求任务分配测试自己的功能&#…